codex-model-change 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +6 -6
  2. package/cx.py +33 -22
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -44,14 +44,14 @@ cd codex-model-change
44
44
  | 命令 | 作用 |
45
45
  |---|---|
46
46
  | `cx status` | 查看默认模型 / provider / 最近会话各自用的模型 |
47
- | `cx use deepseek` | 切换到 DeepSeek 直连(改写 `~/.codex/config.toml`,自动备份) |
47
+ | `cx fix-all deepseek\|gpt` | **批量把所有老会话切换到目标模型**(需退 App);切到 gpt 时自动清理旧代理遗留的不兼容历史条目(`reasoning.content` 等),避免续聊报 `Invalid 'input[..].content'` |
48
+ | `cx fix-all deepseek --limit 10` | 只处理最近 10 个会话(`--limit` 可按需调整,省略则处理全部) |
49
+ | `cx use deepseek` | 切换默认模型(**只对新会话生效**;改写 `~/.codex/config.toml`,自动备份) |
48
50
  | `cx use gpt` | 切回原生 ChatGPT(走 ChatGPT 登录态,无需 API key) |
49
51
  | `cx key <API_KEY>` | 保存 DeepSeek key 并注入 GUI 环境(桌面 App 需要) |
50
52
  | `cx doctor` | 体检:key 有效性 / 直连连通性 / 会话健康 |
51
53
  | `cx fix <会话ID>` | 修复某个打不开/报 404 的会话(ID 取 `cx status` 里显示的前 8 位即可) |
52
54
  | `cx fix last` | 修复最近一个会话 |
53
- | `cx fix-all <目标> [--limit N]` | **批量把所有老会话切换到目标模型**(`deepseek` 或 `gpt`,需退 App);切到 gpt 时自动清理旧代理遗留的不兼容历史条目(`reasoning.content` 等),避免续聊报 `Invalid 'input[..].content'` |
54
- | `cx fix-all deepseek --limit 10` | 只处理最近 10 个会话(`--limit` 可按需调整,省略则处理全部) |
55
55
 
56
56
  **关于老会话**:每个会话记录着自己创建时的模型,`cx use` 只影响新会话——老会话继续用原模型,互不干扰。想把老会话搬到新模型:单个用 `cx fix`,全部用 `cx fix-all`(会先备份数据库和会话文件,确认后执行)。
57
57
 
@@ -85,7 +85,7 @@ env_key = "DEEPSEEK_API_KEY"
85
85
  wire_api = "responses"
