@wlv-zedd/dsh-chatgpt-web 1.0.4 → 1.0.5
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.
- package/lib/cli.js +98 -32
- package/package.json +1 -1
- package/src/adapters/chatgpt-web/browser-worker.ts +56 -19
- package/src/adapters/chatgpt-web/model.ts +10 -6
- package/src/chatgpt-session.ts +14 -4
- package/src/chatgpt-web-models.ts +44 -10
- package/src/model-catalog.ts +1 -1
- package/src/version.ts +1 -1
package/lib/cli.js
CHANGED
|
@@ -25,6 +25,7 @@ import { tmpdir } from "node:os";
|
|
|
25
25
|
var CHATGPT_WEB_MODEL_PREFIX = "chatgpt-web/";
|
|
26
26
|
var CHATGPT_WEB_BACKEND_MODEL = "gpt-5.6-sol";
|
|
27
27
|
var CHATGPT_WEB_LUNA_BACKEND_MODEL = "gpt-5.6-luna";
|
|
28
|
+
var CHATGPT_WEB_GPT6_BACKEND_MODEL = "gpt-6";
|
|
28
29
|
var CHATGPT_WEB_ZERO_RISK_BACKEND_MODEL = "chatgpt-web-zero-risk";
|
|
29
30
|
var CHATGPT_WEB_ZERO_RISK_PRO_BACKEND_MODEL = "chatgpt-web-zero-risk-pro";
|
|
30
31
|
var CHATGPT_WEB_INSTANT_CONTEXT_WINDOW = 41000;
|
|
@@ -166,8 +167,8 @@ var CHATGPT_WEB_LUNA_MODEL_ROUTES = [
|
|
|
166
167
|
var CHATGPT_WEB_MODEL_ROUTES = [
|
|
167
168
|
{
|
|
168
169
|
slug: "chatgpt-web/light",
|
|
169
|
-
displayName: "ChatGPT Web — Instant",
|
|
170
|
-
description: "
|
|
170
|
+
displayName: "ChatGPT Web — GPT-5.6 Sol Instant (即时)",
|
|
171
|
+
description: "通过原生 Codex 通道的 ChatGPT Web 即时档 (Instant)。",
|
|
171
172
|
interactionMode: "automatic",
|
|
172
173
|
backendModel: CHATGPT_WEB_BACKEND_MODEL,
|
|
173
174
|
codexEffort: "low",
|
|
@@ -176,8 +177,8 @@ var CHATGPT_WEB_MODEL_ROUTES = [
|
|
|
176
177
|
},
|
|
177
178
|
{
|
|
178
179
|
slug: "chatgpt-web/medium",
|
|
179
|
-
displayName: "ChatGPT Web — Medium",
|
|
180
|
-
description: "
|
|
180
|
+
displayName: "ChatGPT Web — GPT-5.6 Sol Medium (中等)",
|
|
181
|
+
description: "通过原生 Codex 通道的 ChatGPT Web 中等档 (Medium)。",
|
|
181
182
|
interactionMode: "automatic",
|
|
182
183
|
backendModel: CHATGPT_WEB_BACKEND_MODEL,
|
|
183
184
|
codexEffort: "medium",
|
|
@@ -186,18 +187,48 @@ var CHATGPT_WEB_MODEL_ROUTES = [
|
|
|
186
187
|
},
|
|
187
188
|
{
|
|
188
189
|
slug: "chatgpt-web/high",
|
|
189
|
-
displayName: "ChatGPT Web — High",
|
|
190
|
-
description: "
|
|
190
|
+
displayName: "ChatGPT Web — GPT-5.6 Sol High (高)",
|
|
191
|
+
description: "通过原生 Codex 通道的 ChatGPT Web 高档 (High)。",
|
|
191
192
|
interactionMode: "automatic",
|
|
192
193
|
backendModel: CHATGPT_WEB_BACKEND_MODEL,
|
|
193
194
|
codexEffort: "high",
|
|
194
195
|
adapterEffort: "high",
|
|
195
196
|
requiresPro: false
|
|
196
197
|
},
|
|
198
|
+
{
|
|
199
|
+
slug: "chatgpt-web/gpt-6-light",
|
|
200
|
+
displayName: "ChatGPT Web — GPT-6 Instant (即时)",
|
|
201
|
+
description: "通过原生 Codex 通道的 ChatGPT GPT-6 即时档(Plus 选择器,2026-10 / GPT-6 Instant)。",
|
|
202
|
+
interactionMode: "automatic",
|
|
203
|
+
backendModel: CHATGPT_WEB_GPT6_BACKEND_MODEL,
|
|
204
|
+
codexEffort: "low",
|
|
205
|
+
adapterEffort: "low",
|
|
206
|
+
requiresPro: false
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
slug: "chatgpt-web/gpt-6-medium",
|
|
210
|
+
displayName: "ChatGPT Web — GPT-6 Medium (中等)",
|
|
211
|
+
description: "通过原生 Codex 通道的 ChatGPT GPT-6 中等档(Plus 选择器,2026-10 / GPT-6 Medium)。",
|
|
212
|
+
interactionMode: "automatic",
|
|
213
|
+
backendModel: CHATGPT_WEB_GPT6_BACKEND_MODEL,
|
|
214
|
+
codexEffort: "medium",
|
|
215
|
+
adapterEffort: "medium",
|
|
216
|
+
requiresPro: false
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
slug: "chatgpt-web/gpt-6-high",
|
|
220
|
+
displayName: "ChatGPT Web — GPT-6 High (高)",
|
|
221
|
+
description: "通过原生 Codex 通道的 ChatGPT GPT-6 高档(Plus 选择器,2026-10 / GPT-6 High)。",
|
|
222
|
+
interactionMode: "automatic",
|
|
223
|
+
backendModel: CHATGPT_WEB_GPT6_BACKEND_MODEL,
|
|
224
|
+
codexEffort: "high",
|
|
225
|
+
adapterEffort: "high",
|
|
226
|
+
requiresPro: false
|
|
227
|
+
},
|
|
197
228
|
{
|
|
198
229
|
slug: "chatgpt-web/extra-high",
|
|
199
|
-
displayName: "ChatGPT Web — Extra High",
|
|
200
|
-
description: "
|
|
230
|
+
displayName: "ChatGPT Web — Extra High (超高)",
|
|
231
|
+
description: "按账号开放的超高档 ChatGPT Web (Extra High,通过原生 Codex 通道)。",
|
|
201
232
|
interactionMode: "automatic",
|
|
202
233
|
backendModel: CHATGPT_WEB_BACKEND_MODEL,
|
|
203
234
|
codexEffort: "xhigh",
|
|
@@ -207,7 +238,7 @@ var CHATGPT_WEB_MODEL_ROUTES = [
|
|
|
207
238
|
{
|
|
208
239
|
slug: "chatgpt-web/pro",
|
|
209
240
|
displayName: "ChatGPT Web — Pro",
|
|
210
|
-
description: "
|
|
241
|
+
description: "按账号开放的 ChatGPT Pro (通过原生 Codex 通道)。",
|
|
211
242
|
interactionMode: "automatic",
|
|
212
243
|
backendModel: CHATGPT_WEB_BACKEND_MODEL,
|
|
213
244
|
codexEffort: "ultra",
|
|
@@ -270,7 +301,7 @@ function requireChatGptWebModelRoute(modelId, capabilities) {
|
|
|
270
301
|
}
|
|
271
302
|
|
|
272
303
|
// src/version.ts
|
|
273
|
-
var VERSION = "1.0.
|
|
304
|
+
var VERSION = "1.0.5";
|
|
274
305
|
|
|
275
306
|
// src/config.ts
|
|
276
307
|
var CHATGPT_CONNECTOR_NAME = "Codex Native2";
|
|
@@ -844,15 +875,20 @@ var CHATGPT_COMPOSER_SELECTOR = [
|
|
|
844
875
|
].join(", ");
|
|
845
876
|
var CHATGPT_EFFORT_CONTROL_SELECTOR = [
|
|
846
877
|
'button[aria-haspopup="menu"][data-tone="neutral"]',
|
|
847
|
-
'button[data-testid="model-switcher-dropdown-button"][aria-haspopup="menu"]'
|
|
878
|
+
'button[data-testid="model-switcher-dropdown-button"][aria-haspopup="menu"]',
|
|
879
|
+
'button[aria-haspopup="menu"][aria-label="选择 ChatGPT 模型"]',
|
|
880
|
+
'button[aria-haspopup="menu"][aria-label*="ChatGPT"][aria-label*="model" i]'
|
|
848
881
|
].join(", ");
|
|
849
882
|
var CHATGPT_EFFORT_MENU_SELECTOR = [
|
|
850
|
-
'[data-testid="composer-intelligence-picker-content"]:has([role="menuitemradio"], [data-model-reasoning-effort-slider])',
|
|
851
|
-
'[role="menu"]:has([role="menuitemradio"], [data-model-reasoning-effort-slider])',
|
|
852
|
-
'[role="group"]:has([role="menuitemradio"], [data-model-reasoning-effort-slider])'
|
|
883
|
+
'[data-testid="composer-intelligence-picker-content"]:has([role="menuitemradio"], [data-model-reasoning-effort-slider], [data-model-picker-power-slider])',
|
|
884
|
+
'[role="menu"]:has([role="menuitemradio"], [data-model-reasoning-effort-slider], [data-model-picker-power-slider])',
|
|
885
|
+
'[role="group"]:has([role="menuitemradio"], [data-model-reasoning-effort-slider], [data-model-picker-power-slider])'
|
|
853
886
|
].join(", ");
|
|
854
887
|
var CHATGPT_EFFORT_ITEM_SELECTOR = '[role="menuitemradio"]';
|
|
855
|
-
var CHATGPT_EFFORT_SLIDER_SELECTOR =
|
|
888
|
+
var CHATGPT_EFFORT_SLIDER_SELECTOR = [
|
|
889
|
+
'[data-model-picker-power-slider] [role="slider"]',
|
|
890
|
+
'[data-model-reasoning-effort-slider] [role="slider"]'
|
|
891
|
+
].join(", ");
|
|
856
892
|
var CHATGPT_EFFORT_SLIDER_MAX_OPTIONS = 5;
|
|
857
893
|
var CHATGPT_STOP_BUTTON_SELECTOR = [
|
|
858
894
|
'[data-testid="stop-button"]',
|
|
@@ -7334,6 +7370,7 @@ class ChatGptMarkdownBuffer {
|
|
|
7334
7370
|
|
|
7335
7371
|
// src/adapters/chatgpt-web/model.ts
|
|
7336
7372
|
var CHATGPT_WEB_MODEL_ID = CHATGPT_WEB_BACKEND_MODEL;
|
|
7373
|
+
var CHATGPT_WEB_GPT6_MODEL_ID = CHATGPT_WEB_GPT6_BACKEND_MODEL;
|
|
7337
7374
|
var CHATGPT_WEB_LUNA_MODEL_ID = CHATGPT_WEB_LUNA_BACKEND_MODEL;
|
|
7338
7375
|
function resolveChatGptWebModelMode(modelId, reasoning, capabilities) {
|
|
7339
7376
|
if (modelId === CHATGPT_WEB_LUNA_MODEL_ID) {
|
|
@@ -7354,7 +7391,7 @@ function resolveChatGptWebModelMode(modelId, reasoning, capabilities) {
|
|
|
7354
7391
|
localTools: capabilities.localToolsEnabled
|
|
7355
7392
|
};
|
|
7356
7393
|
}
|
|
7357
|
-
if (modelId !== CHATGPT_WEB_MODEL_ID) {
|
|
7394
|
+
if (modelId !== CHATGPT_WEB_MODEL_ID && modelId !== CHATGPT_WEB_GPT6_MODEL_ID) {
|
|
7358
7395
|
throw new Error(`ChatGPT web model is not supported: ${modelId}`);
|
|
7359
7396
|
}
|
|
7360
7397
|
if (!capabilities.solAvailable) {
|
|
@@ -7363,15 +7400,15 @@ function resolveChatGptWebModelMode(modelId, reasoning, capabilities) {
|
|
|
7363
7400
|
const effort = reasoning ?? "high";
|
|
7364
7401
|
switch (effort) {
|
|
7365
7402
|
case "low":
|
|
7366
|
-
return { modelId, effort, displayLabel: "Instant", uiEffortIndex: 0, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
7403
|
+
return { modelId, effort, displayLabel: "Instant (即时)", uiEffortIndex: 0, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
7367
7404
|
case "medium":
|
|
7368
|
-
return { modelId, effort, displayLabel: "Medium", uiEffortIndex: 1, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
7405
|
+
return { modelId, effort, displayLabel: "Medium (中等)", uiEffortIndex: 1, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
7369
7406
|
case "high":
|
|
7370
|
-
return { modelId, effort, displayLabel: "High", uiEffortIndex: 2, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
7407
|
+
return { modelId, effort, displayLabel: "High (高)", uiEffortIndex: 2, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
7371
7408
|
case "xhigh":
|
|
7372
7409
|
if (!capabilities.proAvailable)
|
|
7373
7410
|
throw new Error("ChatGPT Extra High effort is not available for this account");
|
|
7374
|
-
return { modelId, effort, displayLabel: "Extra High", uiEffortIndex: 3, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
7411
|
+
return { modelId, effort, displayLabel: "Extra High (超高)", uiEffortIndex: 3, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
7375
7412
|
case "max":
|
|
7376
7413
|
if (!capabilities.proAvailable)
|
|
7377
7414
|
throw new Error("ChatGPT Pro effort is not available for this account");
|
|
@@ -10856,7 +10893,7 @@ async function resolveChatGptToolConfirmation(page, appName, autoApprove, signal
|
|
|
10856
10893
|
return true;
|
|
10857
10894
|
}
|
|
10858
10895
|
function assertChatGptWebInputWithinLimits(estimatedInputTokens, estimatedMessageTokens, modelId, effort, capabilities, promptChars, composerCharLimitOverride) {
|
|
10859
|
-
if (modelId !== CHATGPT_WEB_MODEL_ID && modelId !== CHATGPT_WEB_LUNA_MODEL_ID) {
|
|
10896
|
+
if (modelId !== CHATGPT_WEB_MODEL_ID && modelId !== CHATGPT_WEB_LUNA_MODEL_ID && modelId !== CHATGPT_WEB_GPT6_MODEL_ID) {
|
|
10860
10897
|
throw new Error(`ChatGPT web context limit is not defined for model: ${modelId}`);
|
|
10861
10898
|
}
|
|
10862
10899
|
if (modelId === CHATGPT_WEB_LUNA_MODEL_ID && estimatedInputTokens > CHATGPT_LUNA_BROWSER_INPUT_TOKEN_BUDGET) {
|
|
@@ -10879,7 +10916,7 @@ function assertChatGptWebMultipartInputWithinLimits(estimatedInputTokens, estima
|
|
|
10879
10916
|
if (modelId === CHATGPT_WEB_LUNA_MODEL_ID) {
|
|
10880
10917
|
throw new ChatGptWebAdapterError("Bigger Context is unavailable for Luna because every later browser request includes the accumulated transcript inside the same 28,000-token transport budget.", { status: 400, errorType: "invalid_request_error", code: "context_length_exceeded", retryable: false });
|
|
10881
10918
|
}
|
|
10882
|
-
if (modelId !== CHATGPT_WEB_MODEL_ID) {
|
|
10919
|
+
if (modelId !== CHATGPT_WEB_MODEL_ID && modelId !== CHATGPT_WEB_GPT6_MODEL_ID) {
|
|
10883
10920
|
throw new Error(`ChatGPT Bigger Context limit is not defined for model: ${modelId}`);
|
|
10884
10921
|
}
|
|
10885
10922
|
const { contextWindow: baseContextWindow } = resolveChatGptWebContextLimits(modelId, effort, { ...capabilities, experimentalBiggerContext: false });
|
|
@@ -10908,7 +10945,7 @@ function resolveChatGptWebMultipartStagingMode(modelId, capabilities, requestedE
|
|
|
10908
10945
|
if (modelId === CHATGPT_WEB_LUNA_MODEL_ID || !capabilities.solAvailable) {
|
|
10909
10946
|
throw new ChatGptWebAdapterError("Bigger Context staging is unavailable for a Luna-only account.", { status: 400, errorType: "invalid_request_error", code: "context_length_exceeded", retryable: false });
|
|
10910
10947
|
}
|
|
10911
|
-
if (modelId !== CHATGPT_WEB_MODEL_ID) {
|
|
10948
|
+
if (modelId !== CHATGPT_WEB_MODEL_ID && modelId !== CHATGPT_WEB_GPT6_MODEL_ID) {
|
|
10912
10949
|
throw new Error(`ChatGPT Bigger Context staging mode is not defined for model: ${modelId}`);
|
|
10913
10950
|
}
|
|
10914
10951
|
const efforts = capabilities.proAvailable ? ["low", "medium", "max"] : ["low", "medium"];
|
|
@@ -11560,6 +11597,34 @@ function insertPlainTextIntoComposer(element, value) {
|
|
|
11560
11597
|
}
|
|
11561
11598
|
return document.execCommand("insertText", false, value);
|
|
11562
11599
|
}
|
|
11600
|
+
var CHATGPT_SEND_BUTTON_SELECTORS = [
|
|
11601
|
+
'[data-testid="send-button"]',
|
|
11602
|
+
'button[aria-label="Send"]',
|
|
11603
|
+
'button[aria-label="发送"]',
|
|
11604
|
+
'button[aria-label="发送消息"]',
|
|
11605
|
+
'button[aria-label*="Send" i]',
|
|
11606
|
+
'button[aria-label*="发送"]'
|
|
11607
|
+
].join(", ");
|
|
11608
|
+
async function resolveChatGptComposerContainer(composer, page) {
|
|
11609
|
+
const formScope = composer.locator("xpath=ancestor::form[1]");
|
|
11610
|
+
if (await formScope.count().catch(() => 0) > 0)
|
|
11611
|
+
return formScope.first();
|
|
11612
|
+
const containerScope = composer.locator("xpath=ancestor::*[self::form or self::div or @role='group' or @role='region'][1]");
|
|
11613
|
+
if (await containerScope.count().catch(() => 0) > 0)
|
|
11614
|
+
return containerScope.first();
|
|
11615
|
+
return composer;
|
|
11616
|
+
}
|
|
11617
|
+
async function resolveChatGptSendButton(composer, page) {
|
|
11618
|
+
const formScope = composer.locator("xpath=ancestor::form[1]").locator(CHATGPT_SEND_BUTTON_SELECTORS);
|
|
11619
|
+
if (await formScope.count().catch(() => 0) > 0)
|
|
11620
|
+
return formScope.first();
|
|
11621
|
+
const containerScope = composer.locator("xpath=ancestor::*[self::form or self::div or @role='group' or @role='region'][1]").locator(CHATGPT_SEND_BUTTON_SELECTORS);
|
|
11622
|
+
if (await containerScope.count().catch(() => 0) > 0)
|
|
11623
|
+
return containerScope.first();
|
|
11624
|
+
if (page)
|
|
11625
|
+
return page.locator(CHATGPT_SEND_BUTTON_SELECTORS).first();
|
|
11626
|
+
return composer.locator(CHATGPT_SEND_BUTTON_SELECTORS).first();
|
|
11627
|
+
}
|
|
11563
11628
|
|
|
11564
11629
|
class ChatGptBrowserWorker {
|
|
11565
11630
|
config;
|
|
@@ -11858,7 +11923,7 @@ class ChatGptBrowserWorker {
|
|
|
11858
11923
|
await throwIfChatGptRateLimitDialog(page);
|
|
11859
11924
|
if (ready === "session-expired")
|
|
11860
11925
|
await throwIfChatGptSessionFailureAlert(page);
|
|
11861
|
-
if (
|
|
11926
|
+
if (await effortSlider.isVisible().catch(() => false))
|
|
11862
11927
|
ready = "slider";
|
|
11863
11928
|
await captureDiagnostic?.(ready === "slider" ? "effort-slider-visible" : "effort-choice-visible");
|
|
11864
11929
|
} catch (error) {
|
|
@@ -11875,11 +11940,11 @@ class ChatGptBrowserWorker {
|
|
|
11875
11940
|
if (!sliderState) {
|
|
11876
11941
|
throw chatGptModelControlUnavailableAdapterError("ChatGPT effort slider exposed an invalid ARIA range");
|
|
11877
11942
|
}
|
|
11878
|
-
const
|
|
11879
|
-
if (
|
|
11880
|
-
|
|
11881
|
-
throw chatGptModelControlUnavailableAdapterError(`ChatGPT effort slider does not expose item index ${uiEffortIndex}` + ` (min=${sliderState.min}; max=${sliderState.max})` + proUsageLimitHint);
|
|
11943
|
+
const requestedStop = sliderState.min + uiEffortIndex;
|
|
11944
|
+
if (requestedStop > sliderState.max) {
|
|
11945
|
+
throw chatGptModelControlUnavailableAdapterError(`ChatGPT effort slider does not expose item index ${uiEffortIndex}` + ` (min=${sliderState.min}; max=${sliderState.max})` + ". This account's picker exposes three effort stops only.");
|
|
11882
11946
|
}
|
|
11947
|
+
const targetValue = requestedStop;
|
|
11883
11948
|
const sliderControl = effortSlider.locator("xpath=ancestor::*[@role='menuitem'][1]");
|
|
11884
11949
|
while (sliderState.value !== targetValue) {
|
|
11885
11950
|
await throwIfChatGptRateLimitDialog(page);
|
|
@@ -12575,7 +12640,8 @@ class ChatGptBrowserWorker {
|
|
|
12575
12640
|
}
|
|
12576
12641
|
async sendAttachedPrompt(page, baseline, captureDiagnostic, abortSignal, externalProgress, submissionLifecycle, completionTracker, recoverObservation) {
|
|
12577
12642
|
const composer = await this.activeComposer(page);
|
|
12578
|
-
const sendButton = composer
|
|
12643
|
+
const sendButton = await resolveChatGptSendButton(composer, page);
|
|
12644
|
+
await captureDiagnostic?.("send-button-resolved");
|
|
12579
12645
|
await sendButton.waitFor({ state: "visible", timeout: browserStageTimeouts.send });
|
|
12580
12646
|
await settleChatGptUi();
|
|
12581
12647
|
const sendEnableDeadline = Date.now() + this.config.tuning.sendEnableGraceMs;
|
|
@@ -12791,17 +12857,17 @@ class ChatGptBrowserWorker {
|
|
|
12791
12857
|
if (files.length === 0)
|
|
12792
12858
|
return;
|
|
12793
12859
|
const composer = await this.activeComposer(page);
|
|
12794
|
-
const
|
|
12860
|
+
const composerContainer = await resolveChatGptComposerContainer(composer, page);
|
|
12795
12861
|
const input = page.locator('input[data-testid="upload-photos-input"]');
|
|
12796
12862
|
await input.waitFor({ state: "attached", timeout: 20000 });
|
|
12797
12863
|
await input.setInputFiles(files);
|
|
12798
12864
|
try {
|
|
12799
|
-
await Promise.all(files.map((file) =>
|
|
12865
|
+
await Promise.all(files.map((file) => composerContainer.getByRole("group", { name: file.name, exact: true }).waitFor({ state: "visible", timeout: 60000 })));
|
|
12800
12866
|
} catch {
|
|
12801
12867
|
const alerts = (await page.locator('[role="alert"]').allInnerTexts().catch(() => [])).map((text) => text.replace(/\s+/g, " ").trim()).filter(Boolean);
|
|
12802
12868
|
throw new Error(`ChatGPT did not accept all prompt attachments` + (alerts.length > 0 ? `: ${alerts.join(" | ")}` : ""));
|
|
12803
12869
|
}
|
|
12804
|
-
const send =
|
|
12870
|
+
const send = await resolveChatGptSendButton(composer, page);
|
|
12805
12871
|
const deadline = Date.now() + 60000;
|
|
12806
12872
|
while (Date.now() < deadline) {
|
|
12807
12873
|
if (await send.isEnabled().catch(() => false))
|
package/package.json
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
type ChatGptMarkdownSegment,
|
|
25
25
|
} from "./markdown";
|
|
26
26
|
import {
|
|
27
|
+
CHATGPT_WEB_GPT6_MODEL_ID,
|
|
27
28
|
CHATGPT_WEB_LUNA_MODEL_ID,
|
|
28
29
|
CHATGPT_WEB_MODEL_ID,
|
|
29
30
|
resolveChatGptWebModelMode,
|
|
@@ -879,7 +880,11 @@ export function assertChatGptWebInputWithinLimits(
|
|
|
879
880
|
promptChars?: number,
|
|
880
881
|
composerCharLimitOverride?: number,
|
|
881
882
|
): void {
|
|
882
|
-
if (
|
|
883
|
+
if (
|
|
884
|
+
modelId !== CHATGPT_WEB_MODEL_ID
|
|
885
|
+
&& modelId !== CHATGPT_WEB_LUNA_MODEL_ID
|
|
886
|
+
&& modelId !== CHATGPT_WEB_GPT6_MODEL_ID
|
|
887
|
+
) {
|
|
883
888
|
throw new Error(`ChatGPT web context limit is not defined for model: ${modelId}`);
|
|
884
889
|
}
|
|
885
890
|
if (
|
|
@@ -945,7 +950,8 @@ export function assertChatGptWebMultipartInputWithinLimits(
|
|
|
945
950
|
{ status: 400, errorType: "invalid_request_error", code: "context_length_exceeded", retryable: false },
|
|
946
951
|
);
|
|
947
952
|
}
|
|
948
|
-
|
|
953
|
+
// GPT-6 shares the Sol-class Plus transport windows, so Bigger Context applies to it too.
|
|
954
|
+
if (modelId !== CHATGPT_WEB_MODEL_ID && modelId !== CHATGPT_WEB_GPT6_MODEL_ID) {
|
|
949
955
|
throw new Error(`ChatGPT Bigger Context limit is not defined for model: ${modelId}`);
|
|
950
956
|
}
|
|
951
957
|
const { contextWindow: baseContextWindow } = resolveChatGptWebContextLimits(
|
|
@@ -1016,7 +1022,7 @@ export function resolveChatGptWebMultipartStagingMode(
|
|
|
1016
1022
|
{ status: 400, errorType: "invalid_request_error", code: "context_length_exceeded", retryable: false },
|
|
1017
1023
|
);
|
|
1018
1024
|
}
|
|
1019
|
-
if (modelId !== CHATGPT_WEB_MODEL_ID) {
|
|
1025
|
+
if (modelId !== CHATGPT_WEB_MODEL_ID && modelId !== CHATGPT_WEB_GPT6_MODEL_ID) {
|
|
1020
1026
|
throw new Error(`ChatGPT Bigger Context staging mode is not defined for model: ${modelId}`);
|
|
1021
1027
|
}
|
|
1022
1028
|
const efforts: readonly ChatGptWebModelMode["effort"][] = capabilities.proAvailable
|
|
@@ -2013,6 +2019,37 @@ export function insertPlainTextIntoComposer(element: HTMLElement, value: string)
|
|
|
2013
2019
|
return document.execCommand("insertText", false, value);
|
|
2014
2020
|
}
|
|
2015
2021
|
|
|
2022
|
+
export const CHATGPT_SEND_BUTTON_SELECTORS = [
|
|
2023
|
+
'[data-testid="send-button"]',
|
|
2024
|
+
'button[aria-label="Send"]',
|
|
2025
|
+
'button[aria-label="发送"]',
|
|
2026
|
+
'button[aria-label="发送消息"]',
|
|
2027
|
+
'button[aria-label*="Send" i]',
|
|
2028
|
+
'button[aria-label*="发送"]',
|
|
2029
|
+
].join(", ");
|
|
2030
|
+
|
|
2031
|
+
export async function resolveChatGptComposerContainer(composer: Locator, page?: Page): Promise<Locator> {
|
|
2032
|
+
const formScope = composer.locator("xpath=ancestor::form[1]");
|
|
2033
|
+
if (await formScope.count().catch(() => 0) > 0) return formScope.first();
|
|
2034
|
+
const containerScope = composer.locator("xpath=ancestor::*[self::form or self::div or @role='group' or @role='region'][1]");
|
|
2035
|
+
if (await containerScope.count().catch(() => 0) > 0) return containerScope.first();
|
|
2036
|
+
return composer;
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
export async function resolveChatGptSendButton(composer: Locator, page?: Page): Promise<Locator> {
|
|
2040
|
+
// Strategy 1: Ancestor form if present
|
|
2041
|
+
const formScope = composer.locator("xpath=ancestor::form[1]").locator(CHATGPT_SEND_BUTTON_SELECTORS);
|
|
2042
|
+
if (await formScope.count().catch(() => 0) > 0) return formScope.first();
|
|
2043
|
+
|
|
2044
|
+
// Strategy 2: Ancestor container (div, role=group, role=region)
|
|
2045
|
+
const containerScope = composer.locator("xpath=ancestor::*[self::form or self::div or @role='group' or @role='region'][1]").locator(CHATGPT_SEND_BUTTON_SELECTORS);
|
|
2046
|
+
if (await containerScope.count().catch(() => 0) > 0) return containerScope.first();
|
|
2047
|
+
|
|
2048
|
+
// Strategy 3: Page-level active send button fallback
|
|
2049
|
+
if (page) return page.locator(CHATGPT_SEND_BUTTON_SELECTORS).first();
|
|
2050
|
+
return composer.locator(CHATGPT_SEND_BUTTON_SELECTORS).first();
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2016
2053
|
export class ChatGptBrowserWorker {
|
|
2017
2054
|
static forProvider(provider: CodexProviderConfig): ChatGptBrowserWorker {
|
|
2018
2055
|
const config = resolveBrowserConfig(provider);
|
|
@@ -2371,9 +2408,10 @@ export class ChatGptBrowserWorker {
|
|
|
2371
2408
|
]);
|
|
2372
2409
|
if (ready === "rate-limit") await throwIfChatGptRateLimitDialog(page);
|
|
2373
2410
|
if (ready === "session-expired") await throwIfChatGptSessionFailureAlert(page);
|
|
2374
|
-
// The current picker exposes model rows as menuitemradio
|
|
2375
|
-
// Those rows
|
|
2376
|
-
|
|
2411
|
+
// The current picker exposes model rows as menuitemradio ALONGSIDE the effort slider.
|
|
2412
|
+
// Those rows are models, not effort choices, so a visible slider is authoritative:
|
|
2413
|
+
// we drive effort with arrow keys and never index the rows.
|
|
2414
|
+
if (await effortSlider.isVisible().catch(() => false)) ready = "slider";
|
|
2377
2415
|
await captureDiagnostic?.(ready === "slider" ? "effort-slider-visible" : "effort-choice-visible");
|
|
2378
2416
|
} catch (error) {
|
|
2379
2417
|
if (error instanceof ChatGptWebAdapterError) throw error;
|
|
@@ -2397,17 +2435,18 @@ export class ChatGptBrowserWorker {
|
|
|
2397
2435
|
"ChatGPT effort slider exposed an invalid ARIA range",
|
|
2398
2436
|
);
|
|
2399
2437
|
}
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2438
|
+
// The Plus picker only exposes three stops (Low/Medium/High). If the caller requested a
|
|
2439
|
+
// higher stop that the UI cannot reach, reject it here instead of letting the slider
|
|
2440
|
+
// loop fail silently or silently cap to a lower level.
|
|
2441
|
+
const requestedStop = sliderState.min + uiEffortIndex;
|
|
2442
|
+
if (requestedStop > sliderState.max) {
|
|
2405
2443
|
throw chatGptModelControlUnavailableAdapterError(
|
|
2406
2444
|
`ChatGPT effort slider does not expose item index ${uiEffortIndex}`
|
|
2407
2445
|
+ ` (min=${sliderState.min}; max=${sliderState.max})`
|
|
2408
|
-
+
|
|
2446
|
+
+ ". This account's picker exposes three effort stops only.",
|
|
2409
2447
|
);
|
|
2410
2448
|
}
|
|
2449
|
+
const targetValue = requestedStop;
|
|
2411
2450
|
const sliderControl = effortSlider.locator("xpath=ancestor::*[@role='menuitem'][1]");
|
|
2412
2451
|
while (sliderState.value !== targetValue) {
|
|
2413
2452
|
await throwIfChatGptRateLimitDialog(page);
|
|
@@ -3414,10 +3453,8 @@ export class ChatGptBrowserWorker {
|
|
|
3414
3453
|
recoverObservation?: ChatGptObservationRecovery,
|
|
3415
3454
|
): Promise<ChatGptSubmissionEvidence> {
|
|
3416
3455
|
const composer = await this.activeComposer(page);
|
|
3417
|
-
const sendButton = composer
|
|
3418
|
-
|
|
3419
|
-
.locator('[data-testid="send-button"], button[aria-label="Send"]')
|
|
3420
|
-
.first();
|
|
3456
|
+
const sendButton = await resolveChatGptSendButton(composer, page);
|
|
3457
|
+
await captureDiagnostic?.("send-button-resolved");
|
|
3421
3458
|
await sendButton.waitFor({ state: "visible", timeout: browserStageTimeouts.send });
|
|
3422
3459
|
await settleChatGptUi();
|
|
3423
3460
|
const sendEnableDeadline = Date.now() + this.config.tuning.sendEnableGraceMs;
|
|
@@ -3734,13 +3771,13 @@ export class ChatGptBrowserWorker {
|
|
|
3734
3771
|
const files = chatGptPromptFilePayloads(prompt);
|
|
3735
3772
|
if (files.length === 0) return;
|
|
3736
3773
|
const composer = await this.activeComposer(page);
|
|
3737
|
-
const
|
|
3774
|
+
const composerContainer = await resolveChatGptComposerContainer(composer, page);
|
|
3738
3775
|
const input = page.locator('input[data-testid="upload-photos-input"]');
|
|
3739
3776
|
await input.waitFor({ state: "attached", timeout: 20_000 });
|
|
3740
3777
|
await input.setInputFiles(files);
|
|
3741
3778
|
try {
|
|
3742
3779
|
await Promise.all(files.map(file => (
|
|
3743
|
-
|
|
3780
|
+
composerContainer.getByRole("group", { name: file.name, exact: true })
|
|
3744
3781
|
.waitFor({ state: "visible", timeout: 60_000 })
|
|
3745
3782
|
)));
|
|
3746
3783
|
} catch {
|
|
@@ -3752,7 +3789,7 @@ export class ChatGptBrowserWorker {
|
|
|
3752
3789
|
+ (alerts.length > 0 ? `: ${alerts.join(" | ")}` : ""),
|
|
3753
3790
|
);
|
|
3754
3791
|
}
|
|
3755
|
-
const send =
|
|
3792
|
+
const send = await resolveChatGptSendButton(composer, page);
|
|
3756
3793
|
const deadline = Date.now() + 60_000;
|
|
3757
3794
|
while (Date.now() < deadline) {
|
|
3758
3795
|
if (await send.isEnabled().catch(() => false)) return;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CHATGPT_WEB_BACKEND_MODEL,
|
|
3
|
+
CHATGPT_WEB_GPT6_BACKEND_MODEL,
|
|
3
4
|
CHATGPT_WEB_LUNA_BACKEND_MODEL,
|
|
4
5
|
} from "../../chatgpt-web-models";
|
|
5
6
|
|
|
6
7
|
export const CHATGPT_WEB_MODEL_ID = CHATGPT_WEB_BACKEND_MODEL;
|
|
8
|
+
export const CHATGPT_WEB_GPT6_MODEL_ID = CHATGPT_WEB_GPT6_BACKEND_MODEL;
|
|
7
9
|
export const CHATGPT_WEB_LUNA_MODEL_ID = CHATGPT_WEB_LUNA_BACKEND_MODEL;
|
|
8
10
|
|
|
9
11
|
export interface ChatGptWebCapabilities {
|
|
@@ -15,7 +17,7 @@ export interface ChatGptWebCapabilities {
|
|
|
15
17
|
export interface ChatGptWebModelMode {
|
|
16
18
|
modelId: string;
|
|
17
19
|
effort: "low" | "medium" | "high" | "xhigh" | "max";
|
|
18
|
-
displayLabel: "Luna" | "Think" | "Instant" | "Medium" | "High" | "Extra High" | "Pro";
|
|
20
|
+
displayLabel: "Luna" | "Think" | "Instant (即时)" | "Medium (中等)" | "High (高)" | "Extra High (超高)" | "Pro";
|
|
19
21
|
uiEffortIndex: 0 | 1 | 2 | 3 | 4 | null;
|
|
20
22
|
thinkEnabled: boolean;
|
|
21
23
|
localTools: boolean;
|
|
@@ -44,7 +46,7 @@ export function resolveChatGptWebModelMode(
|
|
|
44
46
|
localTools: capabilities.localToolsEnabled,
|
|
45
47
|
};
|
|
46
48
|
}
|
|
47
|
-
if (modelId !== CHATGPT_WEB_MODEL_ID) {
|
|
49
|
+
if (modelId !== CHATGPT_WEB_MODEL_ID && modelId !== CHATGPT_WEB_GPT6_MODEL_ID) {
|
|
48
50
|
throw new Error(`ChatGPT web model is not supported: ${modelId}`);
|
|
49
51
|
}
|
|
50
52
|
if (!capabilities.solAvailable) {
|
|
@@ -53,14 +55,16 @@ export function resolveChatGptWebModelMode(
|
|
|
53
55
|
const effort = reasoning ?? "high";
|
|
54
56
|
switch (effort) {
|
|
55
57
|
case "low":
|
|
56
|
-
return { modelId, effort, displayLabel: "Instant", uiEffortIndex: 0, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
58
|
+
return { modelId, effort, displayLabel: "Instant (即时)", uiEffortIndex: 0, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
57
59
|
case "medium":
|
|
58
|
-
return { modelId, effort, displayLabel: "Medium", uiEffortIndex: 1, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
60
|
+
return { modelId, effort, displayLabel: "Medium (中等)", uiEffortIndex: 1, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
59
61
|
case "high":
|
|
60
|
-
return { modelId, effort, displayLabel: "High", uiEffortIndex: 2, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
62
|
+
return { modelId, effort, displayLabel: "High (高)", uiEffortIndex: 2, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
63
|
+
// The Plus picker exposes only three effort stops (Low/Medium/High). Higher stops are
|
|
64
|
+
// Pro-account only; this check runs before the turn reaches the browser layer.
|
|
61
65
|
case "xhigh":
|
|
62
66
|
if (!capabilities.proAvailable) throw new Error("ChatGPT Extra High effort is not available for this account");
|
|
63
|
-
return { modelId, effort, displayLabel: "Extra High", uiEffortIndex: 3, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
67
|
+
return { modelId, effort, displayLabel: "Extra High (超高)", uiEffortIndex: 3, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
|
64
68
|
case "max":
|
|
65
69
|
if (!capabilities.proAvailable) throw new Error("ChatGPT Pro effort is not available for this account");
|
|
66
70
|
return { modelId, effort, displayLabel: "Pro", uiEffortIndex: 4, thinkEnabled: false, localTools: capabilities.localToolsEnabled };
|
package/src/chatgpt-session.ts
CHANGED
|
@@ -12,14 +12,24 @@ export const CHATGPT_COMPOSER_SELECTOR = [
|
|
|
12
12
|
export const CHATGPT_EFFORT_CONTROL_SELECTOR = [
|
|
13
13
|
'button[aria-haspopup="menu"][data-tone="neutral"]',
|
|
14
14
|
'button[data-testid="model-switcher-dropdown-button"][aria-haspopup="menu"]',
|
|
15
|
+
// 2026-10 UI: a plain button whose stable hooks are aria-haspopup="menu" plus a localized
|
|
16
|
+
// aria-label. Match the zh label and a bilingual pattern so the probe does not silently
|
|
17
|
+
// degrade to a Luna-only account on non-English UI.
|
|
18
|
+
'button[aria-haspopup="menu"][aria-label="选择 ChatGPT 模型"]',
|
|
19
|
+
'button[aria-haspopup="menu"][aria-label*="ChatGPT"][aria-label*="model" i]',
|
|
15
20
|
].join(", ");
|
|
16
21
|
export const CHATGPT_EFFORT_MENU_SELECTOR = [
|
|
17
|
-
'[data-testid="composer-intelligence-picker-content"]:has([role="menuitemradio"], [data-model-reasoning-effort-slider])',
|
|
18
|
-
'[role="menu"]:has([role="menuitemradio"], [data-model-reasoning-effort-slider])',
|
|
19
|
-
'[role="group"]:has([role="menuitemradio"], [data-model-reasoning-effort-slider])',
|
|
22
|
+
'[data-testid="composer-intelligence-picker-content"]:has([role="menuitemradio"], [data-model-reasoning-effort-slider], [data-model-picker-power-slider])',
|
|
23
|
+
'[role="menu"]:has([role="menuitemradio"], [data-model-reasoning-effort-slider], [data-model-picker-power-slider])',
|
|
24
|
+
'[role="group"]:has([role="menuitemradio"], [data-model-reasoning-effort-slider], [data-model-picker-power-slider])',
|
|
20
25
|
].join(", ");
|
|
21
26
|
export const CHATGPT_EFFORT_ITEM_SELECTOR = '[role="menuitemradio"]';
|
|
22
|
-
|
|
27
|
+
// 2026-10 UI renamed the wrapper attribute to data-model-picker-power-slider. Keep the old
|
|
28
|
+
// anchor so a rollback still resolves the slider.
|
|
29
|
+
export const CHATGPT_EFFORT_SLIDER_SELECTOR = [
|
|
30
|
+
'[data-model-picker-power-slider] [role="slider"]',
|
|
31
|
+
'[data-model-reasoning-effort-slider] [role="slider"]',
|
|
32
|
+
].join(", ");
|
|
23
33
|
export const CHATGPT_EFFORT_SLIDER_MAX_OPTIONS = 5;
|
|
24
34
|
export const CHATGPT_STOP_BUTTON_SELECTOR = [
|
|
25
35
|
'[data-testid="stop-button"]',
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export const CHATGPT_WEB_MODEL_PREFIX = "chatgpt-web/";
|
|
2
2
|
export const CHATGPT_WEB_BACKEND_MODEL = "gpt-5.6-sol";
|
|
3
3
|
export const CHATGPT_WEB_LUNA_BACKEND_MODEL = "gpt-5.6-luna";
|
|
4
|
+
/** GPT-6 appears in the Plus picker (2026-10) alongside GPT-5.6 Sol. Selecting it is a
|
|
5
|
+
* pure browser-UI action (click the model row), so it needs no extra transport window. */
|
|
6
|
+
export const CHATGPT_WEB_GPT6_BACKEND_MODEL = "gpt-6";
|
|
4
7
|
/** Internal adapter identity for a turn whose ChatGPT model is selected by the user in the launcher. */
|
|
5
8
|
export const CHATGPT_WEB_ZERO_RISK_BACKEND_MODEL = "chatgpt-web-zero-risk";
|
|
6
9
|
/** Internal adapter identity for the explicitly enabled, Pro-sized Zero Risk context profile. */
|
|
@@ -8,7 +11,8 @@ export const CHATGPT_WEB_ZERO_RISK_PRO_BACKEND_MODEL = "chatgpt-web-zero-risk-pr
|
|
|
8
11
|
|
|
9
12
|
export type ChatGptWebAutomaticBackendModel =
|
|
10
13
|
| typeof CHATGPT_WEB_BACKEND_MODEL
|
|
11
|
-
| typeof CHATGPT_WEB_LUNA_BACKEND_MODEL
|
|
14
|
+
| typeof CHATGPT_WEB_LUNA_BACKEND_MODEL
|
|
15
|
+
| typeof CHATGPT_WEB_GPT6_BACKEND_MODEL;
|
|
12
16
|
export type ChatGptWebBackendModel =
|
|
13
17
|
| ChatGptWebAutomaticBackendModel
|
|
14
18
|
| ChatGptWebZeroRiskBackendModel;
|
|
@@ -291,8 +295,8 @@ export const CHATGPT_WEB_LUNA_MODEL_ROUTES: readonly ChatGptWebModelRoute[] = [
|
|
|
291
295
|
export const CHATGPT_WEB_MODEL_ROUTES: readonly ChatGptWebAutomaticModelRoute[] = [
|
|
292
296
|
{
|
|
293
297
|
slug: "chatgpt-web/light",
|
|
294
|
-
displayName: "ChatGPT Web — Instant",
|
|
295
|
-
description: "
|
|
298
|
+
displayName: "ChatGPT Web — GPT-5.6 Sol Instant (即时)",
|
|
299
|
+
description: "通过原生 Codex 通道的 ChatGPT Web 即时档 (Instant)。",
|
|
296
300
|
interactionMode: "automatic",
|
|
297
301
|
backendModel: CHATGPT_WEB_BACKEND_MODEL,
|
|
298
302
|
codexEffort: "low",
|
|
@@ -301,8 +305,8 @@ export const CHATGPT_WEB_MODEL_ROUTES: readonly ChatGptWebAutomaticModelRoute[]
|
|
|
301
305
|
},
|
|
302
306
|
{
|
|
303
307
|
slug: "chatgpt-web/medium",
|
|
304
|
-
displayName: "ChatGPT Web — Medium",
|
|
305
|
-
description: "
|
|
308
|
+
displayName: "ChatGPT Web — GPT-5.6 Sol Medium (中等)",
|
|
309
|
+
description: "通过原生 Codex 通道的 ChatGPT Web 中等档 (Medium)。",
|
|
306
310
|
interactionMode: "automatic",
|
|
307
311
|
backendModel: CHATGPT_WEB_BACKEND_MODEL,
|
|
308
312
|
codexEffort: "medium",
|
|
@@ -311,18 +315,48 @@ export const CHATGPT_WEB_MODEL_ROUTES: readonly ChatGptWebAutomaticModelRoute[]
|
|
|
311
315
|
},
|
|
312
316
|
{
|
|
313
317
|
slug: "chatgpt-web/high",
|
|
314
|
-
displayName: "ChatGPT Web — High",
|
|
315
|
-
description: "
|
|
318
|
+
displayName: "ChatGPT Web — GPT-5.6 Sol High (高)",
|
|
319
|
+
description: "通过原生 Codex 通道的 ChatGPT Web 高档 (High)。",
|
|
316
320
|
interactionMode: "automatic",
|
|
317
321
|
backendModel: CHATGPT_WEB_BACKEND_MODEL,
|
|
318
322
|
codexEffort: "high",
|
|
319
323
|
adapterEffort: "high",
|
|
320
324
|
requiresPro: false,
|
|
321
325
|
},
|
|
326
|
+
{
|
|
327
|
+
slug: "chatgpt-web/gpt-6-light",
|
|
328
|
+
displayName: "ChatGPT Web — GPT-6 Instant (即时)",
|
|
329
|
+
description: "通过原生 Codex 通道的 ChatGPT GPT-6 即时档(Plus 选择器,2026-10 / GPT-6 Instant)。",
|
|
330
|
+
interactionMode: "automatic",
|
|
331
|
+
backendModel: CHATGPT_WEB_GPT6_BACKEND_MODEL,
|
|
332
|
+
codexEffort: "low",
|
|
333
|
+
adapterEffort: "low",
|
|
334
|
+
requiresPro: false,
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
slug: "chatgpt-web/gpt-6-medium",
|
|
338
|
+
displayName: "ChatGPT Web — GPT-6 Medium (中等)",
|
|
339
|
+
description: "通过原生 Codex 通道的 ChatGPT GPT-6 中等档(Plus 选择器,2026-10 / GPT-6 Medium)。",
|
|
340
|
+
interactionMode: "automatic",
|
|
341
|
+
backendModel: CHATGPT_WEB_GPT6_BACKEND_MODEL,
|
|
342
|
+
codexEffort: "medium",
|
|
343
|
+
adapterEffort: "medium",
|
|
344
|
+
requiresPro: false,
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
slug: "chatgpt-web/gpt-6-high",
|
|
348
|
+
displayName: "ChatGPT Web — GPT-6 High (高)",
|
|
349
|
+
description: "通过原生 Codex 通道的 ChatGPT GPT-6 高档(Plus 选择器,2026-10 / GPT-6 High)。",
|
|
350
|
+
interactionMode: "automatic",
|
|
351
|
+
backendModel: CHATGPT_WEB_GPT6_BACKEND_MODEL,
|
|
352
|
+
codexEffort: "high",
|
|
353
|
+
adapterEffort: "high",
|
|
354
|
+
requiresPro: false,
|
|
355
|
+
},
|
|
322
356
|
{
|
|
323
357
|
slug: "chatgpt-web/extra-high",
|
|
324
|
-
displayName: "ChatGPT Web — Extra High",
|
|
325
|
-
description: "
|
|
358
|
+
displayName: "ChatGPT Web — Extra High (超高)",
|
|
359
|
+
description: "按账号开放的超高档 ChatGPT Web (Extra High,通过原生 Codex 通道)。",
|
|
326
360
|
interactionMode: "automatic",
|
|
327
361
|
backendModel: CHATGPT_WEB_BACKEND_MODEL,
|
|
328
362
|
codexEffort: "xhigh",
|
|
@@ -332,7 +366,7 @@ export const CHATGPT_WEB_MODEL_ROUTES: readonly ChatGptWebAutomaticModelRoute[]
|
|
|
332
366
|
{
|
|
333
367
|
slug: "chatgpt-web/pro",
|
|
334
368
|
displayName: "ChatGPT Web — Pro",
|
|
335
|
-
description: "
|
|
369
|
+
description: "按账号开放的 ChatGPT Pro (通过原生 Codex 通道)。",
|
|
336
370
|
interactionMode: "automatic",
|
|
337
371
|
backendModel: CHATGPT_WEB_BACKEND_MODEL,
|
|
338
372
|
codexEffort: "ultra",
|
package/src/model-catalog.ts
CHANGED
|
@@ -52,7 +52,7 @@ function routedModelPriority(
|
|
|
52
52
|
throw new Error("Native Codex model template priority cannot reserve the Compatibility V1 roster");
|
|
53
53
|
}
|
|
54
54
|
// Codex V1 exposes at most five model overrides. Keep the native Sol row plus the four useful
|
|
55
|
-
// delegated Web efforts (
|
|
55
|
+
// delegated Web efforts (中等 / 高 / 超高 / Pro); 即时 remains a selectable root model
|
|
56
56
|
// but does not displace Pro from spawn_agent's bounded registry.
|
|
57
57
|
return priority + 1;
|
|
58
58
|
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '1.0.
|
|
1
|
+
export const VERSION = '1.0.5';
|