@xhscopy-ai/cli 0.0.141 → 0.0.143
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.
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
"description": "100 万上下文 | 12.8 万输出 | 低延迟 | 高频轻量任务",
|
|
40
|
-
"group": "
|
|
40
|
+
"group": "grp_6eg2dq9ywgrg",
|
|
41
41
|
"group_name": "",
|
|
42
42
|
"hidden": false,
|
|
43
43
|
"id": "claude-haiku-5-5",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
49
|
-
"group": "
|
|
49
|
+
"group": "grp_6co8aqwefsoh",
|
|
50
50
|
"group_name": "",
|
|
51
51
|
"hidden": false,
|
|
52
52
|
"id": "claude-opus-4-6",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
58
|
-
"group": "
|
|
58
|
+
"group": "grp_6lyxfgbs440g",
|
|
59
59
|
"group_name": "",
|
|
60
60
|
"hidden": false,
|
|
61
61
|
"id": "claude-opus-4-7",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
66
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
67
|
-
"group": "
|
|
67
|
+
"group": "grp_pzxnceygmqlp",
|
|
68
68
|
"group_name": "",
|
|
69
69
|
"hidden": false,
|
|
70
70
|
"id": "claude-opus-4-8",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
"description": "100 万上下文 | 12.8 万输出 | 自适应思考五档 | Agent 编程",
|
|
76
|
-
"group": "
|
|
76
|
+
"group": "grp_6lyxfgbs440g",
|
|
77
77
|
"group_name": "",
|
|
78
78
|
"hidden": false,
|
|
79
79
|
"id": "claude-opus-5",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
84
|
"description": "100 万上下文 | 长时 Agent 编程 | 知识工作",
|
|
85
|
-
"group": "
|
|
85
|
+
"group": "grp_irydsgijuckh",
|
|
86
86
|
"group_name": "",
|
|
87
87
|
"hidden": false,
|
|
88
88
|
"id": "claude-opus-5-5",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
},
|
|
101
101
|
{
|
|
102
102
|
"description": "100 万上下文 | Agent 编程 | 工具调用 | 知识工作",
|
|
103
|
-
"group": "
|
|
103
|
+
"group": "grp_pzxnceygmqlp",
|
|
104
104
|
"group_name": "",
|
|
105
105
|
"hidden": false,
|
|
106
106
|
"id": "claude-sonnet-5",
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
},
|
|
110
110
|
{
|
|
111
111
|
"description": "100 万上下文 | 12.8 万输出 | Agent 编程 | 知识工作",
|
|
112
|
-
"group": "
|
|
112
|
+
"group": "grp_pzxnceygmqlp",
|
|
113
113
|
"group_name": "",
|
|
114
114
|
"hidden": false,
|
|
115
115
|
"id": "claude-sonnet-5-5",
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"codex": [
|
|
121
121
|
{
|
|
122
122
|
"description": "105 万上下文 | 12.8 万输出 | 大批量低成本档",
|
|
123
|
-
"group": "
|
|
123
|
+
"group": "grp_squ2qzjnehps",
|
|
124
124
|
"group_name": "",
|
|
125
125
|
"hidden": false,
|
|
126
126
|
"id": "gpt-5.6-luna",
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
},
|
|
157
157
|
{
|
|
158
158
|
"description": "转发至 gpt-6-sol | 实际由 gpt-6-sol 响应 | 105 万上下文 | 12.8 万输出",
|
|
159
|
-
"group": "
|
|
159
|
+
"group": "grp_mb5v069lpnze",
|
|
160
160
|
"group_name": "",
|
|
161
161
|
"hidden": false,
|
|
162
162
|
"id": "gpt-6-luna",
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
},
|
|
166
166
|
{
|
|
167
167
|
"description": "105 万上下文 | 12.8 万输出 | 复杂编程与 Agent 工作流",
|
|
168
|
-
"group": "
|
|
168
|
+
"group": "grp_squ2qzjnehps",
|
|
169
169
|
"group_name": "",
|
|
170
170
|
"hidden": false,
|
|
171
171
|
"id": "gpt-6-sol",
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
},
|
|
175
175
|
{
|
|
176
176
|
"description": "105 万上下文 | 12.8 万输出 | 文字与图像输入 | 工具调用、联网搜索、结构化输出 | 工具调用使用 Responses API",
|
|
177
|
-
"group": "
|
|
177
|
+
"group": "grp_bsbtt432saoq",
|
|
178
178
|
"group_name": "",
|
|
179
179
|
"hidden": false,
|
|
180
180
|
"id": "gpt-6.1-sol",
|
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
},
|
|
222
222
|
{
|
|
223
223
|
"description": "约 100 万上下文 | 深度推理 | 密集长文档",
|
|
224
|
-
"group": "
|
|
224
|
+
"group": "grp_z5khwusxuh2j",
|
|
225
225
|
"group_name": "",
|
|
226
226
|
"hidden": false,
|
|
227
227
|
"id": "gemini-3.1-pro",
|
|
@@ -230,7 +230,7 @@
|
|
|
230
230
|
},
|
|
231
231
|
{
|
|
232
232
|
"description": "Gemini 3.1 Pro 预览版 | 约 100 万上下文 | 深度推理 | 文本、图像、音视频输入",
|
|
233
|
-
"group": "
|
|
233
|
+
"group": "grp_3pi5kyqkp51b",
|
|
234
234
|
"group_name": "",
|
|
235
235
|
"hidden": false,
|
|
236
236
|
"id": "gemini-3.1-pro-preview",
|
|
@@ -248,7 +248,7 @@
|
|
|
248
248
|
},
|
|
249
249
|
{
|
|
250
250
|
"description": "约 208 token/秒 | 高吞吐 | 多语言 | 编码",
|
|
251
|
-
"group": "
|
|
251
|
+
"group": "grp_z5khwusxuh2j",
|
|
252
252
|
"group_name": "",
|
|
253
253
|
"hidden": false,
|
|
254
254
|
"id": "gemini-3.6-flash",
|
|
@@ -257,7 +257,7 @@
|
|
|
257
257
|
},
|
|
258
258
|
{
|
|
259
259
|
"description": "Agent 主力 | 软件工程 | 网页开发",
|
|
260
|
-
"group": "
|
|
260
|
+
"group": "grp_z5khwusxuh2j",
|
|
261
261
|
"group_name": "",
|
|
262
262
|
"hidden": false,
|
|
263
263
|
"id": "gemini-3.7-flash",
|
|
@@ -266,7 +266,7 @@
|
|
|
266
266
|
},
|
|
267
267
|
{
|
|
268
268
|
"description": "推理与编码 | HLE-Verified 54.9% | 长文档工作流",
|
|
269
|
-
"group": "
|
|
269
|
+
"group": "grp_z5khwusxuh2j",
|
|
270
270
|
"group_name": "",
|
|
271
271
|
"hidden": false,
|
|
272
272
|
"id": "gemini-3.8-flash",
|
|
@@ -313,7 +313,7 @@
|
|
|
313
313
|
},
|
|
314
314
|
{
|
|
315
315
|
"description": "50 万上下文 | 长时 Agent | 编码与视觉项目",
|
|
316
|
-
"group": "
|
|
316
|
+
"group": "grp_l34dwliv4yas",
|
|
317
317
|
"group_name": "",
|
|
318
318
|
"hidden": false,
|
|
319
319
|
"id": "grok-4.7",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
"description": "100 万上下文 | 12.8 万输出 | 低延迟 | 高频轻量任务",
|
|
40
|
-
"group": "
|
|
40
|
+
"group": "grp_6eg2dq9ywgrg",
|
|
41
41
|
"group_name": "",
|
|
42
42
|
"hidden": false,
|
|
43
43
|
"id": "claude-haiku-5-5",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
49
|
-
"group": "
|
|
49
|
+
"group": "grp_6co8aqwefsoh",
|
|
50
50
|
"group_name": "",
|
|
51
51
|
"hidden": false,
|
|
52
52
|
"id": "claude-opus-4-6",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
58
|
-
"group": "
|
|
58
|
+
"group": "grp_6lyxfgbs440g",
|
|
59
59
|
"group_name": "",
|
|
60
60
|
"hidden": false,
|
|
61
61
|
"id": "claude-opus-4-7",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
66
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
67
|
-
"group": "
|
|
67
|
+
"group": "grp_pzxnceygmqlp",
|
|
68
68
|
"group_name": "",
|
|
69
69
|
"hidden": false,
|
|
70
70
|
"id": "claude-opus-4-8",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
"description": "100 万上下文 | 12.8 万输出 | 自适应思考五档 | Agent 编程",
|
|
76
|
-
"group": "
|
|
76
|
+
"group": "grp_6lyxfgbs440g",
|
|
77
77
|
"group_name": "",
|
|
78
78
|
"hidden": false,
|
|
79
79
|
"id": "claude-opus-5",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
84
|
"description": "100 万上下文 | 长时 Agent 编程 | 知识工作",
|
|
85
|
-
"group": "
|
|
85
|
+
"group": "grp_irydsgijuckh",
|
|
86
86
|
"group_name": "",
|
|
87
87
|
"hidden": false,
|
|
88
88
|
"id": "claude-opus-5-5",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
},
|
|
101
101
|
{
|
|
102
102
|
"description": "100 万上下文 | Agent 编程 | 工具调用 | 知识工作",
|
|
103
|
-
"group": "
|
|
103
|
+
"group": "grp_pzxnceygmqlp",
|
|
104
104
|
"group_name": "",
|
|
105
105
|
"hidden": false,
|
|
106
106
|
"id": "claude-sonnet-5",
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
},
|
|
110
110
|
{
|
|
111
111
|
"description": "100 万上下文 | 12.8 万输出 | Agent 编程 | 知识工作",
|
|
112
|
-
"group": "
|
|
112
|
+
"group": "grp_pzxnceygmqlp",
|
|
113
113
|
"group_name": "",
|
|
114
114
|
"hidden": false,
|
|
115
115
|
"id": "claude-sonnet-5-5",
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"codex": [
|
|
121
121
|
{
|
|
122
122
|
"description": "105 万上下文 | 12.8 万输出 | 大批量低成本档",
|
|
123
|
-
"group": "
|
|
123
|
+
"group": "grp_squ2qzjnehps",
|
|
124
124
|
"group_name": "",
|
|
125
125
|
"hidden": false,
|
|
126
126
|
"id": "gpt-5.6-luna",
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
},
|
|
157
157
|
{
|
|
158
158
|
"description": "转发至 gpt-6-sol | 实际由 gpt-6-sol 响应 | 105 万上下文 | 12.8 万输出",
|
|
159
|
-
"group": "
|
|
159
|
+
"group": "grp_mb5v069lpnze",
|
|
160
160
|
"group_name": "",
|
|
161
161
|
"hidden": false,
|
|
162
162
|
"id": "gpt-6-luna",
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
},
|
|
166
166
|
{
|
|
167
167
|
"description": "105 万上下文 | 12.8 万输出 | 复杂编程与 Agent 工作流",
|
|
168
|
-
"group": "
|
|
168
|
+
"group": "grp_squ2qzjnehps",
|
|
169
169
|
"group_name": "",
|
|
170
170
|
"hidden": false,
|
|
171
171
|
"id": "gpt-6-sol",
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
},
|
|
175
175
|
{
|
|
176
176
|
"description": "105 万上下文 | 12.8 万输出 | 文字与图像输入 | 工具调用、联网搜索、结构化输出 | 工具调用使用 Responses API",
|
|
177
|
-
"group": "
|
|
177
|
+
"group": "grp_bsbtt432saoq",
|
|
178
178
|
"group_name": "",
|
|
179
179
|
"hidden": false,
|
|
180
180
|
"id": "gpt-6.1-sol",
|
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
},
|
|
222
222
|
{
|
|
223
223
|
"description": "约 100 万上下文 | 深度推理 | 密集长文档",
|
|
224
|
-
"group": "
|
|
224
|
+
"group": "grp_z5khwusxuh2j",
|
|
225
225
|
"group_name": "",
|
|
226
226
|
"hidden": false,
|
|
227
227
|
"id": "gemini-3.1-pro",
|
|
@@ -230,7 +230,7 @@
|
|
|
230
230
|
},
|
|
231
231
|
{
|
|
232
232
|
"description": "Gemini 3.1 Pro 预览版 | 约 100 万上下文 | 深度推理 | 文本、图像、音视频输入",
|
|
233
|
-
"group": "
|
|
233
|
+
"group": "grp_3pi5kyqkp51b",
|
|
234
234
|
"group_name": "",
|
|
235
235
|
"hidden": false,
|
|
236
236
|
"id": "gemini-3.1-pro-preview",
|
|
@@ -248,7 +248,7 @@
|
|
|
248
248
|
},
|
|
249
249
|
{
|
|
250
250
|
"description": "约 208 token/秒 | 高吞吐 | 多语言 | 编码",
|
|
251
|
-
"group": "
|
|
251
|
+
"group": "grp_z5khwusxuh2j",
|
|
252
252
|
"group_name": "",
|
|
253
253
|
"hidden": false,
|
|
254
254
|
"id": "gemini-3.6-flash",
|
|
@@ -257,7 +257,7 @@
|
|
|
257
257
|
},
|
|
258
258
|
{
|
|
259
259
|
"description": "Agent 主力 | 软件工程 | 网页开发",
|
|
260
|
-
"group": "
|
|
260
|
+
"group": "grp_z5khwusxuh2j",
|
|
261
261
|
"group_name": "",
|
|
262
262
|
"hidden": false,
|
|
263
263
|
"id": "gemini-3.7-flash",
|
|
@@ -266,7 +266,7 @@
|
|
|
266
266
|
},
|
|
267
267
|
{
|
|
268
268
|
"description": "推理与编码 | HLE-Verified 54.9% | 长文档工作流",
|
|
269
|
-
"group": "
|
|
269
|
+
"group": "grp_z5khwusxuh2j",
|
|
270
270
|
"group_name": "",
|
|
271
271
|
"hidden": false,
|
|
272
272
|
"id": "gemini-3.8-flash",
|
|
@@ -313,7 +313,7 @@
|
|
|
313
313
|
},
|
|
314
314
|
{
|
|
315
315
|
"description": "50 万上下文 | 长时 Agent | 编码与视觉项目",
|
|
316
|
-
"group": "
|
|
316
|
+
"group": "grp_l34dwliv4yas",
|
|
317
317
|
"group_name": "",
|
|
318
318
|
"hidden": false,
|
|
319
319
|
"id": "grok-4.7",
|
package/dist/lib/tools/codex.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash as e}from"crypto";import{existsSync as t,mkdirSync as o,readdirSync as n,readFileSync as r,rmSync as i,statSync as s,writeFileSync as l}from"fs";import{join as a}from"path";import*as c from"@iarna/toml";import{logger as d}from"../../utils/logger.js";import{i18n as u}from"../i18n.js";import{backupBeforeWrite as m,atomicWriteFile as p}from"./backup.js";import{codexHome as f,pickModel as g,toolHome as _,withV1 as x}from"./types.js";import{moveSessionsToProvider as h,NO_STATE_DB as y,runningCodexPids as k}from"../codex-sessions.js";import{codexFormat as b,codexRolloutFiles as v}from"../sessions/formats.js";import{getToolDefaultModel as j}from"../model-registry.js";import{configManager as w}from"../config.js";import{maskHome as C,track as O}from"../telemetry.js";import{buildCodexCatalog as S,catalogRejections as M,codexCatalogPath as A,fillFromOlderEntries as E,installedCodexBinaries as N,loadBundledCodexModels as P,loadPreviousCodexModels as T,previousGatewayModelIds as D}from"./codex-catalog.js";import{gatewayModelSpecs as I,modelFamily as L}from"../gateway-models.js";import{findInstalls as $,mirrorInstallCommand as J,brandInstallScripts as G}from"./tool-installs.js";const R=()=>f(),K=()=>a(R(),"config.toml"),X="sessions_move_declined",B=["browser_use","browser_use_external","computer_use"];function W(e){const t=e.features;if(!Q(t)||!B.every(e=>!1===t[e]))return!1;for(const e of B)delete t[e];return!0}export function codexWorkModeOn(){try{const e=Z();return e.model_provider===Y&&Q(e.desktop)&&"STEPS_PROSE"===e.desktop.conversationDetailMode}catch{return!1}}function q(){try{if(Q(Z().desktop))return!0}catch{}if("darwin"===process.platform)return["/Applications",a(_(),"Applications")].some(e=>["ChatGPT.app","Codex.app"].some(o=>t(a(e,o))));if("win32"===process.platform){const e=a(process.env.LOCALAPPDATA||a(_(),"AppData","Local"),"Packages");try{return n(e).some(e=>/^OpenAI\.(Codex|ChatGPT)/i.test(e))}catch{return!1}}return t("/usr/lib/chatgpt/ChatGPT")}export function codexConfigPath(){return K()}const U=()=>a(R(),"auth.json"),z="OPENAI_API_KEY",Y="custom",F=1e6,H=9e5;export const CODEX_ONE_MILLION_CONTEXT_SETTING="one_million_context";function Q(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function V(e,t){return Q(e[t])||(e[t]={}),e[t]}function Z(){if(!t(K()))return{};const e=r(K(),"utf-8");if(!e.trim())return{};try{const t=c.parse(e);if(!Q(t))throw new Error("config.toml root must be a TOML table");return t}catch(e){throw new Error(`Existing ~/.codex/config.toml cannot be parsed; back it up and fix it first: ${e instanceof Error?e.message:String(e)}`)}}function ee(){if(!t(U()))return{};try{const e=JSON.parse(r(U(),"utf-8"));return Q(e)?e:{}}catch{return{}}}let te=null;function oe(e){const t=e.profiles;if(Q(t)){for(const[e,o]of Object.entries(t))Q(o)&&2===Object.keys(o).length&&o.model_provider===Y&&o.model===e&&delete t[e];0===Object.keys(t).length&&delete e.profiles}}let ne=null;const re=()=>a(w.getConfigDir(),"codex-catalog-check.json");function ie(e){const o=A();t(o)&&r(o,"utf-8")===e||(m(o),p(o,e))}function se(t,n){if(0===n.length)return[];const i=function(t,o){const n=e("sha256").update(t);for(const e of o)try{const t=s(e);n.update(`\0${e}\0${t.size}\0${t.mtimeMs}`)}catch{n.update(`\0${e}`)}return n.digest("hex")}(t,n);if(function(e){try{return JSON.parse(r(re(),"utf-8")).signature===e}catch{return!1}}(i))return[];const a=M(A(),n);return 0===a.length&&function(e){try{o(w.getConfigDir(),{recursive:!0}),l(re(),JSON.stringify({signature:e})+"\n")}catch(e){d.logError("codexAdapter.rememberAccepted",e)}}(i),a}function le(e,t,o){const n=!1!==t.settings?.one_million_context;!function(e){e.model_context_window===F&&delete e.model_context_window,e.model_auto_compact_token_limit===H&&delete e.model_auto_compact_token_limit}(e);const r=()=>{e.model_catalog_json===A()&&delete e.model_catalog_json,n&&(e.model_context_window=F,e.model_auto_compact_token_limit=H)},s=P()??T();if(!s)return d.logError("codexAdapter.writeModelCatalog",new Error("no Codex binary found; model catalog skipped")),ne="skipped",void r();const l=t.catalog,a=e=>S({bundled:e,specs:I("codex",l?.clientModels),...l?{keyModels:l.models}:{},gatewayAvailable:l?.models??D(),oneMillion:n,selectedModel:o,..."gateway"===l?.oneMillionSource?{claudeOneMillion:l.oneMillion}:{}}),c=e=>JSON.stringify(e,null,2)+"\n";let u=a(s);ie(c(u));const m=N(),p=se(c(u),m);if(p.length>0){const e=Date.now();let t=!1;for(const e of p){const o=P(e.bin);if(o){for(const e of[{models:E(u.models,o)},{models:E(a(o).models,o)}])if(ie(c(e)),0===se(c(e),m).length){u=e,t=!0;break}if(t)break}}if(O("codex-catalog",t?"fallback":"fail",{duration_ms:Date.now()-e,error:p[0].error,detail:{rejected_by:p.map(e=>({version:e.version,path:C(e.bin)}))}}),!t)return ne={rejectedBy:p[0]},i(A(),{force:!0}),void r()}ne={listed:u.models.filter(e=>"list"===e.visibility).map(e=>({id:String(e.slug),name:String(e.display_name??e.slug)}))},e.model_catalog_json=A()}export function codexCatalogRejection(){let e;try{e=Z()}catch{return null}return e.model_catalog_json===A()&&t(A())?M(A())[0]??null:null}export function setCodexOneMillionContext(e,t){const o=Z(),n=c.stringify(o),r="string"==typeof o.model?o.model:j("codex");le(o,{settings:{[CODEX_ONE_MILLION_CONTEXT_SETTING]:e},catalog:t},r);const i=c.stringify(o);i!==n&&(m(K()),p(K(),i))}const ae={command:"codex",npmPackage:"@openai/codex",native:{binDir:"win32"===process.platform?["AppData","Local","Programs","OpenAI","Codex","bin"]:[".local","bin"],updateArgs:["update"],updateTimeoutMs:12e4,dataDirs:[[".codex","packages","standalone"]]},mirrorScript:G("codex"),brew:"codex"};export const codexAdapter={name:"codex",displayName:"Codex",command:"codex",installCommand:J(ae),installSpec:ae,configPath:K(),sessions:{format:b,files:()=>[...v(a(f(),"sessions")),...v(a(f(),"archived_sessions"))],resumeCommand:e=>({command:"codex",args:["resume",e]})},wantsModelCatalog:!0,listedModels(){if(Z().model_catalog_json!==A())return null;try{return(JSON.parse(r(A(),"utf-8")).models??[]).filter(e=>"list"===e.visibility).map(e=>String(e.slug))}catch{return null}},refreshModelMenu(e){if(Z().model_catalog_json!==A())return;setCodexOneMillionContext(!1!==e.settings?.one_million_context,e.catalog);const t=Z();W(t)&&(m(K()),p(K(),c.stringify(t)))},async followUp(){if(Z().model_provider!==Y)return null;const e=await h(Y,{dryRun:!0}),t=Math.max(e.moved.length,e.dbRows);if(0===t)return null;const o=w.getToolSettings("codex")[X];if("number"==typeof o&&t<=o)return null;const n={count:String(t)};return k().length>0?{hint:u.t("tools.codex.sessions_hidden_running",n)}:{prompt:u.t("tools.codex.sessions_offer",n),hint:u.t("tools.codex.sessions_hidden",n),async run(){const e=await h(Y),t=[...new Set(e.moved.map(e=>e.from))].join("、")||"-",o=String(Math.max(e.moved.length,e.dbRows)),n=[{kind:"summary",text:u.t("codex_sessions.moved",{count:o,from:t,target:Y})},{kind:"summary",text:u.t("codex_sessions.backup",{dir:e.backupDir??""})}];return e.dbSkipped&&e.dbSkipped!==y&&n.push({kind:"action",text:u.t("codex_sessions.db_skipped",{reason:e.dbSkipped})}),n},decline(){w.setToolSetting("codex",X,t)}}},applyNotes(){if("skipped"===ne)return 0===$(ae).length?[]:[{kind:"action",text:u.t("tools.codex.catalog_skipped")}];if(!ne)return[];if("rejectedBy"in ne){const{bin:e,version:t}=ne.rejectedBy;return[{kind:"action",text:u.t("tools.codex.catalog_rejected",{path:e,version:t??"?"})}]}const e=new Map;for(const t of ne.listed)e.set(L(t.id),(e.get(L(t.id))??0)+1);const t=["gpt","claude","gemini","other","grok"].filter(t=>e.has(t)).map(t=>`${u.t(`tools.model_family.${t}`)} ${e.get(t)}`).join(" · ");return[{kind:"summary",text:u.t("tools.codex.catalog_written",{count:String(ne.listed.length),breakdown:t})},{kind:"detail",text:ne.listed.map(e=>e.name).join(", ")},...codexWorkModeOn()||q()?[{kind:"action",text:u.t(codexWorkModeOn()?"tools.codex.work_mode_on":"tools.codex.work_mode_hint")}]:[]]},loadPrivateConfig(e){const t=j("codex"),o=g(e.models,t),n=function(e){return/(?:^|\/)claude(?:-|$)/i.test(e)}(o)?t:o,r=x(e.baseUrl),i=Z();i.model=n,i.model_provider=Y,i.model_reasoning_effort="high",le(i,e,n);const s=V(i,"model_providers"),l=Q(s[Y])?{...s[Y]}:{};delete l.env_key;const{experimental_bearer_token:a,...d}=l;s[Y]={...d,name:"custom",wire_api:"responses",requires_openai_auth:!0,base_url:r},oe(i),V(V(i,"tui"),"model_availability_nux")[n]=4;const u=V(i,"features");u.goals=!0,u.js_repl=!1,W(i),m(K()),p(K(),c.stringify(i)),function(e){const t=e.trim();if(!t)return;const o={...ee(),auth_mode:"apikey",[z]:t};m(U()),p(U(),JSON.stringify(o,null,2)+"\n",384)}(e.apiKey)},holdsOurConfig(e){const t=ee()[z];return"string"==typeof t&&e.includes(t.trim())},unloadPrivateConfig(e){if(te=function(e){const t=ee(),o="string"==typeof t[z]?t[z].trim():"";if(!o)return Q(t.tokens)?"chatgpt":null;if(!e.includes(o))return"other_key";const{[z]:n,auth_mode:r,...s}=t;return m(U()),Q(s.tokens)?(p(U(),JSON.stringify({...s,auth_mode:"chatgpt"},null,2)+"\n",384),"chatgpt"):(i(U(),{force:!0}),"signed_out")}(e?.savedKeys??[]),!t(K()))return;let o;try{o=Z()}catch(e){return void d.logError("codexAdapter.unloadPrivateConfig",e)}const n=o.model_providers;Q(n)&&(delete n[Y],0===Object.keys(n).length&&delete o.model_providers),o.model_provider===Y&&delete o.model_provider,o.model_catalog_json===A()&&delete o.model_catalog_json,W(o),oe(o),m(K()),p(K(),c.stringify(o))},unloadNotes(){switch(te){case"chatgpt":return[{kind:"action",text:u.t("tools.codex.unload_chatgpt_restored")}];case"other_key":return[{kind:"action",text:u.t("tools.codex.unload_other_key")}];default:return[{kind:"action",text:u.t("tools.codex.unload_sign_in")}]}},detectCurrentConfig(){const e=ee()[z];return{apiKey:"string"==typeof e&&e.trim()?e.trim():null}},getConfig(){try{return Z()}catch(e){return d.logError("codexAdapter.getConfig",e),null}},backupPaths:()=>[K(),U(),A()]};export function codexAuthProblem(){try{const e=Z(),t=e.model_providers?.[Y];if(e.model_provider!==Y||!t)return null;if("string"==typeof t.experimental_bearer_token&&t.experimental_bearer_token)return"stale_bearer";const o=ee();return!0===t.requires_openai_auth&&"chatgpt"===o.auth_mode?"chatgpt_login":null}catch{return null}}
|
|
1
|
+
import{createHash as e}from"crypto";import{existsSync as t,mkdirSync as o,readdirSync as n,readFileSync as r,rmSync as i,statSync as s,writeFileSync as a}from"fs";import{join as l}from"path";import*as c from"@iarna/toml";import{logger as d}from"../../utils/logger.js";import{i18n as u}from"../i18n.js";import{backupBeforeWrite as m,atomicWriteFile as p}from"./backup.js";import{codexHome as f,pickModel as _,toolHome as g,withV1 as x}from"./types.js";import{moveSessionsToProvider as h,NO_STATE_DB as y,runningCodexPids as k}from"../codex-sessions.js";import{codexFormat as b,codexRolloutFiles as v}from"../sessions/formats.js";import{getToolDefaultModel as w}from"../model-registry.js";import{configManager as j}from"../config.js";import{maskHome as C,track as O}from"../telemetry.js";import{buildCodexCatalog as S,catalogRejections as M,codexCatalogPath as A,fillFromOlderEntries as E,installedCodexBinaries as N,loadBundledCodexModels as P,loadPreviousCodexModels as T,previousGatewayModelIds as D}from"./codex-catalog.js";import{gatewayModelSpecs as I,modelFamily as L}from"../gateway-models.js";import{findInstalls as $,mirrorInstallCommand as J,brandInstallScripts as G}from"./tool-installs.js";const R=()=>f(),K=()=>l(R(),"config.toml"),X="sessions_move_declined",B=["browser_use","browser_use_external","computer_use"];function U(e){const t=e.features;if(!Q(t)||!B.every(e=>!1===t[e]))return!1;for(const e of B)delete t[e];return!0}export function codexWorkModeOn(){try{const e=Z();return e.model_provider===Y&&Q(e.desktop)&&"STEPS_PROSE"===e.desktop.conversationDetailMode}catch{return!1}}function W(){try{if(Q(Z().desktop))return!0}catch{}if("darwin"===process.platform)return["/Applications",l(g(),"Applications")].some(e=>["ChatGPT.app","Codex.app"].some(o=>t(l(e,o))));if("win32"===process.platform){const e=l(process.env.LOCALAPPDATA||l(g(),"AppData","Local"),"Packages");try{return n(e).some(e=>/^OpenAI\.(Codex|ChatGPT)/i.test(e))}catch{return!1}}return t("/usr/lib/chatgpt/ChatGPT")}export function codexConfigPath(){return K()}const q=()=>l(R(),"auth.json"),z="OPENAI_API_KEY",Y="custom",F=1e6,H=9e5;export const CODEX_ONE_MILLION_CONTEXT_SETTING="one_million_context";function Q(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function V(e,t){return Q(e[t])||(e[t]={}),e[t]}function Z(){if(!t(K()))return{};const e=r(K(),"utf-8");if(!e.trim())return{};try{const t=c.parse(e);if(!Q(t))throw new Error("config.toml root must be a TOML table");return t}catch(e){throw new Error(`Existing ~/.codex/config.toml cannot be parsed; back it up and fix it first: ${e instanceof Error?e.message:String(e)}`)}}function ee(){if(!t(q()))return{};try{const e=JSON.parse(r(q(),"utf-8"));return Q(e)?e:{}}catch{return{}}}let te=null;function oe(e){const t=e.profiles;if(Q(t)){for(const[e,o]of Object.entries(t))Q(o)&&2===Object.keys(o).length&&o.model_provider===Y&&o.model===e&&delete t[e];0===Object.keys(t).length&&delete e.profiles}}let ne=null;const re=()=>l(j.getConfigDir(),"codex-catalog-check.json");function ie(e){const o=A();t(o)&&r(o,"utf-8")===e||(m(o),p(o,e))}function se(t,n){if(0===n.length)return[];const i=function(t,o){const n=e("sha256").update(t);for(const e of o)try{const t=s(e);n.update(`\0${e}\0${t.size}\0${t.mtimeMs}`)}catch{n.update(`\0${e}`)}return n.digest("hex")}(t,n);if(function(e){try{return JSON.parse(r(re(),"utf-8")).signature===e}catch{return!1}}(i))return[];const l=M(A(),n);return 0===l.length&&function(e){try{o(j.getConfigDir(),{recursive:!0}),a(re(),JSON.stringify({signature:e})+"\n")}catch(e){d.logError("codexAdapter.rememberAccepted",e)}}(i),l}function ae(e,t,o){const n=!1!==t.settings?.one_million_context;!function(e){e.model_context_window===F&&delete e.model_context_window,e.model_auto_compact_token_limit===H&&delete e.model_auto_compact_token_limit}(e);const r=()=>{e.model_catalog_json===A()&&delete e.model_catalog_json,n&&(e.model_context_window=F,e.model_auto_compact_token_limit=H)},s=P()??T();if(!s)return d.logError("codexAdapter.writeModelCatalog",new Error("no Codex binary found; model catalog skipped")),ne="skipped",void r();const a=t.catalog,l=e=>S({bundled:e,specs:I("codex",a?.clientModels),...a?{keyModels:a.models}:{},gatewayAvailable:a?.models??D(),oneMillion:n,selectedModel:o,..."gateway"===a?.oneMillionSource?{claudeOneMillion:a.oneMillion}:{}}),c=e=>JSON.stringify(e,null,2)+"\n";let u=l(s);ie(c(u));const m=N(),p=se(c(u),m);if(p.length>0){const e=Date.now();let t=!1;for(const e of p){const o=P(e.bin);if(o){for(const e of[{models:E(u.models,o)},{models:E(l(o).models,o)}])if(ie(c(e)),0===se(c(e),m).length){u=e,t=!0;break}if(t)break}}if(O("codex-catalog",t?"fallback":"fail",{duration_ms:Date.now()-e,error:p[0].error,detail:{rejected_by:p.map(e=>({version:e.version,path:C(e.bin)}))}}),!t)return ne={rejectedBy:p[0]},i(A(),{force:!0}),void r()}ne={listed:u.models.filter(e=>"list"===e.visibility).map(e=>({id:String(e.slug),name:String(e.display_name??e.slug)}))},e.model_catalog_json=A()}export function codexCatalogRejection(){let e;try{e=Z()}catch{return null}return e.model_catalog_json===A()&&t(A())?M(A())[0]??null:null}export function setCodexOneMillionContext(e,t){const o=Z(),n=c.stringify(o),r="string"==typeof o.model?o.model:w("codex");ae(o,{settings:{[CODEX_ONE_MILLION_CONTEXT_SETTING]:e},catalog:t},r);const i=c.stringify(o);i!==n&&(m(K()),p(K(),i))}const le={command:"codex",npmPackage:"@openai/codex",native:{binDir:"win32"===process.platform?["AppData","Local","Programs","OpenAI","Codex","bin"]:[".local","bin"],updateArgs:["update"],updateTimeoutMs:12e4,dataDirs:[[".codex","packages","standalone"]]},mirrorScript:G("codex"),brew:"codex"};export const codexAdapter={name:"codex",displayName:"Codex",command:"codex",installCommand:J(le),installSpec:le,configPath:K(),sessions:{format:b,files:()=>[...v(l(f(),"sessions")),...v(l(f(),"archived_sessions"))],resumeCommand:e=>({command:"codex",args:["resume",e]})},wantsModelCatalog:!0,listedModels(){if(Z().model_catalog_json!==A())return null;try{return(JSON.parse(r(A(),"utf-8")).models??[]).filter(e=>"list"===e.visibility).map(e=>String(e.slug))}catch{return null}},refreshModelMenu(e){if(Z().model_catalog_json!==A())return;setCodexOneMillionContext(!1!==e.settings?.one_million_context,e.catalog);const t=Z(),o=function(e,t){const o=Q(e.model_providers)?e.model_providers[Y]:void 0;return!(!Q(o)||o.base_url!==t||!0===o.supports_standalone_web_search||(o.supports_standalone_web_search=!0,0))}(t,x(e.baseUrl));(U(t)||o)&&(m(K()),p(K(),c.stringify(t)))},async followUp(){if(Z().model_provider!==Y)return null;const e=await h(Y,{dryRun:!0}),t=Math.max(e.moved.length,e.dbRows);if(0===t)return null;const o=j.getToolSettings("codex")[X];if("number"==typeof o&&t<=o)return null;const n={count:String(t)};return k().length>0?{hint:u.t("tools.codex.sessions_hidden_running",n)}:{prompt:u.t("tools.codex.sessions_offer",n),hint:u.t("tools.codex.sessions_hidden",n),async run(){const e=await h(Y),t=[...new Set(e.moved.map(e=>e.from))].join("、")||"-",o=String(Math.max(e.moved.length,e.dbRows)),n=[{kind:"summary",text:u.t("codex_sessions.moved",{count:o,from:t,target:Y})},{kind:"summary",text:u.t("codex_sessions.backup",{dir:e.backupDir??""})}];return e.dbSkipped&&e.dbSkipped!==y&&n.push({kind:"action",text:u.t("codex_sessions.db_skipped",{reason:e.dbSkipped})}),n},decline(){j.setToolSetting("codex",X,t)}}},applyNotes(){if("skipped"===ne)return 0===$(le).length?[]:[{kind:"action",text:u.t("tools.codex.catalog_skipped")}];if(!ne)return[];if("rejectedBy"in ne){const{bin:e,version:t}=ne.rejectedBy;return[{kind:"action",text:u.t("tools.codex.catalog_rejected",{path:e,version:t??"?"})}]}const e=new Map;for(const t of ne.listed)e.set(L(t.id),(e.get(L(t.id))??0)+1);const t=["gpt","claude","gemini","other","grok"].filter(t=>e.has(t)).map(t=>`${u.t(`tools.model_family.${t}`)} ${e.get(t)}`).join(" · ");return[{kind:"summary",text:u.t("tools.codex.catalog_written",{count:String(ne.listed.length),breakdown:t})},{kind:"detail",text:ne.listed.map(e=>e.name).join(", ")},...codexWorkModeOn()||W()?[{kind:"action",text:u.t(codexWorkModeOn()?"tools.codex.work_mode_on":"tools.codex.work_mode_hint")}]:[]]},loadPrivateConfig(e){const t=w("codex"),o=_(e.models,t),n=function(e){return/(?:^|\/)claude(?:-|$)/i.test(e)}(o)?t:o,r=x(e.baseUrl),i=Z();i.model=n,i.model_provider=Y,i.model_reasoning_effort="high",ae(i,e,n);const s=V(i,"model_providers"),a=Q(s[Y])?{...s[Y]}:{};delete a.env_key;const{experimental_bearer_token:l,...d}=a;s[Y]={...d,name:"custom",wire_api:"responses",requires_openai_auth:!0,supports_standalone_web_search:!0,base_url:r},oe(i),V(V(i,"tui"),"model_availability_nux")[n]=4;const u=V(i,"features");u.goals=!0,u.js_repl=!1,U(i),m(K()),p(K(),c.stringify(i)),function(e){const t=e.trim();if(!t)return;const o={...ee(),auth_mode:"apikey",[z]:t};m(q()),p(q(),JSON.stringify(o,null,2)+"\n",384)}(e.apiKey)},holdsOurConfig(e){const t=ee()[z];return"string"==typeof t&&e.includes(t.trim())},unloadPrivateConfig(e){if(te=function(e){const t=ee(),o="string"==typeof t[z]?t[z].trim():"";if(!o)return Q(t.tokens)?"chatgpt":null;if(!e.includes(o))return"other_key";const{[z]:n,auth_mode:r,...s}=t;return m(q()),Q(s.tokens)?(p(q(),JSON.stringify({...s,auth_mode:"chatgpt"},null,2)+"\n",384),"chatgpt"):(i(q(),{force:!0}),"signed_out")}(e?.savedKeys??[]),!t(K()))return;let o;try{o=Z()}catch(e){return void d.logError("codexAdapter.unloadPrivateConfig",e)}const n=o.model_providers;Q(n)&&(delete n[Y],0===Object.keys(n).length&&delete o.model_providers),o.model_provider===Y&&delete o.model_provider,o.model_catalog_json===A()&&delete o.model_catalog_json,U(o),oe(o),m(K()),p(K(),c.stringify(o))},unloadNotes(){switch(te){case"chatgpt":return[{kind:"action",text:u.t("tools.codex.unload_chatgpt_restored")}];case"other_key":return[{kind:"action",text:u.t("tools.codex.unload_other_key")}];default:return[{kind:"action",text:u.t("tools.codex.unload_sign_in")}]}},detectCurrentConfig(){const e=ee()[z];return{apiKey:"string"==typeof e&&e.trim()?e.trim():null}},getConfig(){try{return Z()}catch(e){return d.logError("codexAdapter.getConfig",e),null}},backupPaths:()=>[K(),q(),A()]};export function codexAuthProblem(){try{const e=Z(),t=e.model_providers?.[Y];if(e.model_provider!==Y||!t)return null;if("string"==typeof t.experimental_bearer_token&&t.experimental_bearer_token)return"stale_bearer";const o=ee();return!0===t.requires_openai_auth&&"chatgpt"===o.auth_mode?"chatgpt_login":null}catch{return null}}
|