@eddyskywalker/dsh-chatgpt-subscription 0.56.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 +36 -0
- package/README.md +3 -3
- package/lib/client.js +56 -0
- package/lib/client.js.map +1 -1
- package/lib/index.js +964 -491
- package/lib/tool-result-pruner.js +1 -1
- package/lib/types/client/locales-ru/progress-updates.d.ts.map +1 -1
- package/lib/types/client/minimax-code/commands-contract.d.ts +1 -1
- package/lib/types/client/progress-updates/locales.d.ts +8 -2
- package/lib/types/client/progress-updates/locales.d.ts.map +1 -1
- package/lib/types/client/progress-updates/settings-binding.d.ts +8 -1
- package/lib/types/client/progress-updates/settings-binding.d.ts.map +1 -1
- package/lib/types/client/progress-updates/settings-section.d.ts +2 -1
- package/lib/types/client/progress-updates/settings-section.d.ts.map +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/team-policy-cache-guard.d.ts +44 -0
- package/lib/types/host/team-policy-cache-guard.d.ts.map +1 -0
- 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/index.d.ts +14 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/shared/workbuddy-contracts.d.ts +8 -8
- package/package.json +49 -46
- package/presets/dispatch/README.md +26 -6
- package/presets/dispatch/agent.cordis.yml +8 -8
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
|
|
@@ -86900,7 +87083,7 @@ function installToolResultPrunerGuard(ctx, options = {}) {
|
|
|
86900
87083
|
return next === void 0 ? void 0 : next();
|
|
86901
87084
|
};
|
|
86902
87085
|
for (const event of GUARDED_EVENTS$1) {
|
|
86903
|
-
const disposer = subscribe$
|
|
87086
|
+
const disposer = subscribe$4(host, event, handleAgentEvent);
|
|
86904
87087
|
if (disposer !== void 0) disposers.push(disposer);
|
|
86905
87088
|
}
|
|
86906
87089
|
scanAndWrap();
|
|
@@ -86930,7 +87113,7 @@ function installToolResultPrunerGuard(ctx, options = {}) {
|
|
|
86930
87113
|
* @param listener - 回调。
|
|
86931
87114
|
* @returns 移除监听器的 disposer;宿主不支持事件时为 `undefined`。
|
|
86932
87115
|
*/
|
|
86933
|
-
function subscribe$
|
|
87116
|
+
function subscribe$4(host, event, listener) {
|
|
86934
87117
|
const on = host?.on;
|
|
86935
87118
|
if (typeof on !== "function") return void 0;
|
|
86936
87119
|
for (const options of [
|
|
@@ -87107,7 +87290,7 @@ function markPatched$3(patched, holder, name) {
|
|
|
87107
87290
|
//#endregion
|
|
87108
87291
|
//#region src/host/plan-mode-cache-guard.ts
|
|
87109
87292
|
/** 没有 scope 的装配(会话标题之类)用的桶键。 */
|
|
87110
|
-
const GLOBAL_KEY$
|
|
87293
|
+
const GLOBAL_KEY$2 = Object.freeze({});
|
|
87111
87294
|
/**
|
|
87112
87295
|
* 读一个可选服务。
|
|
87113
87296
|
* @param ctx - 宿主上下文。
|
|
@@ -87128,8 +87311,8 @@ function serviceOf$1(ctx, service) {
|
|
|
87128
87311
|
* @param value - scope / agent。
|
|
87129
87312
|
* @returns WeakMap 键。
|
|
87130
87313
|
*/
|
|
87131
|
-
function bucketOf(value) {
|
|
87132
|
-
return typeof value === "object" && value !== null ? value : GLOBAL_KEY$
|
|
87314
|
+
function bucketOf$1(value) {
|
|
87315
|
+
return typeof value === "object" && value !== null ? value : GLOBAL_KEY$2;
|
|
87133
87316
|
}
|
|
87134
87317
|
/**
|
|
87135
87318
|
* 订阅一个事件。
|
|
@@ -87138,7 +87321,7 @@ function bucketOf(value) {
|
|
|
87138
87321
|
* @param listener - 监听器。
|
|
87139
87322
|
* @returns 解绑函数或 undefined。
|
|
87140
87323
|
*/
|
|
87141
|
-
function subscribe$
|
|
87324
|
+
function subscribe$3(ctx, event, listener) {
|
|
87142
87325
|
const on = ctx?.on;
|
|
87143
87326
|
if (typeof on !== "function") return void 0;
|
|
87144
87327
|
try {
|
|
@@ -87191,7 +87374,7 @@ function installPlanModeCacheGuard(ctx) {
|
|
|
87191
87374
|
}
|
|
87192
87375
|
kept.push(section);
|
|
87193
87376
|
}
|
|
87194
|
-
const state = stateOf(bucketOf(context?.scope ?? context?.agent));
|
|
87377
|
+
const state = stateOf(bucketOf$1(context?.scope ?? context?.agent));
|
|
87195
87378
|
if (policy !== void 0) if (policy.trim() === "") {
|
|
87196
87379
|
state.pending = void 0;
|
|
87197
87380
|
state.delivered = false;
|
|
@@ -87210,7 +87393,7 @@ function installPlanModeCacheGuard(ctx) {
|
|
|
87210
87393
|
if (decision === void 0 || decision.kind === "reject") return decision;
|
|
87211
87394
|
if (payload?.signal?.aborted === true) return decision;
|
|
87212
87395
|
const agent = payload?.agent;
|
|
87213
|
-
const key = bucketOf(agent ?? void 0);
|
|
87396
|
+
const key = bucketOf$1(agent ?? void 0);
|
|
87214
87397
|
const state = states.get(key);
|
|
87215
87398
|
if (state === void 0) return decision;
|
|
87216
87399
|
if (state.delivered) if (planActiveOf(ctx, agent?.session) === false) state.delivered = false;
|
|
@@ -87225,8 +87408,8 @@ function installPlanModeCacheGuard(ctx) {
|
|
|
87225
87408
|
messages: [...messages, createPlanNotice(text, void 0, "Plan mode guidance")]
|
|
87226
87409
|
};
|
|
87227
87410
|
};
|
|
87228
|
-
const offAssemble = subscribe$
|
|
87229
|
-
const offPreStep = subscribe$
|
|
87411
|
+
const offAssemble = subscribe$3(ctx, "system-prompt/assemble", onAssemble);
|
|
87412
|
+
const offPreStep = subscribe$3(ctx, "agent/pre-step", onPreStep);
|
|
87230
87413
|
if (offAssemble !== void 0) restores.push(() => {
|
|
87231
87414
|
offAssemble();
|
|
87232
87415
|
});
|
|
@@ -87255,7 +87438,7 @@ function installPlanModeCacheGuard(ctx) {
|
|
|
87255
87438
|
restoreMethod$2(target);
|
|
87256
87439
|
});
|
|
87257
87440
|
if (typeof tools.get === "function") try {
|
|
87258
|
-
if (tools.get("exit_plan_mode") !== void 0) logWarn(ctx, "[dsh-chatgpt-subscription] plan-mode cache guard was installed after exit_plan_mode was already registered; this session keeps the conditional admission");
|
|
87441
|
+
if (tools.get("exit_plan_mode") !== void 0) logWarn$1(ctx, "[dsh-chatgpt-subscription] plan-mode cache guard was installed after exit_plan_mode was already registered; this session keeps the conditional admission");
|
|
87259
87442
|
} catch {}
|
|
87260
87443
|
};
|
|
87261
87444
|
const tools = serviceOf$1(ctx, "tools");
|
|
@@ -87302,7 +87485,7 @@ function planActiveOf(ctx, session) {
|
|
|
87302
87485
|
* @param ctx - 宿主上下文。
|
|
87303
87486
|
* @param message - 正文。
|
|
87304
87487
|
*/
|
|
87305
|
-
function logWarn(ctx, message) {
|
|
87488
|
+
function logWarn$1(ctx, message) {
|
|
87306
87489
|
const logger = ctx?.logger;
|
|
87307
87490
|
try {
|
|
87308
87491
|
logger?.warn(message);
|
|
@@ -87415,7 +87598,7 @@ const DEFAULT_PTC_SDK_CACHE_PROVIDERS = Object.freeze(["kimi-code", "minimax-cod
|
|
|
87415
87598
|
/** PTC 生成的 SDK 段名。 */
|
|
87416
87599
|
const PTC_SDK_SECTION_NAME = "tools:sdk";
|
|
87417
87600
|
/** 没有 scope 的装配(会话标题之类)用的桶键。 */
|
|
87418
|
-
const GLOBAL_KEY = Object.freeze({});
|
|
87601
|
+
const GLOBAL_KEY$1 = Object.freeze({});
|
|
87419
87602
|
/**
|
|
87420
87603
|
* 读一个装配 scope 的 provider。
|
|
87421
87604
|
*
|
|
@@ -87509,7 +87692,7 @@ function installPtcSdkCacheGuard(ctx, options = {}) {
|
|
|
87509
87692
|
* @param scope - 装配 scope。
|
|
87510
87693
|
* @returns WeakMap 键。
|
|
87511
87694
|
*/
|
|
87512
|
-
const bucketOf = (scope) => typeof scope === "object" && scope !== null ? scope : GLOBAL_KEY;
|
|
87695
|
+
const bucketOf = (scope) => typeof scope === "object" && scope !== null ? scope : GLOBAL_KEY$1;
|
|
87513
87696
|
/**
|
|
87514
87697
|
* 算未过滤工具集的名字指纹。
|
|
87515
87698
|
*
|
|
@@ -87599,7 +87782,7 @@ function installPtcSdkCacheGuard(ctx, options = {}) {
|
|
|
87599
87782
|
});
|
|
87600
87783
|
return result;
|
|
87601
87784
|
};
|
|
87602
|
-
const offAssemble = subscribe$
|
|
87785
|
+
const offAssemble = subscribe$2(host, "system-prompt/assemble", onAssemble);
|
|
87603
87786
|
if (offAssemble !== void 0) disposers.push(offAssemble);
|
|
87604
87787
|
const initialTools = serviceOf(host, "tools");
|
|
87605
87788
|
if (initialTools !== void 0) {
|
|
@@ -87656,7 +87839,7 @@ function serviceOf(ctx, service) {
|
|
|
87656
87839
|
* @param listener - 回调。
|
|
87657
87840
|
* @returns 移除监听器的 disposer;宿主不支持事件时为 `undefined`。
|
|
87658
87841
|
*/
|
|
87659
|
-
function subscribe$
|
|
87842
|
+
function subscribe$2(host, event, listener) {
|
|
87660
87843
|
const on = host?.["on"];
|
|
87661
87844
|
if (typeof on !== "function") return void 0;
|
|
87662
87845
|
for (const options of [
|
|
@@ -87787,6 +87970,233 @@ function markPatched$1(patched, holder, name) {
|
|
|
87787
87970
|
else names.add(name);
|
|
87788
87971
|
}
|
|
87789
87972
|
//#endregion
|
|
87973
|
+
//#region src/host/team-policy-cache-guard.ts
|
|
87974
|
+
/**
|
|
87975
|
+
* 「Agent Teams 策略段前缀缓存守卫」—— 把内置 `team:policy` 段从 system 里摘掉,
|
|
87976
|
+
* 改为切开关时**尾部投递**一次。
|
|
87977
|
+
*
|
|
87978
|
+
* ## 为什么需要它
|
|
87979
|
+
*
|
|
87980
|
+
* 内置 `@deepseek-ai/dsh-tool-agent-team` 注册一个段 `team:policy`,正文是
|
|
87981
|
+
* `enabled(agent) ? TEAM_POLICY : ''`:团队开关一开,system prompt 里凭空多出整段
|
|
87982
|
+
* 指引,从那里起的前缀全部作废。这与计划模式当初那处重建同构,本仓库已经用
|
|
87983
|
+
* 「摘段 + 尾部投递」把它压平过(见 `plan-mode-cache-guard.ts`),这里复用同一套
|
|
87984
|
+
* 做法,只是触发器从 `enter_plan_mode` 换成客户端远程调用 `agentTeams.setEnabled`
|
|
87985
|
+
* ——那一步只往会话里追加 `team/mode` 事件,段正文在**装配时**才翻面,所以守卫只要
|
|
87986
|
+
* 盯着装配结果就够,不需要订阅任何 team 服务。
|
|
87987
|
+
*
|
|
87988
|
+
* ## 三条动作
|
|
87989
|
+
*
|
|
87990
|
+
* 1. `system-prompt/assemble` 瀑布:把 `team:policy` 段从呈现里摘掉,并记下它的
|
|
87991
|
+
* 正文。system 段从此在开关前后逐字节恒定。
|
|
87992
|
+
* 2. `agent/pre-step`:把记下的正文作为**尾部用户消息**投一次(每次激活一次)。
|
|
87993
|
+
* 末尾追加不改变已发前缀,指引没有丢,只是从最前面的 system 段搬到了末尾。
|
|
87994
|
+
* 3. 段正文回到空串 = 本次激活结束:复位投递状态,并在下一步投一条**撤销**通知,
|
|
87995
|
+
* 免得历史里那句「这里有一块共享任务板」在关闭后继续误导模型。
|
|
87996
|
+
*
|
|
87997
|
+
* ## 抓的是官方原文,不是抄的副本
|
|
87998
|
+
*
|
|
87999
|
+
* 投递的正文永远是装配时从官方段里捕获到的那一份,不落任何本包的副本。harness 改
|
|
88000
|
+
* 措辞(它已经改过三次)不会让这里过期。代价是它依赖段名 `team:policy`:启用后
|
|
88001
|
+
* 若从未观察到该段,守卫记一条 warn 点名,而不是安静地什么都不做。
|
|
88002
|
+
*
|
|
88003
|
+
* ## 默认开启
|
|
88004
|
+
*
|
|
88005
|
+
* 会话中途切开关才会付一次重建;开会话时就是目标状态则本来就零成本。守卫本身不
|
|
88006
|
+
* 增加任何工具声明面,所以默认开着没有代价,由 `teamPolicyCacheGuard` 关闭,
|
|
88007
|
+
* 每次装配/每步重读活引用。
|
|
88008
|
+
*
|
|
88009
|
+
* @module @eddyskywalker/dsh-chatgpt-subscription/host/team-policy-cache-guard
|
|
88010
|
+
*/
|
|
88011
|
+
/** 官方 Agent Teams 的指引段名。 */
|
|
88012
|
+
const TEAM_POLICY_SECTION = "team:policy";
|
|
88013
|
+
/** 尾部撤销通知的来源 kind(本包自有,见下方 MessageSourceMap 增补)。 */
|
|
88014
|
+
const TEAM_BOARD_NOTICE_SOURCE_KIND = "team-board-notice";
|
|
88015
|
+
/** 开关关掉时补投的那句话。 */
|
|
88016
|
+
const BOARD_OFF_NOTICE = "The shared team task board was turned off. Ignore earlier guidance describing an available board and coordinate through list_agents and send_message.";
|
|
88017
|
+
/**
|
|
88018
|
+
* 从插件配置里读开关。
|
|
88019
|
+
* @param config - 插件配置(结构化:只读一个键)。
|
|
88020
|
+
* @returns 是否启用本守卫;未声明时按开启处理(宿主 schema 的默认值)。
|
|
88021
|
+
*/
|
|
88022
|
+
function resolveTeamPolicyCacheGuardEnabled(config) {
|
|
88023
|
+
return config?.teamPolicyCacheGuard !== false;
|
|
88024
|
+
}
|
|
88025
|
+
/** 没有 scope 的装配(会话标题之类)用的桶键。 */
|
|
88026
|
+
const GLOBAL_KEY = Object.freeze({});
|
|
88027
|
+
/**
|
|
88028
|
+
* 桶键:agent 对象本身,或全局桶。
|
|
88029
|
+
* @param value - scope / agent。
|
|
88030
|
+
* @returns WeakMap 键。
|
|
88031
|
+
*/
|
|
88032
|
+
function bucketOf(value) {
|
|
88033
|
+
return typeof value === "object" && value !== null ? value : GLOBAL_KEY;
|
|
88034
|
+
}
|
|
88035
|
+
/**
|
|
88036
|
+
* 订阅一个事件。
|
|
88037
|
+
* @param ctx - 宿主上下文。
|
|
88038
|
+
* @param event - 事件名。
|
|
88039
|
+
* @param listener - 监听器。
|
|
88040
|
+
* @returns 解绑函数或 undefined。
|
|
88041
|
+
*/
|
|
88042
|
+
function subscribe$1(ctx, event, listener) {
|
|
88043
|
+
const on = ctx?.on;
|
|
88044
|
+
if (typeof on !== "function") return void 0;
|
|
88045
|
+
try {
|
|
88046
|
+
return on.call(ctx, event, listener);
|
|
88047
|
+
} catch {
|
|
88048
|
+
return;
|
|
88049
|
+
}
|
|
88050
|
+
}
|
|
88051
|
+
/**
|
|
88052
|
+
* 记一条警告。
|
|
88053
|
+
* @param ctx - 宿主上下文。
|
|
88054
|
+
* @param message - 正文。
|
|
88055
|
+
*/
|
|
88056
|
+
function logWarn(ctx, message) {
|
|
88057
|
+
try {
|
|
88058
|
+
ctx?.logger?.warn(message);
|
|
88059
|
+
} catch {}
|
|
88060
|
+
}
|
|
88061
|
+
/**
|
|
88062
|
+
* 造一条尾部通知消息。
|
|
88063
|
+
* @param text - 正文。
|
|
88064
|
+
* @param summary - 卡片上显示的一句摘要。
|
|
88065
|
+
* @returns 用户角色的通知消息。
|
|
88066
|
+
*/
|
|
88067
|
+
function createBoardNotice(text, summary) {
|
|
88068
|
+
return createUserMessage({
|
|
88069
|
+
content: [{
|
|
88070
|
+
type: "text",
|
|
88071
|
+
text
|
|
88072
|
+
}],
|
|
88073
|
+
source: {
|
|
88074
|
+
kind: TEAM_BOARD_NOTICE_SOURCE_KIND,
|
|
88075
|
+
form: "notice",
|
|
88076
|
+
summary
|
|
88077
|
+
}
|
|
88078
|
+
});
|
|
88079
|
+
}
|
|
88080
|
+
/**
|
|
88081
|
+
* 装一台「Agent Teams 策略段缓存守卫」。
|
|
88082
|
+
*
|
|
88083
|
+
* 幂等性留给调用方:同一个 ctx 装两次会得到两条监听器,宿主入口应当只装一次。
|
|
88084
|
+
* @param ctx - 宿主上下文(结构化:老代 ctx 也认)。
|
|
88085
|
+
* @param options - 开关读取器。
|
|
88086
|
+
* @returns 句柄,dispose 摘掉全部挂载。
|
|
88087
|
+
*/
|
|
88088
|
+
function installTeamPolicyCacheGuard(ctx, options = {}) {
|
|
88089
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
88090
|
+
const stats = {
|
|
88091
|
+
seen: false,
|
|
88092
|
+
warned: false
|
|
88093
|
+
};
|
|
88094
|
+
const restores = [];
|
|
88095
|
+
let closed = false;
|
|
88096
|
+
const enabled = () => {
|
|
88097
|
+
try {
|
|
88098
|
+
return options.enabled?.() === true;
|
|
88099
|
+
} catch {
|
|
88100
|
+
return false;
|
|
88101
|
+
}
|
|
88102
|
+
};
|
|
88103
|
+
const stateOf = (key) => {
|
|
88104
|
+
let state = states.get(key);
|
|
88105
|
+
if (state === void 0) {
|
|
88106
|
+
state = {
|
|
88107
|
+
policy: "",
|
|
88108
|
+
pending: void 0,
|
|
88109
|
+
delivered: false,
|
|
88110
|
+
revoked: false
|
|
88111
|
+
};
|
|
88112
|
+
states.set(key, state);
|
|
88113
|
+
}
|
|
88114
|
+
return state;
|
|
88115
|
+
};
|
|
88116
|
+
const onAssemble = async (_assembly, context, next) => {
|
|
88117
|
+
const result = await next();
|
|
88118
|
+
if (closed || !enabled()) return result;
|
|
88119
|
+
const sections = Array.isArray(result?.sections) ? result.sections : void 0;
|
|
88120
|
+
if (sections === void 0) return result;
|
|
88121
|
+
const kept = [];
|
|
88122
|
+
let policy;
|
|
88123
|
+
for (const section of sections) {
|
|
88124
|
+
if (section?.name === "team:policy") {
|
|
88125
|
+
stats.seen = true;
|
|
88126
|
+
policy = typeof section.text === "string" ? section.text : "";
|
|
88127
|
+
continue;
|
|
88128
|
+
}
|
|
88129
|
+
kept.push(section);
|
|
88130
|
+
}
|
|
88131
|
+
if (policy === void 0) {
|
|
88132
|
+
if (!stats.seen && !stats.warned) {
|
|
88133
|
+
stats.warned = true;
|
|
88134
|
+
logWarn(ctx, `[dsh-chatgpt-subscription] team policy cache guard is enabled but no "${TEAM_POLICY_SECTION}" section has appeared; the guard is inert on this deployment`);
|
|
88135
|
+
}
|
|
88136
|
+
return result;
|
|
88137
|
+
}
|
|
88138
|
+
const state = stateOf(bucketOf(context?.scope ?? context?.agent));
|
|
88139
|
+
if (policy.trim() === "") {
|
|
88140
|
+
if (state.delivered) state.revoked = true;
|
|
88141
|
+
state.delivered = false;
|
|
88142
|
+
state.pending = void 0;
|
|
88143
|
+
} else {
|
|
88144
|
+
state.policy = policy;
|
|
88145
|
+
state.revoked = false;
|
|
88146
|
+
if (!state.delivered) state.pending = policy;
|
|
88147
|
+
}
|
|
88148
|
+
if (kept.length === sections.length) return result;
|
|
88149
|
+
return {
|
|
88150
|
+
...result,
|
|
88151
|
+
sections: kept
|
|
88152
|
+
};
|
|
88153
|
+
};
|
|
88154
|
+
const onPreStep = async (payload, next) => {
|
|
88155
|
+
const decision = await next();
|
|
88156
|
+
if (closed || decision === void 0 || decision.kind === "reject") return decision;
|
|
88157
|
+
if (payload?.signal?.aborted === true) return decision;
|
|
88158
|
+
if (!enabled()) return decision;
|
|
88159
|
+
const state = states.get(bucketOf(payload?.agent ?? void 0));
|
|
88160
|
+
if (state === void 0) return decision;
|
|
88161
|
+
const messages = Array.isArray(decision.messages) ? decision.messages : [];
|
|
88162
|
+
if (!state.delivered) {
|
|
88163
|
+
const text = state.pending;
|
|
88164
|
+
if (text !== void 0) {
|
|
88165
|
+
state.pending = void 0;
|
|
88166
|
+
state.delivered = true;
|
|
88167
|
+
state.revoked = false;
|
|
88168
|
+
return {
|
|
88169
|
+
...decision,
|
|
88170
|
+
messages: [...messages, createBoardNotice(text, "Team board guidance")]
|
|
88171
|
+
};
|
|
88172
|
+
}
|
|
88173
|
+
}
|
|
88174
|
+
if (state.revoked) {
|
|
88175
|
+
state.revoked = false;
|
|
88176
|
+
return {
|
|
88177
|
+
...decision,
|
|
88178
|
+
messages: [...messages, createBoardNotice(BOARD_OFF_NOTICE, "Team board off")]
|
|
88179
|
+
};
|
|
88180
|
+
}
|
|
88181
|
+
return decision;
|
|
88182
|
+
};
|
|
88183
|
+
const offAssemble = subscribe$1(ctx, "system-prompt/assemble", onAssemble);
|
|
88184
|
+
const offPreStep = subscribe$1(ctx, "agent/pre-step", onPreStep);
|
|
88185
|
+
if (offAssemble !== void 0) restores.push(() => {
|
|
88186
|
+
offAssemble();
|
|
88187
|
+
});
|
|
88188
|
+
if (offPreStep !== void 0) restores.push(() => {
|
|
88189
|
+
offPreStep();
|
|
88190
|
+
});
|
|
88191
|
+
return { dispose() {
|
|
88192
|
+
if (closed) return;
|
|
88193
|
+
closed = true;
|
|
88194
|
+
for (const restore of restores.splice(0)) try {
|
|
88195
|
+
restore();
|
|
88196
|
+
} catch {}
|
|
88197
|
+
} };
|
|
88198
|
+
}
|
|
88199
|
+
//#endregion
|
|
87790
88200
|
//#region src/host/compaction-policy-guard.ts
|
|
87791
88201
|
/**
|
|
87792
88202
|
* 「压缩策略守卫」——把 `compaction-basic` 的预算换成 Kimi Code 的口径,
|
|
@@ -92150,13 +92560,13 @@ const DISPATCH_PRESET = {
|
|
|
92150
92560
|
[Execution Pipeline] R0.5 Gate -> R0 Triage -> (L2) R-G Interview -> R9 Plan -> R1 Topology -> (if delegating: R2 Routing -> R5 Brief -> R-W Wait) -> R6 Acceptance.
|
|
92151
92561
|
|
|
92152
92562
|
## R0.5 · Compatibility Gate (Once per New Session, Before R0)
|
|
92153
|
-
|
|
92154
|
-
Criterion: whether spawn_teammate
|
|
92155
|
-
-
|
|
92156
|
-
-
|
|
92157
|
-
1. State in one sentence that
|
|
92158
|
-
2. Call ask_user_question once
|
|
92159
|
-
3. **Do nothing else** until the user replies:
|
|
92563
|
+
A legacy Agent Teams runtime (pre-#7519) registers spawn_teammate and replaces send_message / list_agents / interrupt_agent with team-scoped variants, leaving spawned subagents unreachable. The current runtime only adds a shared task board (team_task_create and its list/get/update siblings) and reuses this mode's tools.
|
|
92564
|
+
Criterion: whether spawn_teammate exists (PTC: tools.spawn_teammate). Never gate on wait_agent, send_message, list_agents, or interrupt_agent: this mode mounts those itself.
|
|
92565
|
+
- Absent -> Write "Orchestration ready: subagent" and proceed to R0. The board tools stay visible in the PTC SDK whether or not the board is on - frozen declaration, not availability - so confirm with team_task_list before relying on it. When the board is on it is bookkeeping, not a second dispatcher: the dispatch ledger stays the dispatch authority and R5 briefs stay the task contract; publish cross-agent dependencies (blocked_by) and write scopes on one team task per brief, claimed and completed by the child that owns it; never start work because a task is ready, and never reassign a task to skip R6.
|
|
92566
|
+
- Present -> This session runs the legacy runtime and is **not orchestratable**. In order, and nothing else:
|
|
92567
|
+
1. State in one sentence that the legacy runtime shadows the coordination tools and this mode has no degraded path.
|
|
92568
|
+
2. Call ask_user_question once (see R-W) offering: disable the legacy runtime, restart Host, **start a new session**; switch preset; or execute this task directly.
|
|
92569
|
+
3. **Do nothing else** until the user replies: no triage, plan, dispatch, file edits, or workarounds.
|
|
92160
92570
|
|
|
92161
92571
|
## R0 · Complexity Triage (Triage First, Then Choose the Workflow)
|
|
92162
92572
|
Upon receiving a task, determine its tier by semantic impact and uncertainty first, write one line stating "Tier + Rationale", and run the matching workflow:
|
|
@@ -92226,7 +92636,7 @@ Fallback is a task-scoped, non-session-wide exception for delegated briefs: it c
|
|
|
92226
92636
|
|
|
92227
92637
|
## Anti-Patterns (Any Occurrence Is a Violation)
|
|
92228
92638
|
1. Orchestrating or opening Plan Mode for an L0/L1 task, or before the R-G interview has converged (21. Entering Plan Mode for an L0/L1 task, or before the R-G interview has converged; 22. Using leave_plan_mode to bypass exit_plan_mode approval).
|
|
92229
|
-
2. Switching to teammate vocabulary to keep orchestrating
|
|
92639
|
+
2. Switching to teammate vocabulary to keep orchestrating under the legacy team runtime, or Treating the team task board as a substitute for R1 topology, R2 routing, R5 briefs, R6 acceptance, or R-W waiting (R0.5).
|
|
92230
92640
|
3. Omitting provider/model under [State: Listed], Second-guessing list_subagent_models output by hunting through local config or source files just to check which subagent models are allowed, or Reporting a route as "authorized", or claiming per-task routing is in force, when the session recorded no allowlist (R2).
|
|
92231
92641
|
4. Writing a task brief with a range where a cap belongs ("2–5 files", "a few attempts"), or Asking a subagent to restate its rules as a correctness check (R0, R5).
|
|
92232
92642
|
5. Running sleep, polling loops, or placeholder long commands to wait, Proactively creating a goal at the start of a task, or Ending with a paragraph of prose to wait for user sign-off instead of calling ask_user_question (R-W).
|
|
@@ -95118,14 +95528,14 @@ const WORKBUDDY_STANDARD_EFFORTS = [
|
|
|
95118
95528
|
* Snap a level onto the nearest rung a model's ladder actually exposes.
|
|
95119
95529
|
*
|
|
95120
95530
|
* The gateway names a default from a wider vocabulary than the ladder it
|
|
95121
|
-
* publishes for the same model: an effort-only entry
|
|
95122
|
-
*
|
|
95123
|
-
*
|
|
95124
|
-
*
|
|
95125
|
-
*
|
|
95126
|
-
*
|
|
95127
|
-
* samples, versus 282-659 with the field). Ties resolve upward, which is
|
|
95128
|
-
* 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
|
|
95129
95539
|
* no level (a text-only model) yields nothing to converge to.
|
|
95130
95540
|
*/
|
|
95131
95541
|
function convergeWorkBuddyEffort(effort, ladder) {
|
|
@@ -95408,96 +95818,27 @@ function refreshSourceForDomain(domain) {
|
|
|
95408
95818
|
/**
|
|
95409
95819
|
* Models the gateway serves but does not publish in `/v3/config`.
|
|
95410
95820
|
*
|
|
95411
|
-
* The catalog is a published list, not the served one: measured on
|
|
95412
|
-
* international backend, `gpt-6-sol`, `gpt-6-luna` and `gemini-3.8-flash`
|
|
95413
|
-
*
|
|
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
|
|
95414
95824
|
* `/v3/config` entirely, and a reachable gateway *replaces* the shipped table
|
|
95415
|
-
* with that list
|
|
95416
|
-
*
|
|
95417
|
-
*
|
|
95418
|
-
*
|
|
95419
|
-
*
|
|
95420
|
-
*
|
|
95421
|
-
*
|
|
95422
|
-
*
|
|
95423
|
-
*
|
|
95424
|
-
|
|
95425
|
-
|
|
95426
|
-
* - **Context window, output cap and `canDisableThinking` are inherited from the
|
|
95427
|
-
* published sibling in the same family** — `gpt-6-astra` for `gpt-6-sol` and
|
|
95428
|
-
* `gpt-6-luna`, `gemini-3.5-flash` for `gemini-3.8-flash`. They are marked
|
|
95429
|
-
* here rather than measured because the gateway publishes nothing for these
|
|
95430
|
-
* ids and offers no cheap way to read the real figure: it accepts a
|
|
95431
|
-
* `max_tokens` larger than any published window (even for `gpt-6-astra`, whose
|
|
95432
|
-
* own catalog caps at 128000), so the number is neither enforced nor
|
|
95433
|
-
* discoverable from the request side.
|
|
95434
|
-
*
|
|
95435
|
-
* Every field stays overridable per model from the settings card, and an
|
|
95436
|
-
* inherited window errs low rather than high: over-declaring overflows the
|
|
95437
|
-
* gateway mid-session, while under-declaring only compresses earlier.
|
|
95438
|
-
*/
|
|
95439
|
-
const UNPUBLISHED_MODELS = [
|
|
95440
|
-
{
|
|
95441
|
-
id: "gpt-6-sol",
|
|
95442
|
-
name: "GPT-6-Sol",
|
|
95443
|
-
contextWindow: 4e5,
|
|
95444
|
-
maxContextWindow: 1e6,
|
|
95445
|
-
maxTokens: 128e3,
|
|
95446
|
-
regions: ["intl"],
|
|
95447
|
-
supportsImage: true,
|
|
95448
|
-
reasoningEfforts: [
|
|
95449
|
-
"low",
|
|
95450
|
-
"medium",
|
|
95451
|
-
"high",
|
|
95452
|
-
"xhigh",
|
|
95453
|
-
"max"
|
|
95454
|
-
],
|
|
95455
|
-
defaultReasoningEffort: "high",
|
|
95456
|
-
canDisableThinking: true,
|
|
95457
|
-
description: "OpenAI 旗舰模型,擅长复杂推理与长程任务"
|
|
95458
|
-
},
|
|
95459
|
-
{
|
|
95460
|
-
id: "gpt-6-luna",
|
|
95461
|
-
name: "GPT-6-Luna",
|
|
95462
|
-
contextWindow: 4e5,
|
|
95463
|
-
maxContextWindow: 1e6,
|
|
95464
|
-
maxTokens: 128e3,
|
|
95465
|
-
regions: ["intl"],
|
|
95466
|
-
supportsImage: true,
|
|
95467
|
-
reasoningEfforts: [
|
|
95468
|
-
"low",
|
|
95469
|
-
"medium",
|
|
95470
|
-
"high",
|
|
95471
|
-
"xhigh",
|
|
95472
|
-
"max"
|
|
95473
|
-
],
|
|
95474
|
-
defaultReasoningEffort: "high",
|
|
95475
|
-
canDisableThinking: true,
|
|
95476
|
-
description: "OpenAI 轻量模型,响应快速,适合日常任务"
|
|
95477
|
-
},
|
|
95478
|
-
{
|
|
95479
|
-
id: "gemini-3.8-flash",
|
|
95480
|
-
name: "Gemini-3.8-Flash",
|
|
95481
|
-
contextWindow: 1e6,
|
|
95482
|
-
maxContextWindow: 1e6,
|
|
95483
|
-
maxTokens: 65536,
|
|
95484
|
-
regions: ["intl"],
|
|
95485
|
-
supportsImage: true,
|
|
95486
|
-
reasoningEfforts: [
|
|
95487
|
-
"low",
|
|
95488
|
-
"high",
|
|
95489
|
-
"max"
|
|
95490
|
-
],
|
|
95491
|
-
defaultReasoningEffort: "medium",
|
|
95492
|
-
canDisableThinking: false,
|
|
95493
|
-
description: "能力均衡,适合日常使用"
|
|
95494
|
-
}
|
|
95495
|
-
];
|
|
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 = [];
|
|
95496
95836
|
/**
|
|
95497
95837
|
* Offline fallback catalog, transcribed from a live `/v3/config` read.
|
|
95498
95838
|
*
|
|
95499
|
-
*
|
|
95500
|
-
* 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.
|
|
95501
95842
|
*/
|
|
95502
95843
|
const FALLBACK_MODELS$1 = [
|
|
95503
95844
|
{
|
|
@@ -95513,20 +95854,6 @@ const FALLBACK_MODELS$1 = [
|
|
|
95513
95854
|
canDisableThinking: false,
|
|
95514
95855
|
description: "优秀的编码模型,适合日常使用"
|
|
95515
95856
|
},
|
|
95516
|
-
{
|
|
95517
|
-
id: "default",
|
|
95518
|
-
name: "Default",
|
|
95519
|
-
contextWindow: 56e3,
|
|
95520
|
-
maxContextWindow: 56e3,
|
|
95521
|
-
maxTokens: 24e3,
|
|
95522
|
-
regions: ["cn"],
|
|
95523
|
-
credits: { cn: "2.00" },
|
|
95524
|
-
supportsImage: false,
|
|
95525
|
-
reasoningEfforts: [],
|
|
95526
|
-
defaultReasoningEffort: null,
|
|
95527
|
-
canDisableThinking: false,
|
|
95528
|
-
description: ""
|
|
95529
|
-
},
|
|
95530
95857
|
{
|
|
95531
95858
|
id: "fast-model",
|
|
95532
95859
|
name: "Fast",
|
|
@@ -95541,7 +95868,7 @@ const FALLBACK_MODELS$1 = [
|
|
|
95541
95868
|
"high",
|
|
95542
95869
|
"max"
|
|
95543
95870
|
],
|
|
95544
|
-
defaultReasoningEffort: "
|
|
95871
|
+
defaultReasoningEffort: "high",
|
|
95545
95872
|
canDisableThinking: false,
|
|
95546
95873
|
description: "响应快,适合简单任务"
|
|
95547
95874
|
},
|
|
@@ -95559,7 +95886,7 @@ const FALLBACK_MODELS$1 = [
|
|
|
95559
95886
|
"high",
|
|
95560
95887
|
"max"
|
|
95561
95888
|
],
|
|
95562
|
-
defaultReasoningEffort: "
|
|
95889
|
+
defaultReasoningEffort: "high",
|
|
95563
95890
|
canDisableThinking: false,
|
|
95564
95891
|
description: "速度与质量兼顾,日常工作首选"
|
|
95565
95892
|
},
|
|
@@ -95582,20 +95909,65 @@ const FALLBACK_MODELS$1 = [
|
|
|
95582
95909
|
description: "高质量输出,胜任复杂任务"
|
|
95583
95910
|
},
|
|
95584
95911
|
{
|
|
95585
|
-
id: "
|
|
95586
|
-
name: "
|
|
95587
|
-
contextWindow:
|
|
95588
|
-
maxContextWindow:
|
|
95589
|
-
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,
|
|
95590
95938
|
regions: ["intl"],
|
|
95591
|
-
credits: { intl: "
|
|
95939
|
+
credits: { intl: "0.03" },
|
|
95592
95940
|
supportsImage: true,
|
|
95593
|
-
reasoningEfforts: [
|
|
95594
|
-
|
|
95941
|
+
reasoningEfforts: [
|
|
95942
|
+
"low",
|
|
95943
|
+
"high",
|
|
95944
|
+
"max"
|
|
95945
|
+
],
|
|
95946
|
+
defaultReasoningEffort: "high",
|
|
95595
95947
|
canDisableThinking: false,
|
|
95596
|
-
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: "原生多模态模型,擅长视觉理解与专业任务"
|
|
95597
95970
|
},
|
|
95598
|
-
...UNPUBLISHED_MODELS.filter((model) => model.id === "gpt-6-sol" || model.id === "gpt-6-luna"),
|
|
95599
95971
|
{
|
|
95600
95972
|
id: "gpt-6-astra",
|
|
95601
95973
|
name: "GPT-6-Astra",
|
|
@@ -95616,6 +95988,37 @@ const FALLBACK_MODELS$1 = [
|
|
|
95616
95988
|
canDisableThinking: true,
|
|
95617
95989
|
description: "OpenAI 旗舰模型,擅长复杂推理与长程任务"
|
|
95618
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
|
+
},
|
|
95619
96022
|
{
|
|
95620
96023
|
id: "gpt-5.6-sol",
|
|
95621
96024
|
name: "GPT-5.6-Sol",
|
|
@@ -95722,8 +96125,8 @@ const FALLBACK_MODELS$1 = [
|
|
|
95722
96125
|
maxTokens: 48e3,
|
|
95723
96126
|
regions: ["intl", "cn"],
|
|
95724
96127
|
credits: {
|
|
95725
|
-
cn: "0.
|
|
95726
|
-
intl: "0.
|
|
96128
|
+
cn: "0.69",
|
|
96129
|
+
intl: "0.69"
|
|
95727
96130
|
},
|
|
95728
96131
|
supportsImage: true,
|
|
95729
96132
|
reasoningEfforts: [
|
|
@@ -95732,30 +96135,9 @@ const FALLBACK_MODELS$1 = [
|
|
|
95732
96135
|
"max"
|
|
95733
96136
|
],
|
|
95734
96137
|
defaultReasoningEffort: "high",
|
|
95735
|
-
canDisableThinking:
|
|
96138
|
+
canDisableThinking: false,
|
|
95736
96139
|
description: "能力均衡,适合日常使用"
|
|
95737
96140
|
},
|
|
95738
|
-
{
|
|
95739
|
-
id: "glm-5.3-flash",
|
|
95740
|
-
name: "GLM-5.3-Flash",
|
|
95741
|
-
contextWindow: 3e5,
|
|
95742
|
-
maxContextWindow: 1e6,
|
|
95743
|
-
maxTokens: 32e3,
|
|
95744
|
-
regions: ["intl", "cn"],
|
|
95745
|
-
credits: {
|
|
95746
|
-
cn: "0.06",
|
|
95747
|
-
intl: "0.06"
|
|
95748
|
-
},
|
|
95749
|
-
supportsImage: true,
|
|
95750
|
-
reasoningEfforts: [
|
|
95751
|
-
"low",
|
|
95752
|
-
"high",
|
|
95753
|
-
"max"
|
|
95754
|
-
],
|
|
95755
|
-
defaultReasoningEffort: "high",
|
|
95756
|
-
canDisableThinking: true,
|
|
95757
|
-
description: "原生多模态模型,擅长视觉理解与专业任务"
|
|
95758
|
-
},
|
|
95759
96141
|
{
|
|
95760
96142
|
id: "glm-5.2",
|
|
95761
96143
|
name: "GLM-5.2",
|
|
@@ -95768,101 +96150,63 @@ const FALLBACK_MODELS$1 = [
|
|
|
95768
96150
|
intl: "0.79"
|
|
95769
96151
|
},
|
|
95770
96152
|
supportsImage: true,
|
|
95771
|
-
reasoningEfforts: ["high"
|
|
96153
|
+
reasoningEfforts: ["high"],
|
|
95772
96154
|
defaultReasoningEffort: "high",
|
|
95773
|
-
canDisableThinking:
|
|
96155
|
+
canDisableThinking: false,
|
|
95774
96156
|
description: "1M 上下文,擅长长程任务"
|
|
95775
96157
|
},
|
|
95776
96158
|
{
|
|
95777
|
-
id: "
|
|
95778
|
-
name: "
|
|
95779
|
-
contextWindow:
|
|
95780
|
-
maxContextWindow:
|
|
95781
|
-
maxTokens:
|
|
95782
|
-
regions: ["cn"],
|
|
95783
|
-
credits: {
|
|
96159
|
+
id: "minimax-m3.1-flash",
|
|
96160
|
+
name: "MiniMax-M3.1-Flash",
|
|
96161
|
+
contextWindow: 3e5,
|
|
96162
|
+
maxContextWindow: 1e6,
|
|
96163
|
+
maxTokens: 128e3,
|
|
96164
|
+
regions: ["intl", "cn"],
|
|
96165
|
+
credits: {
|
|
96166
|
+
cn: "0.08",
|
|
96167
|
+
intl: "0.08"
|
|
96168
|
+
},
|
|
95784
96169
|
supportsImage: true,
|
|
95785
96170
|
reasoningEfforts: [
|
|
95786
96171
|
"low",
|
|
96172
|
+
"medium",
|
|
95787
96173
|
"high",
|
|
96174
|
+
"xhigh",
|
|
95788
96175
|
"max"
|
|
95789
96176
|
],
|
|
95790
|
-
defaultReasoningEffort: "
|
|
96177
|
+
defaultReasoningEffort: "max",
|
|
95791
96178
|
canDisableThinking: false,
|
|
95792
|
-
description: ""
|
|
96179
|
+
description: "原生多模态,擅长office、agentic、编程任务,推理速度优异"
|
|
95793
96180
|
},
|
|
95794
96181
|
{
|
|
95795
|
-
id: "
|
|
95796
|
-
name: "
|
|
95797
|
-
contextWindow:
|
|
95798
|
-
maxContextWindow:
|
|
95799
|
-
maxTokens:
|
|
95800
|
-
regions: ["cn"],
|
|
95801
|
-
credits: {
|
|
96182
|
+
id: "kimi-k3.1-pro",
|
|
96183
|
+
name: "Kimi-K3.1-Pro",
|
|
96184
|
+
contextWindow: 3e5,
|
|
96185
|
+
maxContextWindow: 1e6,
|
|
96186
|
+
maxTokens: 32e3,
|
|
96187
|
+
regions: ["intl", "cn"],
|
|
96188
|
+
credits: {
|
|
96189
|
+
cn: "0.97",
|
|
96190
|
+
intl: "0.97"
|
|
96191
|
+
},
|
|
95802
96192
|
supportsImage: true,
|
|
95803
96193
|
reasoningEfforts: [
|
|
95804
96194
|
"low",
|
|
95805
96195
|
"high",
|
|
95806
96196
|
"max"
|
|
95807
96197
|
],
|
|
95808
|
-
defaultReasoningEffort: "
|
|
95809
|
-
canDisableThinking: false,
|
|
95810
|
-
description: ""
|
|
95811
|
-
},
|
|
95812
|
-
{
|
|
95813
|
-
id: "glm-5.0",
|
|
95814
|
-
name: "GLM-5.0",
|
|
95815
|
-
contextWindow: 2e5,
|
|
95816
|
-
maxContextWindow: 2e5,
|
|
95817
|
-
maxTokens: 48e3,
|
|
95818
|
-
regions: ["cn"],
|
|
95819
|
-
credits: { cn: "0.80" },
|
|
95820
|
-
supportsImage: false,
|
|
95821
|
-
reasoningEfforts: [],
|
|
95822
|
-
defaultReasoningEffort: null,
|
|
95823
|
-
canDisableThinking: false,
|
|
95824
|
-
description: ""
|
|
95825
|
-
},
|
|
95826
|
-
{
|
|
95827
|
-
id: "glm-5.0-turbo",
|
|
95828
|
-
name: "GLM-5.0-Turbo",
|
|
95829
|
-
contextWindow: 2e5,
|
|
95830
|
-
maxContextWindow: 2e5,
|
|
95831
|
-
maxTokens: 48e3,
|
|
95832
|
-
regions: ["cn"],
|
|
95833
|
-
credits: { cn: "0.95" },
|
|
95834
|
-
supportsImage: false,
|
|
95835
|
-
reasoningEfforts: [
|
|
95836
|
-
"low",
|
|
95837
|
-
"high",
|
|
95838
|
-
"max"
|
|
95839
|
-
],
|
|
95840
|
-
defaultReasoningEffort: "medium",
|
|
95841
|
-
canDisableThinking: false,
|
|
95842
|
-
description: ""
|
|
95843
|
-
},
|
|
95844
|
-
{
|
|
95845
|
-
id: "glm-4.7",
|
|
95846
|
-
name: "GLM-4.7",
|
|
95847
|
-
contextWindow: 2e5,
|
|
95848
|
-
maxContextWindow: 2e5,
|
|
95849
|
-
maxTokens: 48e3,
|
|
95850
|
-
regions: ["cn"],
|
|
95851
|
-
credits: { cn: "0.23" },
|
|
95852
|
-
supportsImage: false,
|
|
95853
|
-
reasoningEfforts: [],
|
|
95854
|
-
defaultReasoningEffort: null,
|
|
96198
|
+
defaultReasoningEffort: "high",
|
|
95855
96199
|
canDisableThinking: false,
|
|
95856
|
-
description: ""
|
|
96200
|
+
description: "Kimi 全新旗舰模型,3万亿级参数。办公、代码、3D 创作与长程 Agent 能力全面升级。"
|
|
95857
96201
|
},
|
|
95858
96202
|
{
|
|
95859
|
-
id: "
|
|
95860
|
-
name: "
|
|
95861
|
-
contextWindow:
|
|
95862
|
-
maxContextWindow:
|
|
96203
|
+
id: "kimi-k3.1-pro-highspeed",
|
|
96204
|
+
name: "Kimi-K3.1-Pro-Highspeed",
|
|
96205
|
+
contextWindow: 3e5,
|
|
96206
|
+
maxContextWindow: 1e6,
|
|
95863
96207
|
maxTokens: 32e3,
|
|
95864
|
-
regions: ["
|
|
95865
|
-
credits: {
|
|
96208
|
+
regions: ["intl"],
|
|
96209
|
+
credits: { intl: "1.56" },
|
|
95866
96210
|
supportsImage: true,
|
|
95867
96211
|
reasoningEfforts: [
|
|
95868
96212
|
"low",
|
|
@@ -95871,21 +96215,7 @@ const FALLBACK_MODELS$1 = [
|
|
|
95871
96215
|
],
|
|
95872
96216
|
defaultReasoningEffort: "high",
|
|
95873
96217
|
canDisableThinking: false,
|
|
95874
|
-
description: ""
|
|
95875
|
-
},
|
|
95876
|
-
{
|
|
95877
|
-
id: "glm-4.6",
|
|
95878
|
-
name: "GLM-4.6",
|
|
95879
|
-
contextWindow: 168e3,
|
|
95880
|
-
maxContextWindow: 168e3,
|
|
95881
|
-
maxTokens: 32e3,
|
|
95882
|
-
regions: ["cn"],
|
|
95883
|
-
credits: { cn: "0.23" },
|
|
95884
|
-
supportsImage: false,
|
|
95885
|
-
reasoningEfforts: [],
|
|
95886
|
-
defaultReasoningEffort: null,
|
|
95887
|
-
canDisableThinking: false,
|
|
95888
|
-
description: ""
|
|
96218
|
+
description: "K3.1 Pro 高速版本,响应速度提升至 K3.1 Pro 的 2–3 倍,交互更流畅。"
|
|
95889
96219
|
},
|
|
95890
96220
|
{
|
|
95891
96221
|
id: "kimi-k3",
|
|
@@ -95901,166 +96231,121 @@ const FALLBACK_MODELS$1 = [
|
|
|
95901
96231
|
"high",
|
|
95902
96232
|
"max"
|
|
95903
96233
|
],
|
|
95904
|
-
defaultReasoningEffort: "
|
|
96234
|
+
defaultReasoningEffort: "high",
|
|
95905
96235
|
canDisableThinking: false,
|
|
95906
96236
|
description: "擅长处理复杂的长程自主任务,前端开发能力突出,同时在知识工作与科研推理上表现出色。"
|
|
95907
96237
|
},
|
|
95908
96238
|
{
|
|
95909
|
-
id: "
|
|
95910
|
-
name: "
|
|
95911
|
-
contextWindow:
|
|
95912
|
-
maxContextWindow:
|
|
95913
|
-
maxTokens:
|
|
95914
|
-
regions: ["
|
|
95915
|
-
credits: {
|
|
96239
|
+
id: "grok-4.7",
|
|
96240
|
+
name: "Grok-4.7",
|
|
96241
|
+
contextWindow: 2e5,
|
|
96242
|
+
maxContextWindow: 5e5,
|
|
96243
|
+
maxTokens: 128e3,
|
|
96244
|
+
regions: ["intl"],
|
|
96245
|
+
credits: { intl: "1.90" },
|
|
95916
96246
|
supportsImage: true,
|
|
95917
96247
|
reasoningEfforts: [
|
|
95918
96248
|
"low",
|
|
96249
|
+
"medium",
|
|
95919
96250
|
"high",
|
|
95920
|
-
"
|
|
96251
|
+
"xhigh"
|
|
95921
96252
|
],
|
|
95922
|
-
defaultReasoningEffort: "
|
|
96253
|
+
defaultReasoningEffort: "high",
|
|
95923
96254
|
canDisableThinking: false,
|
|
95924
|
-
description: "
|
|
96255
|
+
description: "SpaceXAI 打造的前沿模型,专为编程、智能体任务及知识型工作而设计。"
|
|
95925
96256
|
},
|
|
95926
96257
|
{
|
|
95927
|
-
id: "
|
|
95928
|
-
name: "
|
|
96258
|
+
id: "gemini-3.8-flash",
|
|
96259
|
+
name: "Gemini-3.8-Flash",
|
|
95929
96260
|
contextWindow: 3e5,
|
|
95930
96261
|
maxContextWindow: 1e6,
|
|
95931
|
-
maxTokens:
|
|
95932
|
-
regions: ["intl"
|
|
95933
|
-
credits: {
|
|
95934
|
-
cn: "0.77",
|
|
95935
|
-
intl: "0.77"
|
|
95936
|
-
},
|
|
95937
|
-
supportsImage: true,
|
|
95938
|
-
reasoningEfforts: [
|
|
95939
|
-
"low",
|
|
95940
|
-
"high",
|
|
95941
|
-
"max"
|
|
95942
|
-
],
|
|
95943
|
-
defaultReasoningEffort: "high",
|
|
95944
|
-
canDisableThinking: true,
|
|
95945
|
-
description: "擅长处理复杂的长程自主任务,前端开发能力突出,同时在知识工作与科研推理上表现出色。"
|
|
95946
|
-
},
|
|
95947
|
-
{
|
|
95948
|
-
id: "kimi-k2.7",
|
|
95949
|
-
name: "Kimi-K2.7-Code",
|
|
95950
|
-
contextWindow: 256e3,
|
|
95951
|
-
maxContextWindow: 256e3,
|
|
95952
|
-
maxTokens: 32e3,
|
|
95953
|
-
regions: ["cn"],
|
|
95954
|
-
credits: { cn: "0.57" },
|
|
95955
|
-
supportsImage: true,
|
|
95956
|
-
reasoningEfforts: [
|
|
95957
|
-
"low",
|
|
95958
|
-
"high",
|
|
95959
|
-
"max"
|
|
95960
|
-
],
|
|
95961
|
-
defaultReasoningEffort: "medium",
|
|
95962
|
-
canDisableThinking: false,
|
|
95963
|
-
description: ""
|
|
95964
|
-
},
|
|
95965
|
-
{
|
|
95966
|
-
id: "kimi-k2.6",
|
|
95967
|
-
name: "Kimi-K2.6",
|
|
95968
|
-
contextWindow: 256e3,
|
|
95969
|
-
maxContextWindow: 256e3,
|
|
95970
|
-
maxTokens: 32e3,
|
|
95971
|
-
regions: ["intl", "cn"],
|
|
95972
|
-
credits: {
|
|
95973
|
-
cn: "0.52",
|
|
95974
|
-
intl: "0.52"
|
|
95975
|
-
},
|
|
96262
|
+
maxTokens: 65536,
|
|
96263
|
+
regions: ["intl"],
|
|
96264
|
+
credits: { intl: "0.95" },
|
|
95976
96265
|
supportsImage: true,
|
|
95977
96266
|
reasoningEfforts: [
|
|
95978
96267
|
"low",
|
|
95979
|
-
"
|
|
95980
|
-
"
|
|
96268
|
+
"medium",
|
|
96269
|
+
"high"
|
|
95981
96270
|
],
|
|
95982
96271
|
defaultReasoningEffort: "medium",
|
|
95983
96272
|
canDisableThinking: false,
|
|
95984
|
-
description: "
|
|
96273
|
+
description: "能力均衡,适合日常使用"
|
|
95985
96274
|
},
|
|
95986
96275
|
{
|
|
95987
|
-
id: "
|
|
95988
|
-
name: "
|
|
95989
|
-
contextWindow:
|
|
95990
|
-
maxContextWindow:
|
|
95991
|
-
maxTokens:
|
|
95992
|
-
regions: ["
|
|
95993
|
-
credits: {
|
|
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" },
|
|
95994
96283
|
supportsImage: true,
|
|
95995
96284
|
reasoningEfforts: [
|
|
95996
96285
|
"low",
|
|
96286
|
+
"medium",
|
|
95997
96287
|
"high",
|
|
95998
|
-
"
|
|
95999
|
-
],
|
|
96000
|
-
defaultReasoningEffort: "high",
|
|
96001
|
-
canDisableThinking: false,
|
|
96002
|
-
description: ""
|
|
96003
|
-
},
|
|
96004
|
-
{
|
|
96005
|
-
id: "kimi-k2-thinking",
|
|
96006
|
-
name: "Kimi-K2-Thinking",
|
|
96007
|
-
contextWindow: 164e3,
|
|
96008
|
-
maxContextWindow: 164e3,
|
|
96009
|
-
maxTokens: 32e3,
|
|
96010
|
-
regions: ["cn"],
|
|
96011
|
-
credits: { cn: "0.54" },
|
|
96012
|
-
supportsImage: false,
|
|
96013
|
-
reasoningEfforts: [
|
|
96014
|
-
"low",
|
|
96015
|
-
"high",
|
|
96016
|
-
"max"
|
|
96288
|
+
"xhigh"
|
|
96017
96289
|
],
|
|
96018
96290
|
defaultReasoningEffort: "high",
|
|
96019
96291
|
canDisableThinking: false,
|
|
96020
|
-
description: ""
|
|
96292
|
+
description: "专为复杂编码和智能体工作流构建的模型"
|
|
96021
96293
|
},
|
|
96022
96294
|
{
|
|
96023
|
-
id: "
|
|
96024
|
-
name: "
|
|
96025
|
-
contextWindow:
|
|
96295
|
+
id: "gpt-6-luna",
|
|
96296
|
+
name: "GPT-6-Luna",
|
|
96297
|
+
contextWindow: 1e6,
|
|
96026
96298
|
maxContextWindow: 1e6,
|
|
96027
96299
|
maxTokens: 128e3,
|
|
96028
|
-
regions: ["intl"
|
|
96029
|
-
credits: {
|
|
96030
|
-
cn: "0.11",
|
|
96031
|
-
intl: "0.00"
|
|
96032
|
-
},
|
|
96300
|
+
regions: ["intl"],
|
|
96301
|
+
credits: { intl: "0.07" },
|
|
96033
96302
|
supportsImage: true,
|
|
96034
96303
|
reasoningEfforts: [
|
|
96035
96304
|
"low",
|
|
96305
|
+
"medium",
|
|
96036
96306
|
"high",
|
|
96037
|
-
"
|
|
96307
|
+
"xhigh"
|
|
96038
96308
|
],
|
|
96039
96309
|
defaultReasoningEffort: "high",
|
|
96040
96310
|
canDisableThinking: false,
|
|
96041
|
-
description: "
|
|
96311
|
+
description: "专为单一聚焦、高吞吐量任务打造的高效模型"
|
|
96042
96312
|
},
|
|
96043
96313
|
{
|
|
96044
|
-
id: "
|
|
96045
|
-
name: "
|
|
96046
|
-
contextWindow:
|
|
96314
|
+
id: "gpt-6.1-sol",
|
|
96315
|
+
name: "GPT-6.1-Sol",
|
|
96316
|
+
contextWindow: 272e3,
|
|
96047
96317
|
maxContextWindow: 1e6,
|
|
96048
96318
|
maxTokens: 128e3,
|
|
96049
96319
|
regions: ["intl"],
|
|
96050
|
-
credits: { intl: "
|
|
96320
|
+
credits: { intl: "1.33" },
|
|
96051
96321
|
supportsImage: true,
|
|
96052
96322
|
reasoningEfforts: [
|
|
96053
96323
|
"low",
|
|
96324
|
+
"medium",
|
|
96054
96325
|
"high",
|
|
96055
|
-
"
|
|
96326
|
+
"xhigh"
|
|
96056
96327
|
],
|
|
96057
96328
|
defaultReasoningEffort: "high",
|
|
96058
96329
|
canDisableThinking: false,
|
|
96059
|
-
description: "
|
|
96330
|
+
description: "专为复杂编码和智能体工作流构建的模型"
|
|
96331
|
+
},
|
|
96332
|
+
{
|
|
96333
|
+
id: "default",
|
|
96334
|
+
name: "Default",
|
|
96335
|
+
contextWindow: 56e3,
|
|
96336
|
+
maxContextWindow: 56e3,
|
|
96337
|
+
maxTokens: 24e3,
|
|
96338
|
+
regions: ["cn"],
|
|
96339
|
+
credits: { cn: "2.00" },
|
|
96340
|
+
supportsImage: false,
|
|
96341
|
+
reasoningEfforts: [],
|
|
96342
|
+
defaultReasoningEffort: null,
|
|
96343
|
+
canDisableThinking: false,
|
|
96344
|
+
description: ""
|
|
96060
96345
|
},
|
|
96061
96346
|
{
|
|
96062
96347
|
id: "deepseek-v4-pro",
|
|
96063
|
-
name: "
|
|
96348
|
+
name: "DeepSeek-V4-Pro",
|
|
96064
96349
|
contextWindow: 1e6,
|
|
96065
96350
|
maxContextWindow: 1e6,
|
|
96066
96351
|
maxTokens: 128e3,
|
|
@@ -96113,52 +96398,190 @@ const FALLBACK_MODELS$1 = [
|
|
|
96113
96398
|
description: ""
|
|
96114
96399
|
},
|
|
96115
96400
|
{
|
|
96116
|
-
id: "
|
|
96117
|
-
name: "
|
|
96401
|
+
id: "minimax-m2.5",
|
|
96402
|
+
name: "MiniMax-M2.5",
|
|
96118
96403
|
contextWindow: 2e5,
|
|
96119
|
-
maxContextWindow:
|
|
96120
|
-
maxTokens:
|
|
96121
|
-
regions: ["
|
|
96122
|
-
credits: {
|
|
96123
|
-
|
|
96124
|
-
|
|
96125
|
-
|
|
96404
|
+
maxContextWindow: 2e5,
|
|
96405
|
+
maxTokens: 48e3,
|
|
96406
|
+
regions: ["cn"],
|
|
96407
|
+
credits: { cn: "0.18" },
|
|
96408
|
+
supportsImage: false,
|
|
96409
|
+
reasoningEfforts: [
|
|
96410
|
+
"low",
|
|
96411
|
+
"high",
|
|
96412
|
+
"max"
|
|
96413
|
+
],
|
|
96414
|
+
defaultReasoningEffort: "high",
|
|
96415
|
+
canDisableThinking: false,
|
|
96416
|
+
description: ""
|
|
96417
|
+
},
|
|
96418
|
+
{
|
|
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" },
|
|
96126
96426
|
supportsImage: true,
|
|
96127
|
-
reasoningEfforts: [
|
|
96427
|
+
reasoningEfforts: [
|
|
96428
|
+
"low",
|
|
96429
|
+
"high",
|
|
96430
|
+
"max"
|
|
96431
|
+
],
|
|
96128
96432
|
defaultReasoningEffort: "high",
|
|
96129
96433
|
canDisableThinking: false,
|
|
96130
|
-
description: "
|
|
96434
|
+
description: ""
|
|
96131
96435
|
},
|
|
96132
96436
|
{
|
|
96133
|
-
id: "
|
|
96134
|
-
name: "
|
|
96437
|
+
id: "glm-5.0",
|
|
96438
|
+
name: "GLM-5.0",
|
|
96439
|
+
contextWindow: 2e5,
|
|
96440
|
+
maxContextWindow: 2e5,
|
|
96441
|
+
maxTokens: 48e3,
|
|
96442
|
+
regions: ["cn"],
|
|
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,
|
|
96459
|
+
reasoningEfforts: [
|
|
96460
|
+
"low",
|
|
96461
|
+
"high",
|
|
96462
|
+
"max"
|
|
96463
|
+
],
|
|
96464
|
+
defaultReasoningEffort: "high",
|
|
96465
|
+
canDisableThinking: false,
|
|
96466
|
+
description: ""
|
|
96467
|
+
},
|
|
96468
|
+
{
|
|
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,
|
|
96487
|
+
maxTokens: 32e3,
|
|
96488
|
+
regions: ["cn"],
|
|
96489
|
+
credits: { cn: "0.23" },
|
|
96490
|
+
supportsImage: false,
|
|
96491
|
+
reasoningEfforts: [],
|
|
96492
|
+
defaultReasoningEffort: null,
|
|
96493
|
+
canDisableThinking: false,
|
|
96494
|
+
description: ""
|
|
96495
|
+
},
|
|
96496
|
+
{
|
|
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" },
|
|
96504
|
+
supportsImage: true,
|
|
96505
|
+
reasoningEfforts: [
|
|
96506
|
+
"low",
|
|
96507
|
+
"high",
|
|
96508
|
+
"max"
|
|
96509
|
+
],
|
|
96510
|
+
defaultReasoningEffort: "high",
|
|
96511
|
+
canDisableThinking: false,
|
|
96512
|
+
description: ""
|
|
96513
|
+
},
|
|
96514
|
+
{
|
|
96515
|
+
id: "kimi-k3-1",
|
|
96516
|
+
name: "Kimi-K3",
|
|
96135
96517
|
contextWindow: 1e6,
|
|
96136
96518
|
maxContextWindow: 1e6,
|
|
96137
|
-
maxTokens:
|
|
96519
|
+
maxTokens: 32e3,
|
|
96138
96520
|
regions: ["cn"],
|
|
96139
|
-
credits: { cn: "
|
|
96521
|
+
credits: { cn: "1.62" },
|
|
96140
96522
|
supportsImage: true,
|
|
96141
|
-
reasoningEfforts: [
|
|
96523
|
+
reasoningEfforts: [
|
|
96524
|
+
"low",
|
|
96525
|
+
"high",
|
|
96526
|
+
"max"
|
|
96527
|
+
],
|
|
96142
96528
|
defaultReasoningEffort: "high",
|
|
96143
96529
|
canDisableThinking: false,
|
|
96144
|
-
description: "
|
|
96530
|
+
description: "擅长处理复杂的长程自主任务,前端开发能力突出,同时在知识工作与科研推理上表现出色。"
|
|
96145
96531
|
},
|
|
96146
96532
|
{
|
|
96147
|
-
id: "
|
|
96148
|
-
name: "
|
|
96149
|
-
contextWindow:
|
|
96150
|
-
maxContextWindow:
|
|
96533
|
+
id: "kimi-k2.8-preview",
|
|
96534
|
+
name: "Kimi-K2.8-Preview",
|
|
96535
|
+
contextWindow: 1e6,
|
|
96536
|
+
maxContextWindow: 1e6,
|
|
96151
96537
|
maxTokens: 64e3,
|
|
96152
|
-
regions: ["
|
|
96153
|
-
credits: {
|
|
96154
|
-
cn: "0.00",
|
|
96155
|
-
intl: "0.00"
|
|
96156
|
-
},
|
|
96538
|
+
regions: ["cn"],
|
|
96539
|
+
credits: { cn: "0.77" },
|
|
96157
96540
|
supportsImage: true,
|
|
96158
|
-
reasoningEfforts: [
|
|
96541
|
+
reasoningEfforts: [
|
|
96542
|
+
"low",
|
|
96543
|
+
"high",
|
|
96544
|
+
"max"
|
|
96545
|
+
],
|
|
96546
|
+
defaultReasoningEffort: "high",
|
|
96547
|
+
canDisableThinking: true,
|
|
96548
|
+
description: "Moonshot AI · 擅长复杂长程自主任务、知识工作与科研推理,前端开发突出"
|
|
96549
|
+
},
|
|
96550
|
+
{
|
|
96551
|
+
id: "kimi-k2.5",
|
|
96552
|
+
name: "Kimi-K2.5",
|
|
96553
|
+
contextWindow: 164e3,
|
|
96554
|
+
maxContextWindow: 164e3,
|
|
96555
|
+
maxTokens: 32e3,
|
|
96556
|
+
regions: ["cn"],
|
|
96557
|
+
credits: { cn: "0.45" },
|
|
96558
|
+
supportsImage: true,
|
|
96559
|
+
reasoningEfforts: [
|
|
96560
|
+
"low",
|
|
96561
|
+
"high",
|
|
96562
|
+
"max"
|
|
96563
|
+
],
|
|
96159
96564
|
defaultReasoningEffort: "high",
|
|
96160
96565
|
canDisableThinking: false,
|
|
96161
|
-
description: "
|
|
96566
|
+
description: ""
|
|
96567
|
+
},
|
|
96568
|
+
{
|
|
96569
|
+
id: "kimi-k2-thinking",
|
|
96570
|
+
name: "Kimi-K2-Thinking",
|
|
96571
|
+
contextWindow: 164e3,
|
|
96572
|
+
maxContextWindow: 164e3,
|
|
96573
|
+
maxTokens: 32e3,
|
|
96574
|
+
regions: ["cn"],
|
|
96575
|
+
credits: { cn: "0.54" },
|
|
96576
|
+
supportsImage: false,
|
|
96577
|
+
reasoningEfforts: [
|
|
96578
|
+
"low",
|
|
96579
|
+
"high",
|
|
96580
|
+
"max"
|
|
96581
|
+
],
|
|
96582
|
+
defaultReasoningEffort: "high",
|
|
96583
|
+
canDisableThinking: false,
|
|
96584
|
+
description: ""
|
|
96162
96585
|
},
|
|
96163
96586
|
{
|
|
96164
96587
|
id: "hy3-x",
|
|
@@ -96178,6 +96601,20 @@ const FALLBACK_MODELS$1 = [
|
|
|
96178
96601
|
canDisableThinking: false,
|
|
96179
96602
|
description: "混元思考模型,具有增强的推理能力"
|
|
96180
96603
|
},
|
|
96604
|
+
{
|
|
96605
|
+
id: "hy4-preview-x",
|
|
96606
|
+
name: "Hy4 preview",
|
|
96607
|
+
contextWindow: 1e6,
|
|
96608
|
+
maxContextWindow: 1e6,
|
|
96609
|
+
maxTokens: 64e3,
|
|
96610
|
+
regions: ["cn"],
|
|
96611
|
+
credits: { cn: "0.29" },
|
|
96612
|
+
supportsImage: true,
|
|
96613
|
+
reasoningEfforts: ["high"],
|
|
96614
|
+
defaultReasoningEffort: "high",
|
|
96615
|
+
canDisableThinking: false,
|
|
96616
|
+
description: "混元思考模型,具有增强的推理能力"
|
|
96617
|
+
},
|
|
96181
96618
|
{
|
|
96182
96619
|
id: "hunyuan-chat",
|
|
96183
96620
|
name: "Hunyuan-Turbos",
|
|
@@ -96213,77 +96650,68 @@ const FALLBACK_MODELS$1 = [
|
|
|
96213
96650
|
description: "推理速度极快,编码能力强劲,并支持原生多模态输入的匿名大模型"
|
|
96214
96651
|
},
|
|
96215
96652
|
{
|
|
96216
|
-
id: "
|
|
96217
|
-
name: "
|
|
96218
|
-
contextWindow:
|
|
96219
|
-
maxContextWindow:
|
|
96653
|
+
id: "step-5-preview",
|
|
96654
|
+
name: "Step-5-Preview",
|
|
96655
|
+
contextWindow: 1e6,
|
|
96656
|
+
maxContextWindow: 1e6,
|
|
96220
96657
|
maxTokens: 64e3,
|
|
96221
96658
|
regions: ["cn"],
|
|
96222
|
-
credits: { cn: "0.
|
|
96659
|
+
credits: { cn: "0.33" },
|
|
96223
96660
|
supportsImage: true,
|
|
96224
96661
|
reasoningEfforts: [
|
|
96225
96662
|
"low",
|
|
96226
|
-
"
|
|
96227
|
-
"
|
|
96663
|
+
"medium",
|
|
96664
|
+
"high"
|
|
96228
96665
|
],
|
|
96229
|
-
defaultReasoningEffort: "
|
|
96666
|
+
defaultReasoningEffort: "high",
|
|
96230
96667
|
canDisableThinking: false,
|
|
96231
|
-
description: "
|
|
96668
|
+
description: "阶跃 StepFun 面向真实任务的新一代旗舰基模"
|
|
96232
96669
|
},
|
|
96233
96670
|
{
|
|
96234
|
-
id: "
|
|
96235
|
-
name: "
|
|
96236
|
-
contextWindow:
|
|
96237
|
-
maxContextWindow:
|
|
96238
|
-
maxTokens:
|
|
96671
|
+
id: "mimo-v2.6-pro",
|
|
96672
|
+
name: "Xiaomi MiMo-V2.6-Pro",
|
|
96673
|
+
contextWindow: 1e6,
|
|
96674
|
+
maxContextWindow: 1e6,
|
|
96675
|
+
maxTokens: 128e3,
|
|
96239
96676
|
regions: ["cn"],
|
|
96240
|
-
credits: { cn: "0.
|
|
96677
|
+
credits: { cn: "0.13" },
|
|
96241
96678
|
supportsImage: true,
|
|
96242
96679
|
reasoningEfforts: [
|
|
96243
96680
|
"low",
|
|
96244
96681
|
"high",
|
|
96245
96682
|
"max"
|
|
96246
96683
|
],
|
|
96247
|
-
defaultReasoningEffort: "
|
|
96684
|
+
defaultReasoningEffort: "high",
|
|
96248
96685
|
canDisableThinking: false,
|
|
96249
|
-
description: ""
|
|
96686
|
+
description: "Xiaomi · 旗舰推理模型,面向专业、复杂长程工作流,兼顾高阶科研与网络安全"
|
|
96250
96687
|
},
|
|
96251
96688
|
{
|
|
96252
|
-
id: "
|
|
96253
|
-
name: "
|
|
96254
|
-
contextWindow:
|
|
96255
|
-
maxContextWindow:
|
|
96256
|
-
maxTokens:
|
|
96689
|
+
id: "hy4free",
|
|
96690
|
+
name: "Hy4 Free",
|
|
96691
|
+
contextWindow: 1e6,
|
|
96692
|
+
maxContextWindow: 1e6,
|
|
96693
|
+
maxTokens: 64e3,
|
|
96257
96694
|
regions: ["cn"],
|
|
96258
|
-
credits: { cn: "0.
|
|
96259
|
-
supportsImage:
|
|
96260
|
-
reasoningEfforts: [
|
|
96261
|
-
"low",
|
|
96262
|
-
"high",
|
|
96263
|
-
"max"
|
|
96264
|
-
],
|
|
96695
|
+
credits: { cn: "0.00" },
|
|
96696
|
+
supportsImage: true,
|
|
96697
|
+
reasoningEfforts: ["high"],
|
|
96265
96698
|
defaultReasoningEffort: "high",
|
|
96266
96699
|
canDisableThinking: false,
|
|
96267
|
-
description: ""
|
|
96700
|
+
description: "最新旗舰模型,Agent与多模专长"
|
|
96268
96701
|
},
|
|
96269
|
-
...UNPUBLISHED_MODELS.filter((model) => model.id === "gemini-3.8-flash"),
|
|
96270
96702
|
{
|
|
96271
|
-
id: "
|
|
96272
|
-
name: "
|
|
96703
|
+
id: "hy4std",
|
|
96704
|
+
name: "Hy4",
|
|
96273
96705
|
contextWindow: 1e6,
|
|
96274
96706
|
maxContextWindow: 1e6,
|
|
96275
|
-
maxTokens:
|
|
96276
|
-
regions: ["
|
|
96277
|
-
credits: {
|
|
96707
|
+
maxTokens: 64e3,
|
|
96708
|
+
regions: ["cn"],
|
|
96709
|
+
credits: { cn: "0.29" },
|
|
96278
96710
|
supportsImage: true,
|
|
96279
|
-
reasoningEfforts: [
|
|
96280
|
-
|
|
96281
|
-
"high",
|
|
96282
|
-
"max"
|
|
96283
|
-
],
|
|
96284
|
-
defaultReasoningEffort: "medium",
|
|
96711
|
+
reasoningEfforts: ["high"],
|
|
96712
|
+
defaultReasoningEffort: "high",
|
|
96285
96713
|
canDisableThinking: false,
|
|
96286
|
-
description: "
|
|
96714
|
+
description: "最新旗舰模型,Agent与多模专长"
|
|
96287
96715
|
}
|
|
96288
96716
|
];
|
|
96289
96717
|
/**
|
|
@@ -96295,11 +96723,41 @@ const FALLBACK_MODELS$1 = [
|
|
|
96295
96723
|
* the account's region can actually call.
|
|
96296
96724
|
*/
|
|
96297
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 = [[
|
|
96298
96742
|
"glm-5.3",
|
|
96299
96743
|
"deepseek-v4.1-flash",
|
|
96300
96744
|
"hy4-preview",
|
|
96301
96745
|
"kimi-k2.6"
|
|
96302
|
-
];
|
|
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
|
+
}
|
|
96303
96761
|
/** Every id the fallback knows, in declaration order. */
|
|
96304
96762
|
const WORKBUDDY_MODEL_IDS = FALLBACK_MODELS$1.map((model) => model.id);
|
|
96305
96763
|
/**
|
|
@@ -96404,6 +96862,18 @@ const WORKBUDDY_VENDOR_RULES = [
|
|
|
96404
96862
|
re: /^minimax-/,
|
|
96405
96863
|
family: "minimax"
|
|
96406
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
|
+
},
|
|
96407
96877
|
{
|
|
96408
96878
|
re: /^space-bunny$/,
|
|
96409
96879
|
family: "space-bunny"
|
|
@@ -100325,8 +100795,7 @@ function isPoolPausedError(error) {
|
|
|
100325
100795
|
*/
|
|
100326
100796
|
function resolveEnabledModelIds$2(stored, available, enabled = true) {
|
|
100327
100797
|
if (!enabled) return [];
|
|
100328
|
-
|
|
100329
|
-
if (stored.length > 0 && stored.length === shippedDefaults.size && stored.every((id) => shippedDefaults.has(id))) return [...available];
|
|
100798
|
+
if (isUntouchedModelSelection(stored)) return [...available];
|
|
100330
100799
|
const known = new Set(available);
|
|
100331
100800
|
return stored.filter((id) => known.has(id));
|
|
100332
100801
|
}
|
|
@@ -101993,8 +102462,7 @@ async function readRequestJson(request) {
|
|
|
101993
102462
|
*/
|
|
101994
102463
|
function resolveEnabledModelIds$1(stored, available, enabled = true) {
|
|
101995
102464
|
if (!enabled) return [];
|
|
101996
|
-
|
|
101997
|
-
if (stored.length > 0 && stored.length === shippedDefaults.size && stored.every((id) => shippedDefaults.has(id))) return [...available];
|
|
102465
|
+
if (isUntouchedModelSelection(stored)) return [...available];
|
|
101998
102466
|
const known = new Set(available);
|
|
101999
102467
|
return stored.filter((id) => known.has(id));
|
|
102000
102468
|
}
|
|
@@ -103039,6 +103507,7 @@ const Config = z$1.object({
|
|
|
103039
103507
|
]).default("auto").volatile().description("进展更新的输出语言:auto 跟随对话语言,zh 中文,en 英文。"),
|
|
103040
103508
|
planModePipeline: z$1.boolean().default(true).volatile().description("启用计划模式管线:允许调度模式在澄清访谈收敛后用 enter_plan_mode 进入计划模式,放弃规划时用 leave_plan_mode 退出。"),
|
|
103041
103509
|
dispatchExecutionGuard: z$1.boolean().default(true).volatile().description("启用调度执行守卫:在执行期拦截子代理越权调用主控专用工具,并拦截等待子代理期间的纯 sleep 空等命令;不修改工具声明面,零损耗保护 Kimi 缓存。"),
|
|
103510
|
+
teamPolicyCacheGuard: z$1.boolean().default(true).volatile().description("把内置 Agent Teams 的 team:policy 段从 system prompt 摘掉,改为开关切换时以尾部用户消息投递一次,避免中途开团队协作时刷掉整段前缀缓存;默认开启。"),
|
|
103042
103511
|
cacheWarmup: z$1.boolean().default(true).volatile().description(CACHE_WARMUP_SETTING_DESCRIPTION),
|
|
103043
103512
|
cacheWarmupRetrieval: z$1.boolean().default(true).volatile().description(CACHE_WARMUP_RETRIEVAL_SETTING_DESCRIPTION),
|
|
103044
103513
|
cacheWaitWarmup: z$1.boolean().default(true).volatile().description(CACHE_WAIT_WARMUP_SETTING_DESCRIPTION),
|
|
@@ -103107,6 +103576,10 @@ function apply(ctx, pluginConfig = {}) {
|
|
|
103107
103576
|
const guard = installPtcSdkCacheGuard(ctx);
|
|
103108
103577
|
return () => guard.dispose();
|
|
103109
103578
|
}, "dsh-chatgpt-subscription: PTC SDK cache guard");
|
|
103579
|
+
ctx.effect(() => {
|
|
103580
|
+
const guard = installTeamPolicyCacheGuard(ctx, { enabled: () => resolveTeamPolicyCacheGuardEnabled(pluginConfig) });
|
|
103581
|
+
return () => guard.dispose();
|
|
103582
|
+
}, "dsh-chatgpt-subscription: team policy cache guard");
|
|
103110
103583
|
ctx.effect(() => {
|
|
103111
103584
|
const guard = installCompactionPolicyGuard(ctx);
|
|
103112
103585
|
return () => guard.dispose();
|