86
86
  ```
87
87
 
88
- 并把顶部改为 `model_provider = "deepseek"` / `model = "deepseek-chat"`,同时生成模型目录 `~/.codex/cx-catalog.json`。
88
+ 并把顶部改为 `model_provider = "deepseek"` / `model = "deepseek-flash"`,同时生成模型目录 `~/.codex/cx-catalog.json`。
89
89
 
90
90
  **第 4 步:完成桌面 App 配置**(见下方「桌面 App 的一次性配置」),然后完全退出并重开 App。
91
91
 
@@ -147,9 +147,9 @@ App 没读到 `DEEPSEEK_API_KEY`。执行上面「桌面 App 的一次性配置
147
147
 
148
148
  - macOS(依赖 `launchctl` 做 GUI 环境变量注入;纯 CLI 使用则不依赖)
149
149
  - Codex CLI / ChatGPT 桌面 App(内含 codex 的版本)
150
- - DeepSeek `deepseek-chat` / `deepseek-reasoner`(Responses API)
150
+ - DeepSeek `deepseek-flash`(V4.1,默认)/ `deepseek-v4-pro`(Responses API)
151
151
 
152
- > 注意:DeepSeek 的上下文窗口(128K 级)与 GPT 不同,cx 生成的模型目录已按 DeepSeek 实际参数配置(截断策略、auto-compact 阈值等),请勿手工改坏后不带备份地覆盖。
152
+ > 上下文:cx 生成的模型目录按官方 **1M** 窗口配置(`context_window = 1048576`、auto-compact 阈值 900K、最大输出 384K),对应官方 **DeepSeek-V4** 系列。V3.1 时代的 `deepseek-chat` / `deepseek-reasoner` 只有 128K 级,且已被服务端当作兼容别名静默指向 `deepseek-flash`;**cx 1.0.8 起不再使用这两个旧名**(如账号可用的模型名有变化,`cx doctor` 会告警)。
153
153
 
154
154
  ## License
155
155
 
package/cx.py CHANGED
@@ -3,17 +3,18 @@
3
3
 
4
4
  无代理、无常驻进程。Codex 直连 deepseek(Responses API) / 原生 ChatGPT。
5
5
  命令:
6
- cx status 查看当前模型配置与最近会话
7
- cx use deepseek|gpt 切换默认模型(改写 ~/.codex/config.toml, 自动备份)
8
- cx doctor 体检: key/直连/会话健康
9
- cx key <API_KEY> 保存 deepseek key 并注入 GUI 环境(launchctl setenv)
10
- cx fix <会话ID> 修复单个会话(续跑一轮写入正确模型)
11
- cx fix-all <目标> 把所有老会话批量切换到目标模型(需退 App)
12
- 例: cx fix-all deepseek --limit 10 (只改最近 10 个)
6
+ cx status 查看当前模型配置与最近会话
7
+ cx fix-all deepseek|gpt
8
+ 把所有老会话批量切换到目标模型(需退 App)
9
+ 例: cx fix-all deepseek --limit 10 (只改最近 10 个)
10
+ cx use deepseek|gpt 切换默认模型(只针对新会话生效)
11
+ cx doctor 体检: key/直连/会话健康
12
+ cx key <API_KEY> 保存 deepseek key 并注入 GUI 环境(launchctl setenv)
13
+ cx fix <会话ID> 修复单个会话(续跑一轮写入正确模型)
13
14
  """
14
15
  import json, os, re, glob, sqlite3, subprocess, sys, shutil, time, urllib.request, urllib.error
15
16
 
16
- CX_VERSION = "1.0.6"
17
+ CX_VERSION = "1.0.8"
17
18
 
18
19
  CODEX_HOME = os.environ.get("CODEX_HOME", os.path.expanduser("~/.codex"))
19
20
  CONFIG = os.path.join(CODEX_HOME, "config.toml")
@@ -23,7 +24,7 @@ CATALOG = os.path.join(CODEX_HOME, "cx-catalog.json")
23
24
  CODEX_BIN = "/opt/homebrew/bin/codex"
24
25
  APP_PGREP = "/Applications/ChatGPT.app/Contents/MacOS/ChatGPT"
25
26
 
26
- DS_MODEL = "deepseek-chat"
27
+ DS_MODEL = "deepseek-flash" # V4.1-Flash;旧的 deepseek-chat/deepseek-reasoner 已被服务端别名到它,不再使用
27
28
  DS_PROVIDER_BLOCK = """
28
29
  # --- added by cx (direct deepseek) ---
29
30
  [model_providers.deepseek]
@@ -41,13 +42,13 @@ HELP = """cx — Codex 模型直连切换器
41
42
 
42
43
  命令一览:
43
44
  status 查看默认模型/provider/最近会话(不带参数执行 cx 等同于此)
44
- use deepseek|gpt 切换默认模型(改写 config.toml,自动备份)
45
+ fix-all deepseek|gpt 批量把所有老会话切换到目标模型(需退 App)
46
+ 用法: cx fix-all deepseek|gpt [--limit N]
47
+ 例: cx fix-all deepseek --limit 10 (只改最近 10 个)
48
+ use deepseek|gpt 切换默认模型(只针对新会话生效)
45
49
  key <API_KEY> 保存 deepseek key 并注入 GUI 环境(桌面 App 需要)
46
50
  doctor 体检: key 有效性/直连连通性/会话健康
47
51
  fix <会话ID|last> 修复单个会话(ID 取 status 里显示的前 8 位即可)
48
- fix-all <目标> 批量把所有老会话切换到目标模型(需退 App)
49
- 用法: cx fix-all deepseek|gpt [--limit N]
50
- 例: cx fix-all deepseek --limit 10 (只改最近 10 个)
51
52
  version 显示 cx 版本
52
53
  help 显示本帮助
53
54
 
@@ -60,6 +61,7 @@ HELP = """cx — Codex 模型直连切换器
60
61
  def err(m): print("❌ " + m); sys.exit(1)
61
62
  def ok(m): print("✅ " + m)
62
63
  def info(m): print("ℹ️ " + m)
64
+ def warn(m): print("⚠️ " + m)
63
65
 
64
66
  def read_cfg():
65
67
  if not os.path.exists(CONFIG): err(f"找不到 {CONFIG}")
@@ -77,7 +79,7 @@ def load_key():
77
79
  return open(KEY_FILE).read().strip() or None
78
80
 
79
81
  # ---------- 目录文件 ----------
80
- def _ds_entry(slug, name, desc, priority):
82
+ def _ds_entry(slug, name, desc, priority, ctx=1048576, compact=900000):
81
83
  return {
82
84
  "slug": slug, "display_name": name, "description": desc,
83
85
  "default_reasoning_level": "high",
@@ -98,21 +100,19 @@ def _ds_entry(slug, name, desc, priority):
98
100
  "supports_search_tool": False, "tool_mode": "default",
99
101
  "node_repl_disabled": True, "node_repl_auto_review_required": False,
100
102
  "include_plugin_usage_instructions": False, "include_apps_usage_instructions": False,
101
- "supports_reasoning_summaries": False, "context_window": 131072,
102
- "max_context_window": 131072, "auto_compact_token_limit": 118000,
103
+ "supports_reasoning_summaries": False, "context_window": ctx,
104
+ "max_context_window": ctx, "auto_compact_token_limit": compact,
103
105
  "auto_review_model_override": None,
104
106
  }
105
107
 
106
108
  CATALOG_MODELS = [
107
- _ds_entry("deepseek-chat", "DeepSeek Chat", "DeepSeek 直连 (deepseek-chat)。", 5),
108
- _ds_entry("deepseek-reasoner", "DeepSeek Reasoner", "DeepSeek 直连 (deepseek-reasoner)。", 4),
109
+ _ds_entry("deepseek-flash", "DeepSeek Flash", "DeepSeek 直连 (deepseek-flash / V4.1, 1M 上下文)。", 5),
110
+ _ds_entry("deepseek-v4-pro", "DeepSeek V4 Pro", "DeepSeek 直连 (deepseek-v4-pro, 1M 上下文)。", 4),
109
111
  ]
110
112
  for slug in ("gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.5", "gpt-5.4"):
111
- e = _ds_entry(slug, slug, slug, 1)
113
+ e = _ds_entry(slug, slug, slug, 1, ctx=400000, compact=360000)
112
114
  e["visibility"] = "hide"
113
115
  e["input_modalities"] = ["text", "image"]
114
- e["context_window"] = e["max_context_window"] = 400000
115
- e["auto_compact_token_limit"] = 360000
116
116
  e["supports_reasoning_summaries"] = True
117
117
  CATALOG_MODELS.append(e)
118
118
 
@@ -290,7 +290,18 @@ def cmd_doctor():
290
290
  req = urllib.request.Request("https://api.deepseek.com/v1/models",
291
291
  headers={"Authorization": f"Bearer {key}"})
292
292
  try:
293
- urllib.request.urlopen(req, timeout=10); ok("deepseek API 直连: key 有效")
293
+ with urllib.request.urlopen(req, timeout=10) as r:
294
+ ids = [m.get("id") for m in json.load(r).get("data", []) if m.get("id")]
295
+ ok("deepseek API 直连: key 有效")
296
+ if ids:
297
+ info("账号可用模型: " + ", ".join(ids))
298
+ gone = [m["slug"] for m in CATALOG_MODELS
299
+ if m.get("slug", "").startswith("deepseek") and m["slug"] not in ids]
300
+ if gone:
301
+ warn("模型目录里这些名字已不在账号可用列表: " + ", ".join(gone)
302
+ + " (运行 cx use deepseek 重建目录,或升级 cx)")
303
+ else:
304
+ ok("模型目录中的 deepseek 模型名均可用")
294
305
  except urllib.error.HTTPError as e:
295
306
  err(f"deepseek API 返回 {e.code}(key 可能无效)")
296
307
  except Exception as e:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-model-change",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Switch OpenAI Codex (CLI / desktop app) between DeepSeek direct-connect and native ChatGPT. No proxy, no daemon.",
5
5
  "bin": {
6
6
  "cx": "bin/cx.js"