dsh-connect-trae 2.0.6 → 2.2.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 +62 -0
- package/README.en.md +25 -3
- package/README.md +25 -3
- package/lib/client.js +293 -38
- package/lib/index.d.ts +147 -5
- package/lib/index.js +225 -41
- package/package.json +3 -3
package/lib/index.d.ts
CHANGED
|
@@ -1156,6 +1156,21 @@ declare class TraeDelegatingUpstreamClient implements TraeUpstreamClient {
|
|
|
1156
1156
|
declare const TRAE_PAY_BASE = "https://api.trae.cn";
|
|
1157
1157
|
interface TraeUsageOptions {
|
|
1158
1158
|
credential(): Promise<TraeCredential | undefined>;
|
|
1159
|
+
/**
|
|
1160
|
+
* Device identity of the credential's own installation, sent as
|
|
1161
|
+
* `x-device-id` on the check-in routes.
|
|
1162
|
+
*
|
|
1163
|
+
* The claim endpoint is the one WRITE in this client, and it is guarded
|
|
1164
|
+
* server-side by that header: with the same Authorization but no
|
|
1165
|
+
* `x-device-id`, the upstream answers HTTP 200 with business code `9004`
|
|
1166
|
+
* ("The submitted order parameters are incorrect") and grants nothing —
|
|
1167
|
+
* verified 2026-09-24 against a live CN account, where adding the header
|
|
1168
|
+
* flipped the same request to `code: 0` and the daily reward landed. The
|
|
1169
|
+
* official client sends it on every check-in call
|
|
1170
|
+
* (`main.js`'s `fb(headers)` sets `x-device-id` from `guaranteedDeviceId`).
|
|
1171
|
+
* Absent, the client still reads status; only the claim refuses.
|
|
1172
|
+
*/
|
|
1173
|
+
deviceId?(): Promise<string | undefined>;
|
|
1159
1174
|
fetchImpl?: typeof fetch;
|
|
1160
1175
|
baseUrl?: string;
|
|
1161
1176
|
timeoutMs?: number;
|
|
@@ -1209,8 +1224,27 @@ interface TraeUsageSnapshot {
|
|
|
1209
1224
|
}
|
|
1210
1225
|
interface TraeCheckinStatus {
|
|
1211
1226
|
checkedIn: boolean;
|
|
1227
|
+
/** Reward for one check-in, as reported by the upstream (`credits`). */
|
|
1212
1228
|
credits: number;
|
|
1213
1229
|
enabled: boolean;
|
|
1230
|
+
/**
|
|
1231
|
+
* Whether today's reward was claimed in a previous session. The upstream
|
|
1232
|
+
* reports `did_checked_in` separately from `checked_in`: the app uses the
|
|
1233
|
+
* former to keep the claim button disabled for the rest of the Beijing day
|
|
1234
|
+
* even when the status read happens to report `checked_in: false`.
|
|
1235
|
+
*/
|
|
1236
|
+
didCheckedIn: boolean;
|
|
1237
|
+
/** Bonus credit granted on top of the base reward, when the upstream reports one. */
|
|
1238
|
+
extraCredits?: number;
|
|
1239
|
+
}
|
|
1240
|
+
/** Result of claiming today's check-in reward. */
|
|
1241
|
+
interface TraeCheckinClaim {
|
|
1242
|
+
/** Whether the upstream accepted the claim (`code === 0`). */
|
|
1243
|
+
claimed: boolean;
|
|
1244
|
+
/** Business code from the answer; `0` on success. */
|
|
1245
|
+
code: number;
|
|
1246
|
+
/** Upstream message, verbatim but truncated — never token material. */
|
|
1247
|
+
message: string;
|
|
1214
1248
|
}
|
|
1215
1249
|
interface TraeActivityRule {
|
|
1216
1250
|
activityId: string;
|
|
@@ -1226,8 +1260,11 @@ interface TraeUsageView {
|
|
|
1226
1260
|
activities: TraeActivityRule[];
|
|
1227
1261
|
}
|
|
1228
1262
|
/**
|
|
1229
|
-
* A
|
|
1230
|
-
*
|
|
1263
|
+
* A client for the verified Trae usage/credits endpoints.
|
|
1264
|
+
*
|
|
1265
|
+
* Every method is read-only except {@link TraeUsageClient.claimCheckin}, which
|
|
1266
|
+
* claims the daily check-in reward — the one deliberate mutation, requested by
|
|
1267
|
+
* the user from the card and guarded before it is sent.
|
|
1231
1268
|
*/
|
|
1232
1269
|
declare class TraeUsageClient {
|
|
1233
1270
|
private readonly options;
|
|
@@ -1243,6 +1280,13 @@ declare class TraeUsageClient {
|
|
|
1243
1280
|
* international region its own verified pay gateway.
|
|
1244
1281
|
*/
|
|
1245
1282
|
private payBase;
|
|
1283
|
+
/**
|
|
1284
|
+
* Device id for the check-in routes, or undefined when the machine's
|
|
1285
|
+
* installation identity cannot be read. Best-effort on purpose: a missing
|
|
1286
|
+
* identity must not break the read-only status query, which the upstream
|
|
1287
|
+
* answers with or without the header.
|
|
1288
|
+
*/
|
|
1289
|
+
private deviceIdHeader;
|
|
1246
1290
|
private authedHeaders;
|
|
1247
1291
|
private post;
|
|
1248
1292
|
/**
|
|
@@ -1260,8 +1304,26 @@ declare class TraeUsageClient {
|
|
|
1260
1304
|
private requireCnRegion;
|
|
1261
1305
|
/** Total entitlements / credits and per-pack breakdown. */
|
|
1262
1306
|
snapshot(signal?: AbortSignal): Promise<TraeUsageSnapshot>;
|
|
1263
|
-
/**
|
|
1307
|
+
/**
|
|
1308
|
+
* Daily check-in status. Read-only, and answered with or without the device
|
|
1309
|
+
* header — the claim is what needs it.
|
|
1310
|
+
*/
|
|
1264
1311
|
checkinStatus(signal?: AbortSignal): Promise<TraeCheckinStatus>;
|
|
1312
|
+
/**
|
|
1313
|
+
* Claim today's check-in reward. The ONLY state-changing call in this client.
|
|
1314
|
+
*
|
|
1315
|
+
* The upstream is idempotent per Beijing day (verified 2026-09-24: repeating
|
|
1316
|
+
* the call on an already-claimed day answers `code: 0` while the entitlement
|
|
1317
|
+
* total stays byte-identical), so a double click cannot double-grant. The
|
|
1318
|
+
* card and its route still guard, because "cannot double-grant" is a property
|
|
1319
|
+
* of the upstream we verify rather than one we rely on.
|
|
1320
|
+
*
|
|
1321
|
+
* A business refusal arrives as HTTP 200 with a non-zero `code` — most often
|
|
1322
|
+
* `9004` when the request carries no `x-device-id`. That is reported as
|
|
1323
|
+
* `claimed: false` rather than thrown, so the caller can tell "the upstream
|
|
1324
|
+
* refused this" apart from "the request never arrived".
|
|
1325
|
+
*/
|
|
1326
|
+
claimCheckin(signal?: AbortSignal): Promise<TraeCheckinClaim>;
|
|
1265
1327
|
/** Rewards / activity rules. */
|
|
1266
1328
|
activities(signal?: AbortSignal): Promise<TraeActivityRule[]>;
|
|
1267
1329
|
/** Convenience: snapshot + check-in + activities in one call (best-effort, non-fatal on missing). */
|
|
@@ -1271,6 +1333,11 @@ declare class TraeUsageClient {
|
|
|
1271
1333
|
//#region src/status-paths.d.ts
|
|
1272
1334
|
/** Plugin-owned usage endpoint consumed by its browser half. */
|
|
1273
1335
|
declare const TRAE_USAGE_PATH = "/plugins/dsh-connect-trae/usage";
|
|
1336
|
+
/**
|
|
1337
|
+
* Plugin-owned daily check-in claim endpoint. POST, loopback-only, and the only
|
|
1338
|
+
* route in this plugin that changes upstream account state.
|
|
1339
|
+
*/
|
|
1340
|
+
declare const TRAE_CHECKIN_PATH = "/plugins/dsh-connect-trae/checkin";
|
|
1274
1341
|
/** Query parameter naming the region a card request addresses. */
|
|
1275
1342
|
declare const TRAE_REGION_PARAM = "region";
|
|
1276
1343
|
/** Every region, in card tab order. */
|
|
@@ -1316,10 +1383,32 @@ interface TraeWebModel {
|
|
|
1316
1383
|
};
|
|
1317
1384
|
maxContextWindow?: number;
|
|
1318
1385
|
}
|
|
1319
|
-
/**
|
|
1386
|
+
/**
|
|
1387
|
+
* Daily check-in state rendered below the credit stats.
|
|
1388
|
+
*
|
|
1389
|
+
* `didCheckedIn` is not redundant with `checkedIn`: the upstream reports them
|
|
1390
|
+
* separately, and the official client keeps the claim button disabled for the
|
|
1391
|
+
* rest of the Beijing day off `did_checked_in` even when a status read comes
|
|
1392
|
+
* back `checked_in: false`. The card mirrors that rule so a stale-looking
|
|
1393
|
+
* status cannot invite a pointless second claim.
|
|
1394
|
+
*/
|
|
1320
1395
|
interface TraeWebCheckin {
|
|
1321
1396
|
checkedIn: boolean;
|
|
1397
|
+
didCheckedIn: boolean;
|
|
1322
1398
|
credits: number;
|
|
1399
|
+
enabled: boolean;
|
|
1400
|
+
extraCredits?: number;
|
|
1401
|
+
}
|
|
1402
|
+
/** The claim route's answer, so the card can report a business refusal verbatim. */
|
|
1403
|
+
interface TraeWebCheckinClaim {
|
|
1404
|
+
/** False when the upstream answered a non-zero business code (e.g. 9004). */
|
|
1405
|
+
claimed: boolean;
|
|
1406
|
+
/** True when today was already claimed, so nothing was sent upstream. */
|
|
1407
|
+
alreadyCheckedIn: boolean;
|
|
1408
|
+
code?: number;
|
|
1409
|
+
message?: string;
|
|
1410
|
+
/** The refreshed check-in state, present whenever the claim path ran. */
|
|
1411
|
+
checkin?: TraeWebCheckin;
|
|
1323
1412
|
}
|
|
1324
1413
|
/** One reward activity rule (name + work/general credits when present). */
|
|
1325
1414
|
interface TraeWebActivity {
|
|
@@ -1346,6 +1435,31 @@ interface TraeWebSearchPath {
|
|
|
1346
1435
|
reason: 'missing' | 'unreadable' | 'invalid';
|
|
1347
1436
|
message?: string;
|
|
1348
1437
|
}
|
|
1438
|
+
/**
|
|
1439
|
+
* Peel ONE `{get(): T}` live reference, the shape DSH 0.1.7 delivers a
|
|
1440
|
+
* volatile-marked settings field as (see {@link unwrapVolatileDeep}).
|
|
1441
|
+
*/
|
|
1442
|
+
declare function unwrapVolatile<T>(value: T): T;
|
|
1443
|
+
/**
|
|
1444
|
+
* Deep copy of a value with every `{get(): T}` live reference replaced by the
|
|
1445
|
+
* value it resolves to.
|
|
1446
|
+
*
|
|
1447
|
+
* DSH 0.1.7 hands volatile-marked fields back as live references, and a live
|
|
1448
|
+
* reference is still `typeof === 'object'` — so it passes a naive object check
|
|
1449
|
+
* and every lookup on it is `undefined`. Worse, spreading one (`{ ...ref }`)
|
|
1450
|
+
* does NOT read the field: it produces `{ get: <function> }`. Any merge that
|
|
1451
|
+
* spreads a resolved field to preserve its siblings — the card's "write one
|
|
1452
|
+
* region, keep the other" write, or the account map's spread — would otherwise
|
|
1453
|
+
* DROP every sibling and leak a function into the document.
|
|
1454
|
+
*
|
|
1455
|
+
* Both halves therefore unwrap before touching a resolved field. This lives in
|
|
1456
|
+
* the node-free host↔client bridge because the browser half needs it too.
|
|
1457
|
+
*
|
|
1458
|
+
* Non-reference values are recursed into so a nested volatile field is caught
|
|
1459
|
+
* as well; arrays and objects are rebuilt rather than mutated, so the caller's
|
|
1460
|
+
* value is never touched.
|
|
1461
|
+
*/
|
|
1462
|
+
declare function unwrapVolatileDeep<T>(value: T): T;
|
|
1349
1463
|
/**
|
|
1350
1464
|
* Build the next `regions` settings value for the card's save. The write
|
|
1351
1465
|
* targets ONLY the signed-in account's region slot; every other region's slot
|
|
@@ -1425,6 +1539,14 @@ type TraeWebUsage = {
|
|
|
1425
1539
|
};
|
|
1426
1540
|
credits?: TraeWebCredits;
|
|
1427
1541
|
creditsError?: string;
|
|
1542
|
+
/**
|
|
1543
|
+
* Daily check-in state (CN only). Absent on the international region,
|
|
1544
|
+
* whose check-in surface does not exist — probed 2026-09-24: the
|
|
1545
|
+
* `/trae/api/v2/ug/*` family answers 404 on every ai gateway, so the card
|
|
1546
|
+
* shows no claim button there rather than a button that cannot work.
|
|
1547
|
+
*/
|
|
1548
|
+
checkin?: TraeWebCheckin;
|
|
1549
|
+
checkinError?: string;
|
|
1428
1550
|
/** Subscription status of an international account (region ai only). */
|
|
1429
1551
|
payStatus?: TraeWebPayStatus;
|
|
1430
1552
|
payStatusError?: string;
|
|
@@ -1558,7 +1680,27 @@ declare function regionStateOf(config: Config, region: TraeRegion): TraeRegionSt
|
|
|
1558
1680
|
* disagree about a region's state.
|
|
1559
1681
|
*/
|
|
1560
1682
|
declare function regionEnabled(config: Config, region: TraeRegion): boolean;
|
|
1683
|
+
/**
|
|
1684
|
+
* Mark a schema's field as volatile on the DSH lines that support it.
|
|
1685
|
+
*
|
|
1686
|
+
* `volatile()` exists from schemastery 3.18.3 (the DSH 0.1.7 line, which is the
|
|
1687
|
+
* only line whose settings write gate reads the marker). Older pinning (3.18.2,
|
|
1688
|
+
* the 0.1.5 line) has no such method, and the schema must stay byte-identical
|
|
1689
|
+
* to the unmarked original there: hand-writing `meta.volatile = true` would
|
|
1690
|
+
* bypass schemastery's own `validateVolatileSchema` checks and produce a schema
|
|
1691
|
+
* no 0.1.5 consumer understands — so on that line this degrades to an identity
|
|
1692
|
+
* no-op.
|
|
1693
|
+
*
|
|
1694
|
+
* Without the marker, 0.1.7's settings write gate REJECTS every write with
|
|
1695
|
+
* `Plugin entry "trae" has no volatile fields` while the scope's `set()` still
|
|
1696
|
+
* resolves — so the card would look like it saved and silently revert.
|
|
1697
|
+
*
|
|
1698
|
+
* Exported so BOTH arms are testable on any machine: the capability is decided
|
|
1699
|
+
* by whichever schemastery the dependency tree resolves, so without a seam the
|
|
1700
|
+
* no-op arm would silently stop being exercised the moment the pin moved up.
|
|
1701
|
+
*/
|
|
1702
|
+
declare function asVolatile<S>(schema: S): S;
|
|
1561
1703
|
declare const Config: z<Config>;
|
|
1562
1704
|
declare function apply(ctx: Context, config: Config): void;
|
|
1563
1705
|
//#endregion
|
|
1564
|
-
export { Config, FALLBACK_TRAE_MODELS, FALLBACK_TRAE_MODELS_AI, REGION_GATEWAYS, type RawChatDelta, type RawChatMessage, type RawChatTool, SseDecoder, type SseEvent, TRAE_AI_PROVIDER, TRAE_CN_AGENT_TASK_PATH, TRAE_CN_TITLE_PATH, TRAE_MODEL_DETAIL_FUNCTIONS, TRAE_MODEL_DETAIL_PATH, TRAE_PAY_BASE, TRAE_PROVIDER, TRAE_PROVIDERS, TRAE_PROVIDER_DISPLAY_NAMES, TRAE_RAW_CHAT_V1_PATH, TRAE_RAW_CHAT_V2_PATH, TRAE_REASONING_EFFORTS, TRAE_REGIONS, TRAE_REGION_PARAM, TRAE_SETTINGS_NS, TRAE_SOLO_CHAT_PATH, TRAE_SOLO_FUNCTION, TRAE_SOLO_MODELS_PATH, TRAE_SOLO_REMOTE_BASE, TRAE_STREAM_IDLE_TIMEOUT_MS, TRAE_USAGE_PATH, TRAE_VERSION_CODE_FALLBACK, type TraeActivityRule, type TraeAdapter, type TraeCachedModelConfig, TraeCatalog, type TraeChatResult, type TraeCheckinStatus, type TraeContextBudget, type TraeCredential, TraeCredentialStore, TraeDelegatingUpstreamClient, type TraeDiscoveredModel, type TraeDiscoveredReasoning, type TraeEdition, TraeFallbackUpstreamClient, type TraeFallbackUpstreamOptions, type TraeFusionRawChatEnvelope, TraeGatedUpstreamClient, type TraeGatedUpstreamOptions, type TraeIdentity, type TraeInputModality, type TraeModelDetailRequest, type TraeModelInfo, type TraeObservedModelConfig, TraeRawCapabilityController, type TraeRawCapabilityControllerOptions, type TraeRawCapabilitySnapshot, TraeRawCapabilityState, type TraeRawChatBehaviorConfig, type TraeRawChatCapability, type TraeRawChatClientOptions, type TraeRawChatConfig, type TraeRawChatFailureReason, type TraeRawChatRuntimeConfig, TraeRawChatUpstreamClient, type TraeRawDiagnostic, type TraeRawDiagnosticState, type TraeRawGateway, type TraeRawGatewayOptions, type TraeRawResolverResult, type TraeReasoningCapability, type TraeReasoningEffort, type TraeRefreshDevice, type TraeRegion, type TraeRegionGateways, TraeRegionState, type TraeShim, TraeSoloBridge, type TraeSoloClientOptions, TraeSoloRemoteCatalogClient, type TraeSoloRemoteCatalogOptions, TraeSoloUpstreamClient, type TraeStorageCandidate, type TraeStreamEvent, type TraeUpstreamClient, TraeUsageClient, type TraeUsageOptions, type TraeUsagePack, type TraeUsageRouteOptions, type TraeUsageSnapshot, type TraeUsageSummary, type TraeUsageView, type TraeWebActivity, type TraeWebCheckin, type TraeWebCredits, type TraeWebUsage, type TraeWireModel, UnconfiguredTraeUpstreamClient, apply, applyContextBudgets, applyImageSelection, applyReasoningEffort, bridgeTraeSoloStream, buildTraeAgentTaskBody, buildTraeCnHeaders, buildTraeFusionRawChatEnvelope, buildTraeModelDetailRequest, buildTraeRawChatDraft, buildTraeRawChatRuntimeConfig, classifyTraeRawChatFailure, createTraeAdapter, createTraeRawGateway, createTraeShim, decodeRawChatChunk, decodeTraeEvent, decryptTraeStorageValue, deriveCatalog, discoveredCatalog, fallbackModelsFor, hashTraeRawChatArg, identityHeaders, inject, legacyTraeOwnAuthPath, mergeTraeModelSources, name, nextRegionEnabled, nextRegionSlots, normalizeTraeCredential, normalizeTraeVersionCode, parseObservedModelConfig, parseReasoningCapability, parseTraeAuthValue, parseTraeCachedModel, parseTraeModelExtraConfigLogLine, parseTraeRawChatBehaviorConfig, parseTraeRemoteModel, parseTraeStorageDocument, pickTraeStorageIdentity, prepareSoloBody, probeTraeRawChatCapability, rawCapabilityDiagnostic, rawCapabilityFingerprint, readTraeCachedModel, readTraeCliIdentity, readTraeIdentity, refreshTraeCredential, regionEnabled, regionEnabledOf, regionOfCredential, regionOfEdition, regionOfHost, regionOfTraeProvider, regionOfTraeStatusUrl, regionOfUserRegion, regionStateOf, registerTraeUsageRoute, resolveTraeIdentity, resolveTraeRawRuntime, sanitizeCatalog, traeEndpoint, traeInputModalities, traeModelDisplayName, traeOwnAuthPath, traeRawChatExtraInfo, traeStorageCandidates, traeWebUsage, withTraeRegion };
|
|
1706
|
+
export { Config, FALLBACK_TRAE_MODELS, FALLBACK_TRAE_MODELS_AI, REGION_GATEWAYS, type RawChatDelta, type RawChatMessage, type RawChatTool, SseDecoder, type SseEvent, TRAE_AI_PROVIDER, TRAE_CHECKIN_PATH, TRAE_CN_AGENT_TASK_PATH, TRAE_CN_TITLE_PATH, TRAE_MODEL_DETAIL_FUNCTIONS, TRAE_MODEL_DETAIL_PATH, TRAE_PAY_BASE, TRAE_PROVIDER, TRAE_PROVIDERS, TRAE_PROVIDER_DISPLAY_NAMES, TRAE_RAW_CHAT_V1_PATH, TRAE_RAW_CHAT_V2_PATH, TRAE_REASONING_EFFORTS, TRAE_REGIONS, TRAE_REGION_PARAM, TRAE_SETTINGS_NS, TRAE_SOLO_CHAT_PATH, TRAE_SOLO_FUNCTION, TRAE_SOLO_MODELS_PATH, TRAE_SOLO_REMOTE_BASE, TRAE_STREAM_IDLE_TIMEOUT_MS, TRAE_USAGE_PATH, TRAE_VERSION_CODE_FALLBACK, type TraeActivityRule, type TraeAdapter, type TraeCachedModelConfig, TraeCatalog, type TraeChatResult, type TraeCheckinClaim, type TraeCheckinStatus, type TraeContextBudget, type TraeCredential, TraeCredentialStore, TraeDelegatingUpstreamClient, type TraeDiscoveredModel, type TraeDiscoveredReasoning, type TraeEdition, TraeFallbackUpstreamClient, type TraeFallbackUpstreamOptions, type TraeFusionRawChatEnvelope, TraeGatedUpstreamClient, type TraeGatedUpstreamOptions, type TraeIdentity, type TraeInputModality, type TraeModelDetailRequest, type TraeModelInfo, type TraeObservedModelConfig, TraeRawCapabilityController, type TraeRawCapabilityControllerOptions, type TraeRawCapabilitySnapshot, TraeRawCapabilityState, type TraeRawChatBehaviorConfig, type TraeRawChatCapability, type TraeRawChatClientOptions, type TraeRawChatConfig, type TraeRawChatFailureReason, type TraeRawChatRuntimeConfig, TraeRawChatUpstreamClient, type TraeRawDiagnostic, type TraeRawDiagnosticState, type TraeRawGateway, type TraeRawGatewayOptions, type TraeRawResolverResult, type TraeReasoningCapability, type TraeReasoningEffort, type TraeRefreshDevice, type TraeRegion, type TraeRegionGateways, TraeRegionState, type TraeShim, TraeSoloBridge, type TraeSoloClientOptions, TraeSoloRemoteCatalogClient, type TraeSoloRemoteCatalogOptions, TraeSoloUpstreamClient, type TraeStorageCandidate, type TraeStreamEvent, type TraeUpstreamClient, TraeUsageClient, type TraeUsageOptions, type TraeUsagePack, type TraeUsageRouteOptions, type TraeUsageSnapshot, type TraeUsageSummary, type TraeUsageView, type TraeWebActivity, type TraeWebCheckin, type TraeWebCheckinClaim, type TraeWebCredits, type TraeWebUsage, type TraeWireModel, UnconfiguredTraeUpstreamClient, apply, applyContextBudgets, applyImageSelection, applyReasoningEffort, asVolatile, bridgeTraeSoloStream, buildTraeAgentTaskBody, buildTraeCnHeaders, buildTraeFusionRawChatEnvelope, buildTraeModelDetailRequest, buildTraeRawChatDraft, buildTraeRawChatRuntimeConfig, classifyTraeRawChatFailure, createTraeAdapter, createTraeRawGateway, createTraeShim, decodeRawChatChunk, decodeTraeEvent, decryptTraeStorageValue, deriveCatalog, discoveredCatalog, fallbackModelsFor, hashTraeRawChatArg, identityHeaders, inject, legacyTraeOwnAuthPath, mergeTraeModelSources, name, nextRegionEnabled, nextRegionSlots, normalizeTraeCredential, normalizeTraeVersionCode, parseObservedModelConfig, parseReasoningCapability, parseTraeAuthValue, parseTraeCachedModel, parseTraeModelExtraConfigLogLine, parseTraeRawChatBehaviorConfig, parseTraeRemoteModel, parseTraeStorageDocument, pickTraeStorageIdentity, prepareSoloBody, probeTraeRawChatCapability, rawCapabilityDiagnostic, rawCapabilityFingerprint, readTraeCachedModel, readTraeCliIdentity, readTraeIdentity, refreshTraeCredential, regionEnabled, regionEnabledOf, regionOfCredential, regionOfEdition, regionOfHost, regionOfTraeProvider, regionOfTraeStatusUrl, regionOfUserRegion, regionStateOf, registerTraeUsageRoute, resolveTraeIdentity, resolveTraeRawRuntime, sanitizeCatalog, traeEndpoint, traeInputModalities, traeModelDisplayName, traeOwnAuthPath, traeRawChatExtraInfo, traeStorageCandidates, traeWebUsage, unwrapVolatile, unwrapVolatileDeep, withTraeRegion };
|
package/lib/index.js
CHANGED
|
@@ -3043,8 +3043,11 @@ function parseUsageSnapshot(payload) {
|
|
|
3043
3043
|
};
|
|
3044
3044
|
}
|
|
3045
3045
|
/**
|
|
3046
|
-
* A
|
|
3047
|
-
*
|
|
3046
|
+
* A client for the verified Trae usage/credits endpoints.
|
|
3047
|
+
*
|
|
3048
|
+
* Every method is read-only except {@link TraeUsageClient.claimCheckin}, which
|
|
3049
|
+
* claims the daily check-in reward — the one deliberate mutation, requested by
|
|
3050
|
+
* the user from the card and guarded before it is sent.
|
|
3048
3051
|
*/
|
|
3049
3052
|
var TraeUsageClient = class {
|
|
3050
3053
|
options;
|
|
@@ -3070,6 +3073,20 @@ var TraeUsageClient = class {
|
|
|
3070
3073
|
async payBase() {
|
|
3071
3074
|
return this.baseUrl ?? REGION_GATEWAYS[await this.currentRegion()].pay;
|
|
3072
3075
|
}
|
|
3076
|
+
/**
|
|
3077
|
+
* Device id for the check-in routes, or undefined when the machine's
|
|
3078
|
+
* installation identity cannot be read. Best-effort on purpose: a missing
|
|
3079
|
+
* identity must not break the read-only status query, which the upstream
|
|
3080
|
+
* answers with or without the header.
|
|
3081
|
+
*/
|
|
3082
|
+
async deviceIdHeader() {
|
|
3083
|
+
try {
|
|
3084
|
+
const deviceId = await this.options.deviceId?.();
|
|
3085
|
+
return deviceId === void 0 || deviceId === "" ? {} : { "x-device-id": deviceId };
|
|
3086
|
+
} catch {
|
|
3087
|
+
return {};
|
|
3088
|
+
}
|
|
3089
|
+
}
|
|
3073
3090
|
async authedHeaders() {
|
|
3074
3091
|
const credential = await this.options.credential();
|
|
3075
3092
|
if (credential === void 0 || credential.accessToken === "") throw new Error("Trae credential is not available; cannot query usage");
|
|
@@ -3082,8 +3099,11 @@ var TraeUsageClient = class {
|
|
|
3082
3099
|
"Referer": `${origin}/`
|
|
3083
3100
|
};
|
|
3084
3101
|
}
|
|
3085
|
-
async post(path, data, signal) {
|
|
3086
|
-
const headers =
|
|
3102
|
+
async post(path, data, signal, extraHeaders = {}) {
|
|
3103
|
+
const headers = {
|
|
3104
|
+
...await this.authedHeaders(),
|
|
3105
|
+
...extraHeaders
|
|
3106
|
+
};
|
|
3087
3107
|
const response = await this.fetchImpl(`${await this.payBase()}${path}`, {
|
|
3088
3108
|
method: "POST",
|
|
3089
3109
|
headers,
|
|
@@ -3137,14 +3157,46 @@ var TraeUsageClient = class {
|
|
|
3137
3157
|
await this.requireCnRegion("usage snapshot");
|
|
3138
3158
|
return parseUsageSnapshot(await this.post("/trae/api/v2/pay/web_user_ent_usage", { require_usage: true }, signal));
|
|
3139
3159
|
}
|
|
3140
|
-
/**
|
|
3160
|
+
/**
|
|
3161
|
+
* Daily check-in status. Read-only, and answered with or without the device
|
|
3162
|
+
* header — the claim is what needs it.
|
|
3163
|
+
*/
|
|
3141
3164
|
async checkinStatus(signal) {
|
|
3142
3165
|
await this.requireCnRegion("check-in status");
|
|
3143
|
-
const
|
|
3166
|
+
const headers = await this.deviceIdHeader();
|
|
3167
|
+
const payload = await this.post("/trae/api/v2/ug/checkin_credits/status", {}, signal, headers);
|
|
3168
|
+
const extraCredits = asNumber(payload["extra_credits"]);
|
|
3144
3169
|
return {
|
|
3145
3170
|
checkedIn: payload["checked_in"] === true,
|
|
3146
3171
|
credits: asNumber(payload["credits"]) ?? 0,
|
|
3147
|
-
enabled: payload["enable"] !== false
|
|
3172
|
+
enabled: payload["enable"] !== false,
|
|
3173
|
+
didCheckedIn: payload["did_checked_in"] === true,
|
|
3174
|
+
...extraCredits === void 0 || extraCredits <= 0 ? {} : { extraCredits }
|
|
3175
|
+
};
|
|
3176
|
+
}
|
|
3177
|
+
/**
|
|
3178
|
+
* Claim today's check-in reward. The ONLY state-changing call in this client.
|
|
3179
|
+
*
|
|
3180
|
+
* The upstream is idempotent per Beijing day (verified 2026-09-24: repeating
|
|
3181
|
+
* the call on an already-claimed day answers `code: 0` while the entitlement
|
|
3182
|
+
* total stays byte-identical), so a double click cannot double-grant. The
|
|
3183
|
+
* card and its route still guard, because "cannot double-grant" is a property
|
|
3184
|
+
* of the upstream we verify rather than one we rely on.
|
|
3185
|
+
*
|
|
3186
|
+
* A business refusal arrives as HTTP 200 with a non-zero `code` — most often
|
|
3187
|
+
* `9004` when the request carries no `x-device-id`. That is reported as
|
|
3188
|
+
* `claimed: false` rather than thrown, so the caller can tell "the upstream
|
|
3189
|
+
* refused this" apart from "the request never arrived".
|
|
3190
|
+
*/
|
|
3191
|
+
async claimCheckin(signal) {
|
|
3192
|
+
await this.requireCnRegion("check-in claim");
|
|
3193
|
+
const headers = await this.deviceIdHeader();
|
|
3194
|
+
const payload = await this.post("/trae/api/v2/ug/checkin_credits/claim", {}, signal, headers);
|
|
3195
|
+
const code = asNumber(payload["code"]) ?? 0;
|
|
3196
|
+
return {
|
|
3197
|
+
claimed: code === 0,
|
|
3198
|
+
code,
|
|
3199
|
+
message: typeof payload["message"] === "string" ? payload["message"].slice(0, 200) : ""
|
|
3148
3200
|
};
|
|
3149
3201
|
}
|
|
3150
3202
|
/** Rewards / activity rules. */
|
|
@@ -3189,6 +3241,11 @@ const TRAE_USAGE_PATH = "/plugins/dsh-connect-trae/usage";
|
|
|
3189
3241
|
const TRAE_MODELS_REFRESH_PATH = "/plugins/dsh-connect-trae/models/refresh";
|
|
3190
3242
|
/** Plugin-owned local account rescan endpoint. */
|
|
3191
3243
|
const TRAE_ACCOUNTS_REFRESH_PATH = "/plugins/dsh-connect-trae/accounts/refresh";
|
|
3244
|
+
/**
|
|
3245
|
+
* Plugin-owned daily check-in claim endpoint. POST, loopback-only, and the only
|
|
3246
|
+
* route in this plugin that changes upstream account state.
|
|
3247
|
+
*/
|
|
3248
|
+
const TRAE_CHECKIN_PATH = "/plugins/dsh-connect-trae/checkin";
|
|
3192
3249
|
/** Query parameter naming the region a card request addresses. */
|
|
3193
3250
|
const TRAE_REGION_PARAM = "region";
|
|
3194
3251
|
/** Every region, in card tab order. */
|
|
@@ -3212,6 +3269,42 @@ function regionOfTraeStatusUrl(url) {
|
|
|
3212
3269
|
return TRAE_REGIONS.includes(value) ? value : void 0;
|
|
3213
3270
|
}
|
|
3214
3271
|
/**
|
|
3272
|
+
* Peel ONE `{get(): T}` live reference, the shape DSH 0.1.7 delivers a
|
|
3273
|
+
* volatile-marked settings field as (see {@link unwrapVolatileDeep}).
|
|
3274
|
+
*/
|
|
3275
|
+
function unwrapVolatile(value) {
|
|
3276
|
+
if (value !== null && typeof value === "object" && typeof value.get === "function") return value.get();
|
|
3277
|
+
return value;
|
|
3278
|
+
}
|
|
3279
|
+
/**
|
|
3280
|
+
* Deep copy of a value with every `{get(): T}` live reference replaced by the
|
|
3281
|
+
* value it resolves to.
|
|
3282
|
+
*
|
|
3283
|
+
* DSH 0.1.7 hands volatile-marked fields back as live references, and a live
|
|
3284
|
+
* reference is still `typeof === 'object'` — so it passes a naive object check
|
|
3285
|
+
* and every lookup on it is `undefined`. Worse, spreading one (`{ ...ref }`)
|
|
3286
|
+
* does NOT read the field: it produces `{ get: <function> }`. Any merge that
|
|
3287
|
+
* spreads a resolved field to preserve its siblings — the card's "write one
|
|
3288
|
+
* region, keep the other" write, or the account map's spread — would otherwise
|
|
3289
|
+
* DROP every sibling and leak a function into the document.
|
|
3290
|
+
*
|
|
3291
|
+
* Both halves therefore unwrap before touching a resolved field. This lives in
|
|
3292
|
+
* the node-free host↔client bridge because the browser half needs it too.
|
|
3293
|
+
*
|
|
3294
|
+
* Non-reference values are recursed into so a nested volatile field is caught
|
|
3295
|
+
* as well; arrays and objects are rebuilt rather than mutated, so the caller's
|
|
3296
|
+
* value is never touched.
|
|
3297
|
+
*/
|
|
3298
|
+
function unwrapVolatileDeep(value) {
|
|
3299
|
+
if (value === null || typeof value !== "object") return value;
|
|
3300
|
+
if (typeof value.get === "function") return unwrapVolatileDeep(value.get());
|
|
3301
|
+
if (Array.isArray(value)) return value.map((entry) => unwrapVolatileDeep(entry));
|
|
3302
|
+
const source = value;
|
|
3303
|
+
const out = {};
|
|
3304
|
+
for (const key of Object.keys(source)) out[key] = unwrapVolatileDeep(source[key]);
|
|
3305
|
+
return out;
|
|
3306
|
+
}
|
|
3307
|
+
/**
|
|
3215
3308
|
* Build the next `regions` settings value for the card's save. The write
|
|
3216
3309
|
* targets ONLY the signed-in account's region slot; every other region's slot
|
|
3217
3310
|
* is carried over untouched, so switching accounts never clobbers the other
|
|
@@ -3219,8 +3312,9 @@ function regionOfTraeStatusUrl(url) {
|
|
|
3219
3312
|
* from an empty document.
|
|
3220
3313
|
*/
|
|
3221
3314
|
function nextRegionSlots(regions, region, slot) {
|
|
3315
|
+
const unwrapped = unwrapVolatileDeep(regions);
|
|
3222
3316
|
return {
|
|
3223
|
-
...typeof
|
|
3317
|
+
...typeof unwrapped === "object" && unwrapped !== null && !Array.isArray(unwrapped) ? unwrapped : {},
|
|
3224
3318
|
[region]: slot
|
|
3225
3319
|
};
|
|
3226
3320
|
}
|
|
@@ -3231,17 +3325,23 @@ function nextRegionSlots(regions, region, slot) {
|
|
|
3231
3325
|
* where the map was expected was a real shipped bug — the lookup then read
|
|
3232
3326
|
* `section['cn']` (absent), so the card's checkbox reported `true` forever and
|
|
3233
3327
|
* clicking it appeared to do nothing even though the write succeeded.
|
|
3328
|
+
*
|
|
3329
|
+
* Unwraps live references first: on DSH 0.1.7 the `regions` field arrives as a
|
|
3330
|
+
* `{get(): T}` reference, which passes the `typeof === 'object'` check below
|
|
3331
|
+
* and would otherwise be returned as if it were the map — making every region
|
|
3332
|
+
* read back as absent (and the enabled flag read as "on" forever).
|
|
3234
3333
|
*/
|
|
3235
3334
|
function regionsMapOf(value) {
|
|
3236
|
-
|
|
3237
|
-
|
|
3335
|
+
const unwrapped = unwrapVolatileDeep(value);
|
|
3336
|
+
if (typeof unwrapped !== "object" || unwrapped === null || Array.isArray(unwrapped)) return {};
|
|
3337
|
+
const record = unwrapped;
|
|
3238
3338
|
const nested = record["regions"];
|
|
3239
3339
|
if (typeof nested === "object" && nested !== null && !Array.isArray(nested)) return nested;
|
|
3240
3340
|
return record;
|
|
3241
3341
|
}
|
|
3242
3342
|
/** One region's stored slot as a plain object; any other shape reads as empty. */
|
|
3243
3343
|
function regionSlotOf(value, region) {
|
|
3244
|
-
const slot = regionsMapOf(value)[region];
|
|
3344
|
+
const slot = unwrapVolatile(regionsMapOf(value)[region]);
|
|
3245
3345
|
return typeof slot === "object" && slot !== null && !Array.isArray(slot) ? slot : {};
|
|
3246
3346
|
}
|
|
3247
3347
|
/**
|
|
@@ -3323,6 +3423,16 @@ function toCredits(snapshot) {
|
|
|
3323
3423
|
accounts
|
|
3324
3424
|
};
|
|
3325
3425
|
}
|
|
3426
|
+
/** Map the check-in answer to the card's compact document. */
|
|
3427
|
+
function toCheckin(status) {
|
|
3428
|
+
return {
|
|
3429
|
+
checkedIn: status.checkedIn,
|
|
3430
|
+
didCheckedIn: status.didCheckedIn,
|
|
3431
|
+
credits: status.credits,
|
|
3432
|
+
enabled: status.enabled,
|
|
3433
|
+
...status.extraCredits === void 0 ? {} : { extraCredits: status.extraCredits }
|
|
3434
|
+
};
|
|
3435
|
+
}
|
|
3326
3436
|
/**
|
|
3327
3437
|
* Assemble one region's card document. `region` is the tab the card is on; the
|
|
3328
3438
|
* region-scoped store already answers with only that region's accounts, so the
|
|
@@ -3389,20 +3499,13 @@ async function traeWebUsage(deps, region) {
|
|
|
3389
3499
|
payStatusError: safeMessage(error)
|
|
3390
3500
|
};
|
|
3391
3501
|
}
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
} catch (error) {
|
|
3400
|
-
return {
|
|
3401
|
-
status: "signed-in",
|
|
3402
|
-
...account,
|
|
3403
|
-
creditsError: safeMessage(error)
|
|
3404
|
-
};
|
|
3405
|
-
}
|
|
3502
|
+
const [snapshotResult, checkinResult] = await Promise.allSettled([client.snapshot(), client.checkinStatus()]);
|
|
3503
|
+
return {
|
|
3504
|
+
status: "signed-in",
|
|
3505
|
+
...account,
|
|
3506
|
+
...snapshotResult.status === "fulfilled" ? { credits: toCredits(snapshotResult.value) } : { creditsError: safeMessage(snapshotResult.reason) },
|
|
3507
|
+
...checkinResult.status === "fulfilled" ? { checkin: toCheckin(checkinResult.value) } : { checkinError: safeMessage(checkinResult.reason) }
|
|
3508
|
+
};
|
|
3406
3509
|
}
|
|
3407
3510
|
/**
|
|
3408
3511
|
* The region a request addresses, or a 400 answer. Absent parameter means the
|
|
@@ -3471,7 +3574,49 @@ function registerTraeUsageRoute(ctx, deps) {
|
|
|
3471
3574
|
}
|
|
3472
3575
|
}
|
|
3473
3576
|
});
|
|
3577
|
+
/**
|
|
3578
|
+
* Daily check-in claim — the ONLY route in this plugin that mutates
|
|
3579
|
+
* upstream account state, so it is guarded more tightly than its siblings:
|
|
3580
|
+
* POST only, loopback origin only, and the status read runs FIRST so an
|
|
3581
|
+
* already-claimed day never reaches the upstream claim at all. The upstream
|
|
3582
|
+
* is idempotent per Beijing day anyway (verified 2026-09-24: a repeat claim
|
|
3583
|
+
* answers `code: 0` with the entitlement total unchanged), but relying on
|
|
3584
|
+
* that for correctness would put the guard in someone else's hands.
|
|
3585
|
+
*/
|
|
3586
|
+
const disposeCheckin = ctx.webServer.register({
|
|
3587
|
+
kind: "exact",
|
|
3588
|
+
path: TRAE_CHECKIN_PATH,
|
|
3589
|
+
handler: async (req, res) => {
|
|
3590
|
+
if (req.method !== "POST") return json(res, 405, { error: "method not allowed" });
|
|
3591
|
+
if (!loopbackOrigin(req)) return json(res, 403, { error: "origin-not-trusted" });
|
|
3592
|
+
const region = requestRegion(req, res);
|
|
3593
|
+
if (region === void 0) return;
|
|
3594
|
+
if (region !== "cn") return json(res, 404, { error: "check-in is not available for the international region" });
|
|
3595
|
+
try {
|
|
3596
|
+
const client = deps.client(region);
|
|
3597
|
+
const current = await client.checkinStatus();
|
|
3598
|
+
if (!current.enabled) return json(res, 409, { error: "check-in is not enabled for this account" });
|
|
3599
|
+
if (current.checkedIn || current.didCheckedIn) return json(res, 200, {
|
|
3600
|
+
claimed: false,
|
|
3601
|
+
alreadyCheckedIn: true,
|
|
3602
|
+
checkin: toCheckin(current)
|
|
3603
|
+
});
|
|
3604
|
+
const claim = await client.claimCheckin();
|
|
3605
|
+
const checkin = await client.checkinStatus();
|
|
3606
|
+
json(res, 200, {
|
|
3607
|
+
claimed: claim.claimed,
|
|
3608
|
+
alreadyCheckedIn: false,
|
|
3609
|
+
code: claim.code,
|
|
3610
|
+
message: claim.message,
|
|
3611
|
+
checkin: toCheckin(checkin)
|
|
3612
|
+
});
|
|
3613
|
+
} catch (error) {
|
|
3614
|
+
json(res, 500, { error: safeMessage(error) });
|
|
3615
|
+
}
|
|
3616
|
+
}
|
|
3617
|
+
});
|
|
3474
3618
|
return () => {
|
|
3619
|
+
disposeCheckin();
|
|
3475
3620
|
disposeRefresh();
|
|
3476
3621
|
disposeAccounts();
|
|
3477
3622
|
disposeUsage();
|
|
@@ -3633,7 +3778,7 @@ const TRAE_SETTINGS_NS = "trae";
|
|
|
3633
3778
|
* picks (the same failure workbuddy fixed with its region split).
|
|
3634
3779
|
*/
|
|
3635
3780
|
function regionStateOf(config, region) {
|
|
3636
|
-
const stored = config.regions?.[region];
|
|
3781
|
+
const stored = unwrapVolatile(unwrapVolatile(config.regions)?.[region]);
|
|
3637
3782
|
if (stored !== void 0) return stored;
|
|
3638
3783
|
if (region !== "cn") return {};
|
|
3639
3784
|
return {
|
|
@@ -3654,6 +3799,29 @@ function regionStateOf(config, region) {
|
|
|
3654
3799
|
function regionEnabled(config, region) {
|
|
3655
3800
|
return regionStateOf(config, region).enabled !== false;
|
|
3656
3801
|
}
|
|
3802
|
+
/**
|
|
3803
|
+
* Mark a schema's field as volatile on the DSH lines that support it.
|
|
3804
|
+
*
|
|
3805
|
+
* `volatile()` exists from schemastery 3.18.3 (the DSH 0.1.7 line, which is the
|
|
3806
|
+
* only line whose settings write gate reads the marker). Older pinning (3.18.2,
|
|
3807
|
+
* the 0.1.5 line) has no such method, and the schema must stay byte-identical
|
|
3808
|
+
* to the unmarked original there: hand-writing `meta.volatile = true` would
|
|
3809
|
+
* bypass schemastery's own `validateVolatileSchema` checks and produce a schema
|
|
3810
|
+
* no 0.1.5 consumer understands — so on that line this degrades to an identity
|
|
3811
|
+
* no-op.
|
|
3812
|
+
*
|
|
3813
|
+
* Without the marker, 0.1.7's settings write gate REJECTS every write with
|
|
3814
|
+
* `Plugin entry "trae" has no volatile fields` while the scope's `set()` still
|
|
3815
|
+
* resolves — so the card would look like it saved and silently revert.
|
|
3816
|
+
*
|
|
3817
|
+
* Exported so BOTH arms are testable on any machine: the capability is decided
|
|
3818
|
+
* by whichever schemastery the dependency tree resolves, so without a seam the
|
|
3819
|
+
* no-op arm would silently stop being exercised the moment the pin moved up.
|
|
3820
|
+
*/
|
|
3821
|
+
function asVolatile(schema) {
|
|
3822
|
+
if (typeof schema.volatile === "function") return schema.volatile();
|
|
3823
|
+
return schema;
|
|
3824
|
+
}
|
|
3657
3825
|
const modelConfig = z.object({
|
|
3658
3826
|
id: z.string().required(),
|
|
3659
3827
|
name: z.string().required(),
|
|
@@ -3675,17 +3843,17 @@ const accountSelectionConfig = z.object({
|
|
|
3675
3843
|
ai: z.string().description("Selected international account id (never a token)")
|
|
3676
3844
|
});
|
|
3677
3845
|
const Config = z.object({
|
|
3678
|
-
authFile: z.string().description("Optional Trae storage.json path override"),
|
|
3679
|
-
edition: z.union([
|
|
3846
|
+
authFile: asVolatile(z.string().description("Optional Trae storage.json path override")),
|
|
3847
|
+
edition: asVolatile(z.union([
|
|
3680
3848
|
"auto",
|
|
3681
3849
|
"cn",
|
|
3682
3850
|
"sg",
|
|
3683
3851
|
"solo",
|
|
3684
3852
|
"solo-sg"
|
|
3685
|
-
]).default("auto").description("Trae edition hint"),
|
|
3853
|
+
]).default("auto").description("Trae edition hint")),
|
|
3686
3854
|
accountId: z.string().description("Deprecated: pre-split account selector, attributed to its own region"),
|
|
3687
|
-
accounts: accountSelectionConfig.description("Per-region account selections, keyed cn | ai"),
|
|
3688
|
-
regions: z.dict(regionStateConfig).default({}).description("Per-region model directory and selection, keyed cn | ai"),
|
|
3855
|
+
accounts: asVolatile(accountSelectionConfig.description("Per-region account selections, keyed cn | ai")),
|
|
3856
|
+
regions: asVolatile(z.dict(regionStateConfig).default({}).description("Per-region model directory and selection, keyed cn | ai")),
|
|
3689
3857
|
lastCatalog: z.array(modelConfig).description("Deprecated: pre-region-split CN model directory"),
|
|
3690
3858
|
enabledModelIds: z.array(z.string()).default([]).description("Deprecated: pre-region-split CN selection"),
|
|
3691
3859
|
contextBudgets: z.dict(z.number().step(1).min(1)).default({}).description("Deprecated: pre-region-split CN context budgets"),
|
|
@@ -3744,7 +3912,7 @@ function apply(ctx, config) {
|
|
|
3744
3912
|
*/
|
|
3745
3913
|
let legacyAccountRegion;
|
|
3746
3914
|
const effectiveAccountFor = (region, value) => {
|
|
3747
|
-
const explicit = value.accounts?.[region];
|
|
3915
|
+
const explicit = unwrapVolatile(value.accounts)?.[region];
|
|
3748
3916
|
if (explicit !== void 0) return explicit;
|
|
3749
3917
|
return legacyAccountRegion === region ? value.accountId : void 0;
|
|
3750
3918
|
};
|
|
@@ -3785,10 +3953,12 @@ function apply(ctx, config) {
|
|
|
3785
3953
|
try {
|
|
3786
3954
|
preferred = (await store.current())?.edition;
|
|
3787
3955
|
} catch {}
|
|
3788
|
-
const
|
|
3789
|
-
|
|
3956
|
+
const authFile = unwrapVolatile(config.authFile);
|
|
3957
|
+
const edition = unwrapVolatile(config.edition);
|
|
3958
|
+
const hint = (edition !== void 0 && edition !== "auto" ? edition : void 0) ?? preferred;
|
|
3959
|
+
return resolveTraeIdentity(authFile === void 0 ? traeStorageCandidates().filter((item) => item.source === "desktop" && (hint !== void 0 ? item.edition === hint : regionOfEdition(item.edition) === region)) : [{
|
|
3790
3960
|
edition: hint ?? (region === "ai" ? "sg" : "solo"),
|
|
3791
|
-
path:
|
|
3961
|
+
path: authFile,
|
|
3792
3962
|
source: "desktop"
|
|
3793
3963
|
}], hint ?? (region === "ai" ? "solo-sg" : "cn"));
|
|
3794
3964
|
};
|
|
@@ -3810,8 +3980,8 @@ function apply(ctx, config) {
|
|
|
3810
3980
|
};
|
|
3811
3981
|
const store = new TraeCredentialStore({
|
|
3812
3982
|
region,
|
|
3813
|
-
...config.authFile === void 0 ? {} : { storagePath: config.authFile },
|
|
3814
|
-
edition: config.edition ?? "auto",
|
|
3983
|
+
...unwrapVolatile(config.authFile) === void 0 ? {} : { storagePath: unwrapVolatile(config.authFile) },
|
|
3984
|
+
edition: unwrapVolatile(config.edition) ?? "auto",
|
|
3815
3985
|
refresh: async (credential) => refreshTraeCredential(credential, void 0, await refreshDeviceSafe())
|
|
3816
3986
|
});
|
|
3817
3987
|
const solo = new TraeSoloUpstreamClient({
|
|
@@ -3866,7 +4036,10 @@ function apply(ctx, config) {
|
|
|
3866
4036
|
catalog,
|
|
3867
4037
|
shim,
|
|
3868
4038
|
delegating,
|
|
3869
|
-
usageClient: new TraeUsageClient({
|
|
4039
|
+
usageClient: new TraeUsageClient({
|
|
4040
|
+
credential: () => store.resolve(),
|
|
4041
|
+
deviceId: async () => (await identity()).deviceId
|
|
4042
|
+
}),
|
|
3870
4043
|
discoverModels: async (signal) => {
|
|
3871
4044
|
const merged = mergeTraeModelSources(await withDirectoryRetry(() => remoteCatalog.fetchModels(signal)), await solo.fetchModels(signal));
|
|
3872
4045
|
wire.callableKeys.clear();
|
|
@@ -3936,7 +4109,7 @@ function apply(ctx, config) {
|
|
|
3936
4109
|
const applySelection = (value) => {
|
|
3937
4110
|
for (const region of REGION_KEYS) {
|
|
3938
4111
|
const stack = stacks[region];
|
|
3939
|
-
stack.store.setSource(value.authFile, value.edition ?? "auto", effectiveAccountFor(region, value));
|
|
4112
|
+
stack.store.setSource(unwrapVolatile(value.authFile), unwrapVolatile(value.edition) ?? "auto", effectiveAccountFor(region, value));
|
|
3940
4113
|
stack.catalog.set(configuredModels(value, region));
|
|
3941
4114
|
stack.invalidateAdapter();
|
|
3942
4115
|
}
|
|
@@ -3965,7 +4138,18 @@ function apply(ctx, config) {
|
|
|
3965
4138
|
const legacyInstallSettingsSection = dshSettings.installSettingsSection;
|
|
3966
4139
|
if (typeof legacyInstallSettingsSection === "function") legacyInstallSettingsSection(ctx, TRAE_SETTINGS_NS, Config, config, sectionHooks);
|
|
3967
4140
|
else ctx.inject(["settings"], (settingsCtx) => {
|
|
3968
|
-
settingsCtx.settings
|
|
4141
|
+
const settings = settingsCtx.settings;
|
|
4142
|
+
if (typeof settings.configure === "function") {
|
|
4143
|
+
settings.configure({ auto: true }, ctx.fiber);
|
|
4144
|
+
return;
|
|
4145
|
+
}
|
|
4146
|
+
if (typeof settings.installSection === "function") {
|
|
4147
|
+
const entry = unwrapVolatileDeep(config);
|
|
4148
|
+
settings.installSection(ctx, TRAE_SETTINGS_NS, Config, entry, sectionHooks);
|
|
4149
|
+
}
|
|
4150
|
+
});
|
|
4151
|
+
ctx.on("loader/volatile-update", () => {
|
|
4152
|
+
applySelection(current());
|
|
3969
4153
|
});
|
|
3970
4154
|
let stopped = false;
|
|
3971
4155
|
ctx.effect(() => () => {
|
|
@@ -4048,4 +4232,4 @@ function apply(ctx, config) {
|
|
|
4048
4232
|
});
|
|
4049
4233
|
}
|
|
4050
4234
|
//#endregion
|
|
4051
|
-
export { Config, FALLBACK_TRAE_MODELS, FALLBACK_TRAE_MODELS_AI, REGION_GATEWAYS, SseDecoder, TRAE_AI_PROVIDER, TRAE_CN_AGENT_TASK_PATH, TRAE_CN_TITLE_PATH, TRAE_MODEL_DETAIL_FUNCTIONS, TRAE_MODEL_DETAIL_PATH, TRAE_PAY_BASE, TRAE_PROVIDER, TRAE_PROVIDERS, TRAE_PROVIDER_DISPLAY_NAMES, TRAE_RAW_CHAT_V1_PATH, TRAE_RAW_CHAT_V2_PATH, TRAE_REASONING_EFFORTS, TRAE_REGIONS, TRAE_REGION_PARAM, TRAE_SETTINGS_NS, TRAE_SOLO_CHAT_PATH, TRAE_SOLO_FUNCTION, TRAE_SOLO_MODELS_PATH, TRAE_SOLO_REMOTE_BASE, TRAE_STREAM_IDLE_TIMEOUT_MS, TRAE_USAGE_PATH, TRAE_VERSION_CODE_FALLBACK, TraeCatalog, TraeCredentialStore, TraeDelegatingUpstreamClient, TraeFallbackUpstreamClient, TraeGatedUpstreamClient, TraeRawCapabilityController, TraeRawCapabilityState, TraeRawChatUpstreamClient, TraeSoloBridge, TraeSoloRemoteCatalogClient, TraeSoloUpstreamClient, TraeUsageClient, UnconfiguredTraeUpstreamClient, apply, applyContextBudgets, applyImageSelection, applyReasoningEffort, bridgeTraeSoloStream, buildTraeAgentTaskBody, buildTraeCnHeaders, buildTraeFusionRawChatEnvelope, buildTraeModelDetailRequest, buildTraeRawChatDraft, buildTraeRawChatRuntimeConfig, classifyTraeRawChatFailure, createTraeAdapter, createTraeRawGateway, createTraeShim, decodeRawChatChunk, decodeTraeEvent, decryptTraeStorageValue, deriveCatalog, discoveredCatalog, fallbackModelsFor, hashTraeRawChatArg, identityHeaders, inject, legacyTraeOwnAuthPath, mergeTraeModelSources, name, nextRegionEnabled, nextRegionSlots, normalizeTraeCredential, normalizeTraeVersionCode, parseObservedModelConfig, parseReasoningCapability, parseTraeAuthValue, parseTraeCachedModel, parseTraeModelExtraConfigLogLine, parseTraeRawChatBehaviorConfig, parseTraeRemoteModel, parseTraeStorageDocument, pickTraeStorageIdentity, prepareSoloBody, probeTraeRawChatCapability, rawCapabilityDiagnostic, rawCapabilityFingerprint, readTraeCachedModel, readTraeCliIdentity, readTraeIdentity, refreshTraeCredential, regionEnabled, regionEnabledOf, regionOfCredential, regionOfEdition, regionOfHost, regionOfTraeProvider, regionOfTraeStatusUrl, regionOfUserRegion, regionStateOf, registerTraeUsageRoute, resolveTraeIdentity, resolveTraeRawRuntime, sanitizeCatalog, traeEndpoint, traeInputModalities, traeModelDisplayName, traeOwnAuthPath, traeRawChatExtraInfo, traeStorageCandidates, traeWebUsage, withTraeRegion };
|
|
4235
|
+
export { Config, FALLBACK_TRAE_MODELS, FALLBACK_TRAE_MODELS_AI, REGION_GATEWAYS, SseDecoder, TRAE_AI_PROVIDER, TRAE_CHECKIN_PATH, TRAE_CN_AGENT_TASK_PATH, TRAE_CN_TITLE_PATH, TRAE_MODEL_DETAIL_FUNCTIONS, TRAE_MODEL_DETAIL_PATH, TRAE_PAY_BASE, TRAE_PROVIDER, TRAE_PROVIDERS, TRAE_PROVIDER_DISPLAY_NAMES, TRAE_RAW_CHAT_V1_PATH, TRAE_RAW_CHAT_V2_PATH, TRAE_REASONING_EFFORTS, TRAE_REGIONS, TRAE_REGION_PARAM, TRAE_SETTINGS_NS, TRAE_SOLO_CHAT_PATH, TRAE_SOLO_FUNCTION, TRAE_SOLO_MODELS_PATH, TRAE_SOLO_REMOTE_BASE, TRAE_STREAM_IDLE_TIMEOUT_MS, TRAE_USAGE_PATH, TRAE_VERSION_CODE_FALLBACK, TraeCatalog, TraeCredentialStore, TraeDelegatingUpstreamClient, TraeFallbackUpstreamClient, TraeGatedUpstreamClient, TraeRawCapabilityController, TraeRawCapabilityState, TraeRawChatUpstreamClient, TraeSoloBridge, TraeSoloRemoteCatalogClient, TraeSoloUpstreamClient, TraeUsageClient, UnconfiguredTraeUpstreamClient, apply, applyContextBudgets, applyImageSelection, applyReasoningEffort, asVolatile, bridgeTraeSoloStream, buildTraeAgentTaskBody, buildTraeCnHeaders, buildTraeFusionRawChatEnvelope, buildTraeModelDetailRequest, buildTraeRawChatDraft, buildTraeRawChatRuntimeConfig, classifyTraeRawChatFailure, createTraeAdapter, createTraeRawGateway, createTraeShim, decodeRawChatChunk, decodeTraeEvent, decryptTraeStorageValue, deriveCatalog, discoveredCatalog, fallbackModelsFor, hashTraeRawChatArg, identityHeaders, inject, legacyTraeOwnAuthPath, mergeTraeModelSources, name, nextRegionEnabled, nextRegionSlots, normalizeTraeCredential, normalizeTraeVersionCode, parseObservedModelConfig, parseReasoningCapability, parseTraeAuthValue, parseTraeCachedModel, parseTraeModelExtraConfigLogLine, parseTraeRawChatBehaviorConfig, parseTraeRemoteModel, parseTraeStorageDocument, pickTraeStorageIdentity, prepareSoloBody, probeTraeRawChatCapability, rawCapabilityDiagnostic, rawCapabilityFingerprint, readTraeCachedModel, readTraeCliIdentity, readTraeIdentity, refreshTraeCredential, regionEnabled, regionEnabledOf, regionOfCredential, regionOfEdition, regionOfHost, regionOfTraeProvider, regionOfTraeStatusUrl, regionOfUserRegion, regionStateOf, registerTraeUsageRoute, resolveTraeIdentity, resolveTraeRawRuntime, sanitizeCatalog, traeEndpoint, traeInputModalities, traeModelDisplayName, traeOwnAuthPath, traeRawChatExtraInfo, traeStorageCandidates, traeWebUsage, unwrapVolatile, unwrapVolatileDeep, withTraeRegion };
|