@eddyskywalker/dsh-chatgpt-subscription 0.57.0 → 0.58.0
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/CHANGELOG.md +26 -0
- package/README.md +3 -3
- package/lib/client.js.map +1 -1
- package/lib/index.js +694 -453
- package/lib/tool-result-pruner.js +1 -1
- package/lib/types/client/minimax-code/commands-contract.d.ts +1 -1
- package/lib/types/compat.d.ts +1 -1
- package/lib/types/entry-tool-result-pruner.d.ts +1 -1
- package/lib/types/host/codex-account-pool.d.ts.map +1 -1
- package/lib/types/host/codex-adopt.d.ts.map +1 -1
- package/lib/types/host/codex-catalog.d.ts +5 -3
- package/lib/types/host/codex-catalog.d.ts.map +1 -1
- package/lib/types/host/codex-identity.d.ts +130 -0
- package/lib/types/host/codex-identity.d.ts.map +1 -0
- package/lib/types/host/kimi-code/repeat-breaker.d.ts +1 -1
- package/lib/types/host/oauth-service.d.ts +0 -16
- package/lib/types/host/oauth-service.d.ts.map +1 -1
- package/lib/types/host/token-store.d.ts +9 -0
- package/lib/types/host/token-store.d.ts.map +1 -1
- package/lib/types/host/usage-service.d.ts.map +1 -1
- package/lib/types/host/workbuddy/adapter.d.ts.map +1 -1
- package/lib/types/host/workbuddy/client.d.ts.map +1 -1
- package/lib/types/host/workbuddy/model-catalog.d.ts +56 -44
- package/lib/types/host/workbuddy/model-catalog.d.ts.map +1 -1
- package/lib/types/host/workbuddy/routes.d.ts.map +1 -1
- package/lib/types/shared/workbuddy-contracts.d.ts +8 -8
- package/package.json +49 -46
package/lib/index.js
CHANGED
|
@@ -807,7 +807,7 @@ const ROUTE_PREFIX$5 = "/api/dsh-chatgpt-subscription";
|
|
|
807
807
|
* `test/responses-client.test.ts` asserts the two agree, so a release that
|
|
808
808
|
* forgets this constant fails the suite instead of shipping quietly.
|
|
809
809
|
*/
|
|
810
|
-
const PLUGIN_VERSION = "0.
|
|
810
|
+
const PLUGIN_VERSION = "0.58.0";
|
|
811
811
|
const CODEX_CHATGPT_PROVIDER_ID = "codex-chatgpt";
|
|
812
812
|
const CODEX_API_BASE = "https://chatgpt.com/backend-api/codex";
|
|
813
813
|
const CODEX_RESPONSES_URL = `${CODEX_API_BASE}/responses`;
|
|
@@ -1345,6 +1345,144 @@ async function rehydrateCatalogCache(name, parseModels, accept, currentFetchedAt
|
|
|
1345
1345
|
return snapshot.fetchedAt;
|
|
1346
1346
|
}
|
|
1347
1347
|
//#endregion
|
|
1348
|
+
//#region src/host/codex-identity.ts
|
|
1349
|
+
/**
|
|
1350
|
+
* Who one ChatGPT credential belongs to, and what makes two sign-ins the same
|
|
1351
|
+
* account.
|
|
1352
|
+
*
|
|
1353
|
+
* TWO IDENTITIES, AND THEY ARE NOT THE SAME THING.
|
|
1354
|
+
*
|
|
1355
|
+
* - The WORKSPACE identity is `chatgpt_account_id`, carried as
|
|
1356
|
+
* `credentials.accountId` and sent upstream as `chatgpt-account-id`. It
|
|
1357
|
+
* decides which workspace a request is billed to and what its listing serves,
|
|
1358
|
+
* and every member of that workspace shares it.
|
|
1359
|
+
* - The LOCAL LOGIN identity is (workspace, user): that same workspace id plus a
|
|
1360
|
+
* stable id for the person who signed in. Two members of one workspace are two
|
|
1361
|
+
* accounts here — separate tokens, separate rows, separately selectable — and
|
|
1362
|
+
* re-authorizing the same person updates the row that person already owns.
|
|
1363
|
+
*
|
|
1364
|
+
* Keying the account pool on the workspace alone is the bug this module exists to
|
|
1365
|
+
* prevent. Adding a second member of a workspace replaced the first: the card read
|
|
1366
|
+
* "1 account signed in", the earlier sign-in was gone from the list, and nothing in
|
|
1367
|
+
* the credential was wrong — the pool simply believed both sign-ins were one
|
|
1368
|
+
* account, because that is what the key said.
|
|
1369
|
+
*
|
|
1370
|
+
* The user id is read from the tokens themselves, most explicit claim first:
|
|
1371
|
+
* `chatgpt_user_id` (the field upstream states for exactly this purpose), then
|
|
1372
|
+
* the OIDC `sub` that an id token always carries, then the address. Only when none
|
|
1373
|
+
* of the three is present does the workspace stand in on its own, because nothing
|
|
1374
|
+
* better exists then and merging is what every row written before this module
|
|
1375
|
+
* already did. The workspace id alone is NEVER treated as a user identity while
|
|
1376
|
+
* some user claim is available.
|
|
1377
|
+
*/
|
|
1378
|
+
/** Namespace of the ChatGPT auth claims inside an id or access token. */
|
|
1379
|
+
const CODEX_AUTH_CLAIMS_KEY = "https://api.openai.com/auth";
|
|
1380
|
+
/**
|
|
1381
|
+
* The claims of a JWT, decoded in process, or nothing.
|
|
1382
|
+
*
|
|
1383
|
+
* The payload is the second base64url segment; the signature is never touched and
|
|
1384
|
+
* the result is used only for the non-secret facts above. Never sent anywhere: a
|
|
1385
|
+
* token handed to a decoder service is a token handed away.
|
|
1386
|
+
*
|
|
1387
|
+
* No verification is claimed and none is possible here. What this does instead is
|
|
1388
|
+
* refuse to invent: a token that does not decode is treated as stating nothing,
|
|
1389
|
+
* which leaves the caller on its own fallback rather than on a guessed identity.
|
|
1390
|
+
*/
|
|
1391
|
+
function parseJwtClaims(token) {
|
|
1392
|
+
if (token === void 0) return void 0;
|
|
1393
|
+
const parts = token.split(".");
|
|
1394
|
+
if (parts.length !== 3) return void 0;
|
|
1395
|
+
try {
|
|
1396
|
+
const value = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf8"));
|
|
1397
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
1398
|
+
} catch {
|
|
1399
|
+
return;
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
/**
|
|
1403
|
+
* What the tokens state about their owner.
|
|
1404
|
+
*
|
|
1405
|
+
* The id token is read before the access token, because it is the document that
|
|
1406
|
+
* describes the sign-in; the access token is the fallback for credentials stored
|
|
1407
|
+
* without one. First statement wins, so a value the id token states is never
|
|
1408
|
+
* overwritten by the access token's copy of it.
|
|
1409
|
+
*/
|
|
1410
|
+
function extractIdentity(credentials) {
|
|
1411
|
+
const result = {};
|
|
1412
|
+
let subject;
|
|
1413
|
+
for (const token of [credentials.idToken, credentials.accessToken]) {
|
|
1414
|
+
const claims = parseJwtClaims(token);
|
|
1415
|
+
if (claims === void 0) continue;
|
|
1416
|
+
const nested = claims[CODEX_AUTH_CLAIMS_KEY];
|
|
1417
|
+
result.email ??= stringClaim(claims.email);
|
|
1418
|
+
result.planType ??= stringClaim(claims.chatgpt_plan_type) ?? stringClaim(nested?.chatgpt_plan_type);
|
|
1419
|
+
result.userId ??= stringClaim(claims.chatgpt_user_id) ?? stringClaim(nested?.chatgpt_user_id);
|
|
1420
|
+
result.accountId ??= stringClaim(claims.chatgpt_account_id) ?? stringClaim(nested?.chatgpt_account_id) ?? stringClaim(claims.organizations?.[0]?.id) ?? stringClaim(nested?.organizations?.[0]?.id);
|
|
1421
|
+
subject ??= stringClaim(claims.sub);
|
|
1422
|
+
}
|
|
1423
|
+
result.userId ??= subject;
|
|
1424
|
+
return result;
|
|
1425
|
+
}
|
|
1426
|
+
/**
|
|
1427
|
+
* The stable id of the human behind a credential, or nothing.
|
|
1428
|
+
*
|
|
1429
|
+
* Explicit claim first, then `sub`, and deliberately NOT the email: an address is
|
|
1430
|
+
* the caller's fallback (see {@link codexAccountIdentity}), while this function
|
|
1431
|
+
* answers the narrower question "does this credential name its user outright?".
|
|
1432
|
+
* A persisted `userId` wins over anything re-derived from the tokens, so an opaque
|
|
1433
|
+
* access token handed back by a rotation cannot make an account look like a
|
|
1434
|
+
* different one.
|
|
1435
|
+
*/
|
|
1436
|
+
function codexUserId(credentials) {
|
|
1437
|
+
const stored = nonEmpty$3(credentials.userId);
|
|
1438
|
+
if (stored !== void 0) return stored;
|
|
1439
|
+
return extractIdentity(credentials).userId;
|
|
1440
|
+
}
|
|
1441
|
+
/**
|
|
1442
|
+
* One opaque key per local login: the pool's dedupe key, and the scope of every
|
|
1443
|
+
* per-account cache this line keeps.
|
|
1444
|
+
*
|
|
1445
|
+
* A digest of an EXPLICIT serialization rather than a readable join, for three
|
|
1446
|
+
* reasons that are really one: the string is a label, not data.
|
|
1447
|
+
*
|
|
1448
|
+
* - A separator can be forged. `workspace:user` joins two values that may
|
|
1449
|
+
* themselves contain the separator, so `a` + `b:c` and `a:b` + `c` would have to
|
|
1450
|
+
* be the same key. A JSON array has no such ambiguity: quotes and escapes are
|
|
1451
|
+
* the boundary, and they cannot be re-cut by a value.
|
|
1452
|
+
* - The key becomes a FILE NAME. `catalogSnapshotName` folds everything outside
|
|
1453
|
+
* `[a-z0-9]` to `_`, so a readable key would collide with its neighbours after
|
|
1454
|
+
* folding *and* leave an email address on disk. Hex survives the fold unchanged.
|
|
1455
|
+
* - It is compared for equality only, so nothing is lost by making it opaque.
|
|
1456
|
+
*
|
|
1457
|
+
* `v1` is part of the serialized tuple, not decoration: a future change to the
|
|
1458
|
+
* composition has to produce different keys, and a version tag is what lets that
|
|
1459
|
+
* change be told apart from a corrupted row instead of silently merging two
|
|
1460
|
+
* accounts that the new rule would separate.
|
|
1461
|
+
*
|
|
1462
|
+
* Returns `undefined` when the credential states nothing at all about who it is.
|
|
1463
|
+
* The pool then mints its own `acc_<random>` and ADDS the row, which is the honest
|
|
1464
|
+
* answer: a credential nothing identifies cannot be recognized again, and merging
|
|
1465
|
+
* it with an unrelated one would be worse than a duplicate.
|
|
1466
|
+
*/
|
|
1467
|
+
function codexAccountIdentity(credentials) {
|
|
1468
|
+
const workspace = nonEmpty$3(credentials.accountId);
|
|
1469
|
+
const user = codexUserId(credentials) ?? nonEmpty$3(credentials.email);
|
|
1470
|
+
if (workspace === void 0 && user === void 0) return void 0;
|
|
1471
|
+
const serialized = JSON.stringify([
|
|
1472
|
+
"v1",
|
|
1473
|
+
workspace ?? "",
|
|
1474
|
+
user ?? ""
|
|
1475
|
+
]);
|
|
1476
|
+
return "v1-" + createHash("sha256").update(serialized).digest("hex").slice(0, 32);
|
|
1477
|
+
}
|
|
1478
|
+
function stringClaim(value) {
|
|
1479
|
+
return typeof value === "string" && value !== "" ? value : void 0;
|
|
1480
|
+
}
|
|
1481
|
+
function nonEmpty$3(value) {
|
|
1482
|
+
const trimmed = value?.trim();
|
|
1483
|
+
return trimmed === void 0 || trimmed === "" ? void 0 : trimmed;
|
|
1484
|
+
}
|
|
1485
|
+
//#endregion
|
|
1348
1486
|
//#region src/host/wire-auth.ts
|
|
1349
1487
|
/**
|
|
1350
1488
|
* Turn-state header the Codex backend hands back on a responses response.
|
|
@@ -1441,18 +1579,36 @@ const CATALOG_TTL_MS = 15 * 6e4;
|
|
|
1441
1579
|
* scope a rehydrated listing from one account would answer another's picker.
|
|
1442
1580
|
*/
|
|
1443
1581
|
const SNAPSHOT_SCOPE = "chatgpt-codex";
|
|
1444
|
-
|
|
1582
|
+
/**
|
|
1583
|
+
* How many accounts' listings are held at once.
|
|
1584
|
+
*
|
|
1585
|
+
* One slot was enough while a workspace id was mistaken for an account, because
|
|
1586
|
+
* every member of a workspace then shared one. It is not enough now: a pool
|
|
1587
|
+
* rotates between accounts, and a single slot would have each rotation evict the
|
|
1588
|
+
* other account's listing and re-fetch it, which turns the 15-minute TTL into
|
|
1589
|
+
* "no cache at all" for exactly the multi-account setup this line supports. The
|
|
1590
|
+
* bound is the pool's own order of magnitude, so a real composition always fits
|
|
1591
|
+
* and a pathological one only loses the coldest entry.
|
|
1592
|
+
*/
|
|
1593
|
+
const CATALOG_CACHE_ACCOUNTS = 8;
|
|
1594
|
+
/** Listings held per login identity; see {@link CATALOG_CACHE_ACCOUNTS}. */
|
|
1595
|
+
const catalogCache$2 = /* @__PURE__ */ new Map();
|
|
1596
|
+
/** The entry {@link getCachedCatalog} answers with: the one a load last wrote. */
|
|
1597
|
+
let latestKey = null;
|
|
1445
1598
|
const catalogInFlight$6 = /* @__PURE__ */ new Map();
|
|
1446
|
-
|
|
1599
|
+
/** Snapshots already read back from disk, per identity. */
|
|
1600
|
+
const snapshotRehydrated = /* @__PURE__ */ new Map();
|
|
1447
1601
|
/**
|
|
1448
1602
|
* The listing currently held, or undefined before the first load.
|
|
1449
1603
|
*
|
|
1450
|
-
*
|
|
1451
|
-
*
|
|
1452
|
-
*
|
|
1604
|
+
* "Currently held" is the entry a load wrote last: a picker asks what the
|
|
1605
|
+
* account serving it can call, and that is the account whose listing was fetched
|
|
1606
|
+
* most recently. Callers that need a catalog with no credential read the shipped
|
|
1607
|
+
* table directly; returning it here under a different entry type would force
|
|
1608
|
+
* every one of them to convert it.
|
|
1453
1609
|
*/
|
|
1454
1610
|
function getCachedCatalog$3() {
|
|
1455
|
-
return catalogCache$2?.models;
|
|
1611
|
+
return latestKey === null ? void 0 : catalogCache$2.get(latestKey)?.models;
|
|
1456
1612
|
}
|
|
1457
1613
|
/**
|
|
1458
1614
|
* Read the models this subscription can call.
|
|
@@ -1470,8 +1626,11 @@ function getCachedCatalog$3() {
|
|
|
1470
1626
|
function loadCodexCatalog(credentials, options = {}) {
|
|
1471
1627
|
const key = accountKeyFor$1(credentials);
|
|
1472
1628
|
if (options.force !== true) {
|
|
1473
|
-
const cached = catalogCache$2;
|
|
1474
|
-
if (cached !==
|
|
1629
|
+
const cached = catalogCache$2.get(key);
|
|
1630
|
+
if (cached !== void 0 && Date.now() - cached.at < CATALOG_TTL_MS) {
|
|
1631
|
+
latestKey = key;
|
|
1632
|
+
return Promise.resolve(cached.models);
|
|
1633
|
+
}
|
|
1475
1634
|
}
|
|
1476
1635
|
const pending = catalogInFlight$6.get(key);
|
|
1477
1636
|
if (pending !== void 0) return pending;
|
|
@@ -1488,10 +1647,17 @@ function loadCodexCatalog(credentials, options = {}) {
|
|
|
1488
1647
|
async function performCatalogLoad$1(credentials, options) {
|
|
1489
1648
|
const key = accountKeyFor$1(credentials);
|
|
1490
1649
|
const fetchFn = options.fetchFn ?? fetch;
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1650
|
+
let rehydrated = snapshotRehydrated.get(key);
|
|
1651
|
+
if (rehydrated === void 0) {
|
|
1652
|
+
rehydrated = rehydrateSnapshot(key);
|
|
1653
|
+
snapshotRehydrated.set(key, rehydrated);
|
|
1654
|
+
}
|
|
1655
|
+
await rehydrated;
|
|
1656
|
+
const cached = catalogCache$2.get(key);
|
|
1657
|
+
if (cached !== void 0 && Date.now() - cached.at < CATALOG_TTL_MS) {
|
|
1658
|
+
latestKey = key;
|
|
1659
|
+
return cached.models;
|
|
1660
|
+
}
|
|
1495
1661
|
let models;
|
|
1496
1662
|
let live = false;
|
|
1497
1663
|
try {
|
|
@@ -1510,18 +1676,34 @@ async function performCatalogLoad$1(credentials, options) {
|
|
|
1510
1676
|
live = true;
|
|
1511
1677
|
writeCatalogSnapshot(catalogSnapshotName(SNAPSHOT_SCOPE, key), [...models], Date.now());
|
|
1512
1678
|
} catch {
|
|
1513
|
-
models =
|
|
1679
|
+
models = catalogCache$2.get(key)?.models ?? [];
|
|
1514
1680
|
live = false;
|
|
1515
1681
|
}
|
|
1516
|
-
|
|
1682
|
+
remember(key, {
|
|
1517
1683
|
at: Date.now(),
|
|
1518
1684
|
models,
|
|
1519
1685
|
key,
|
|
1520
1686
|
live
|
|
1521
|
-
};
|
|
1687
|
+
});
|
|
1522
1688
|
return models;
|
|
1523
1689
|
}
|
|
1524
1690
|
/**
|
|
1691
|
+
* File one listing under its identity, keeping the map bounded.
|
|
1692
|
+
*
|
|
1693
|
+
* Eviction is oldest-fetch-first, which is the entry a rotation is least likely to
|
|
1694
|
+
* ask for next; the bound exists so a composition that signs in far more accounts
|
|
1695
|
+
* than the pool holds cannot grow this map without end.
|
|
1696
|
+
*/
|
|
1697
|
+
function remember(key, entry) {
|
|
1698
|
+
catalogCache$2.set(key, entry);
|
|
1699
|
+
latestKey = key;
|
|
1700
|
+
while (catalogCache$2.size > CATALOG_CACHE_ACCOUNTS) {
|
|
1701
|
+
const oldest = [...catalogCache$2.entries()].filter(([candidate]) => candidate !== key).sort((left, right) => left[1].at - right[1].at)[0];
|
|
1702
|
+
if (oldest === void 0) break;
|
|
1703
|
+
catalogCache$2.delete(oldest[0]);
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
/**
|
|
1525
1707
|
* Seed the in-memory cache from the last persisted listing.
|
|
1526
1708
|
*
|
|
1527
1709
|
* Best effort by construction: a missing or malformed snapshot leaves the cache
|
|
@@ -1530,13 +1712,13 @@ async function performCatalogLoad$1(credentials, options) {
|
|
|
1530
1712
|
async function rehydrateSnapshot(key) {
|
|
1531
1713
|
const snapshot = await readCatalogSnapshot(catalogSnapshotName(SNAPSHOT_SCOPE, key), (value) => Array.isArray(value) ? value.flatMap((item) => parseListingEntry$1(item)) : void 0).catch(() => void 0);
|
|
1532
1714
|
if (snapshot === void 0 || snapshot.models.length === 0) return;
|
|
1533
|
-
if (catalogCache$2
|
|
1534
|
-
|
|
1715
|
+
if (catalogCache$2.has(key)) return;
|
|
1716
|
+
remember(key, {
|
|
1535
1717
|
at: snapshot.fetchedAt,
|
|
1536
1718
|
models: snapshot.models,
|
|
1537
1719
|
key,
|
|
1538
1720
|
live: true
|
|
1539
|
-
};
|
|
1721
|
+
});
|
|
1540
1722
|
}
|
|
1541
1723
|
/**
|
|
1542
1724
|
* Read the listing payload.
|
|
@@ -1605,12 +1787,19 @@ function parseEfforts(value) {
|
|
|
1605
1787
|
/**
|
|
1606
1788
|
* Cache identity for one credential.
|
|
1607
1789
|
*
|
|
1608
|
-
* The
|
|
1609
|
-
*
|
|
1610
|
-
*
|
|
1790
|
+
* The listing is served per PLAN, and a plan belongs to the local login — the
|
|
1791
|
+
* workspace id alone is not an identity here either: two members of one workspace
|
|
1792
|
+
* can hold different plans, so filing both listings under the workspace would let
|
|
1793
|
+
* one member's picker answer with models the other member's plan does not serve.
|
|
1794
|
+
* The key is therefore the same composite identity the pool dedupes on, and its
|
|
1795
|
+
* digest form is what keeps the persisted snapshot's file name both distinct after
|
|
1796
|
+
* `catalogSnapshotName` folds it and free of an email address.
|
|
1797
|
+
*
|
|
1798
|
+
* `'default'` answers a credential that states nothing about itself, which is the
|
|
1799
|
+
* single pre-sign-in case this loader ever sees.
|
|
1611
1800
|
*/
|
|
1612
1801
|
function accountKeyFor$1(credentials) {
|
|
1613
|
-
return credentials
|
|
1802
|
+
return codexAccountIdentity(credentials) ?? "default";
|
|
1614
1803
|
}
|
|
1615
1804
|
function asRecord$20(value) {
|
|
1616
1805
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
@@ -1729,6 +1918,7 @@ function parseStoredCredentials(value) {
|
|
|
1729
1918
|
expiresAt: record.expiresAt,
|
|
1730
1919
|
idToken: optional("idToken"),
|
|
1731
1920
|
accountId: optional("accountId"),
|
|
1921
|
+
userId: optional("userId"),
|
|
1732
1922
|
email: optional("email"),
|
|
1733
1923
|
planType: optional("planType")
|
|
1734
1924
|
};
|
|
@@ -4498,17 +4688,6 @@ function buildAuthorizationUrl(verifier, state) {
|
|
|
4498
4688
|
originator: OAUTH_ORIGINATOR
|
|
4499
4689
|
}).toString()}`;
|
|
4500
4690
|
}
|
|
4501
|
-
function parseJwtClaims(token) {
|
|
4502
|
-
if (token === void 0) return void 0;
|
|
4503
|
-
const parts = token.split(".");
|
|
4504
|
-
if (parts.length !== 3) return void 0;
|
|
4505
|
-
try {
|
|
4506
|
-
const value = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf8"));
|
|
4507
|
-
return typeof value === "object" && value !== null ? value : void 0;
|
|
4508
|
-
} catch {
|
|
4509
|
-
return;
|
|
4510
|
-
}
|
|
4511
|
-
}
|
|
4512
4691
|
function publicError(error, fallback = "internal") {
|
|
4513
4692
|
if (error instanceof OAuthServiceError) return {
|
|
4514
4693
|
code: error.code,
|
|
@@ -4535,28 +4714,25 @@ function credentialsFromTokenResponse(response, now, previous) {
|
|
|
4535
4714
|
return {
|
|
4536
4715
|
...base,
|
|
4537
4716
|
accountId: identity.accountId ?? previous?.accountId,
|
|
4717
|
+
userId: identity.userId ?? previous?.userId,
|
|
4538
4718
|
email: identity.email ?? previous?.email,
|
|
4539
4719
|
planType: identity.planType ?? previous?.planType
|
|
4540
4720
|
};
|
|
4541
4721
|
}
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
/** Identity one refresh is keyed by, so a rotation is never redeemed twice. */
|
|
4722
|
+
/**
|
|
4723
|
+
* Identity one refresh is keyed by, so a rotation is never redeemed twice.
|
|
4724
|
+
*
|
|
4725
|
+
* The SAME key the pool dedupes on, and deliberately so: it has to separate two
|
|
4726
|
+
* members of one workspace, because their grants are unrelated and sharing one
|
|
4727
|
+
* in-flight refresh between them would hand one account's rotated token to the
|
|
4728
|
+
* other. A workspace id alone cannot do that — it is what both members have in
|
|
4729
|
+
* common — so this is the composite local login identity, with the rotating
|
|
4730
|
+
* refresh token as the fallback for a credential that states nothing else. That
|
|
4731
|
+
* fallback is the conservative direction: a token that differs always gets its
|
|
4732
|
+
* own flight, and a flight nobody joined simply runs by itself.
|
|
4733
|
+
*/
|
|
4555
4734
|
function refreshKey(credentials) {
|
|
4556
|
-
return credentials
|
|
4557
|
-
}
|
|
4558
|
-
function stringClaim(value) {
|
|
4559
|
-
return typeof value === "string" && value !== "" ? value : void 0;
|
|
4735
|
+
return codexAccountIdentity(credentials) ?? credentials.refreshToken;
|
|
4560
4736
|
}
|
|
4561
4737
|
function maskEmail(email) {
|
|
4562
4738
|
if (email === void 0) return null;
|
|
@@ -4851,8 +5027,6 @@ const CODEX_CLI_CREDENTIAL_FILE = "auth.json";
|
|
|
4851
5027
|
const CODEX_CLI_TOKENS_KEY = "tokens";
|
|
4852
5028
|
/** Where an adopted snapshot came from, for the card and for the pool record. */
|
|
4853
5029
|
const CODEX_CLI_CREDENTIAL_SOURCE = "codex";
|
|
4854
|
-
/** Namespace the id token carries the ChatGPT account claims under. */
|
|
4855
|
-
const CODEX_AUTH_CLAIMS_KEY = "https://api.openai.com/auth";
|
|
4856
5030
|
/**
|
|
4857
5031
|
* What the user is told when an adopted credential has aged out.
|
|
4858
5032
|
*
|
|
@@ -5256,7 +5430,7 @@ var CodexAccountPool = class extends AccountPoolCore {
|
|
|
5256
5430
|
poolFile: codexPoolPath(),
|
|
5257
5431
|
keychainService: "dsh-chatgpt-subscription-pool",
|
|
5258
5432
|
parsePoolData: parseCodexPoolData,
|
|
5259
|
-
dedupeKey: (credentials) => credentials
|
|
5433
|
+
dedupeKey: (credentials) => codexAccountIdentity(credentials),
|
|
5260
5434
|
defaultAlias: (credentials, position) => credentials.email ?? `账号 ${position}`,
|
|
5261
5435
|
createAccount: ({ id, alias, credentials, addedAt, isPrimary }) => {
|
|
5262
5436
|
const adopted = isAdoptedCodexPoolCredential(credentials);
|
|
@@ -15123,8 +15297,17 @@ function readableLimitName(value) {
|
|
|
15123
15297
|
function isWindow(value) {
|
|
15124
15298
|
return value !== null;
|
|
15125
15299
|
}
|
|
15300
|
+
/**
|
|
15301
|
+
* The identity a reading is filed under when no pool row names one.
|
|
15302
|
+
*
|
|
15303
|
+
* The composite local login identity, for the same reason the pool dedupes on it:
|
|
15304
|
+
* with several accounts in one composition, a workspace id alone would make two
|
|
15305
|
+
* members of that workspace share a slot — each showing the other's numbers. The
|
|
15306
|
+
* trailing fallbacks are for a credential that states nothing about itself, which
|
|
15307
|
+
* is the single-account case, where there is nobody to mix up.
|
|
15308
|
+
*/
|
|
15126
15309
|
function identityKey(credentials) {
|
|
15127
|
-
return credentials
|
|
15310
|
+
return codexAccountIdentity(credentials) ?? credentials.planType ?? "signed-in";
|
|
15128
15311
|
}
|
|
15129
15312
|
//#endregion
|
|
15130
15313
|
//#region src/host/routes.ts
|
|
@@ -95345,14 +95528,14 @@ const WORKBUDDY_STANDARD_EFFORTS = [
|
|
|
95345
95528
|
* Snap a level onto the nearest rung a model's ladder actually exposes.
|
|
95346
95529
|
*
|
|
95347
95530
|
* The gateway names a default from a wider vocabulary than the ladder it
|
|
95348
|
-
* publishes for the same model: an effort-only entry
|
|
95349
|
-
*
|
|
95350
|
-
*
|
|
95351
|
-
*
|
|
95352
|
-
*
|
|
95353
|
-
*
|
|
95354
|
-
* samples, versus 282-659 with the field). Ties resolve upward, which is
|
|
95355
|
-
* mapping the sibling Kimi line documents for `medium`. A ladder that names
|
|
95531
|
+
* publishes for the same model: an effort-only entry — the shape `kimi-k3`
|
|
95532
|
+
* publishes — names a single default while exposing only `low`/`high`/`max`.
|
|
95533
|
+
* Letting an unlisted value through is not cosmetic — a default outside the
|
|
95534
|
+
* ladder is discarded by the level-resolution step, the request then carries no
|
|
95535
|
+
* `reasoning_effort`, and the model returns an EMPTY `reasoning_content`
|
|
95536
|
+
* (measured on `minimax-m3` while that id was still served: 0 characters across
|
|
95537
|
+
* three samples, versus 282-659 with the field). Ties resolve upward, which is
|
|
95538
|
+
* the mapping the sibling Kimi line documents for `medium`. A ladder that names
|
|
95356
95539
|
* no level (a text-only model) yields nothing to converge to.
|
|
95357
95540
|
*/
|
|
95358
95541
|
function convergeWorkBuddyEffort(effort, ladder) {
|
|
@@ -95635,96 +95818,27 @@ function refreshSourceForDomain(domain) {
|
|
|
95635
95818
|
/**
|
|
95636
95819
|
* Models the gateway serves but does not publish in `/v3/config`.
|
|
95637
95820
|
*
|
|
95638
|
-
* The catalog is a published list, not the served one: measured on
|
|
95639
|
-
* international backend, `gpt-6-sol`, `gpt-6-luna` and `gemini-3.8-flash`
|
|
95640
|
-
*
|
|
95821
|
+
* The catalog is a published list, not the served one: measured 2026-10-09 on
|
|
95822
|
+
* the international backend, `gpt-6-sol`, `gpt-6-luna` and `gemini-3.8-flash`
|
|
95823
|
+
* all answered a normal streaming completion with 200 while being absent from
|
|
95641
95824
|
* `/v3/config` entirely, and a reachable gateway *replaces* the shipped table
|
|
95642
|
-
* with that list
|
|
95643
|
-
*
|
|
95644
|
-
*
|
|
95645
|
-
*
|
|
95646
|
-
*
|
|
95647
|
-
*
|
|
95648
|
-
*
|
|
95649
|
-
*
|
|
95650
|
-
*
|
|
95651
|
-
|
|
95652
|
-
|
|
95653
|
-
* - **Context window, output cap and `canDisableThinking` are inherited from the
|
|
95654
|
-
* published sibling in the same family** — `gpt-6-astra` for `gpt-6-sol` and
|
|
95655
|
-
* `gpt-6-luna`, `gemini-3.5-flash` for `gemini-3.8-flash`. They are marked
|
|
95656
|
-
* here rather than measured because the gateway publishes nothing for these
|
|
95657
|
-
* ids and offers no cheap way to read the real figure: it accepts a
|
|
95658
|
-
* `max_tokens` larger than any published window (even for `gpt-6-astra`, whose
|
|
95659
|
-
* own catalog caps at 128000), so the number is neither enforced nor
|
|
95660
|
-
* discoverable from the request side.
|
|
95661
|
-
*
|
|
95662
|
-
* Every field stays overridable per model from the settings card, and an
|
|
95663
|
-
* inherited window errs low rather than high: over-declaring overflows the
|
|
95664
|
-
* gateway mid-session, while under-declaring only compresses earlier.
|
|
95665
|
-
*/
|
|
95666
|
-
const UNPUBLISHED_MODELS = [
|
|
95667
|
-
{
|
|
95668
|
-
id: "gpt-6-sol",
|
|
95669
|
-
name: "GPT-6-Sol",
|
|
95670
|
-
contextWindow: 4e5,
|
|
95671
|
-
maxContextWindow: 1e6,
|
|
95672
|
-
maxTokens: 128e3,
|
|
95673
|
-
regions: ["intl"],
|
|
95674
|
-
supportsImage: true,
|
|
95675
|
-
reasoningEfforts: [
|
|
95676
|
-
"low",
|
|
95677
|
-
"medium",
|
|
95678
|
-
"high",
|
|
95679
|
-
"xhigh",
|
|
95680
|
-
"max"
|
|
95681
|
-
],
|
|
95682
|
-
defaultReasoningEffort: "high",
|
|
95683
|
-
canDisableThinking: true,
|
|
95684
|
-
description: "OpenAI 旗舰模型,擅长复杂推理与长程任务"
|
|
95685
|
-
},
|
|
95686
|
-
{
|
|
95687
|
-
id: "gpt-6-luna",
|
|
95688
|
-
name: "GPT-6-Luna",
|
|
95689
|
-
contextWindow: 4e5,
|
|
95690
|
-
maxContextWindow: 1e6,
|
|
95691
|
-
maxTokens: 128e3,
|
|
95692
|
-
regions: ["intl"],
|
|
95693
|
-
supportsImage: true,
|
|
95694
|
-
reasoningEfforts: [
|
|
95695
|
-
"low",
|
|
95696
|
-
"medium",
|
|
95697
|
-
"high",
|
|
95698
|
-
"xhigh",
|
|
95699
|
-
"max"
|
|
95700
|
-
],
|
|
95701
|
-
defaultReasoningEffort: "high",
|
|
95702
|
-
canDisableThinking: true,
|
|
95703
|
-
description: "OpenAI 轻量模型,响应快速,适合日常任务"
|
|
95704
|
-
},
|
|
95705
|
-
{
|
|
95706
|
-
id: "gemini-3.8-flash",
|
|
95707
|
-
name: "Gemini-3.8-Flash",
|
|
95708
|
-
contextWindow: 1e6,
|
|
95709
|
-
maxContextWindow: 1e6,
|
|
95710
|
-
maxTokens: 65536,
|
|
95711
|
-
regions: ["intl"],
|
|
95712
|
-
supportsImage: true,
|
|
95713
|
-
reasoningEfforts: [
|
|
95714
|
-
"low",
|
|
95715
|
-
"high",
|
|
95716
|
-
"max"
|
|
95717
|
-
],
|
|
95718
|
-
defaultReasoningEffort: "medium",
|
|
95719
|
-
canDisableThinking: false,
|
|
95720
|
-
description: "能力均衡,适合日常使用"
|
|
95721
|
-
}
|
|
95722
|
-
];
|
|
95825
|
+
* with that list — so a row living only in the fallback would drop out of the
|
|
95826
|
+
* picker the moment the catalog loaded.
|
|
95827
|
+
*
|
|
95828
|
+
* The list is empty as of the 2026-11-04 read: all three ids are published now,
|
|
95829
|
+
* with figures measured on the wire, and their rows therefore live in
|
|
95830
|
+
* {@link FALLBACK_MODELS} like any other. The seam stays rather than being
|
|
95831
|
+
* deleted because the gap it covers belongs to the gateway, not to those three
|
|
95832
|
+
* models: the next id it serves without listing belongs here, and
|
|
95833
|
+
* {@link withUnpublishedModels} is what keeps such a row offered.
|
|
95834
|
+
*/
|
|
95835
|
+
const UNPUBLISHED_MODELS = [];
|
|
95723
95836
|
/**
|
|
95724
95837
|
* Offline fallback catalog, transcribed from a live `/v3/config` read.
|
|
95725
95838
|
*
|
|
95726
|
-
*
|
|
95727
|
-
* network failure); a reachable
|
|
95839
|
+
* Last transcribed 2026-11-04 from both backends. Used when the gateway cannot
|
|
95840
|
+
* be reached (first run before sign-in, or a network failure); a reachable
|
|
95841
|
+
* gateway always wins.
|
|
95728
95842
|
*/
|
|
95729
95843
|
const FALLBACK_MODELS$1 = [
|
|
95730
95844
|
{
|
|
@@ -95740,20 +95854,6 @@ const FALLBACK_MODELS$1 = [
|
|
|
95740
95854
|
canDisableThinking: false,
|
|
95741
95855
|
description: "优秀的编码模型,适合日常使用"
|
|
95742
95856
|
},
|
|
95743
|
-
{
|
|
95744
|
-
id: "default",
|
|
95745
|
-
name: "Default",
|
|
95746
|
-
contextWindow: 56e3,
|
|
95747
|
-
maxContextWindow: 56e3,
|
|
95748
|
-
maxTokens: 24e3,
|
|
95749
|
-
regions: ["cn"],
|
|
95750
|
-
credits: { cn: "2.00" },
|
|
95751
|
-
supportsImage: false,
|
|
95752
|
-
reasoningEfforts: [],
|
|
95753
|
-
defaultReasoningEffort: null,
|
|
95754
|
-
canDisableThinking: false,
|
|
95755
|
-
description: ""
|
|
95756
|
-
},
|
|
95757
95857
|
{
|
|
95758
95858
|
id: "fast-model",
|
|
95759
95859
|
name: "Fast",
|
|
@@ -95768,7 +95868,7 @@ const FALLBACK_MODELS$1 = [
|
|
|
95768
95868
|
"high",
|
|
95769
95869
|
"max"
|
|
95770
95870
|
],
|
|
95771
|
-
defaultReasoningEffort: "
|
|
95871
|
+
defaultReasoningEffort: "high",
|
|
95772
95872
|
canDisableThinking: false,
|
|
95773
95873
|
description: "响应快,适合简单任务"
|
|
95774
95874
|
},
|
|
@@ -95786,7 +95886,7 @@ const FALLBACK_MODELS$1 = [
|
|
|
95786
95886
|
"high",
|
|
95787
95887
|
"max"
|
|
95788
95888
|
],
|
|
95789
|
-
defaultReasoningEffort: "
|
|
95889
|
+
defaultReasoningEffort: "high",
|
|
95790
95890
|
canDisableThinking: false,
|
|
95791
95891
|
description: "速度与质量兼顾,日常工作首选"
|
|
95792
95892
|
},
|
|
@@ -95809,20 +95909,65 @@ const FALLBACK_MODELS$1 = [
|
|
|
95809
95909
|
description: "高质量输出,胜任复杂任务"
|
|
95810
95910
|
},
|
|
95811
95911
|
{
|
|
95812
|
-
id: "
|
|
95813
|
-
name: "
|
|
95814
|
-
contextWindow:
|
|
95815
|
-
maxContextWindow:
|
|
95816
|
-
maxTokens:
|
|
95912
|
+
id: "deepseek-v4.1-flash",
|
|
95913
|
+
name: "Deepseek-V4.1-Flash",
|
|
95914
|
+
contextWindow: 3e5,
|
|
95915
|
+
maxContextWindow: 1e6,
|
|
95916
|
+
maxTokens: 128e3,
|
|
95917
|
+
regions: ["intl", "cn"],
|
|
95918
|
+
credits: {
|
|
95919
|
+
cn: "0.11",
|
|
95920
|
+
intl: "0.00"
|
|
95921
|
+
},
|
|
95922
|
+
supportsImage: true,
|
|
95923
|
+
reasoningEfforts: [
|
|
95924
|
+
"low",
|
|
95925
|
+
"high",
|
|
95926
|
+
"max"
|
|
95927
|
+
],
|
|
95928
|
+
defaultReasoningEffort: "high",
|
|
95929
|
+
canDisableThinking: false,
|
|
95930
|
+
description: "DeepSeek 旗舰模型,支持 1M 上下文窗口,原生多模态"
|
|
95931
|
+
},
|
|
95932
|
+
{
|
|
95933
|
+
id: "deepseek-v4.1-flash-sg",
|
|
95934
|
+
name: "Deepseek-V4.1-Flash",
|
|
95935
|
+
contextWindow: 3e5,
|
|
95936
|
+
maxContextWindow: 1e6,
|
|
95937
|
+
maxTokens: 128e3,
|
|
95817
95938
|
regions: ["intl"],
|
|
95818
|
-
credits: { intl: "
|
|
95939
|
+
credits: { intl: "0.03" },
|
|
95819
95940
|
supportsImage: true,
|
|
95820
|
-
reasoningEfforts: [
|
|
95821
|
-
|
|
95941
|
+
reasoningEfforts: [
|
|
95942
|
+
"low",
|
|
95943
|
+
"high",
|
|
95944
|
+
"max"
|
|
95945
|
+
],
|
|
95946
|
+
defaultReasoningEffort: "high",
|
|
95822
95947
|
canDisableThinking: false,
|
|
95823
|
-
description: "
|
|
95948
|
+
description: "DeepSeek 旗舰模型,支持 1M 上下文窗口,原生多模态"
|
|
95949
|
+
},
|
|
95950
|
+
{
|
|
95951
|
+
id: "glm-5.3-flash",
|
|
95952
|
+
name: "GLM-5.3-Flash",
|
|
95953
|
+
contextWindow: 3e5,
|
|
95954
|
+
maxContextWindow: 1e6,
|
|
95955
|
+
maxTokens: 32e3,
|
|
95956
|
+
regions: ["intl", "cn"],
|
|
95957
|
+
credits: {
|
|
95958
|
+
cn: "0.08",
|
|
95959
|
+
intl: "0.08"
|
|
95960
|
+
},
|
|
95961
|
+
supportsImage: true,
|
|
95962
|
+
reasoningEfforts: [
|
|
95963
|
+
"low",
|
|
95964
|
+
"high",
|
|
95965
|
+
"max"
|
|
95966
|
+
],
|
|
95967
|
+
defaultReasoningEffort: "high",
|
|
95968
|
+
canDisableThinking: false,
|
|
95969
|
+
description: "原生多模态模型,擅长视觉理解与专业任务"
|
|
95824
95970
|
},
|
|
95825
|
-
...UNPUBLISHED_MODELS.filter((model) => model.id === "gpt-6-sol" || model.id === "gpt-6-luna"),
|
|
95826
95971
|
{
|
|
95827
95972
|
id: "gpt-6-astra",
|
|
95828
95973
|
name: "GPT-6-Astra",
|
|
@@ -95843,6 +95988,37 @@ const FALLBACK_MODELS$1 = [
|
|
|
95843
95988
|
canDisableThinking: true,
|
|
95844
95989
|
description: "OpenAI 旗舰模型,擅长复杂推理与长程任务"
|
|
95845
95990
|
},
|
|
95991
|
+
{
|
|
95992
|
+
id: "hy4-preview",
|
|
95993
|
+
name: "Hy4 Preview",
|
|
95994
|
+
contextWindow: 2e5,
|
|
95995
|
+
maxContextWindow: 1e6,
|
|
95996
|
+
maxTokens: 64e3,
|
|
95997
|
+
regions: ["intl"],
|
|
95998
|
+
credits: { intl: "0.29" },
|
|
95999
|
+
supportsImage: true,
|
|
96000
|
+
reasoningEfforts: ["high"],
|
|
96001
|
+
defaultReasoningEffort: "high",
|
|
96002
|
+
canDisableThinking: false,
|
|
96003
|
+
description: "混元思考模型,具有增强的推理能力"
|
|
96004
|
+
},
|
|
96005
|
+
{
|
|
96006
|
+
id: "hy3",
|
|
96007
|
+
name: "Hy3",
|
|
96008
|
+
contextWindow: 192e3,
|
|
96009
|
+
maxContextWindow: 192e3,
|
|
96010
|
+
maxTokens: 64e3,
|
|
96011
|
+
regions: ["intl", "cn"],
|
|
96012
|
+
credits: {
|
|
96013
|
+
cn: "0.00",
|
|
96014
|
+
intl: "0.00"
|
|
96015
|
+
},
|
|
96016
|
+
supportsImage: true,
|
|
96017
|
+
reasoningEfforts: ["low", "high"],
|
|
96018
|
+
defaultReasoningEffort: "high",
|
|
96019
|
+
canDisableThinking: false,
|
|
96020
|
+
description: "混元思考模型,具有增强的推理能力"
|
|
96021
|
+
},
|
|
95846
96022
|
{
|
|
95847
96023
|
id: "gpt-5.6-sol",
|
|
95848
96024
|
name: "GPT-5.6-Sol",
|
|
@@ -95949,8 +96125,8 @@ const FALLBACK_MODELS$1 = [
|
|
|
95949
96125
|
maxTokens: 48e3,
|
|
95950
96126
|
regions: ["intl", "cn"],
|
|
95951
96127
|
credits: {
|
|
95952
|
-
cn: "0.
|
|
95953
|
-
intl: "0.
|
|
96128
|
+
cn: "0.69",
|
|
96129
|
+
intl: "0.69"
|
|
95954
96130
|
},
|
|
95955
96131
|
supportsImage: true,
|
|
95956
96132
|
reasoningEfforts: [
|
|
@@ -95959,155 +96135,208 @@ const FALLBACK_MODELS$1 = [
|
|
|
95959
96135
|
"max"
|
|
95960
96136
|
],
|
|
95961
96137
|
defaultReasoningEffort: "high",
|
|
95962
|
-
canDisableThinking:
|
|
96138
|
+
canDisableThinking: false,
|
|
95963
96139
|
description: "能力均衡,适合日常使用"
|
|
95964
96140
|
},
|
|
95965
96141
|
{
|
|
95966
|
-
id: "glm-5.
|
|
95967
|
-
name: "GLM-5.
|
|
96142
|
+
id: "glm-5.2",
|
|
96143
|
+
name: "GLM-5.2",
|
|
96144
|
+
contextWindow: 1e6,
|
|
96145
|
+
maxContextWindow: 1e6,
|
|
96146
|
+
maxTokens: 48e3,
|
|
96147
|
+
regions: ["intl", "cn"],
|
|
96148
|
+
credits: {
|
|
96149
|
+
cn: "0.79",
|
|
96150
|
+
intl: "0.79"
|
|
96151
|
+
},
|
|
96152
|
+
supportsImage: true,
|
|
96153
|
+
reasoningEfforts: ["high"],
|
|
96154
|
+
defaultReasoningEffort: "high",
|
|
96155
|
+
canDisableThinking: false,
|
|
96156
|
+
description: "1M 上下文,擅长长程任务"
|
|
96157
|
+
},
|
|
96158
|
+
{
|
|
96159
|
+
id: "minimax-m3.1-flash",
|
|
96160
|
+
name: "MiniMax-M3.1-Flash",
|
|
95968
96161
|
contextWindow: 3e5,
|
|
95969
96162
|
maxContextWindow: 1e6,
|
|
95970
|
-
maxTokens:
|
|
96163
|
+
maxTokens: 128e3,
|
|
95971
96164
|
regions: ["intl", "cn"],
|
|
95972
96165
|
credits: {
|
|
95973
|
-
cn: "0.
|
|
95974
|
-
intl: "0.
|
|
96166
|
+
cn: "0.08",
|
|
96167
|
+
intl: "0.08"
|
|
95975
96168
|
},
|
|
95976
96169
|
supportsImage: true,
|
|
95977
96170
|
reasoningEfforts: [
|
|
95978
96171
|
"low",
|
|
96172
|
+
"medium",
|
|
95979
96173
|
"high",
|
|
96174
|
+
"xhigh",
|
|
95980
96175
|
"max"
|
|
95981
96176
|
],
|
|
95982
|
-
defaultReasoningEffort: "
|
|
95983
|
-
canDisableThinking:
|
|
95984
|
-
description: "
|
|
96177
|
+
defaultReasoningEffort: "max",
|
|
96178
|
+
canDisableThinking: false,
|
|
96179
|
+
description: "原生多模态,擅长office、agentic、编程任务,推理速度优异"
|
|
95985
96180
|
},
|
|
95986
96181
|
{
|
|
95987
|
-
id: "
|
|
95988
|
-
name: "
|
|
95989
|
-
contextWindow:
|
|
96182
|
+
id: "kimi-k3.1-pro",
|
|
96183
|
+
name: "Kimi-K3.1-Pro",
|
|
96184
|
+
contextWindow: 3e5,
|
|
95990
96185
|
maxContextWindow: 1e6,
|
|
95991
|
-
maxTokens:
|
|
96186
|
+
maxTokens: 32e3,
|
|
95992
96187
|
regions: ["intl", "cn"],
|
|
95993
96188
|
credits: {
|
|
95994
|
-
cn: "0.
|
|
95995
|
-
intl: "0.
|
|
96189
|
+
cn: "0.97",
|
|
96190
|
+
intl: "0.97"
|
|
95996
96191
|
},
|
|
95997
96192
|
supportsImage: true,
|
|
95998
|
-
reasoningEfforts: [
|
|
96193
|
+
reasoningEfforts: [
|
|
96194
|
+
"low",
|
|
96195
|
+
"high",
|
|
96196
|
+
"max"
|
|
96197
|
+
],
|
|
95999
96198
|
defaultReasoningEffort: "high",
|
|
96000
|
-
canDisableThinking:
|
|
96001
|
-
description: "
|
|
96199
|
+
canDisableThinking: false,
|
|
96200
|
+
description: "Kimi 全新旗舰模型,3万亿级参数。办公、代码、3D 创作与长程 Agent 能力全面升级。"
|
|
96002
96201
|
},
|
|
96003
96202
|
{
|
|
96004
|
-
id: "
|
|
96005
|
-
name: "
|
|
96006
|
-
contextWindow:
|
|
96007
|
-
maxContextWindow:
|
|
96008
|
-
maxTokens:
|
|
96009
|
-
regions: ["
|
|
96010
|
-
credits: {
|
|
96203
|
+
id: "kimi-k3.1-pro-highspeed",
|
|
96204
|
+
name: "Kimi-K3.1-Pro-Highspeed",
|
|
96205
|
+
contextWindow: 3e5,
|
|
96206
|
+
maxContextWindow: 1e6,
|
|
96207
|
+
maxTokens: 32e3,
|
|
96208
|
+
regions: ["intl"],
|
|
96209
|
+
credits: { intl: "1.56" },
|
|
96011
96210
|
supportsImage: true,
|
|
96012
96211
|
reasoningEfforts: [
|
|
96013
96212
|
"low",
|
|
96014
96213
|
"high",
|
|
96015
96214
|
"max"
|
|
96016
96215
|
],
|
|
96017
|
-
defaultReasoningEffort: "
|
|
96216
|
+
defaultReasoningEffort: "high",
|
|
96018
96217
|
canDisableThinking: false,
|
|
96019
|
-
description: ""
|
|
96218
|
+
description: "K3.1 Pro 高速版本,响应速度提升至 K3.1 Pro 的 2–3 倍,交互更流畅。"
|
|
96020
96219
|
},
|
|
96021
96220
|
{
|
|
96022
|
-
id: "
|
|
96023
|
-
name: "
|
|
96024
|
-
contextWindow:
|
|
96025
|
-
maxContextWindow:
|
|
96026
|
-
maxTokens:
|
|
96027
|
-
regions: ["
|
|
96028
|
-
credits: {
|
|
96221
|
+
id: "kimi-k3",
|
|
96222
|
+
name: "Kimi-K3",
|
|
96223
|
+
contextWindow: 1e6,
|
|
96224
|
+
maxContextWindow: 1e6,
|
|
96225
|
+
maxTokens: 32e3,
|
|
96226
|
+
regions: ["intl"],
|
|
96227
|
+
credits: { intl: "1.62" },
|
|
96029
96228
|
supportsImage: true,
|
|
96030
96229
|
reasoningEfforts: [
|
|
96031
96230
|
"low",
|
|
96032
96231
|
"high",
|
|
96033
96232
|
"max"
|
|
96034
96233
|
],
|
|
96035
|
-
defaultReasoningEffort: "
|
|
96234
|
+
defaultReasoningEffort: "high",
|
|
96036
96235
|
canDisableThinking: false,
|
|
96037
|
-
description: ""
|
|
96236
|
+
description: "擅长处理复杂的长程自主任务,前端开发能力突出,同时在知识工作与科研推理上表现出色。"
|
|
96038
96237
|
},
|
|
96039
96238
|
{
|
|
96040
|
-
id: "
|
|
96041
|
-
name: "
|
|
96239
|
+
id: "grok-4.7",
|
|
96240
|
+
name: "Grok-4.7",
|
|
96042
96241
|
contextWindow: 2e5,
|
|
96043
|
-
maxContextWindow:
|
|
96044
|
-
maxTokens:
|
|
96045
|
-
regions: ["
|
|
96046
|
-
credits: {
|
|
96047
|
-
supportsImage:
|
|
96048
|
-
reasoningEfforts: [
|
|
96049
|
-
|
|
96242
|
+
maxContextWindow: 5e5,
|
|
96243
|
+
maxTokens: 128e3,
|
|
96244
|
+
regions: ["intl"],
|
|
96245
|
+
credits: { intl: "1.90" },
|
|
96246
|
+
supportsImage: true,
|
|
96247
|
+
reasoningEfforts: [
|
|
96248
|
+
"low",
|
|
96249
|
+
"medium",
|
|
96250
|
+
"high",
|
|
96251
|
+
"xhigh"
|
|
96252
|
+
],
|
|
96253
|
+
defaultReasoningEffort: "high",
|
|
96050
96254
|
canDisableThinking: false,
|
|
96051
|
-
description: ""
|
|
96255
|
+
description: "SpaceXAI 打造的前沿模型,专为编程、智能体任务及知识型工作而设计。"
|
|
96052
96256
|
},
|
|
96053
96257
|
{
|
|
96054
|
-
id: "
|
|
96055
|
-
name: "
|
|
96056
|
-
contextWindow:
|
|
96057
|
-
maxContextWindow:
|
|
96058
|
-
maxTokens:
|
|
96059
|
-
regions: ["
|
|
96060
|
-
credits: {
|
|
96061
|
-
supportsImage:
|
|
96258
|
+
id: "gemini-3.8-flash",
|
|
96259
|
+
name: "Gemini-3.8-Flash",
|
|
96260
|
+
contextWindow: 3e5,
|
|
96261
|
+
maxContextWindow: 1e6,
|
|
96262
|
+
maxTokens: 65536,
|
|
96263
|
+
regions: ["intl"],
|
|
96264
|
+
credits: { intl: "0.95" },
|
|
96265
|
+
supportsImage: true,
|
|
96062
96266
|
reasoningEfforts: [
|
|
96063
96267
|
"low",
|
|
96064
|
-
"
|
|
96065
|
-
"
|
|
96268
|
+
"medium",
|
|
96269
|
+
"high"
|
|
96066
96270
|
],
|
|
96067
96271
|
defaultReasoningEffort: "medium",
|
|
96068
96272
|
canDisableThinking: false,
|
|
96069
|
-
description: ""
|
|
96273
|
+
description: "能力均衡,适合日常使用"
|
|
96070
96274
|
},
|
|
96071
96275
|
{
|
|
96072
|
-
id: "
|
|
96073
|
-
name: "
|
|
96074
|
-
contextWindow:
|
|
96075
|
-
maxContextWindow:
|
|
96076
|
-
maxTokens:
|
|
96077
|
-
regions: ["
|
|
96078
|
-
credits: {
|
|
96079
|
-
supportsImage:
|
|
96080
|
-
reasoningEfforts: [
|
|
96081
|
-
|
|
96276
|
+
id: "gpt-6-sol",
|
|
96277
|
+
name: "GPT-6-Sol",
|
|
96278
|
+
contextWindow: 1e6,
|
|
96279
|
+
maxContextWindow: 1e6,
|
|
96280
|
+
maxTokens: 128e3,
|
|
96281
|
+
regions: ["intl"],
|
|
96282
|
+
credits: { intl: "1.33" },
|
|
96283
|
+
supportsImage: true,
|
|
96284
|
+
reasoningEfforts: [
|
|
96285
|
+
"low",
|
|
96286
|
+
"medium",
|
|
96287
|
+
"high",
|
|
96288
|
+
"xhigh"
|
|
96289
|
+
],
|
|
96290
|
+
defaultReasoningEffort: "high",
|
|
96082
96291
|
canDisableThinking: false,
|
|
96083
|
-
description: ""
|
|
96292
|
+
description: "专为复杂编码和智能体工作流构建的模型"
|
|
96084
96293
|
},
|
|
96085
96294
|
{
|
|
96086
|
-
id: "
|
|
96087
|
-
name: "
|
|
96088
|
-
contextWindow:
|
|
96089
|
-
maxContextWindow:
|
|
96090
|
-
maxTokens:
|
|
96091
|
-
regions: ["
|
|
96092
|
-
credits: {
|
|
96295
|
+
id: "gpt-6-luna",
|
|
96296
|
+
name: "GPT-6-Luna",
|
|
96297
|
+
contextWindow: 1e6,
|
|
96298
|
+
maxContextWindow: 1e6,
|
|
96299
|
+
maxTokens: 128e3,
|
|
96300
|
+
regions: ["intl"],
|
|
96301
|
+
credits: { intl: "0.07" },
|
|
96093
96302
|
supportsImage: true,
|
|
96094
96303
|
reasoningEfforts: [
|
|
96095
96304
|
"low",
|
|
96305
|
+
"medium",
|
|
96096
96306
|
"high",
|
|
96097
|
-
"
|
|
96307
|
+
"xhigh"
|
|
96098
96308
|
],
|
|
96099
96309
|
defaultReasoningEffort: "high",
|
|
96100
96310
|
canDisableThinking: false,
|
|
96101
|
-
description: ""
|
|
96311
|
+
description: "专为单一聚焦、高吞吐量任务打造的高效模型"
|
|
96102
96312
|
},
|
|
96103
96313
|
{
|
|
96104
|
-
id: "
|
|
96105
|
-
name: "
|
|
96106
|
-
contextWindow:
|
|
96107
|
-
maxContextWindow:
|
|
96108
|
-
maxTokens:
|
|
96314
|
+
id: "gpt-6.1-sol",
|
|
96315
|
+
name: "GPT-6.1-Sol",
|
|
96316
|
+
contextWindow: 272e3,
|
|
96317
|
+
maxContextWindow: 1e6,
|
|
96318
|
+
maxTokens: 128e3,
|
|
96319
|
+
regions: ["intl"],
|
|
96320
|
+
credits: { intl: "1.33" },
|
|
96321
|
+
supportsImage: true,
|
|
96322
|
+
reasoningEfforts: [
|
|
96323
|
+
"low",
|
|
96324
|
+
"medium",
|
|
96325
|
+
"high",
|
|
96326
|
+
"xhigh"
|
|
96327
|
+
],
|
|
96328
|
+
defaultReasoningEffort: "high",
|
|
96329
|
+
canDisableThinking: false,
|
|
96330
|
+
description: "专为复杂编码和智能体工作流构建的模型"
|
|
96331
|
+
},
|
|
96332
|
+
{
|
|
96333
|
+
id: "default",
|
|
96334
|
+
name: "Default",
|
|
96335
|
+
contextWindow: 56e3,
|
|
96336
|
+
maxContextWindow: 56e3,
|
|
96337
|
+
maxTokens: 24e3,
|
|
96109
96338
|
regions: ["cn"],
|
|
96110
|
-
credits: { cn: "
|
|
96339
|
+
credits: { cn: "2.00" },
|
|
96111
96340
|
supportsImage: false,
|
|
96112
96341
|
reasoningEfforts: [],
|
|
96113
96342
|
defaultReasoningEffort: null,
|
|
@@ -96115,110 +96344,118 @@ const FALLBACK_MODELS$1 = [
|
|
|
96115
96344
|
description: ""
|
|
96116
96345
|
},
|
|
96117
96346
|
{
|
|
96118
|
-
id: "
|
|
96119
|
-
name: "
|
|
96347
|
+
id: "deepseek-v4-pro",
|
|
96348
|
+
name: "DeepSeek-V4-Pro",
|
|
96120
96349
|
contextWindow: 1e6,
|
|
96121
96350
|
maxContextWindow: 1e6,
|
|
96122
|
-
maxTokens:
|
|
96123
|
-
regions: ["
|
|
96124
|
-
credits: {
|
|
96351
|
+
maxTokens: 128e3,
|
|
96352
|
+
regions: ["cn"],
|
|
96353
|
+
credits: { cn: "0.51" },
|
|
96125
96354
|
supportsImage: true,
|
|
96126
96355
|
reasoningEfforts: [
|
|
96127
96356
|
"low",
|
|
96128
96357
|
"high",
|
|
96129
96358
|
"max"
|
|
96130
96359
|
],
|
|
96131
|
-
defaultReasoningEffort: "
|
|
96360
|
+
defaultReasoningEffort: "high",
|
|
96132
96361
|
canDisableThinking: false,
|
|
96133
|
-
description: "
|
|
96362
|
+
description: ""
|
|
96134
96363
|
},
|
|
96135
96364
|
{
|
|
96136
|
-
id: "
|
|
96137
|
-
name: "
|
|
96365
|
+
id: "deepseek-v4-flash",
|
|
96366
|
+
name: "Deepseek-V4-Flash",
|
|
96138
96367
|
contextWindow: 1e6,
|
|
96139
96368
|
maxContextWindow: 1e6,
|
|
96140
|
-
maxTokens:
|
|
96369
|
+
maxTokens: 5e4,
|
|
96141
96370
|
regions: ["cn"],
|
|
96142
|
-
credits: { cn: "
|
|
96371
|
+
credits: { cn: "0.17" },
|
|
96143
96372
|
supportsImage: true,
|
|
96144
96373
|
reasoningEfforts: [
|
|
96145
96374
|
"low",
|
|
96146
96375
|
"high",
|
|
96147
96376
|
"max"
|
|
96148
96377
|
],
|
|
96149
|
-
defaultReasoningEffort: "
|
|
96378
|
+
defaultReasoningEffort: "high",
|
|
96150
96379
|
canDisableThinking: false,
|
|
96151
|
-
description: "
|
|
96380
|
+
description: ""
|
|
96152
96381
|
},
|
|
96153
96382
|
{
|
|
96154
|
-
id: "
|
|
96155
|
-
name: "
|
|
96156
|
-
contextWindow:
|
|
96157
|
-
maxContextWindow:
|
|
96383
|
+
id: "deepseek-v3-2-volc",
|
|
96384
|
+
name: "DeepSeek-V3.2",
|
|
96385
|
+
contextWindow: 96e3,
|
|
96386
|
+
maxContextWindow: 96e3,
|
|
96158
96387
|
maxTokens: 32e3,
|
|
96159
|
-
regions: ["
|
|
96160
|
-
credits: {
|
|
96161
|
-
|
|
96162
|
-
intl: "0.77"
|
|
96163
|
-
},
|
|
96164
|
-
supportsImage: true,
|
|
96388
|
+
regions: ["cn"],
|
|
96389
|
+
credits: { cn: "0.29" },
|
|
96390
|
+
supportsImage: false,
|
|
96165
96391
|
reasoningEfforts: [
|
|
96166
96392
|
"low",
|
|
96167
96393
|
"high",
|
|
96168
96394
|
"max"
|
|
96169
96395
|
],
|
|
96170
96396
|
defaultReasoningEffort: "high",
|
|
96171
|
-
canDisableThinking:
|
|
96172
|
-
description: "
|
|
96397
|
+
canDisableThinking: false,
|
|
96398
|
+
description: ""
|
|
96173
96399
|
},
|
|
96174
96400
|
{
|
|
96175
|
-
id: "
|
|
96176
|
-
name: "
|
|
96177
|
-
contextWindow:
|
|
96178
|
-
maxContextWindow:
|
|
96179
|
-
maxTokens:
|
|
96401
|
+
id: "minimax-m2.5",
|
|
96402
|
+
name: "MiniMax-M2.5",
|
|
96403
|
+
contextWindow: 2e5,
|
|
96404
|
+
maxContextWindow: 2e5,
|
|
96405
|
+
maxTokens: 48e3,
|
|
96180
96406
|
regions: ["cn"],
|
|
96181
|
-
credits: { cn: "0.
|
|
96182
|
-
supportsImage:
|
|
96407
|
+
credits: { cn: "0.18" },
|
|
96408
|
+
supportsImage: false,
|
|
96183
96409
|
reasoningEfforts: [
|
|
96184
96410
|
"low",
|
|
96185
96411
|
"high",
|
|
96186
96412
|
"max"
|
|
96187
96413
|
],
|
|
96188
|
-
defaultReasoningEffort: "
|
|
96414
|
+
defaultReasoningEffort: "high",
|
|
96189
96415
|
canDisableThinking: false,
|
|
96190
96416
|
description: ""
|
|
96191
96417
|
},
|
|
96192
96418
|
{
|
|
96193
|
-
id: "
|
|
96194
|
-
name: "
|
|
96195
|
-
contextWindow:
|
|
96196
|
-
maxContextWindow:
|
|
96197
|
-
maxTokens:
|
|
96198
|
-
regions: ["
|
|
96199
|
-
credits: {
|
|
96200
|
-
cn: "0.52",
|
|
96201
|
-
intl: "0.52"
|
|
96202
|
-
},
|
|
96419
|
+
id: "minimax-m2.7",
|
|
96420
|
+
name: "MiniMax-M2.7",
|
|
96421
|
+
contextWindow: 2e5,
|
|
96422
|
+
maxContextWindow: 2e5,
|
|
96423
|
+
maxTokens: 48e3,
|
|
96424
|
+
regions: ["cn"],
|
|
96425
|
+
credits: { cn: "0.19" },
|
|
96203
96426
|
supportsImage: true,
|
|
96204
96427
|
reasoningEfforts: [
|
|
96205
96428
|
"low",
|
|
96206
96429
|
"high",
|
|
96207
96430
|
"max"
|
|
96208
96431
|
],
|
|
96209
|
-
defaultReasoningEffort: "
|
|
96432
|
+
defaultReasoningEffort: "high",
|
|
96210
96433
|
canDisableThinking: false,
|
|
96211
|
-
description: "
|
|
96434
|
+
description: ""
|
|
96212
96435
|
},
|
|
96213
96436
|
{
|
|
96214
|
-
id: "
|
|
96215
|
-
name: "
|
|
96216
|
-
contextWindow:
|
|
96217
|
-
maxContextWindow:
|
|
96218
|
-
maxTokens:
|
|
96437
|
+
id: "glm-5.0",
|
|
96438
|
+
name: "GLM-5.0",
|
|
96439
|
+
contextWindow: 2e5,
|
|
96440
|
+
maxContextWindow: 2e5,
|
|
96441
|
+
maxTokens: 48e3,
|
|
96219
96442
|
regions: ["cn"],
|
|
96220
|
-
credits: { cn: "0.
|
|
96221
|
-
supportsImage:
|
|
96443
|
+
credits: { cn: "0.80" },
|
|
96444
|
+
supportsImage: false,
|
|
96445
|
+
reasoningEfforts: [],
|
|
96446
|
+
defaultReasoningEffort: null,
|
|
96447
|
+
canDisableThinking: false,
|
|
96448
|
+
description: ""
|
|
96449
|
+
},
|
|
96450
|
+
{
|
|
96451
|
+
id: "glm-5.0-turbo",
|
|
96452
|
+
name: "GLM-5.0-Turbo",
|
|
96453
|
+
contextWindow: 2e5,
|
|
96454
|
+
maxContextWindow: 2e5,
|
|
96455
|
+
maxTokens: 48e3,
|
|
96456
|
+
regions: ["cn"],
|
|
96457
|
+
credits: { cn: "0.95" },
|
|
96458
|
+
supportsImage: false,
|
|
96222
96459
|
reasoningEfforts: [
|
|
96223
96460
|
"low",
|
|
96224
96461
|
"high",
|
|
@@ -96229,34 +96466,41 @@ const FALLBACK_MODELS$1 = [
|
|
|
96229
96466
|
description: ""
|
|
96230
96467
|
},
|
|
96231
96468
|
{
|
|
96232
|
-
id: "
|
|
96233
|
-
name: "
|
|
96234
|
-
contextWindow:
|
|
96235
|
-
maxContextWindow:
|
|
96469
|
+
id: "glm-4.7",
|
|
96470
|
+
name: "GLM-4.7",
|
|
96471
|
+
contextWindow: 2e5,
|
|
96472
|
+
maxContextWindow: 2e5,
|
|
96473
|
+
maxTokens: 48e3,
|
|
96474
|
+
regions: ["cn"],
|
|
96475
|
+
credits: { cn: "0.23" },
|
|
96476
|
+
supportsImage: false,
|
|
96477
|
+
reasoningEfforts: [],
|
|
96478
|
+
defaultReasoningEffort: null,
|
|
96479
|
+
canDisableThinking: false,
|
|
96480
|
+
description: ""
|
|
96481
|
+
},
|
|
96482
|
+
{
|
|
96483
|
+
id: "glm-4.6",
|
|
96484
|
+
name: "GLM-4.6",
|
|
96485
|
+
contextWindow: 168e3,
|
|
96486
|
+
maxContextWindow: 168e3,
|
|
96236
96487
|
maxTokens: 32e3,
|
|
96237
96488
|
regions: ["cn"],
|
|
96238
|
-
credits: { cn: "0.
|
|
96489
|
+
credits: { cn: "0.23" },
|
|
96239
96490
|
supportsImage: false,
|
|
96240
|
-
reasoningEfforts: [
|
|
96241
|
-
|
|
96242
|
-
"high",
|
|
96243
|
-
"max"
|
|
96244
|
-
],
|
|
96245
|
-
defaultReasoningEffort: "high",
|
|
96491
|
+
reasoningEfforts: [],
|
|
96492
|
+
defaultReasoningEffort: null,
|
|
96246
96493
|
canDisableThinking: false,
|
|
96247
96494
|
description: ""
|
|
96248
96495
|
},
|
|
96249
96496
|
{
|
|
96250
|
-
id: "
|
|
96251
|
-
name: "
|
|
96252
|
-
contextWindow:
|
|
96253
|
-
maxContextWindow:
|
|
96254
|
-
maxTokens:
|
|
96255
|
-
regions: ["
|
|
96256
|
-
credits: {
|
|
96257
|
-
cn: "0.11",
|
|
96258
|
-
intl: "0.00"
|
|
96259
|
-
},
|
|
96497
|
+
id: "glm-4.6v",
|
|
96498
|
+
name: "GLM-4.6V",
|
|
96499
|
+
contextWindow: 128e3,
|
|
96500
|
+
maxContextWindow: 128e3,
|
|
96501
|
+
maxTokens: 32e3,
|
|
96502
|
+
regions: ["cn"],
|
|
96503
|
+
credits: { cn: "0.11" },
|
|
96260
96504
|
supportsImage: true,
|
|
96261
96505
|
reasoningEfforts: [
|
|
96262
96506
|
"low",
|
|
@@ -96265,16 +96509,16 @@ const FALLBACK_MODELS$1 = [
|
|
|
96265
96509
|
],
|
|
96266
96510
|
defaultReasoningEffort: "high",
|
|
96267
96511
|
canDisableThinking: false,
|
|
96268
|
-
description: "
|
|
96512
|
+
description: ""
|
|
96269
96513
|
},
|
|
96270
96514
|
{
|
|
96271
|
-
id: "
|
|
96272
|
-
name: "
|
|
96273
|
-
contextWindow:
|
|
96515
|
+
id: "kimi-k3-1",
|
|
96516
|
+
name: "Kimi-K3",
|
|
96517
|
+
contextWindow: 1e6,
|
|
96274
96518
|
maxContextWindow: 1e6,
|
|
96275
|
-
maxTokens:
|
|
96276
|
-
regions: ["
|
|
96277
|
-
credits: {
|
|
96519
|
+
maxTokens: 32e3,
|
|
96520
|
+
regions: ["cn"],
|
|
96521
|
+
credits: { cn: "1.62" },
|
|
96278
96522
|
supportsImage: true,
|
|
96279
96523
|
reasoningEfforts: [
|
|
96280
96524
|
"low",
|
|
@@ -96283,16 +96527,16 @@ const FALLBACK_MODELS$1 = [
|
|
|
96283
96527
|
],
|
|
96284
96528
|
defaultReasoningEffort: "high",
|
|
96285
96529
|
canDisableThinking: false,
|
|
96286
|
-
description: "
|
|
96530
|
+
description: "擅长处理复杂的长程自主任务,前端开发能力突出,同时在知识工作与科研推理上表现出色。"
|
|
96287
96531
|
},
|
|
96288
96532
|
{
|
|
96289
|
-
id: "
|
|
96290
|
-
name: "
|
|
96533
|
+
id: "kimi-k2.8-preview",
|
|
96534
|
+
name: "Kimi-K2.8-Preview",
|
|
96291
96535
|
contextWindow: 1e6,
|
|
96292
96536
|
maxContextWindow: 1e6,
|
|
96293
|
-
maxTokens:
|
|
96537
|
+
maxTokens: 64e3,
|
|
96294
96538
|
regions: ["cn"],
|
|
96295
|
-
credits: { cn: "0.
|
|
96539
|
+
credits: { cn: "0.77" },
|
|
96296
96540
|
supportsImage: true,
|
|
96297
96541
|
reasoningEfforts: [
|
|
96298
96542
|
"low",
|
|
@@ -96300,17 +96544,17 @@ const FALLBACK_MODELS$1 = [
|
|
|
96300
96544
|
"max"
|
|
96301
96545
|
],
|
|
96302
96546
|
defaultReasoningEffort: "high",
|
|
96303
|
-
canDisableThinking:
|
|
96304
|
-
description: ""
|
|
96547
|
+
canDisableThinking: true,
|
|
96548
|
+
description: "Moonshot AI · 擅长复杂长程自主任务、知识工作与科研推理,前端开发突出"
|
|
96305
96549
|
},
|
|
96306
96550
|
{
|
|
96307
|
-
id: "
|
|
96308
|
-
name: "
|
|
96309
|
-
contextWindow:
|
|
96310
|
-
maxContextWindow:
|
|
96311
|
-
maxTokens:
|
|
96551
|
+
id: "kimi-k2.5",
|
|
96552
|
+
name: "Kimi-K2.5",
|
|
96553
|
+
contextWindow: 164e3,
|
|
96554
|
+
maxContextWindow: 164e3,
|
|
96555
|
+
maxTokens: 32e3,
|
|
96312
96556
|
regions: ["cn"],
|
|
96313
|
-
credits: { cn: "0.
|
|
96557
|
+
credits: { cn: "0.45" },
|
|
96314
96558
|
supportsImage: true,
|
|
96315
96559
|
reasoningEfforts: [
|
|
96316
96560
|
"low",
|
|
@@ -96322,13 +96566,13 @@ const FALLBACK_MODELS$1 = [
|
|
|
96322
96566
|
description: ""
|
|
96323
96567
|
},
|
|
96324
96568
|
{
|
|
96325
|
-
id: "
|
|
96326
|
-
name: "
|
|
96327
|
-
contextWindow:
|
|
96328
|
-
maxContextWindow:
|
|
96569
|
+
id: "kimi-k2-thinking",
|
|
96570
|
+
name: "Kimi-K2-Thinking",
|
|
96571
|
+
contextWindow: 164e3,
|
|
96572
|
+
maxContextWindow: 164e3,
|
|
96329
96573
|
maxTokens: 32e3,
|
|
96330
96574
|
regions: ["cn"],
|
|
96331
|
-
credits: { cn: "0.
|
|
96575
|
+
credits: { cn: "0.54" },
|
|
96332
96576
|
supportsImage: false,
|
|
96333
96577
|
reasoningEfforts: [
|
|
96334
96578
|
"low",
|
|
@@ -96340,71 +96584,37 @@ const FALLBACK_MODELS$1 = [
|
|
|
96340
96584
|
description: ""
|
|
96341
96585
|
},
|
|
96342
96586
|
{
|
|
96343
|
-
id: "
|
|
96344
|
-
name: "
|
|
96345
|
-
contextWindow:
|
|
96346
|
-
maxContextWindow:
|
|
96587
|
+
id: "hy3-x",
|
|
96588
|
+
name: "Hy3",
|
|
96589
|
+
contextWindow: 192e3,
|
|
96590
|
+
maxContextWindow: 192e3,
|
|
96347
96591
|
maxTokens: 64e3,
|
|
96348
|
-
regions: ["
|
|
96349
|
-
credits: {
|
|
96350
|
-
cn: "0.29",
|
|
96351
|
-
intl: "0.29"
|
|
96352
|
-
},
|
|
96592
|
+
regions: ["cn"],
|
|
96593
|
+
credits: { cn: "0.05" },
|
|
96353
96594
|
supportsImage: true,
|
|
96354
|
-
reasoningEfforts: [
|
|
96595
|
+
reasoningEfforts: [
|
|
96596
|
+
"low",
|
|
96597
|
+
"high",
|
|
96598
|
+
"max"
|
|
96599
|
+
],
|
|
96355
96600
|
defaultReasoningEffort: "high",
|
|
96356
96601
|
canDisableThinking: false,
|
|
96357
96602
|
description: "混元思考模型,具有增强的推理能力"
|
|
96358
96603
|
},
|
|
96359
96604
|
{
|
|
96360
|
-
id: "hy4-preview-
|
|
96605
|
+
id: "hy4-preview-x",
|
|
96361
96606
|
name: "Hy4 preview",
|
|
96362
96607
|
contextWindow: 1e6,
|
|
96363
96608
|
maxContextWindow: 1e6,
|
|
96364
96609
|
maxTokens: 64e3,
|
|
96365
96610
|
regions: ["cn"],
|
|
96366
|
-
credits: { cn: "0.
|
|
96611
|
+
credits: { cn: "0.29" },
|
|
96367
96612
|
supportsImage: true,
|
|
96368
96613
|
reasoningEfforts: ["high"],
|
|
96369
96614
|
defaultReasoningEffort: "high",
|
|
96370
96615
|
canDisableThinking: false,
|
|
96371
96616
|
description: "混元思考模型,具有增强的推理能力"
|
|
96372
96617
|
},
|
|
96373
|
-
{
|
|
96374
|
-
id: "hy3",
|
|
96375
|
-
name: "Hy3",
|
|
96376
|
-
contextWindow: 192e3,
|
|
96377
|
-
maxContextWindow: 192e3,
|
|
96378
|
-
maxTokens: 64e3,
|
|
96379
|
-
regions: ["intl", "cn"],
|
|
96380
|
-
credits: {
|
|
96381
|
-
cn: "0.00",
|
|
96382
|
-
intl: "0.00"
|
|
96383
|
-
},
|
|
96384
|
-
supportsImage: true,
|
|
96385
|
-
reasoningEfforts: ["low", "high"],
|
|
96386
|
-
defaultReasoningEffort: "high",
|
|
96387
|
-
canDisableThinking: false,
|
|
96388
|
-
description: "混元思考模型,具有增强的推理能力"
|
|
96389
|
-
},
|
|
96390
|
-
{
|
|
96391
|
-
id: "hy3-x",
|
|
96392
|
-
name: "Hy3",
|
|
96393
|
-
contextWindow: 192e3,
|
|
96394
|
-
maxContextWindow: 192e3,
|
|
96395
|
-
maxTokens: 64e3,
|
|
96396
|
-
regions: ["cn"],
|
|
96397
|
-
credits: { cn: "0.05" },
|
|
96398
|
-
supportsImage: true,
|
|
96399
|
-
reasoningEfforts: [
|
|
96400
|
-
"low",
|
|
96401
|
-
"high",
|
|
96402
|
-
"max"
|
|
96403
|
-
],
|
|
96404
|
-
defaultReasoningEffort: "high",
|
|
96405
|
-
canDisableThinking: false,
|
|
96406
|
-
description: "混元思考模型,具有增强的推理能力"
|
|
96407
|
-
},
|
|
96408
96618
|
{
|
|
96409
96619
|
id: "hunyuan-chat",
|
|
96410
96620
|
name: "Hunyuan-Turbos",
|
|
@@ -96440,77 +96650,68 @@ const FALLBACK_MODELS$1 = [
|
|
|
96440
96650
|
description: "推理速度极快,编码能力强劲,并支持原生多模态输入的匿名大模型"
|
|
96441
96651
|
},
|
|
96442
96652
|
{
|
|
96443
|
-
id: "
|
|
96444
|
-
name: "
|
|
96445
|
-
contextWindow:
|
|
96446
|
-
maxContextWindow:
|
|
96653
|
+
id: "step-5-preview",
|
|
96654
|
+
name: "Step-5-Preview",
|
|
96655
|
+
contextWindow: 1e6,
|
|
96656
|
+
maxContextWindow: 1e6,
|
|
96447
96657
|
maxTokens: 64e3,
|
|
96448
96658
|
regions: ["cn"],
|
|
96449
|
-
credits: { cn: "0.
|
|
96659
|
+
credits: { cn: "0.33" },
|
|
96450
96660
|
supportsImage: true,
|
|
96451
96661
|
reasoningEfforts: [
|
|
96452
96662
|
"low",
|
|
96453
|
-
"
|
|
96454
|
-
"
|
|
96663
|
+
"medium",
|
|
96664
|
+
"high"
|
|
96455
96665
|
],
|
|
96456
|
-
defaultReasoningEffort: "
|
|
96666
|
+
defaultReasoningEffort: "high",
|
|
96457
96667
|
canDisableThinking: false,
|
|
96458
|
-
description: "
|
|
96668
|
+
description: "阶跃 StepFun 面向真实任务的新一代旗舰基模"
|
|
96459
96669
|
},
|
|
96460
96670
|
{
|
|
96461
|
-
id: "
|
|
96462
|
-
name: "
|
|
96463
|
-
contextWindow:
|
|
96464
|
-
maxContextWindow:
|
|
96465
|
-
maxTokens:
|
|
96671
|
+
id: "mimo-v2.6-pro",
|
|
96672
|
+
name: "Xiaomi MiMo-V2.6-Pro",
|
|
96673
|
+
contextWindow: 1e6,
|
|
96674
|
+
maxContextWindow: 1e6,
|
|
96675
|
+
maxTokens: 128e3,
|
|
96466
96676
|
regions: ["cn"],
|
|
96467
|
-
credits: { cn: "0.
|
|
96677
|
+
credits: { cn: "0.13" },
|
|
96468
96678
|
supportsImage: true,
|
|
96469
96679
|
reasoningEfforts: [
|
|
96470
96680
|
"low",
|
|
96471
96681
|
"high",
|
|
96472
96682
|
"max"
|
|
96473
96683
|
],
|
|
96474
|
-
defaultReasoningEffort: "
|
|
96684
|
+
defaultReasoningEffort: "high",
|
|
96475
96685
|
canDisableThinking: false,
|
|
96476
|
-
description: ""
|
|
96686
|
+
description: "Xiaomi · 旗舰推理模型,面向专业、复杂长程工作流,兼顾高阶科研与网络安全"
|
|
96477
96687
|
},
|
|
96478
96688
|
{
|
|
96479
|
-
id: "
|
|
96480
|
-
name: "
|
|
96481
|
-
contextWindow:
|
|
96482
|
-
maxContextWindow:
|
|
96483
|
-
maxTokens:
|
|
96689
|
+
id: "hy4free",
|
|
96690
|
+
name: "Hy4 Free",
|
|
96691
|
+
contextWindow: 1e6,
|
|
96692
|
+
maxContextWindow: 1e6,
|
|
96693
|
+
maxTokens: 64e3,
|
|
96484
96694
|
regions: ["cn"],
|
|
96485
|
-
credits: { cn: "0.
|
|
96486
|
-
supportsImage:
|
|
96487
|
-
reasoningEfforts: [
|
|
96488
|
-
"low",
|
|
96489
|
-
"high",
|
|
96490
|
-
"max"
|
|
96491
|
-
],
|
|
96695
|
+
credits: { cn: "0.00" },
|
|
96696
|
+
supportsImage: true,
|
|
96697
|
+
reasoningEfforts: ["high"],
|
|
96492
96698
|
defaultReasoningEffort: "high",
|
|
96493
96699
|
canDisableThinking: false,
|
|
96494
|
-
description: ""
|
|
96700
|
+
description: "最新旗舰模型,Agent与多模专长"
|
|
96495
96701
|
},
|
|
96496
|
-
...UNPUBLISHED_MODELS.filter((model) => model.id === "gemini-3.8-flash"),
|
|
96497
96702
|
{
|
|
96498
|
-
id: "
|
|
96499
|
-
name: "
|
|
96703
|
+
id: "hy4std",
|
|
96704
|
+
name: "Hy4",
|
|
96500
96705
|
contextWindow: 1e6,
|
|
96501
96706
|
maxContextWindow: 1e6,
|
|
96502
|
-
maxTokens:
|
|
96503
|
-
regions: ["
|
|
96504
|
-
credits: {
|
|
96707
|
+
maxTokens: 64e3,
|
|
96708
|
+
regions: ["cn"],
|
|
96709
|
+
credits: { cn: "0.29" },
|
|
96505
96710
|
supportsImage: true,
|
|
96506
|
-
reasoningEfforts: [
|
|
96507
|
-
|
|
96508
|
-
"high",
|
|
96509
|
-
"max"
|
|
96510
|
-
],
|
|
96511
|
-
defaultReasoningEffort: "medium",
|
|
96711
|
+
reasoningEfforts: ["high"],
|
|
96712
|
+
defaultReasoningEffort: "high",
|
|
96512
96713
|
canDisableThinking: false,
|
|
96513
|
-
description: "
|
|
96714
|
+
description: "最新旗舰模型,Agent与多模专长"
|
|
96514
96715
|
}
|
|
96515
96716
|
];
|
|
96516
96717
|
/**
|
|
@@ -96522,11 +96723,41 @@ const FALLBACK_MODELS$1 = [
|
|
|
96522
96723
|
* the account's region can actually call.
|
|
96523
96724
|
*/
|
|
96524
96725
|
const DEFAULT_VISIBLE_MODEL_IDS$1 = [
|
|
96726
|
+
"glm-5.3",
|
|
96727
|
+
"deepseek-v4.1-flash",
|
|
96728
|
+
"hy4std",
|
|
96729
|
+
"kimi-k3.1-pro"
|
|
96730
|
+
];
|
|
96731
|
+
/**
|
|
96732
|
+
* Default selections this table used to ship.
|
|
96733
|
+
*
|
|
96734
|
+
* "Never edited" is recognised by matching the CURRENT shipped set, so replacing
|
|
96735
|
+
* the set outright would turn every existing install into what looks like a user
|
|
96736
|
+
* who hand-picked a short list — and the picker would quietly narrow to it,
|
|
96737
|
+
* because the 2026-11-04 refresh dropped two of the retired ids outright
|
|
96738
|
+
* (`kimi-k2.6` is gone from both regions, `hy4-preview` is intl-only now).
|
|
96739
|
+
* Keeping the retired sets here is what lets the default move without that.
|
|
96740
|
+
*/
|
|
96741
|
+
const RETIRED_DEFAULT_SELECTIONS = [[
|
|
96525
96742
|
"glm-5.3",
|
|
96526
96743
|
"deepseek-v4.1-flash",
|
|
96527
96744
|
"hy4-preview",
|
|
96528
96745
|
"kimi-k2.6"
|
|
96529
|
-
];
|
|
96746
|
+
]];
|
|
96747
|
+
/**
|
|
96748
|
+
* Whether a stored selection is still a shipped default, i.e. the user never
|
|
96749
|
+
* touched the picker.
|
|
96750
|
+
*
|
|
96751
|
+
* Same size and same members, not order-sensitive: the card writes the list in
|
|
96752
|
+
* catalog order, which one default can spell two ways.
|
|
96753
|
+
*/
|
|
96754
|
+
function isUntouchedModelSelection(stored) {
|
|
96755
|
+
if (stored.length === 0) return false;
|
|
96756
|
+
return [DEFAULT_VISIBLE_MODEL_IDS$1, ...RETIRED_DEFAULT_SELECTIONS].some((shipped) => {
|
|
96757
|
+
const known = new Set(shipped);
|
|
96758
|
+
return stored.length === known.size && stored.every((id) => known.has(id));
|
|
96759
|
+
});
|
|
96760
|
+
}
|
|
96530
96761
|
/** Every id the fallback knows, in declaration order. */
|
|
96531
96762
|
const WORKBUDDY_MODEL_IDS = FALLBACK_MODELS$1.map((model) => model.id);
|
|
96532
96763
|
/**
|
|
@@ -96631,6 +96862,18 @@ const WORKBUDDY_VENDOR_RULES = [
|
|
|
96631
96862
|
re: /^minimax-/,
|
|
96632
96863
|
family: "minimax"
|
|
96633
96864
|
},
|
|
96865
|
+
{
|
|
96866
|
+
re: /^mimo-/,
|
|
96867
|
+
family: "xiaomi"
|
|
96868
|
+
},
|
|
96869
|
+
{
|
|
96870
|
+
re: /^step-/,
|
|
96871
|
+
family: "stepfun"
|
|
96872
|
+
},
|
|
96873
|
+
{
|
|
96874
|
+
re: /^grok-/,
|
|
96875
|
+
family: "xai"
|
|
96876
|
+
},
|
|
96634
96877
|
{
|
|
96635
96878
|
re: /^space-bunny$/,
|
|
96636
96879
|
family: "space-bunny"
|
|
@@ -100552,8 +100795,7 @@ function isPoolPausedError(error) {
|
|
|
100552
100795
|
*/
|
|
100553
100796
|
function resolveEnabledModelIds$2(stored, available, enabled = true) {
|
|
100554
100797
|
if (!enabled) return [];
|
|
100555
|
-
|
|
100556
|
-
if (stored.length > 0 && stored.length === shippedDefaults.size && stored.every((id) => shippedDefaults.has(id))) return [...available];
|
|
100798
|
+
if (isUntouchedModelSelection(stored)) return [...available];
|
|
100557
100799
|
const known = new Set(available);
|
|
100558
100800
|
return stored.filter((id) => known.has(id));
|
|
100559
100801
|
}
|
|
@@ -102220,8 +102462,7 @@ async function readRequestJson(request) {
|
|
|
102220
102462
|
*/
|
|
102221
102463
|
function resolveEnabledModelIds$1(stored, available, enabled = true) {
|
|
102222
102464
|
if (!enabled) return [];
|
|
102223
|
-
|
|
102224
|
-
if (stored.length > 0 && stored.length === shippedDefaults.size && stored.every((id) => shippedDefaults.has(id))) return [...available];
|
|
102465
|
+
if (isUntouchedModelSelection(stored)) return [...available];
|
|
102225
102466
|
const known = new Set(available);
|
|
102226
102467
|
return stored.filter((id) => known.has(id));
|
|
102227
102468
|
}
|