Compare commits

..

5 Commits

Author SHA1 Message Date
won
c9ff87229c skip imagegen code mode app-server test on windows 2026-06-02 15:19:44 -07:00
won
7266686103 fix imagegen code mode test runtime 2026-06-02 14:51:16 -07:00
won
9d98f6cf96 Merge remote-tracking branch 'origin/main' into codemode_imagegenext 2026-06-02 14:12:08 -07:00
won
3f51cc1806 integration tests 2026-06-02 13:56:13 -07:00
won
4fc3f11dee draft 2026-06-02 12:48:56 -07:00
29 changed files with 131 additions and 331 deletions

View File

@@ -4916,23 +4916,6 @@
}
]
},
"TurnModerationMetadataNotification": {
"properties": {
"metadata": true,
"threadId": {
"type": "string"
},
"turnId": {
"type": "string"
}
},
"required": [
"metadata",
"threadId",
"turnId"
],
"type": "object"
},
"TurnPlanStep": {
"properties": {
"status": {
@@ -6272,26 +6255,6 @@
"title": "Model/verificationNotification",
"type": "object"
},
{
"properties": {
"method": {
"enum": [
"turn/moderationMetadata"
],
"title": "Turn/moderationMetadataNotificationMethod",
"type": "string"
},
"params": {
"$ref": "#/definitions/TurnModerationMetadataNotification"
}
},
"required": [
"method",
"params"
],
"title": "Turn/moderationMetadataNotification",
"type": "object"
},
{
"properties": {
"method": {

View File

@@ -4904,26 +4904,6 @@
"title": "Model/verificationNotification",
"type": "object"
},
{
"properties": {
"method": {
"enum": [
"turn/moderationMetadata"
],
"title": "Turn/moderationMetadataNotificationMethod",
"type": "string"
},
"params": {
"$ref": "#/definitions/v2/TurnModerationMetadataNotification"
}
},
"required": [
"method",
"params"
],
"title": "Turn/moderationMetadataNotification",
"type": "object"
},
{
"properties": {
"method": {
@@ -18503,25 +18483,6 @@
}
]
},
"TurnModerationMetadataNotification": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"metadata": true,
"threadId": {
"type": "string"
},
"turnId": {
"type": "string"
}
},
"required": [
"metadata",
"threadId",
"turnId"
],
"title": "TurnModerationMetadataNotification",
"type": "object"
},
"TurnPlanStep": {
"properties": {
"status": {

View File

@@ -12302,26 +12302,6 @@
"title": "Model/verificationNotification",
"type": "object"
},
{
"properties": {
"method": {
"enum": [
"turn/moderationMetadata"
],
"title": "Turn/moderationMetadataNotificationMethod",
"type": "string"
},
"params": {
"$ref": "#/definitions/TurnModerationMetadataNotification"
}
},
"required": [
"method",
"params"
],
"title": "Turn/moderationMetadataNotification",
"type": "object"
},
{
"properties": {
"method": {
@@ -16320,25 +16300,6 @@
}
]
},
"TurnModerationMetadataNotification": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"metadata": true,
"threadId": {
"type": "string"
},
"turnId": {
"type": "string"
}
},
"required": [
"metadata",
"threadId",
"turnId"
],
"title": "TurnModerationMetadataNotification",
"type": "object"
},
"TurnPlanStep": {
"properties": {
"status": {

View File

@@ -1,19 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"metadata": true,
"threadId": {
"type": "string"
},
"turnId": {
"type": "string"
}
},
"required": [
"metadata",
"threadId",
"turnId"
],
"title": "TurnModerationMetadataNotification",
"type": "object"
}

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +0,0 @@
// GENERATED CODE! DO NOT MODIFY BY HAND!
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { JsonValue } from "../serde_json/JsonValue";
export type TurnModerationMetadataNotification = { threadId: string, turnId: string, metadata: JsonValue, };

View File

@@ -445,7 +445,6 @@ export type { TurnError } from "./TurnError";
export type { TurnInterruptParams } from "./TurnInterruptParams";
export type { TurnInterruptResponse } from "./TurnInterruptResponse";
export type { TurnItemsView } from "./TurnItemsView";
export type { TurnModerationMetadataNotification } from "./TurnModerationMetadataNotification";
export type { TurnPlanStep } from "./TurnPlanStep";
export type { TurnPlanStepStatus } from "./TurnPlanStepStatus";
export type { TurnPlanUpdatedNotification } from "./TurnPlanUpdatedNotification";

View File

@@ -1537,7 +1537,6 @@ server_notification_definitions! {
ContextCompacted => "thread/compacted" (v2::ContextCompactedNotification),
ModelRerouted => "model/rerouted" (v2::ModelReroutedNotification),
ModelVerification => "model/verification" (v2::ModelVerificationNotification),
TurnModerationMetadata => "turn/moderationMetadata" (v2::TurnModerationMetadataNotification),
Warning => "warning" (v2::WarningNotification),
GuardianWarning => "guardianWarning" (v2::GuardianWarningNotification),
DeprecationNotice => "deprecationNotice" (v2::DeprecationNoticeNotification),

View File

@@ -8,7 +8,6 @@ use codex_protocol::protocol::ModelVerification as CoreModelVerification;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use serde_json::Value as JsonValue;
use ts_rs::TS;
v2_enum_from_core!(
@@ -153,12 +152,3 @@ pub struct ModelVerificationNotification {
pub turn_id: String,
pub verifications: Vec<ModelVerification>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct TurnModerationMetadataNotification {
pub thread_id: String,
pub turn_id: String,
pub metadata: JsonValue,
}

View File

@@ -1242,7 +1242,6 @@ The app-server streams JSON-RPC notifications while a turn is running. Each turn
- `turn/plan/updated``{ turnId, explanation?, plan }` whenever the agent shares or changes its plan; each `plan` entry is `{ step, status }` with `status` in `pending`, `inProgress`, or `completed`.
- `model/rerouted``{ threadId, turnId, fromModel, toModel, reason }` when the backend reroutes a request to a different model (for example, due to high-risk cyber safety checks).
- `model/verification``{ threadId, turnId, verifications }` when the backend flags additional account verification, such as `trustedAccessForCyber`.
- `turn/moderationMetadata``{ threadId, turnId, metadata }` when a first-party backend supplies turn-scoped moderation metadata for client-side presentation.
Today both notifications carry an empty `items` array even when item events were streamed; rely on `item/*` notifications for the canonical item list until this is fixed.

View File

@@ -75,7 +75,6 @@ use codex_app_server_protocol::TurnDiffUpdatedNotification;
use codex_app_server_protocol::TurnError;
use codex_app_server_protocol::TurnInterruptResponse;
use codex_app_server_protocol::TurnItemsView;
use codex_app_server_protocol::TurnModerationMetadataNotification;
use codex_app_server_protocol::TurnPlanStep;
use codex_app_server_protocol::TurnPlanUpdatedNotification;
use codex_app_server_protocol::TurnStartedNotification;
@@ -338,16 +337,6 @@ pub(crate) async fn apply_bespoke_event_handling(
.send_server_notification(ServerNotification::ModelVerification(notification))
.await;
}
EventMsg::TurnModerationMetadata(event) => {
let notification = TurnModerationMetadataNotification {
thread_id: conversation_id.to_string(),
turn_id: event_turn_id.clone(),
metadata: event.metadata,
};
outgoing
.send_server_notification(ServerNotification::TurnModerationMetadata(notification))
.await;
}
EventMsg::RealtimeConversationStarted(event) => {
let notification = ThreadRealtimeStartedNotification {
thread_id: conversation_id.to_string(),

View File

@@ -725,7 +725,6 @@ mod tests {
use codex_app_server_protocol::RateLimitWindow;
use codex_app_server_protocol::ServerResponse;
use codex_app_server_protocol::ToolRequestUserInputParams;
use codex_app_server_protocol::TurnModerationMetadataNotification;
use codex_protocol::ThreadId;
use pretty_assertions::assert_eq;
use serde_json::json;
@@ -952,31 +951,6 @@ mod tests {
);
}
#[test]
fn verify_turn_moderation_metadata_notification_serialization() {
let notification =
ServerNotification::TurnModerationMetadata(TurnModerationMetadataNotification {
thread_id: "thread-1".to_string(),
turn_id: "turn-1".to_string(),
metadata: json!({"presentation": "inline"}),
});
let jsonrpc_notification = OutgoingMessage::AppServerNotification(notification);
assert_eq!(
json!({
"method": "turn/moderationMetadata",
"params": {
"threadId": "thread-1",
"turnId": "turn-1",
"metadata": {"presentation": "inline"},
},
}),
serde_json::to_value(jsonrpc_notification)
.expect("ensure the notification serializes correctly"),
"ensure the notification serializes correctly"
);
}
#[test]
fn server_request_response_from_result_decodes_typed_response() {
let request = ServerRequest::CommandExecutionRequestApproval {

View File

@@ -30,6 +30,12 @@ use wiremock::matchers::path;
const RESULT: &str = "cG5n";
#[derive(Clone, Copy)]
enum ImagegenTestMode {
Direct,
CodeModeOnly,
}
// macOS and Windows Bazel CI can spend tens of seconds starting app-server
// subprocesses or processing test RPCs under load.
#[cfg(any(target_os = "macos", windows))]
@@ -69,7 +75,7 @@ async fn standalone_image_generation_persists_image_and_returns_it_to_model() ->
.await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
create_config_toml(codex_home.path(), &server.uri(), ImagegenTestMode::Direct)?;
write_chatgpt_auth(
codex_home.path(),
ChatGptAuthFixture::new("access-chatgpt"),
@@ -79,34 +85,7 @@ async fn standalone_image_generation_persists_image_and_returns_it_to_model() ->
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
.send_thread_start_request(ThreadStartParams::default())
.await?;
let thread_resp: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_response_message(RequestId::Integer(thread_req)),
)
.await??;
let ThreadStartResponse { thread, .. } = to_response::<ThreadStartResponse>(thread_resp)?;
let turn_req = mcp
.send_turn_start_request(TurnStartParams {
thread_id: thread.id,
client_user_message_id: None,
input: vec![V2UserInput::Text {
text: "Generate an image".to_string(),
text_elements: Vec::new(),
}],
..Default::default()
})
.await?;
let turn_resp: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_response_message(RequestId::Integer(turn_req)),
)
.await??;
let _turn: TurnStartResponse = to_response::<TurnStartResponse>(turn_resp)?;
start_image_generation_turn(&mut mcp).await?;
let completed = timeout(
DEFAULT_READ_TIMEOUT,
@@ -157,6 +136,110 @@ async fn standalone_image_generation_persists_image_and_returns_it_to_model() ->
Ok(())
}
#[cfg_attr(windows, ignore = "covered by Linux and macOS CI")]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn standalone_image_generation_is_callable_from_code_mode_only() -> Result<()> {
let call_id = "code-mode-image-run-1";
let server = responses::start_mock_server().await;
mount_image_response(&server).await;
let response_mock = responses::mount_sse_sequence(
&server,
vec![
responses::sse(vec![
responses::ev_response_created("resp-1"),
responses::ev_custom_tool_call(
call_id,
"exec",
r#"
const result = await tools.image_gen__imagegen({
action: "generate",
prompt: "paint a blue whale",
});
image(result);
"#,
),
responses::ev_completed("resp-1"),
]),
responses::sse(vec![
responses::ev_assistant_message("msg-1", "Done"),
responses::ev_completed("resp-2"),
]),
],
)
.await;
let codex_home = TempDir::new()?;
create_config_toml(
codex_home.path(),
&server.uri(),
ImagegenTestMode::CodeModeOnly,
)?;
write_chatgpt_auth(
codex_home.path(),
ChatGptAuthFixture::new("access-chatgpt"),
AuthCredentialsStoreMode::File,
)?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
start_image_generation_turn(&mut mcp).await?;
timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_notification_message("turn/completed"),
)
.await??;
let requests = response_mock.requests();
assert_eq!(requests.len(), 2);
assert!(requests[0].body_contains_text("image_gen__imagegen"));
let output = requests[1].custom_tool_call_output(call_id);
assert_eq!(
output["output"][1],
json!({
"type": "input_image",
"image_url": format!("data:image/png;base64,{RESULT}"),
"detail": "high",
})
);
assert_eq!(output["output"].as_array().map(Vec::len), Some(2));
Ok(())
}
async fn start_image_generation_turn(mcp: &mut TestAppServer) -> Result<()> {
let thread_req = mcp
.send_thread_start_request(ThreadStartParams::default())
.await?;
let thread_resp: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_response_message(RequestId::Integer(thread_req)),
)
.await??;
let ThreadStartResponse { thread, .. } = to_response::<ThreadStartResponse>(thread_resp)?;
let turn_req = mcp
.send_turn_start_request(TurnStartParams {
thread_id: thread.id,
client_user_message_id: None,
input: vec![V2UserInput::Text {
text: "Generate an image".to_string(),
text_elements: Vec::new(),
}],
..Default::default()
})
.await?;
let turn_resp: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_response_message(RequestId::Integer(turn_req)),
)
.await??;
let _turn: TurnStartResponse = to_response::<TurnStartResponse>(turn_resp)?;
Ok(())
}
async fn wait_for_image_generation_completed(
mcp: &mut TestAppServer,
) -> Result<ItemCompletedNotification> {
@@ -187,7 +270,15 @@ async fn mount_image_response(server: &MockServer) {
.await;
}
fn create_config_toml(codex_home: &Path, server_uri: &str) -> std::io::Result<()> {
fn create_config_toml(
codex_home: &Path,
server_uri: &str,
mode: ImagegenTestMode,
) -> std::io::Result<()> {
let code_mode_only = match mode {
ImagegenTestMode::Direct => "",
ImagegenTestMode::CodeModeOnly => "code_mode_only = true",
};
std::fs::write(
codex_home.join("config.toml"),
format!(
@@ -200,6 +291,7 @@ chatgpt_base_url = "{server_uri}"
[features]
imagegenext = true
{code_mode_only}
[model_providers.openai-custom]
name = "OpenAI"

View File

@@ -17,7 +17,7 @@ mod experimental_feature_list;
mod external_agent_config;
mod fs;
mod hooks_list;
mod image_generation;
mod imagegen_extension;
mod initialize;
mod marketplace_add;
mod marketplace_remove;

View File

@@ -6,7 +6,6 @@ use codex_protocol::openai_models::ReasoningEffort as ReasoningEffortConfig;
use codex_protocol::protocol::ModelVerification;
use codex_protocol::protocol::RateLimitSnapshot;
use codex_protocol::protocol::TokenUsage;
use codex_protocol::protocol::TurnModerationMetadataEvent;
use codex_protocol::protocol::W3cTraceContext;
use futures::Stream;
use serde::Deserialize;
@@ -79,8 +78,6 @@ pub enum ResponseEvent {
ServerModel(String),
/// Emitted when the server recommends additional account verification.
ModelVerifications(Vec<ModelVerification>),
/// Emitted when the server includes moderation metadata for first-party turn presentation.
TurnModerationMetadata(TurnModerationMetadataEvent),
/// Emitted when `X-Reasoning-Included: true` is present on the response,
/// meaning the server already accounted for past reasoning tokens and the
/// client should not re-estimate them.

View File

@@ -718,7 +718,6 @@ async fn run_websocket_response_stream(
}
};
let model_verifications = event.model_verifications();
let turn_moderation_metadata = event.turn_moderation_metadata();
if event.kind() == "codex.rate_limits" {
if let Some(snapshot) = parse_rate_limit_event(&text) {
let _ = tx_event.send(Ok(ResponseEvent::RateLimits(snapshot))).await;
@@ -743,16 +742,6 @@ async fn run_websocket_response_stream(
"response event consumer dropped".to_string(),
));
}
if let Some(metadata) = turn_moderation_metadata
&& tx_event
.send(Ok(ResponseEvent::TurnModerationMetadata(metadata)))
.await
.is_err()
{
return Err(ApiError::Stream(
"response event consumer dropped".to_string(),
));
}
match process_responses_event(event) {
Ok(Some(event)) => {
let is_completed = matches!(event, ResponseEvent::Completed { .. });

View File

@@ -8,7 +8,6 @@ use codex_client::StreamResponse;
use codex_protocol::models::ResponseItem;
use codex_protocol::protocol::ModelVerification;
use codex_protocol::protocol::TokenUsage;
use codex_protocol::protocol::TurnModerationMetadataEvent;
use eventsource_stream::Eventsource;
use futures::StreamExt;
use serde::Deserialize;
@@ -194,18 +193,6 @@ impl ResponsesStreamEvent {
.and_then(|metadata| metadata.get("openai_verification_recommendation"))
.and_then(model_verifications_from_json_value)
}
pub(crate) fn turn_moderation_metadata(&self) -> Option<TurnModerationMetadataEvent> {
if self.kind() != "response.metadata" {
return None;
}
self.metadata
.as_ref()
.and_then(|metadata| metadata.get("openai_chatgpt_moderation_metadata"))
.cloned()
.map(|metadata| TurnModerationMetadataEvent { metadata })
}
}
fn header_openai_model_value_from_json(value: &Value) -> Option<String> {
@@ -457,7 +444,6 @@ pub async fn process_sse(
}
};
let model_verifications = event.model_verifications();
let turn_moderation_metadata = event.turn_moderation_metadata();
if let Some(model) = event.response_model()
&& last_server_model.as_deref() != Some(model.as_str())
@@ -479,14 +465,6 @@ pub async fn process_sse(
{
return;
}
if let Some(metadata) = turn_moderation_metadata
&& tx_event
.send(Ok(ResponseEvent::TurnModerationMetadata(metadata)))
.await
.is_err()
{
return;
}
match process_responses_event(event) {
Ok(Some(event)) => {
@@ -1237,41 +1215,6 @@ mod tests {
);
}
#[tokio::test]
async fn process_sse_emits_turn_moderation_metadata_field() {
let events = run_sse(vec![
json!({
"type": "response.metadata",
"metadata": {
"openai_chatgpt_moderation_metadata": {
"presentation": "inline"
}
}
}),
json!({
"type": "response.completed",
"response": {
"id": "resp-1"
}
}),
])
.await;
assert_matches!(
&events[0],
ResponseEvent::TurnModerationMetadata(result)
if result.metadata == json!({"presentation": "inline"})
);
assert_matches!(
&events[1],
ResponseEvent::Completed {
response_id,
token_usage: None,
end_turn: None,
} if response_id == "resp-1"
);
}
#[test]
fn responses_stream_event_response_model_reads_top_level_headers() {
let ev: ResponsesStreamEvent = serde_json::from_value(json!({

View File

@@ -20,6 +20,7 @@ use codex_protocol::protocol::EventMsg;
use codex_protocol::protocol::InitialHistory;
use codex_protocol::protocol::Op;
use codex_protocol::protocol::RolloutItem;
use codex_protocol::protocol::SandboxPolicy;
use codex_protocol::protocol::SessionSource;
use codex_protocol::protocol::SubAgentSource;
use codex_protocol::protocol::TokenUsage;
@@ -718,7 +719,9 @@ async fn run_review_on_session(
.total_token_usage()
.await
.unwrap_or_default();
// The legacy SandboxPolicy should match the PermissionProfile.
let guardian_permission_profile = PermissionProfile::read_only();
let legacy_sandbox_policy = SandboxPolicy::new_read_only_policy();
let submit_result = run_before_review_deadline(
deadline,
@@ -733,7 +736,7 @@ async fn run_review_on_session(
#[allow(deprecated)]
cwd: Some(params.parent_turn.cwd.to_path_buf()),
approval_policy: Some(AskForApproval::Never),
sandbox_policy: None,
sandbox_policy: Some(legacy_sandbox_policy),
permission_profile: Some(guardian_permission_profile),
summary: Some(params.reasoning_summary),
personality: params.personality,

View File

@@ -359,7 +359,6 @@ use codex_protocol::protocol::ThreadMemoryMode;
use codex_protocol::protocol::TokenCountEvent;
use codex_protocol::protocol::TokenUsage;
use codex_protocol::protocol::TokenUsageInfo;
use codex_protocol::protocol::TurnModerationMetadataEvent;
use codex_protocol::protocol::WarningEvent;
use codex_protocol::user_input::UserInput;
use codex_tools::ToolEnvironmentMode;
@@ -2629,15 +2628,6 @@ impl Session {
.await;
}
pub(crate) async fn emit_turn_moderation_metadata(
self: &Arc<Self>,
turn_context: &Arc<TurnContext>,
metadata: TurnModerationMetadataEvent,
) {
self.send_event(turn_context, EventMsg::TurnModerationMetadata(metadata))
.await;
}
pub(crate) async fn replace_history(
&self,
items: Vec<ResponseItem>,

View File

@@ -1322,7 +1322,6 @@ pub(super) fn realtime_text_for_event(msg: &EventMsg) -> Option<String> {
| EventMsg::RealtimeConversationClosed(_)
| EventMsg::ModelReroute(_)
| EventMsg::ModelVerification(_)
| EventMsg::TurnModerationMetadata(_)
| EventMsg::ContextCompacted(_)
| EventMsg::ThreadRolledBack(_)
| EventMsg::TurnStarted(_)
@@ -1988,10 +1987,6 @@ async fn try_run_sampling_request(
.await;
}
}
ResponseEvent::TurnModerationMetadata(metadata) => {
sess.emit_turn_moderation_metadata(&turn_context, metadata)
.await;
}
ResponseEvent::ServerReasoningIncluded(included) => {
sess.set_server_reasoning_included(included).await;
}

View File

@@ -147,7 +147,6 @@ fn response_event_records_turn_ttft(event: &ResponseEvent) -> bool {
ResponseEvent::Created
| ResponseEvent::ServerModel(_)
| ResponseEvent::ModelVerifications(_)
| ResponseEvent::TurnModerationMetadata(_)
| ResponseEvent::ServerReasoningIncluded(_)
| ResponseEvent::ToolCallInputDelta { .. }
| ResponseEvent::Completed { .. }

View File

@@ -77,9 +77,9 @@ impl ToolExecutor<ToolCall> for ImageGenerationTool {
imagegen_tool_spec()
}
/// Keeps this model-facing tool out of the nested code-mode tool surface.
/// Exposes image generation directly and through the nested code-mode tool surface.
fn exposure(&self) -> ToolExposure {
ToolExposure::DirectModelOnly
ToolExposure::Direct
}
/// Executes the selected image operation and returns the completed image result.

View File

@@ -266,8 +266,7 @@ async fn run_codex_tool_session_inner(
}
EventMsg::Warning(_)
| EventMsg::GuardianWarning(_)
| EventMsg::ModelVerification(_)
| EventMsg::TurnModerationMetadata(_) => {
| EventMsg::ModelVerification(_) => {
continue;
}
EventMsg::GuardianAssessment(_) => {

View File

@@ -1177,7 +1177,6 @@ impl SessionTelemetry {
}
ResponseEvent::ServerModel(_) => "server_model".into(),
ResponseEvent::ModelVerifications(_) => "model_verifications".into(),
ResponseEvent::TurnModerationMetadata(_) => "turn_moderation_metadata".into(),
ResponseEvent::ServerReasoningIncluded(_) => "server_reasoning_included".into(),
ResponseEvent::RateLimits(_) => "rate_limits".into(),
ResponseEvent::ModelsEtag(_) => "models_etag".into(),

View File

@@ -1186,9 +1186,6 @@ pub enum EventMsg {
/// Backend recommends additional account verification for this turn.
ModelVerification(ModelVerificationEvent),
/// Backend moderation metadata intended for first-party turn presentation.
TurnModerationMetadata(TurnModerationMetadataEvent),
/// Conversation history was compacted (either automatically or manually).
ContextCompacted(ContextCompactedEvent),
@@ -1853,11 +1850,6 @@ pub struct ModelVerificationEvent {
pub verifications: Vec<ModelVerification>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema, TS)]
pub struct TurnModerationMetadataEvent {
pub metadata: Value,
}
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
pub struct ContextCompactedEvent;

View File

@@ -224,7 +224,6 @@ pub(crate) fn tool_runtime_trace_event(event: &EventMsg) -> Option<ToolRuntimeTr
| EventMsg::RealtimeConversationSdp(_)
| EventMsg::ModelReroute(_)
| EventMsg::ModelVerification(_)
| EventMsg::TurnModerationMetadata(_)
| EventMsg::ContextCompacted(_)
| EventMsg::ThreadRolledBack(_)
| EventMsg::ThreadGoalUpdated(_)
@@ -298,7 +297,6 @@ pub(crate) fn wrapped_protocol_event_type(event: &EventMsg) -> Option<&'static s
| EventMsg::RealtimeConversationSdp(_)
| EventMsg::ModelReroute(_)
| EventMsg::ModelVerification(_)
| EventMsg::TurnModerationMetadata(_)
| EventMsg::ContextCompacted(_)
| EventMsg::ThreadSettingsApplied(_)
| EventMsg::TokenCount(_)

View File

@@ -115,7 +115,6 @@ pub fn should_persist_event_msg(ev: &EventMsg) -> bool {
| EventMsg::RealtimeConversationClosed(_)
| EventMsg::ModelReroute(_)
| EventMsg::ModelVerification(_)
| EventMsg::TurnModerationMetadata(_)
| EventMsg::AgentReasoningSectionBreak(_)
| EventMsg::RawResponseItem(_)
| EventMsg::SessionConfigured(_)

View File

@@ -118,9 +118,6 @@ pub(super) fn server_notification_thread_target(
ServerNotification::ModelVerification(notification) => {
Some(notification.thread_id.as_str())
}
ServerNotification::TurnModerationMetadata(notification) => {
Some(notification.thread_id.as_str())
}
ServerNotification::ThreadRealtimeStarted(notification) => {
Some(notification.thread_id.as_str())
}

View File

@@ -233,7 +233,6 @@ impl ChatWidget {
| ServerNotification::RemoteControlStatusChanged(_)
| ServerNotification::ExternalAgentConfigImportCompleted(_)
| ServerNotification::FsChanged(_)
| ServerNotification::TurnModerationMetadata(_)
| ServerNotification::FuzzyFileSearchSessionUpdated(_)
| ServerNotification::FuzzyFileSearchSessionCompleted(_)
| ServerNotification::ThreadRealtimeTranscriptDelta(_)