对齐 Codex CLI 0.159.3 的通用画像、模型能力与原生协议

This commit is contained in:
MMEXA
2026-10-01 17:54:04 +08:00
parent 54fbcc25a1
commit 14befeda2c
38 changed files with 1938 additions and 383 deletions
+1
View File
@@ -10,6 +10,7 @@ description = "Pure AI API format, surface, planning, and finalize logic for Aet
aether-contracts.workspace = true
base64.workspace = true
http.workspace = true
os_info = { version = "=3.12.0", default-features = false }
regex.workspace = true
serde.workspace = true
serde_json.workspace = true
+21 -5
View File
@@ -1,4 +1,6 @@
use std::sync::{OnceLock, RwLock};
use std::sync::{LazyLock, OnceLock, RwLock};
static OS_INFO: LazyLock<os_info::Info> = LazyLock::new(os_info::get);
/// 当前支持的 Codex 客户端类型。
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@@ -32,7 +34,19 @@ impl CodexClientProfile {
Ok(Self {
client_kind: CodexClientKind::Cli,
codex_version: version.to_owned(),
user_agent: format!("{}/{}", originator, version),
// 按 CLI 格式使用当前网关的公开平台信息。无客户端终端时使用官方
// unknown 标识,不复制调用方终端后缀、安装标识或个人身份。
user_agent: format!(
"{}/{} ({} {}; {}) unknown",
originator,
version,
OS_INFO.os_type(),
OS_INFO.version(),
OS_INFO.architecture().unwrap_or(std::env::consts::ARCH),
)
.chars()
.map(|ch| if matches!(ch, ' '..='~') { ch } else { '_' })
.collect(),
originator,
})
}
@@ -40,8 +54,8 @@ impl CodexClientProfile {
impl Default for CodexClientProfile {
fn default() -> Self {
// 远程发布检查不可用时仍保持现有线上行为,避免启动或请求被版本服务拖住。
Self::cli("0.153.4").expect("built-in Codex CLI profile must be valid")
// 最新已核验稳定版本;后台版本刷新继续作为版本真源。
Self::cli("0.159.3").expect("built-in Codex CLI profile must be valid")
}
}
@@ -97,7 +111,9 @@ mod tests {
let profile = CodexClientProfile::cli("0.200.1").expect("valid version");
assert_eq!(profile.client_kind, CodexClientKind::Cli);
assert_eq!(profile.originator, "codex_cli_rs");
assert_eq!(profile.user_agent, "codex_cli_rs/0.200.1");
assert!(profile.user_agent.starts_with("codex_cli_rs/0.200.1 ("));
assert!(profile.user_agent.ends_with(") unknown"));
assert!(profile.user_agent.contains(std::env::consts::ARCH));
}
#[test]
@@ -22,7 +22,7 @@ pub use plan_kinds::{
GEMINI_INTERACTIONS_SYNC_PLAN_KIND, GEMINI_VIDEO_CANCEL_SYNC_PLAN_KIND,
GEMINI_VIDEO_CREATE_SYNC_PLAN_KIND, OPENAI_CHAT_STREAM_PLAN_KIND, OPENAI_CHAT_SYNC_PLAN_KIND,
OPENAI_EMBEDDING_SYNC_PLAN_KIND, OPENAI_IMAGE_STREAM_PLAN_KIND, OPENAI_IMAGE_SYNC_PLAN_KIND,
OPENAI_REALTIME_STREAM_PLAN_KIND, OPENAI_RERANK_SYNC_PLAN_KIND,
OPENAI_MEMORIES_SYNC_PLAN_KIND, OPENAI_REALTIME_STREAM_PLAN_KIND, OPENAI_RERANK_SYNC_PLAN_KIND,
OPENAI_RESPONSES_COMPACT_STREAM_PLAN_KIND, OPENAI_RESPONSES_COMPACT_SYNC_PLAN_KIND,
OPENAI_RESPONSES_STREAM_PLAN_KIND, OPENAI_RESPONSES_SYNC_PLAN_KIND,
OPENAI_SEARCH_SYNC_PLAN_KIND, OPENAI_VIDEO_CANCEL_SYNC_PLAN_KIND,
@@ -49,7 +49,8 @@ pub use report_kinds::{
OPENAI_EMBEDDING_SYNC_ERROR_REPORT_KIND, OPENAI_EMBEDDING_SYNC_FINALIZE_REPORT_KIND,
OPENAI_EMBEDDING_SYNC_SUCCESS_REPORT_KIND, OPENAI_IMAGE_STREAM_SUCCESS_REPORT_KIND,
OPENAI_IMAGE_SYNC_ERROR_REPORT_KIND, OPENAI_IMAGE_SYNC_FINALIZE_REPORT_KIND,
OPENAI_IMAGE_SYNC_SUCCESS_REPORT_KIND, OPENAI_RESPONSES_COMPACT_STREAM_SUCCESS_REPORT_KIND,
OPENAI_IMAGE_SYNC_SUCCESS_REPORT_KIND, OPENAI_MEMORIES_SYNC_SUCCESS_REPORT_KIND,
OPENAI_RESPONSES_COMPACT_STREAM_SUCCESS_REPORT_KIND,
OPENAI_RESPONSES_COMPACT_SYNC_ERROR_REPORT_KIND,
OPENAI_RESPONSES_COMPACT_SYNC_FINALIZE_REPORT_KIND,
OPENAI_RESPONSES_COMPACT_SYNC_SUCCESS_REPORT_KIND, OPENAI_RESPONSES_STREAM_SUCCESS_REPORT_KIND,
@@ -5,6 +5,7 @@ pub const GEMINI_FILES_DELETE_PLAN_KIND: &str = "gemini_files_delete";
pub const GEMINI_FILES_DOWNLOAD_PLAN_KIND: &str = "gemini_files_download";
pub const OPENAI_IMAGE_STREAM_PLAN_KIND: &str = "openai_image_stream";
pub const OPENAI_IMAGE_SYNC_PLAN_KIND: &str = "openai_image_sync";
pub const OPENAI_MEMORIES_SYNC_PLAN_KIND: &str = "openai_memories_sync";
pub const OPENAI_VIDEO_CONTENT_PLAN_KIND: &str = "openai_video_content";
pub const OPENAI_VIDEO_CANCEL_SYNC_PLAN_KIND: &str = "openai_video_cancel_sync";
pub const OPENAI_VIDEO_REMIX_SYNC_PLAN_KIND: &str = "openai_video_remix_sync";
@@ -31,6 +31,8 @@ pub const OPENAI_RESPONSES_COMPACT_SYNC_SUCCESS_REPORT_KIND: &str =
"openai_responses_compact_sync_success";
pub const OPENAI_EMBEDDING_SYNC_SUCCESS_REPORT_KIND: &str = "openai_embedding_sync_success";
pub const OPENAI_SEARCH_SYNC_SUCCESS_REPORT_KIND: &str = "openai_search_sync_success";
pub const OPENAI_MEMORIES_SYNC_FINALIZE_REPORT_KIND: &str = "openai_memories_sync_finalize";
pub const OPENAI_MEMORIES_SYNC_SUCCESS_REPORT_KIND: &str = "openai_memories_sync_success";
pub const GEMINI_EMBEDDING_SYNC_SUCCESS_REPORT_KIND: &str = "gemini_embedding_sync_success";
pub const OPENAI_IMAGE_SYNC_SUCCESS_REPORT_KIND: &str = "openai_image_sync_success";
pub const CLAUDE_CLI_SYNC_SUCCESS_REPORT_KIND: &str = "claude_cli_sync_success";
@@ -62,6 +64,9 @@ pub const GEMINI_CLI_SYNC_ERROR_REPORT_KIND: &str = "gemini_cli_sync_error";
pub fn implicit_sync_finalize_report_kind(plan_kind: &str) -> Option<&'static str> {
match plan_kind {
super::plan_kinds::OPENAI_MEMORIES_SYNC_PLAN_KIND => {
Some(OPENAI_MEMORIES_SYNC_FINALIZE_REPORT_KIND)
}
OPENAI_CHAT_SYNC_PLAN_KIND => Some(OPENAI_CHAT_SYNC_FINALIZE_REPORT_KIND),
CLAUDE_CHAT_SYNC_PLAN_KIND => Some(CLAUDE_CHAT_SYNC_FINALIZE_REPORT_KIND),
GEMINI_CHAT_SYNC_PLAN_KIND => Some(GEMINI_CHAT_SYNC_FINALIZE_REPORT_KIND),
@@ -80,6 +85,7 @@ pub fn implicit_sync_finalize_report_kind(plan_kind: &str) -> Option<&'static st
pub fn core_error_default_client_api_format(report_kind: &str) -> Option<&'static str> {
match report_kind {
OPENAI_MEMORIES_SYNC_FINALIZE_REPORT_KIND => Some("openai:responses"),
OPENAI_CHAT_SYNC_FINALIZE_REPORT_KIND => Some("openai:chat"),
CLAUDE_CHAT_SYNC_FINALIZE_REPORT_KIND => Some("claude:messages"),
GEMINI_CHAT_SYNC_FINALIZE_REPORT_KIND => Some("gemini:generate_content"),
@@ -98,6 +104,7 @@ pub fn core_error_default_client_api_format(report_kind: &str) -> Option<&'stati
pub fn core_error_background_report_kind(report_kind: &str) -> Option<&'static str> {
match report_kind {
OPENAI_MEMORIES_SYNC_FINALIZE_REPORT_KIND => Some(OPENAI_RESPONSES_SYNC_ERROR_REPORT_KIND),
OPENAI_CHAT_SYNC_FINALIZE_REPORT_KIND => Some(OPENAI_CHAT_SYNC_ERROR_REPORT_KIND),
CLAUDE_CHAT_SYNC_FINALIZE_REPORT_KIND => Some(CLAUDE_CHAT_SYNC_ERROR_REPORT_KIND),
GEMINI_CHAT_SYNC_FINALIZE_REPORT_KIND => Some(GEMINI_CHAT_SYNC_ERROR_REPORT_KIND),
@@ -124,6 +131,7 @@ pub fn core_error_background_report_kind(report_kind: &str) -> Option<&'static s
pub fn core_success_background_report_kind(report_kind: &str) -> Option<&'static str> {
match report_kind {
OPENAI_MEMORIES_SYNC_FINALIZE_REPORT_KIND => Some(OPENAI_MEMORIES_SYNC_SUCCESS_REPORT_KIND),
OPENAI_CHAT_SYNC_FINALIZE_REPORT_KIND => Some(OPENAI_CHAT_SYNC_SUCCESS_REPORT_KIND),
CLAUDE_CHAT_SYNC_FINALIZE_REPORT_KIND => Some(CLAUDE_CHAT_SYNC_SUCCESS_REPORT_KIND),
GEMINI_CHAT_SYNC_FINALIZE_REPORT_KIND => Some(GEMINI_CHAT_SYNC_SUCCESS_REPORT_KIND),
@@ -34,6 +34,7 @@ pub enum ApiOperation {
ClaudeMessagesCreate,
ClaudeCountTokens,
OpenAiResponsesCompact,
OpenAiMemoriesSummarize,
}
impl ApiOperation {
@@ -42,6 +43,7 @@ impl ApiOperation {
Self::ClaudeMessagesCreate => "messages",
Self::ClaudeCountTokens => "count_tokens",
Self::OpenAiResponsesCompact => "compact",
Self::OpenAiMemoriesSummarize => "trace_summarize",
}
}
}
@@ -55,5 +57,9 @@ mod tests {
assert_eq!(ClientSurface::ClaudeCode.as_str(), "claude_code");
assert_eq!(ApiOperation::ClaudeMessagesCreate.as_str(), "messages");
assert_eq!(ApiOperation::ClaudeCountTokens.as_str(), "count_tokens");
assert_eq!(
ApiOperation::OpenAiMemoriesSummarize.as_str(),
"trace_summarize"
);
}
}
@@ -380,149 +380,22 @@ fn bundled_codex_model_card(spec: BundledCodexModelCardSpec<'_>) -> Value {
})
}
fn bundled_gpt_5_6_codex_model_card(
model_id: &str,
display_name: &str,
description: &str,
default_reasoning_level: &str,
priority: u64,
multi_agent_version: &str,
supports_ultra: bool,
) -> Value {
let mut efforts = vec!["low", "medium", "high", "xhigh", "max"];
if supports_ultra {
efforts.push("ultra");
}
let mut card = bundled_codex_model_card(BundledCodexModelCardSpec {
model_id,
display_name,
description,
default_reasoning_level,
default_reasoning_summary: "none",
use_responses_lite: true,
efforts: &efforts,
default_verbosity: "low",
supports_priority_tier: true,
});
let object = card
.as_object_mut()
.expect("bundled Codex model card must be an object");
object.extend(
json!({
"shell_type": "shell_command",
"supports_image_detail_original": true,
"supports_search_tool": true,
"input_modalities": ["text", "image"],
"context_window": 372_000,
"max_context_window": 372_000,
"comp_hash": "3000",
"experimental_supported_tools": [],
"visibility": "list",
"supported_in_api": true,
"priority": priority,
"additional_speed_tiers": ["fast"],
"multi_agent_version": multi_agent_version,
"tool_mode": "code_mode_only",
"prefer_websockets": true,
"reasoning_summary_format": "experimental",
"include_skills_usage_instructions": false,
"apply_patch_tool_type": "freeform",
"web_search_tool_type": "text_and_image",
"truncation_policy": { "mode": "tokens", "limit": 10_000 },
"minimal_client_version": "0.144.0",
})
.as_object()
.expect("bundled Codex model card extension must be an object")
.clone(),
);
card
}
fn bundled_codex_auto_review_model_card() -> Value {
let mut card = bundled_codex_model_card(BundledCodexModelCardSpec {
model_id: "codex-auto-review",
display_name: "Codex Auto Review",
description: "Automatic approval review model for Codex.",
default_reasoning_level: "medium",
default_reasoning_summary: "none",
use_responses_lite: false,
efforts: &["low", "medium", "high", "xhigh"],
default_verbosity: "low",
supports_priority_tier: false,
});
let object = card
.as_object_mut()
.expect("bundled Codex model card must be an object");
object.extend(
json!({
"shell_type": "shell_command",
"supports_image_detail_original": true,
"supports_search_tool": true,
"input_modalities": ["text", "image"],
"context_window": 272_000,
"max_context_window": 1_000_000,
"experimental_supported_tools": [],
"visibility": "hide",
"supported_in_api": true,
"priority": 43,
"additional_speed_tiers": [],
"prefer_websockets": true,
"reasoning_summary_format": "experimental",
"include_skills_usage_instructions": false,
"apply_patch_tool_type": "freeform",
"web_search_tool_type": "text_and_image",
"truncation_policy": { "mode": "tokens", "limit": 10_000 },
"minimal_client_version": "0.98.0",
})
.as_object()
.expect("bundled Codex model card extension must be an object")
.clone(),
);
card
}
pub fn bundled_codex_model_cards() -> &'static [Value] {
static CARDS: OnceLock<Vec<Value>> = OnceLock::new();
CARDS.get_or_init(|| {
vec![
bundled_gpt_5_6_codex_model_card(
"gpt-5.6-sol",
"GPT-5.6-Sol",
"Latest frontier agentic coding model.",
"low",
1,
"v2",
true,
),
bundled_gpt_5_6_codex_model_card(
"gpt-5.6-terra",
"GPT-5.6-Terra",
"Balanced agentic coding model for everyday work.",
"medium",
2,
"v2",
true,
),
bundled_gpt_5_6_codex_model_card(
"gpt-5.6-luna",
"GPT-5.6-Luna",
"Fast and affordable agentic coding model.",
"medium",
3,
"v1",
false,
),
bundled_codex_model_card(BundledCodexModelCardSpec {
model_id: "gpt-5.5",
display_name: "GPT-5.5",
description: "Frontier model for complex coding, research, and real-world work.",
default_reasoning_level: "medium",
default_reasoning_summary: "none",
use_responses_lite: false,
efforts: &["low", "medium", "high", "xhigh"],
default_verbosity: "low",
supports_priority_tier: true,
}),
// 公开能力快照来自 openai/codex rust-v0.159.3 的
// codex-rs/models-manager/models.json;账户远端目录继续优先。
let mut cards: Vec<Value> = serde_json::from_str(include_str!("codex_models_0_159_3.json"))
.expect("bundled Codex model capability snapshot must be valid JSON");
for card in &mut cards {
let object = card.as_object_mut().expect("model card must be an object");
object.insert("id".to_string(), object["slug"].clone());
object.insert("object".to_string(), json!("model"));
object.insert("owned_by".to_string(), json!("openai"));
object.insert("api_formats".to_string(), json!(["openai:responses"]));
}
// 保留现有配置路由使用的旧模型标识。
cards.extend(vec![
bundled_codex_model_card(BundledCodexModelCardSpec {
model_id: "gpt-5.4",
display_name: "GPT-5.4",
@@ -556,8 +429,8 @@ pub fn bundled_codex_model_cards() -> &'static [Value] {
default_verbosity: "low",
supports_priority_tier: false,
}),
bundled_codex_auto_review_model_card(),
]
]);
cards
})
}
@@ -2183,10 +2056,46 @@ mod tests {
#[test]
fn codex_client_user_agent_matches_originator_and_version() {
let profile = crate::codex_client_profile();
assert_eq!(
profile.user_agent,
format!("{}/{}", profile.originator, profile.codex_version)
);
assert!(profile.user_agent.starts_with(&format!(
"{}/{} (",
profile.originator, profile.codex_version
)));
assert!(profile.user_agent.ends_with(") unknown"));
}
#[test]
fn bundled_latest_cli_models_preserve_capabilities_without_account_data() {
for model in ["gpt-6-astra", "gpt-6.1-sol"] {
let card = bundled_codex_model_cards()
.iter()
.find(|card| card["slug"] == model)
.unwrap();
assert_eq!(card["context_window"], 272_000);
assert_eq!(card["max_context_window"], 872_000);
assert_eq!(card["minimal_client_version"], "0.153.0");
assert_eq!(
card["supported_reasoning_levels"]
.as_array()
.unwrap()
.iter()
.map(|level| level["effort"].as_str().unwrap())
.collect::<Vec<_>>(),
["low", "medium", "high", "xhigh", "max", "ultra"]
);
for private in [
"account_id",
"user_id",
"installation_id",
"cookie",
"authorization",
"comp_hash",
] {
assert!(
card.get(private).is_none(),
"unexpected account field: {private}"
);
}
}
}
#[test]
@@ -2824,7 +2733,7 @@ mod tests {
"codex-auto-review",
None,
);
assert!(!capabilities.use_responses_lite);
assert!(capabilities.use_responses_lite);
assert_eq!(
capabilities.default_reasoning_effort.as_deref(),
Some("medium")
@@ -2832,7 +2741,7 @@ mod tests {
assert_eq!(capabilities.default_reasoning_summary, None);
assert!(capabilities.supports_parallel_tool_calls);
assert_eq!(capabilities.default_verbosity.as_deref(), Some("low"));
assert!(capabilities.supported_service_tiers.is_empty());
assert_eq!(capabilities.supported_service_tiers, vec!["priority"]);
}
#[test]
@@ -0,0 +1,952 @@
[
{
"slug": "gpt-6-astra",
"prefer_websockets": true,
"support_verbosity": true,
"default_verbosity": "low",
"apply_patch_tool_type": "freeform",
"web_search_tool_type": "text_and_image",
"input_modalities": [
"text",
"image"
],
"supports_image_detail_original": true,
"truncation_policy": {
"mode": "tokens",
"limit": 10000
},
"supports_parallel_tool_calls": true,
"tool_mode": "code_mode_only",
"multi_agent_version": "v2",
"multi_agent_reasoning_effort": "xhigh",
"use_responses_lite": true,
"supports_reasoning_effort_updates": true,
"include_skills_usage_instructions": false,
"include_apps_usage_instructions": false,
"include_plugin_usage_instructions": false,
"guardian": null,
"node_repl_auto_review_required": true,
"node_repl_disabled": false,
"requires_sandboxed_review": false,
"auto_review_model_override": null,
"model_specialty": null,
"context_window": 272000,
"max_context_window": 872000,
"auto_compact_token_limit": null,
"default_reasoning_summary": "none",
"display_name": "GPT-6-Astra",
"description": "Frontier intelligence for the most demanding work.",
"default_reasoning_level": "low",
"supported_reasoning_levels": [
{
"effort": "low",
"description": "Fast responses with lighter reasoning"
},
{
"effort": "medium",
"description": "Balances speed and reasoning depth for everyday tasks"
},
{
"effort": "high",
"description": "Greater reasoning depth for complex problems"
},
{
"effort": "xhigh",
"description": "Extra high reasoning depth for complex problems"
},
{
"effort": "max",
"description": "Maximum reasoning depth for the hardest problems"
},
{
"effort": "ultra",
"description": "Maximum reasoning with automatic task delegation"
}
],
"shell_type": "shell_command",
"visibility": "list",
"minimal_client_version": "0.153.0",
"supported_in_api": true,
"availability_nux": null,
"upgrade": null,
"priority": 2,
"experimental_supported_tools": [
"send_user_message_async",
"clock"
],
"supports_search_tool": true,
"supports_experimental_context": false,
"default_service_tier": null,
"service_tiers": [
{
"id": "priority",
"name": "Fast",
"description": "2x speed, increased usage"
}
],
"additional_speed_tiers": [
"fast"
],
"supports_reasoning_summary_parameter": true,
"supports_reasoning_summaries": true
},
{
"slug": "gpt-6.1-sol",
"prefer_websockets": true,
"support_verbosity": true,
"default_verbosity": "low",
"apply_patch_tool_type": "freeform",
"web_search_tool_type": "text_and_image",
"input_modalities": [
"text",
"image"
],
"supports_image_detail_original": true,
"truncation_policy": {
"mode": "tokens",
"limit": 10000
},
"supports_parallel_tool_calls": true,
"tool_mode": "code_mode_only",
"multi_agent_version": "v2",
"multi_agent_reasoning_effort": "xhigh",
"use_responses_lite": true,
"include_skills_usage_instructions": false,
"include_apps_usage_instructions": false,
"include_plugin_usage_instructions": false,
"guardian": null,
"node_repl_auto_review_required": true,
"node_repl_disabled": false,
"requires_sandboxed_review": false,
"auto_review_model_override": null,
"model_specialty": null,
"context_window": 272000,
"max_context_window": 872000,
"auto_compact_token_limit": null,
"default_reasoning_summary": "none",
"display_name": "GPT-6.1-Sol",
"description": "Latest workhorse model for coding and everyday work.",
"default_reasoning_level": "low",
"supported_reasoning_levels": [
{
"effort": "low",
"description": "Fast responses with lighter reasoning"
},
{
"effort": "medium",
"description": "Balances speed and reasoning depth for everyday tasks"
},
{
"effort": "high",
"description": "Greater reasoning depth for complex problems"
},
{
"effort": "xhigh",
"description": "Extra high reasoning depth for complex problems"
},
{
"effort": "max",
"description": "Maximum reasoning depth for the hardest problems"
},
{
"effort": "ultra",
"description": "Maximum reasoning with automatic task delegation"
}
],
"shell_type": "shell_command",
"visibility": "list",
"minimal_client_version": "0.153.0",
"supported_in_api": true,
"availability_nux": {
"message": "Maximize usage with GPT-6.1 Sol. Try it on complex work for near-Astra performance at a lower cost."
},
"upgrade": null,
"priority": 1,
"experimental_supported_tools": [
"send_user_message_async",
"clock"
],
"supports_search_tool": true,
"supports_experimental_context": false,
"default_service_tier": null,
"service_tiers": [
{
"id": "priority",
"name": "Fast",
"description": "2x speed, increased usage"
}
],
"additional_speed_tiers": [
"fast"
],
"supports_reasoning_summary_parameter": true,
"supports_reasoning_summaries": true,
"supports_reasoning_effort_updates": true
},
{
"slug": "gpt-6-sol",
"prefer_websockets": true,
"support_verbosity": true,
"default_verbosity": "low",
"apply_patch_tool_type": "freeform",
"web_search_tool_type": "text_and_image",
"input_modalities": [
"text",
"image"
],
"supports_image_detail_original": true,
"truncation_policy": {
"mode": "tokens",
"limit": 10000
},
"supports_parallel_tool_calls": true,
"tool_mode": "code_mode_only",
"multi_agent_version": "v2",
"multi_agent_reasoning_effort": null,
"use_responses_lite": true,
"include_skills_usage_instructions": false,
"include_apps_usage_instructions": false,
"include_plugin_usage_instructions": false,
"guardian": null,
"node_repl_auto_review_required": true,
"node_repl_disabled": false,
"requires_sandboxed_review": false,
"auto_review_model_override": null,
"model_specialty": null,
"context_window": 272000,
"max_context_window": 872000,
"auto_compact_token_limit": null,
"default_reasoning_summary": "none",
"display_name": "GPT-6-Sol",
"description": "Previous generation workhorse model.",
"default_reasoning_level": "medium",
"supported_reasoning_levels": [
{
"effort": "low",
"description": "Fast responses with lighter reasoning"
},
{
"effort": "medium",
"description": "Balances speed and reasoning depth for everyday tasks"
},
{
"effort": "high",
"description": "Greater reasoning depth for complex problems"
},
{
"effort": "xhigh",
"description": "Extra high reasoning depth for complex problems"
},
{
"effort": "max",
"description": "Maximum reasoning depth for the hardest problems"
},
{
"effort": "ultra",
"description": "Maximum reasoning with automatic task delegation"
}
],
"shell_type": "shell_command",
"visibility": "list",
"minimal_client_version": "0.155.0",
"supported_in_api": true,
"availability_nux": null,
"upgrade": null,
"priority": 3,
"experimental_supported_tools": [
"send_user_message_async",
"clock"
],
"supports_search_tool": true,
"supports_experimental_context": false,
"default_service_tier": "priority",
"service_tiers": [
{
"id": "priority",
"name": "Fast",
"description": "1.5x speed"
}
],
"additional_speed_tiers": [
"fast"
],
"supports_reasoning_summary_parameter": true,
"supports_reasoning_summaries": true
},
{
"slug": "gpt-6-luna",
"prefer_websockets": true,
"support_verbosity": true,
"default_verbosity": "low",
"apply_patch_tool_type": "freeform",
"web_search_tool_type": "text_and_image",
"input_modalities": [
"text",
"image"
],
"supports_image_detail_original": true,
"truncation_policy": {
"mode": "tokens",
"limit": 10000
},
"supports_parallel_tool_calls": true,
"tool_mode": "code_mode_only",
"multi_agent_version": "v2",
"multi_agent_reasoning_effort": null,
"use_responses_lite": true,
"include_skills_usage_instructions": false,
"include_apps_usage_instructions": false,
"include_plugin_usage_instructions": false,
"guardian": null,
"node_repl_auto_review_required": false,
"node_repl_disabled": false,
"requires_sandboxed_review": false,
"auto_review_model_override": null,
"model_specialty": null,
"context_window": 272000,
"max_context_window": 872000,
"auto_compact_token_limit": null,
"default_reasoning_summary": "none",
"display_name": "GPT-6-Luna",
"description": "Fast and affordable model for easier tasks.",
"default_reasoning_level": "medium",
"supported_reasoning_levels": [
{
"effort": "low",
"description": "Fast responses with lighter reasoning"
},
{
"effort": "medium",
"description": "Balances speed and reasoning depth for everyday tasks"
},
{
"effort": "high",
"description": "Greater reasoning depth for complex problems"
},
{
"effort": "xhigh",
"description": "Extra high reasoning depth for complex problems"
},
{
"effort": "max",
"description": "Maximum reasoning depth for the hardest problems"
}
],
"shell_type": "shell_command",
"visibility": "list",
"minimal_client_version": "0.155.0",
"supported_in_api": true,
"availability_nux": null,
"upgrade": null,
"priority": 4,
"experimental_supported_tools": [
"send_user_message_async",
"clock"
],
"supports_search_tool": true,
"supports_experimental_context": false,
"default_service_tier": "priority",
"service_tiers": [
{
"id": "priority",
"name": "Fast",
"description": "1.5x speed"
}
],
"additional_speed_tiers": [
"fast"
],
"supports_reasoning_summary_parameter": true,
"supports_reasoning_summaries": true
},
{
"slug": "gpt-5.6-sol",
"prefer_websockets": true,
"support_verbosity": true,
"default_verbosity": "low",
"apply_patch_tool_type": "freeform",
"web_search_tool_type": "text_and_image",
"input_modalities": [
"text",
"image"
],
"supports_image_detail_original": true,
"truncation_policy": {
"mode": "tokens",
"limit": 10000
},
"supports_parallel_tool_calls": true,
"tool_mode": "code_mode_only",
"multi_agent_version": "v2",
"multi_agent_reasoning_effort": null,
"use_responses_lite": true,
"supports_reasoning_effort_updates": false,
"include_skills_usage_instructions": false,
"include_apps_usage_instructions": true,
"include_plugin_usage_instructions": true,
"guardian": null,
"node_repl_auto_review_required": false,
"node_repl_disabled": false,
"requires_sandboxed_review": false,
"auto_review_model_override": null,
"model_specialty": null,
"context_window": 272000,
"max_context_window": 872000,
"auto_compact_token_limit": null,
"default_reasoning_summary": "none",
"display_name": "GPT-5.6-Sol",
"description": "Older generation workhorse model.",
"default_reasoning_level": "low",
"supported_reasoning_levels": [
{
"effort": "low",
"description": "Fast responses with lighter reasoning"
},
{
"effort": "medium",
"description": "Balances speed and reasoning depth for everyday tasks"
},
{
"effort": "high",
"description": "Greater reasoning depth for complex problems"
},
{
"effort": "xhigh",
"description": "Extra high reasoning depth for complex problems"
},
{
"effort": "max",
"description": "Maximum reasoning depth for the hardest problems"
},
{
"effort": "ultra",
"description": "Maximum reasoning with automatic task delegation"
}
],
"shell_type": "shell_command",
"visibility": "list",
"minimal_client_version": "0.144.0",
"supported_in_api": true,
"availability_nux": null,
"upgrade": {
"model": "gpt-6-sol",
"migration_markdown": "Meet GPT-6 Sol\n\nOur latest Sol is more intelligent and more efficient so your usage limits go further. This model is a great daily driver for complex tasks, especially coding.\n",
"retirement_at": null
},
"priority": 5,
"experimental_supported_tools": [],
"supports_search_tool": true,
"supports_experimental_context": false,
"default_service_tier": null,
"service_tiers": [
{
"id": "priority",
"name": "Fast",
"description": "1.5x speed, increased usage"
}
],
"additional_speed_tiers": [
"fast"
],
"supports_reasoning_summary_parameter": true,
"supports_reasoning_summaries": true
},
{
"slug": "gpt-5.6-terra",
"prefer_websockets": true,
"support_verbosity": true,
"default_verbosity": "low",
"apply_patch_tool_type": "freeform",
"web_search_tool_type": "text_and_image",
"input_modalities": [
"text",
"image"
],
"supports_image_detail_original": true,
"truncation_policy": {
"mode": "tokens",
"limit": 10000
},
"supports_parallel_tool_calls": true,
"tool_mode": "code_mode_only",
"multi_agent_version": "v2",
"multi_agent_reasoning_effort": null,
"use_responses_lite": true,
"supports_reasoning_effort_updates": false,
"include_skills_usage_instructions": false,
"include_apps_usage_instructions": true,
"include_plugin_usage_instructions": true,
"guardian": null,
"node_repl_auto_review_required": false,
"node_repl_disabled": false,
"requires_sandboxed_review": false,
"auto_review_model_override": null,
"model_specialty": null,
"context_window": 272000,
"max_context_window": 872000,
"auto_compact_token_limit": null,
"default_reasoning_summary": "none",
"display_name": "GPT-5.6-Terra",
"description": "Older balanced model for straightforward work.",
"default_reasoning_level": "medium",
"supported_reasoning_levels": [
{
"effort": "low",
"description": "Fast responses with lighter reasoning"
},
{
"effort": "medium",
"description": "Balances speed and reasoning depth for everyday tasks"
},
{
"effort": "high",
"description": "Greater reasoning depth for complex problems"
},
{
"effort": "xhigh",
"description": "Extra high reasoning depth for complex problems"
},
{
"effort": "max",
"description": "Maximum reasoning depth for the hardest problems"
},
{
"effort": "ultra",
"description": "Maximum reasoning with automatic task delegation"
}
],
"shell_type": "shell_command",
"visibility": "list",
"minimal_client_version": "0.144.0",
"supported_in_api": true,
"availability_nux": null,
"upgrade": {
"model": "gpt-6-sol",
"migration_markdown": "Meet GPT-6 Sol\n\nOur latest Sol is more intelligent and more efficient so your usage limits go further. This model is a great daily driver for complex tasks, especially coding.\n",
"retirement_at": null
},
"priority": 8,
"experimental_supported_tools": [],
"supports_search_tool": true,
"supports_experimental_context": false,
"default_service_tier": null,
"service_tiers": [
{
"id": "priority",
"name": "Fast",
"description": "1.5x speed, increased usage"
}
],
"additional_speed_tiers": [
"fast"
],
"supports_reasoning_summary_parameter": true,
"supports_reasoning_summaries": true
},
{
"slug": "gpt-5.6-luna",
"prefer_websockets": true,
"support_verbosity": true,
"default_verbosity": "low",
"apply_patch_tool_type": "freeform",
"web_search_tool_type": "text_and_image",
"input_modalities": [
"text",
"image"
],
"supports_image_detail_original": true,
"truncation_policy": {
"mode": "tokens",
"limit": 10000
},
"supports_parallel_tool_calls": true,
"tool_mode": "code_mode_only",
"multi_agent_version": "v1",
"multi_agent_reasoning_effort": null,
"use_responses_lite": true,
"supports_reasoning_effort_updates": false,
"include_skills_usage_instructions": false,
"include_apps_usage_instructions": true,
"include_plugin_usage_instructions": true,
"guardian": null,
"node_repl_auto_review_required": false,
"node_repl_disabled": false,
"requires_sandboxed_review": false,
"auto_review_model_override": null,
"model_specialty": null,
"context_window": 272000,
"max_context_window": 872000,
"auto_compact_token_limit": null,
"default_reasoning_summary": "none",
"display_name": "GPT-5.6-Luna",
"description": "Older fast and efficient model.",
"default_reasoning_level": "medium",
"supported_reasoning_levels": [
{
"effort": "low",
"description": "Fast responses with lighter reasoning"
},
{
"effort": "medium",
"description": "Balances speed and reasoning depth for everyday tasks"
},
{
"effort": "high",
"description": "Greater reasoning depth for complex problems"
},
{
"effort": "xhigh",
"description": "Extra high reasoning depth for complex problems"
},
{
"effort": "max",
"description": "Maximum reasoning depth for the hardest problems"
}
],
"shell_type": "shell_command",
"visibility": "list",
"minimal_client_version": "0.144.0",
"supported_in_api": true,
"availability_nux": null,
"upgrade": {
"model": "gpt-6-luna",
"migration_markdown": "Meet GPT-6 Luna\n\nOur latest Luna is significantly more efficient, so your usage limits go even further. Reach for it for any job that doesn't require frontier intelligence.\n",
"retirement_at": null
},
"priority": 9,
"experimental_supported_tools": [],
"supports_search_tool": true,
"supports_experimental_context": false,
"default_service_tier": null,
"service_tiers": [
{
"id": "priority",
"name": "Fast",
"description": "1.5x speed, increased usage"
}
],
"additional_speed_tiers": [
"fast"
],
"supports_reasoning_summary_parameter": true,
"supports_reasoning_summaries": true
},
{
"slug": "gpt-daybreak-blue-latest",
"prefer_websockets": true,
"support_verbosity": true,
"default_verbosity": "low",
"apply_patch_tool_type": "freeform",
"web_search_tool_type": "text_and_image",
"input_modalities": [
"text",
"image"
],
"supports_image_detail_original": true,
"truncation_policy": {
"mode": "tokens",
"limit": 10000
},
"supports_parallel_tool_calls": true,
"tool_mode": "code_mode_only",
"multi_agent_version": "v2",
"use_responses_lite": true,
"include_skills_usage_instructions": false,
"include_apps_usage_instructions": true,
"include_plugin_usage_instructions": true,
"node_repl_auto_review_required": false,
"node_repl_disabled": false,
"auto_review_model_override": null,
"model_specialty": "cyber",
"context_window": 272000,
"max_context_window": 872000,
"auto_compact_token_limit": null,
"default_reasoning_summary": "none",
"display_name": "Daybreak Blue",
"description": "Latest frontier agentic coding model for broad defensive cybersecurity work.",
"default_reasoning_level": "low",
"supported_reasoning_levels": [
{
"effort": "low",
"description": "Fast responses with lighter reasoning"
},
{
"effort": "medium",
"description": "Balances speed and reasoning depth for everyday tasks"
},
{
"effort": "high",
"description": "Greater reasoning depth for complex problems"
},
{
"effort": "xhigh",
"description": "Extra high reasoning depth for complex problems"
},
{
"effort": "max",
"description": "Maximum reasoning depth for the hardest problems"
},
{
"effort": "ultra",
"description": "Maximum reasoning with automatic task delegation"
}
],
"shell_type": "shell_command",
"visibility": "hide",
"minimal_client_version": "0.142.2",
"supported_in_api": true,
"availability_nux": null,
"upgrade": null,
"priority": 11,
"experimental_supported_tools": [],
"supports_search_tool": true,
"default_service_tier": null,
"service_tiers": [],
"additional_speed_tiers": [],
"supports_reasoning_summary_parameter": true,
"supports_reasoning_summaries": true
},
{
"slug": "gpt-daybreak-red-latest",
"prefer_websockets": true,
"support_verbosity": true,
"default_verbosity": "high",
"apply_patch_tool_type": "freeform",
"web_search_tool_type": "text_and_image",
"input_modalities": [
"text",
"image"
],
"supports_image_detail_original": true,
"truncation_policy": {
"mode": "tokens",
"limit": 10000
},
"supports_parallel_tool_calls": true,
"tool_mode": "code_mode_only",
"multi_agent_version": "v2",
"use_responses_lite": true,
"include_skills_usage_instructions": false,
"include_apps_usage_instructions": false,
"include_plugin_usage_instructions": false,
"node_repl_auto_review_required": false,
"node_repl_disabled": false,
"auto_review_model_override": null,
"model_specialty": "cyber",
"context_window": 372000,
"max_context_window": 372000,
"auto_compact_token_limit": null,
"default_reasoning_summary": "none",
"display_name": "Daybreak Red",
"description": "Cyber-permissive variant of our latest frontier agentic coding model for advanced, authorized cybersecurity research.",
"default_reasoning_level": "medium",
"supported_reasoning_levels": [
{
"effort": "low",
"description": "Fast responses with lighter reasoning"
},
{
"effort": "medium",
"description": "Balances speed and reasoning depth for everyday tasks"
},
{
"effort": "high",
"description": "Greater reasoning depth for complex problems"
},
{
"effort": "xhigh",
"description": "Extra high reasoning depth for complex problems"
},
{
"effort": "max",
"description": "Maximum reasoning depth for the hardest problems"
},
{
"effort": "ultra",
"description": "Maximum reasoning with automatic task delegation"
}
],
"shell_type": "shell_command",
"visibility": "hide",
"minimal_client_version": "0.142.2",
"supported_in_api": true,
"availability_nux": null,
"upgrade": null,
"priority": 12,
"experimental_supported_tools": [],
"supports_search_tool": true,
"default_service_tier": null,
"service_tiers": [],
"additional_speed_tiers": [],
"supports_reasoning_summary_parameter": true,
"supports_reasoning_summaries": true
},
{
"slug": "gpt-5.5",
"prefer_websockets": true,
"support_verbosity": true,
"default_verbosity": "low",
"apply_patch_tool_type": "freeform",
"web_search_tool_type": "text_and_image",
"input_modalities": [
"text",
"image"
],
"supports_image_detail_original": true,
"truncation_policy": {
"mode": "tokens",
"limit": 10000
},
"supports_parallel_tool_calls": true,
"tool_mode": null,
"multi_agent_version": null,
"multi_agent_reasoning_effort": null,
"use_responses_lite": false,
"supports_reasoning_effort_updates": false,
"include_skills_usage_instructions": true,
"include_apps_usage_instructions": true,
"include_plugin_usage_instructions": true,
"guardian": null,
"node_repl_auto_review_required": false,
"node_repl_disabled": false,
"requires_sandboxed_review": false,
"auto_review_model_override": null,
"model_specialty": null,
"context_window": 272000,
"max_context_window": 272000,
"auto_compact_token_limit": null,
"default_reasoning_summary": "none",
"display_name": "GPT-5.5",
"description": "Legacy coding model.",
"default_reasoning_level": "medium",
"supported_reasoning_levels": [
{
"effort": "low",
"description": "Fast responses with lighter reasoning"
},
{
"effort": "medium",
"description": "Balances speed and reasoning depth for everyday tasks"
},
{
"effort": "high",
"description": "Greater reasoning depth for complex problems"
},
{
"effort": "xhigh",
"description": "Extra high reasoning depth for complex problems"
}
],
"shell_type": "shell_command",
"visibility": "list",
"minimal_client_version": "0.124.0",
"supported_in_api": true,
"availability_nux": null,
"upgrade": {
"model": "gpt-6-sol",
"migration_markdown": "Meet GPT-6 Sol\n\nOur latest Sol is more intelligent and more efficient so your usage limits go further. This model is a great daily driver for complex tasks, especially coding.\n",
"retirement_at": null
},
"priority": 13,
"experimental_supported_tools": [],
"supports_search_tool": true,
"supports_experimental_context": false,
"default_service_tier": null,
"service_tiers": [
{
"id": "priority",
"name": "Fast",
"description": "1.5x speed, increased usage"
}
],
"additional_speed_tiers": [
"fast"
],
"supports_reasoning_summary_parameter": true,
"supports_reasoning_summaries": true
},
{
"slug": "codex-auto-review",
"prefer_websockets": true,
"support_verbosity": true,
"default_verbosity": "low",
"apply_patch_tool_type": "freeform",
"web_search_tool_type": "text_and_image",
"input_modalities": [
"text",
"image"
],
"supports_image_detail_original": true,
"truncation_policy": {
"mode": "tokens",
"limit": 10000
},
"supports_parallel_tool_calls": true,
"tool_mode": "code_mode_only",
"multi_agent_version": "v1",
"multi_agent_reasoning_effort": null,
"use_responses_lite": true,
"supports_reasoning_effort_updates": false,
"include_skills_usage_instructions": false,
"include_apps_usage_instructions": false,
"include_plugin_usage_instructions": false,
"guardian": null,
"node_repl_auto_review_required": false,
"node_repl_disabled": false,
"requires_sandboxed_review": false,
"auto_review_model_override": null,
"model_specialty": null,
"context_window": 272000,
"max_context_window": 872000,
"auto_compact_token_limit": null,
"default_reasoning_summary": "none",
"display_name": "Codex Auto Review",
"description": "Automatic approval review model for Codex.",
"default_reasoning_level": "medium",
"supported_reasoning_levels": [
{
"effort": "low",
"description": "Fast responses with lighter reasoning"
},
{
"effort": "medium",
"description": "Balances speed and reasoning depth for everyday tasks"
},
{
"effort": "high",
"description": "Greater reasoning depth for complex problems"
},
{
"effort": "xhigh",
"description": "Extra high reasoning depth for complex problems"
},
{
"effort": "max",
"description": "Maximum reasoning depth for the hardest problems"
}
],
"shell_type": "shell_command",
"visibility": "hide",
"minimal_client_version": "0.98.0",
"supported_in_api": true,
"availability_nux": null,
"upgrade": null,
"priority": 43,
"experimental_supported_tools": [],
"supports_search_tool": true,
"supports_experimental_context": false,
"default_service_tier": null,
"service_tiers": [
{
"id": "priority",
"name": "Fast",
"description": "1.5x speed, increased usage"
}
],
"additional_speed_tiers": [
"fast"
],
"supports_reasoning_summary_parameter": true,
"supports_reasoning_summaries": true
}
]
@@ -7,6 +7,7 @@ use crate::contracts::{
GEMINI_EMBEDDING_SYNC_SUCCESS_REPORT_KIND, GEMINI_INTERACTIONS_STREAM_PLAN_KIND,
GEMINI_INTERACTIONS_STREAM_SUCCESS_REPORT_KIND, GEMINI_INTERACTIONS_SYNC_PLAN_KIND,
GEMINI_INTERACTIONS_SYNC_SUCCESS_REPORT_KIND, OPENAI_EMBEDDING_SYNC_PLAN_KIND,
OPENAI_MEMORIES_SYNC_PLAN_KIND, OPENAI_MEMORIES_SYNC_SUCCESS_REPORT_KIND,
OPENAI_REALTIME_STREAM_PLAN_KIND, OPENAI_RERANK_SYNC_PLAN_KIND, OPENAI_SEARCH_SYNC_PLAN_KIND,
OPENAI_SEARCH_SYNC_SUCCESS_REPORT_KIND,
};
@@ -29,6 +30,14 @@ pub struct LocalSameFormatProviderSpec {
pub fn resolve_sync_spec(plan_kind: &str) -> Option<LocalSameFormatProviderSpec> {
match plan_kind {
OPENAI_MEMORIES_SYNC_PLAN_KIND => Some(LocalSameFormatProviderSpec {
api_format: "openai:responses",
decision_kind: OPENAI_MEMORIES_SYNC_PLAN_KIND,
report_kind: OPENAI_MEMORIES_SYNC_SUCCESS_REPORT_KIND,
family: LocalSameFormatProviderFamily::Standard,
require_streaming: false,
operation: Some(ApiOperation::OpenAiMemoriesSummarize),
}),
CLAUDE_CHAT_SYNC_PLAN_KIND => Some(LocalSameFormatProviderSpec {
api_format: "claude:messages",
decision_kind: CLAUDE_CHAT_SYNC_PLAN_KIND,
@@ -260,4 +269,16 @@ mod tests {
assert_eq!(spec.report_kind, "openai_search_sync_success");
assert!(!spec.require_streaming);
}
#[test]
fn memories_uses_responses_permissions_and_a_native_sync_operation() {
let spec = resolve_sync_spec("openai_memories_sync").expect("memory spec");
assert_eq!(spec.api_format, "openai:responses");
assert_eq!(
spec.operation,
Some(crate::ApiOperation::OpenAiMemoriesSummarize)
);
assert_eq!(spec.report_kind, "openai_memories_sync_success");
assert!(!spec.require_streaming);
}
}
@@ -11,13 +11,13 @@ use crate::contracts::{
GEMINI_INTERACTIONS_STREAM_PLAN_KIND, GEMINI_INTERACTIONS_SYNC_PLAN_KIND,
GEMINI_VIDEO_CANCEL_SYNC_PLAN_KIND, GEMINI_VIDEO_CREATE_SYNC_PLAN_KIND,
OPENAI_CHAT_STREAM_PLAN_KIND, OPENAI_CHAT_SYNC_PLAN_KIND, OPENAI_EMBEDDING_SYNC_PLAN_KIND,
OPENAI_IMAGE_STREAM_PLAN_KIND, OPENAI_IMAGE_SYNC_PLAN_KIND, OPENAI_REALTIME_STREAM_PLAN_KIND,
OPENAI_RERANK_SYNC_PLAN_KIND, OPENAI_RESPONSES_COMPACT_STREAM_PLAN_KIND,
OPENAI_RESPONSES_COMPACT_SYNC_PLAN_KIND, OPENAI_RESPONSES_STREAM_PLAN_KIND,
OPENAI_RESPONSES_SYNC_PLAN_KIND, OPENAI_SEARCH_SYNC_PLAN_KIND,
OPENAI_VIDEO_CANCEL_SYNC_PLAN_KIND, OPENAI_VIDEO_CONTENT_PLAN_KIND,
OPENAI_VIDEO_CREATE_SYNC_PLAN_KIND, OPENAI_VIDEO_DELETE_SYNC_PLAN_KIND,
OPENAI_VIDEO_REMIX_SYNC_PLAN_KIND,
OPENAI_IMAGE_STREAM_PLAN_KIND, OPENAI_IMAGE_SYNC_PLAN_KIND, OPENAI_MEMORIES_SYNC_PLAN_KIND,
OPENAI_REALTIME_STREAM_PLAN_KIND, OPENAI_RERANK_SYNC_PLAN_KIND,
OPENAI_RESPONSES_COMPACT_STREAM_PLAN_KIND, OPENAI_RESPONSES_COMPACT_SYNC_PLAN_KIND,
OPENAI_RESPONSES_STREAM_PLAN_KIND, OPENAI_RESPONSES_SYNC_PLAN_KIND,
OPENAI_SEARCH_SYNC_PLAN_KIND, OPENAI_VIDEO_CANCEL_SYNC_PLAN_KIND,
OPENAI_VIDEO_CONTENT_PLAN_KIND, OPENAI_VIDEO_CREATE_SYNC_PLAN_KIND,
OPENAI_VIDEO_DELETE_SYNC_PLAN_KIND, OPENAI_VIDEO_REMIX_SYNC_PLAN_KIND,
};
use crate::formats::openai::image::request::is_openai_image_stream_request;
@@ -193,6 +193,14 @@ pub fn resolve_execution_runtime_sync_plan_kind_with_client_surface(
return None;
}
if route_family == Some("openai")
&& route_kind == Some("memories")
&& *method == Method::POST
&& path == "/v1/memories/trace_summarize"
{
return Some(OPENAI_MEMORIES_SYNC_PLAN_KIND);
}
if route_family == Some("openai")
&& route_kind == Some("video")
&& *method == Method::POST
@@ -580,6 +588,7 @@ pub fn supports_sync_execution_decision_kind(plan_kind: &str) -> bool {
matches!(
plan_kind,
OPENAI_CHAT_SYNC_PLAN_KIND
| OPENAI_MEMORIES_SYNC_PLAN_KIND
| OPENAI_EMBEDDING_SYNC_PLAN_KIND
| OPENAI_RERANK_SYNC_PLAN_KIND
| OPENAI_SEARCH_SYNC_PLAN_KIND
@@ -746,6 +746,9 @@ fn maybe_build_standard_same_format_sync_body(
}
let body_json = body_json?;
if report_kind == "openai_memories_sync_finalize" {
return Some(body_json.clone());
}
if is_error_like_sync_body(body_json) {
return None;
}
@@ -1949,6 +1952,7 @@ fn is_openai_responses_finalize_kind(report_kind: &str) -> bool {
fn standard_same_format_api_format(report_kind: &str) -> Option<&'static str> {
match report_kind {
"openai_memories_sync_finalize" => Some("openai:responses"),
"openai_chat_sync_finalize" => Some("openai:chat"),
"claude_chat_sync_finalize" => Some("claude:messages"),
"gemini_chat_sync_finalize" => Some("gemini:generate_content"),
@@ -4163,6 +4167,24 @@ mod tests {
use base64::Engine as _;
use serde_json::json;
#[test]
fn native_memories_response_keeps_output_array_and_future_fields() {
let body = json!({"output":[{"trace_summary":"synthetic", "memory_summary":"memory"}], "future_response_field":{"enabled":true}});
let context = json!({"provider_api_format":"openai:responses","client_api_format":"openai:responses","needs_conversion":false,"requested_model":"gpt-6.1-sol-max"});
assert_eq!(
maybe_build_standard_same_format_sync_body_from_normalized_payload(
"openai_memories_sync_finalize",
200,
Some(&context),
Some(&body),
None
)
.expect("native response")
.expect("body"),
body
);
}
#[test]
fn converts_openai_images_sync_body_to_gemini_image_body() {
let provider_body_json = json!({