接入DirectProject交互请求事件

将app-server审批与用户输入请求投影为标准运行态事件\n仅转发请求标识,不暴露完整请求载荷
This commit is contained in:
2026-09-15 18:29:16 +08:00
committed by kdletters
parent feb20ee659
commit 48fa394bfc
@@ -563,6 +563,10 @@ enum CodexTurnEvent {
completed: bool,
params: serde_json::Value,
},
Request {
event_type: &'static str,
params: serde_json::Value,
},
RawItem(serde_json::Value),
Terminal(serde_json::Value),
TransportClosed(String),
@@ -919,6 +923,16 @@ fn direct_codex_safe_activity_for_notification(method: &str) -> Option<&'static
}
}
fn direct_codex_request_event_type(method: &str) -> Option<&'static str> {
match method {
"item/fileChange/requestApproval"
| "item/commandExecution/requestApproval"
| "item/permissions/requestApproval" => Some("approval.requested"),
"item/tool/requestUserInput" | "item/mcpToolCall/requestUserInput" => Some("ask.requested"),
_ => None,
}
}
fn direct_codex_intermediate_text_for_notification(
method: &str,
params: &serde_json::Value,
@@ -2964,6 +2978,27 @@ impl CodexAppServerConnection {
);
}
}
Some(CodexTurnEvent::Request { event_type, params }) => {
if self.inner.workspace_mode == CodexAppServerWorkspaceMode::DirectProject {
let request_id = params
.get("requestId")
.and_then(serde_json::Value::as_str)
.or_else(|| params.get("id").and_then(serde_json::Value::as_str))
.filter(|value| !value.is_empty())
.map(str::to_string);
append_direct_thread_event(
&direct_thread_id,
DirectThreadRawEventDraft {
event_type: event_type.to_string(),
turn_id: turn_id.clone(),
item_id: None,
payload: request_id
.map(|id| serde_json::json!({ "requestId": id }))
.unwrap_or_else(|| serde_json::json!({})),
},
);
}
}
Some(CodexTurnEvent::Activity(activity)) => {
if let Some(observer) = direct_observer.as_deref_mut() {
observer(DirectCodexTurnObservation::Activity(activity));
@@ -3508,7 +3543,8 @@ async fn read_game_creator_codex_app_server_stdout(
| "item/completed"
| "rawResponseItem/completed"
| "turn/completed"
) && safe_activity.is_none()
) && direct_codex_request_event_type(method).is_none()
&& safe_activity.is_none()
&& intermediate_text.is_none()
{
continue;
@@ -3594,6 +3630,13 @@ async fn read_game_creator_codex_app_server_stdout(
.cloned()
.unwrap_or(serde_json::Value::Null),
),
method if direct_codex_request_event_type(method).is_some() => {
CodexTurnEvent::Request {
event_type: direct_codex_request_event_type(method)
.expect("request event type checked above"),
params,
}
}
_ => CodexTurnEvent::Terminal(params),
}
};