mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Emit plugin ID on MCP tool call analytics events (#27483)
MCP tool-call items already carry the runtime-resolved plugin owner, but the analytics reducer dropped that field. Forwarding the existing value provides direct attribution without downstream server-name inference. ## Summary - emit `plugin_id` on `codex_mcp_tool_call_event` payloads - preserve `null` for MCP calls without a plugin owner - verify the serialized field through the MCP item lifecycle test ## Test - `cd codex-rs && just test -p codex-analytics` - `cd codex-rs && just fix -p codex-analytics` - `cd codex-rs && just fmt`
This commit is contained in:
committed by
GitHub
Unverified
parent
1e5b87b4d7
commit
df9dd22248
@@ -3863,6 +3863,32 @@ async fn turn_event_counts_completed_tool_items() {
|
||||
)
|
||||
.await;
|
||||
|
||||
let mcp_tool_call_item = |status, duration_ms| ThreadItem::McpToolCall {
|
||||
id: "mcp-1".to_string(),
|
||||
server: "server".to_string(),
|
||||
tool: "search".to_string(),
|
||||
status,
|
||||
arguments: json!({}),
|
||||
mcp_app_resource_uri: None,
|
||||
plugin_id: Some("sample@test".to_string()),
|
||||
result: None,
|
||||
error: None,
|
||||
duration_ms,
|
||||
};
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::Notification(Box::new(ServerNotification::ItemStarted(
|
||||
ItemStartedNotification {
|
||||
thread_id: "thread-2".to_string(),
|
||||
turn_id: "turn-2".to_string(),
|
||||
started_at_ms: 998,
|
||||
item: mcp_tool_call_item(McpToolCallStatus::InProgress, None),
|
||||
},
|
||||
))),
|
||||
&mut out,
|
||||
)
|
||||
.await;
|
||||
|
||||
let completed_tool_items = vec![
|
||||
sample_command_execution_item(CommandExecutionStatus::Completed, Some(0), Some(1)),
|
||||
ThreadItem::FileChange {
|
||||
@@ -3870,18 +3896,7 @@ async fn turn_event_counts_completed_tool_items() {
|
||||
changes: Vec::new(),
|
||||
status: PatchApplyStatus::Completed,
|
||||
},
|
||||
ThreadItem::McpToolCall {
|
||||
id: "mcp-1".to_string(),
|
||||
server: "server".to_string(),
|
||||
tool: "search".to_string(),
|
||||
status: McpToolCallStatus::Completed,
|
||||
arguments: json!({}),
|
||||
mcp_app_resource_uri: None,
|
||||
plugin_id: None,
|
||||
result: None,
|
||||
error: None,
|
||||
duration_ms: Some(2),
|
||||
},
|
||||
mcp_tool_call_item(McpToolCallStatus::Completed, Some(2)),
|
||||
ThreadItem::DynamicToolCall {
|
||||
id: "dynamic-1".to_string(),
|
||||
namespace: None,
|
||||
@@ -3939,6 +3954,13 @@ async fn turn_event_counts_completed_tool_items() {
|
||||
.await;
|
||||
}
|
||||
|
||||
let mcp_tool_call_event = out
|
||||
.iter()
|
||||
.find(|event| matches!(event, TrackEventRequest::McpToolCall(_)))
|
||||
.expect("MCP tool call event should be emitted");
|
||||
let payload = serde_json::to_value(mcp_tool_call_event).expect("serialize MCP tool call event");
|
||||
assert_eq!(payload["event_params"]["plugin_id"], json!("sample@test"));
|
||||
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::Notification(Box::new(sample_turn_completed_notification(
|
||||
|
||||
@@ -633,6 +633,7 @@ pub(crate) struct CodexMcpToolCallEventParams {
|
||||
pub(crate) mcp_server_name: String,
|
||||
pub(crate) mcp_tool_name: String,
|
||||
pub(crate) mcp_error_present: bool,
|
||||
pub(crate) plugin_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
||||
@@ -1751,6 +1751,7 @@ fn tool_item_event(input: ToolItemEventInput<'_>) -> Option<TrackEventRequest> {
|
||||
status,
|
||||
error,
|
||||
duration_ms,
|
||||
plugin_id,
|
||||
..
|
||||
} => {
|
||||
let (terminal_status, failure_kind) = mcp_tool_call_outcome(status)?;
|
||||
@@ -1780,6 +1781,7 @@ fn tool_item_event(input: ToolItemEventInput<'_>) -> Option<TrackEventRequest> {
|
||||
mcp_server_name: server.clone(),
|
||||
mcp_tool_name: tool.clone(),
|
||||
mcp_error_present: error.is_some(),
|
||||
plugin_id: plugin_id.clone(),
|
||||
},
|
||||
},
|
||||
))
|
||||
|
||||
Reference in New Issue
Block a user