感谢这个项目,中继管理体验很好。在使用第三方模型(如 deepseek-v4-pro 支持 1M、Claude 系列默认 200K)时遇到三个相关的上下文配置问题,希望统一优化。本 issue 在 #931 已确认的运行时根因基础上,补充 CodexPlusPlus 源码侧的根因与自动化实现方案。
背景与诉求
按模型自动配置上下文长度 :目前上下文窗口是按中继配置(relay profile)整体设置一个值。希望模型列表里每个模型能独立声明上下文窗口,例如 deepseek-v4-pro 用 1M、claude-sonnet 用 200K,切换模型即生效,而不必为每个模型建独立 profile。
自动压缩阈值可配置 :codex 默认在接近窗口上限时自动压缩。希望在设置页能配置「按比例」(如窗口的 85%)或「按绝对长度」触发压缩,最好也能按模型精细化。
插件/前端按模型显示真实上下文长度 :现在模型列表都按同一长度(如 256K/272K)显示,无法反映各模型实际能力。
现状分析(CodexPlusPlus)
运行时 258K cap 的现象与 codex.exe 二进制硬编码 272000 的根因,#931 已详细确认,并验证 model_catalog_json(正确路径格式)可扩展到 950K。以下聚焦 CodexPlusPlus 源码侧的增量根因。
上下文窗口与压缩阈值已支持 per-profile 配置:RelayProfile.context_window / auto_compact_limit,写入 config.toml 顶层的 model_context_window / model_auto_compact_token_limit(crates/codex-plus-core/src/relay_config.rs 的 apply_context_limits_to_config)。但这是按 profile 单值 ,不是按模型。
已能读取 codex 的 model_catalog_json(crates/codex-plus-core/src/model_catalog.rs 的 models_from_config_model_catalog_json),但 parse_model_catalog_json_models 只提取模型 slug,丢弃了 context_window 字段 ,因此前端无法按模型显示窗口(诉求 3 的根因之一)。
无生成 catalog 的能力 :测试 apply_relay_profile_does_not_write_model_catalog_json_for_selected_models 明确验证「不写」,apply_relay_profile_preserves_user_model_catalog_json 仅保留用户手写内容。代理层(protocol_proxy.rs / proxy.rs / relay_switch.rs)不改写 context_window。因此用户当前只能借助 cc-switch 生成 catalog 文件再手改 model_catalog_json 指针(见 Custom provider context window capped at 258K, ignoring 1M configuration #931 的解法),门槛高且 Windows 路径转义是坑。
内置 crates/codex-plus-core/assets/codex-models.json 中第三方模型无元数据时回落默认值,加剧「都按同一长度显示」。
参考实现:cc-switch
cc-switch 对 codex 采用了 codex 原生的 model_catalog_json 机制(src-tauri/src/codex_config.rs):
每个 provider preset 的 modelCatalog 是模型数组,每条带 contextWindow 字段(如 deepseek-v4-pro → 1000000),设置页表格里每行模型都有独立的上下文窗口输入框。
后端把这些规格生成 catalog JSON,每条模型写入 context_window + max_context_window,并在 config.toml 写入 model_catalog_json = "..." 指针。
codex 客户端运行时读取该 catalog,按模型识别各自窗口;顶层 model_context_window 作为未单独配置时的回退默认值。
注:cc-switch 的 [1M] 后缀写法是 Claude Desktop / Anthropic 的机制(通过 ANTHROPIC_DEFAULT_SONNET_MODEL env 带 [1M] 后缀),codex 侧未采用后缀方式,而是用 catalog 文件实现按模型窗口,更贴合 codex 原生能力。
建议方案
方案一:按模型上下文窗口(诉求 1 + 3)
利用 codex 原生 model_catalog_json 字段:
在模型列表(relay profile 的 model_list)每行增加 contextWindow 输入,UI 仿 cc-switch 的 modelCatalog 表格。
应用 profile 时,生成 <profile>-model-catalog.json,每条模型写入 slug / display_name / context_window / max_context_window,并在 config.toml 写入 model_catalog_json 指针(已有读取能力,补齐生成即可,并把测试 apply_relay_profile_does_not_write_model_catalog_json_for_selected_models 的行为反转)。同时自动处理路径格式,规避 Custom provider context window capped at 258K, ignoring 1M configuration #931 踩过的转义坑。
顶层 model_context_window 保留作为回退默认。
这样 codex 客户端、/model 列表、前端显示都能按模型反映真实窗口(诉求 3 同步解决),并解决 Custom provider context window capped at 258K, ignoring 1M configuration #931 workaround「只能配单模型、其余从列表消失」的副作用。
parse_model_catalog_json_models 读取时保留 context_window 一并返回前端,前端按模型展示。
方案二:按模型/按比例自动压缩(诉求 2)
codex 原生 catalog 条目支持 auto_compact_token_limit 字段(内置目录中现为 null),可在此基础上扩展:
预期效果
模型
context_window
auto_compact_token_limit
deepseek-v4-pro
1000000
850000(1M × 85%)
claude-sonnet-4
200000
170000
gpt-5.5
272000
231200
切换模型即生效,无需为每个模型单独建 profile;前端与 /model 列表按模型显示真实窗口。
兼容性
完全基于 codex 原生字段(model_catalog_json / model_context_window / model_auto_compact_token_limit),不引入非标改动。
未配置 contextWindow 的模型回落顶层默认值,与现有 per-profile 行为兼容。
现有 profile 的单值配置可继续作为该 profile 的回退默认。
相关 issue
感谢这个项目,中继管理体验很好。在使用第三方模型(如 deepseek-v4-pro 支持 1M、Claude 系列默认 200K)时遇到三个相关的上下文配置问题,希望统一优化。本 issue 在 #931 已确认的运行时根因基础上,补充 CodexPlusPlus 源码侧的根因与自动化实现方案。
背景与诉求
现状分析(CodexPlusPlus)
RelayProfile.context_window/auto_compact_limit,写入 config.toml 顶层的model_context_window/model_auto_compact_token_limit(crates/codex-plus-core/src/relay_config.rs的apply_context_limits_to_config)。但这是按 profile 单值,不是按模型。model_catalog_json(crates/codex-plus-core/src/model_catalog.rs的models_from_config_model_catalog_json),但parse_model_catalog_json_models只提取模型slug,丢弃了context_window字段,因此前端无法按模型显示窗口(诉求 3 的根因之一)。apply_relay_profile_does_not_write_model_catalog_json_for_selected_models明确验证「不写」,apply_relay_profile_preserves_user_model_catalog_json仅保留用户手写内容。代理层(protocol_proxy.rs/proxy.rs/relay_switch.rs)不改写 context_window。因此用户当前只能借助 cc-switch 生成 catalog 文件再手改model_catalog_json指针(见 Custom provider context window capped at 258K, ignoring 1M configuration #931 的解法),门槛高且 Windows 路径转义是坑。crates/codex-plus-core/assets/codex-models.json中第三方模型无元数据时回落默认值,加剧「都按同一长度显示」。参考实现:cc-switch
cc-switch 对 codex 采用了 codex 原生的
model_catalog_json机制(src-tauri/src/codex_config.rs):modelCatalog是模型数组,每条带contextWindow字段(如deepseek-v4-pro→1000000),设置页表格里每行模型都有独立的上下文窗口输入框。context_window+max_context_window,并在 config.toml 写入model_catalog_json = "..."指针。model_context_window作为未单独配置时的回退默认值。建议方案
方案一:按模型上下文窗口(诉求 1 + 3)
利用 codex 原生
model_catalog_json字段:model_list)每行增加contextWindow输入,UI 仿 cc-switch 的 modelCatalog 表格。<profile>-model-catalog.json,每条模型写入slug/display_name/context_window/max_context_window,并在 config.toml 写入model_catalog_json指针(已有读取能力,补齐生成即可,并把测试apply_relay_profile_does_not_write_model_catalog_json_for_selected_models的行为反转)。同时自动处理路径格式,规避 Custom provider context window capped at 258K, ignoring 1M configuration #931 踩过的转义坑。model_context_window保留作为回退默认。/model列表、前端显示都能按模型反映真实窗口(诉求 3 同步解决),并解决 Custom provider context window capped at 258K, ignoring 1M configuration #931 workaround「只能配单模型、其余从列表消失」的副作用。parse_model_catalog_json_models读取时保留context_window一并返回前端,前端按模型展示。方案二:按模型/按比例自动压缩(诉求 2)
codex 原生 catalog 条目支持
auto_compact_token_limit字段(内置目录中现为null),可在此基础上扩展:auto_compact_token_limit,实现每模型独立压缩阈值(替代 Custom provider context window capped at 258K, ignoring 1M configuration #931 写死的 850000)。context_window × 比例自动计算绝对值写入;也保留「绝对长度」手动输入模式。model_auto_compact_token_limit保留作为回退。预期效果
切换模型即生效,无需为每个模型单独建 profile;前端与
/model列表按模型显示真实窗口。兼容性
model_catalog_json/model_context_window/model_auto_compact_token_limit),不引入非标改动。相关 issue