dsh-codex-subscription 2.2.2 → 2.2.4
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/README.en.md +150 -153
- package/README.md +150 -154
- package/lib/client.js +459 -18
- package/lib/index.js +540 -71
- package/locale/en.json +6 -0
- package/locale/zh-CN.json +6 -0
- package/package.json +4 -2
package/lib/index.js
CHANGED
|
@@ -369,6 +369,54 @@ const PREFERENCE_FIELDS = Object.freeze({
|
|
|
369
369
|
}
|
|
370
370
|
});
|
|
371
371
|
//#endregion
|
|
372
|
+
//#region src/diagnostic-events.js
|
|
373
|
+
const areas$1 = /* @__PURE__ */ new Set([
|
|
374
|
+
"login",
|
|
375
|
+
"model",
|
|
376
|
+
"catalog",
|
|
377
|
+
"quota",
|
|
378
|
+
"quota-reset",
|
|
379
|
+
"search",
|
|
380
|
+
"image"
|
|
381
|
+
]);
|
|
382
|
+
const codes$1 = /* @__PURE__ */ new Set([
|
|
383
|
+
"timeout",
|
|
384
|
+
"dns",
|
|
385
|
+
"tls",
|
|
386
|
+
"connection",
|
|
387
|
+
"network",
|
|
388
|
+
"http-error"
|
|
389
|
+
]);
|
|
390
|
+
/** Process-local bounded evidence. No bodies, URLs, exception strings or identities. */
|
|
391
|
+
function createDiagnosticEvents({ limit = 32, now = Date.now } = {}) {
|
|
392
|
+
const events = [];
|
|
393
|
+
const capacity = Math.max(1, Math.min(128, Number.isInteger(limit) ? limit : 32));
|
|
394
|
+
let dropped = 0, sequence = 0;
|
|
395
|
+
return {
|
|
396
|
+
record(area, value) {
|
|
397
|
+
if (!areas$1.has(area) || !["ok", "failed"].includes(value?.status)) return;
|
|
398
|
+
events.push({
|
|
399
|
+
sequence: ++sequence,
|
|
400
|
+
area,
|
|
401
|
+
status: value.status,
|
|
402
|
+
observedAt: now(),
|
|
403
|
+
...codes$1.has(value.code) ? { code: value.code } : {},
|
|
404
|
+
...Number.isInteger(value.httpStatus) && value.httpStatus >= 100 && value.httpStatus <= 599 ? { httpStatus: value.httpStatus } : {}
|
|
405
|
+
});
|
|
406
|
+
if (events.length > capacity) {
|
|
407
|
+
events.shift();
|
|
408
|
+
dropped++;
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
snapshot: () => ({
|
|
412
|
+
scope: "plugin-process",
|
|
413
|
+
capacity,
|
|
414
|
+
dropped,
|
|
415
|
+
events: events.map((value) => ({ ...value }))
|
|
416
|
+
})
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
//#endregion
|
|
372
420
|
//#region src/oauth-network.js
|
|
373
421
|
const execFileAsync = promisify(execFile);
|
|
374
422
|
const CODEX_AUTH_HOST = "auth.openai.com";
|
|
@@ -612,6 +660,11 @@ const elapsedBucket = (elapsed) => elapsed < 1e3 ? "under-1s" : elapsed < 5e3 ?
|
|
|
612
660
|
function createCodexNetworkTransport(options = {}) {
|
|
613
661
|
const attempts = /* @__PURE__ */ new Map();
|
|
614
662
|
const now = options.now ?? Date.now;
|
|
663
|
+
const evidence = createDiagnosticEvents({ now });
|
|
664
|
+
const remember = (area, value) => {
|
|
665
|
+
attempts.set(area, value);
|
|
666
|
+
evidence.record(area, value);
|
|
667
|
+
};
|
|
615
668
|
const run = async (area, operation, connection = {}) => {
|
|
616
669
|
const startedAt = now();
|
|
617
670
|
let route = attempts.get(area)?.route ?? "direct";
|
|
@@ -625,7 +678,7 @@ function createCodexNetworkTransport(options = {}) {
|
|
|
625
678
|
routed = true;
|
|
626
679
|
}
|
|
627
680
|
});
|
|
628
|
-
if (value instanceof Response && !value.ok)
|
|
681
|
+
if (value instanceof Response && !value.ok) remember(area, {
|
|
629
682
|
status: "failed",
|
|
630
683
|
stage: "http",
|
|
631
684
|
code: "http-error",
|
|
@@ -633,14 +686,14 @@ function createCodexNetworkTransport(options = {}) {
|
|
|
633
686
|
route,
|
|
634
687
|
elapsed: elapsedBucket(now() - startedAt)
|
|
635
688
|
});
|
|
636
|
-
else if (routed || value instanceof Response)
|
|
689
|
+
else if (routed || value instanceof Response) remember(area, {
|
|
637
690
|
status: "ok",
|
|
638
691
|
route,
|
|
639
692
|
elapsed: elapsedBucket(now() - startedAt)
|
|
640
693
|
});
|
|
641
694
|
return value;
|
|
642
695
|
} catch (error) {
|
|
643
|
-
if (routed)
|
|
696
|
+
if (routed) remember(area, {
|
|
644
697
|
status: "failed",
|
|
645
698
|
stage: "transport",
|
|
646
699
|
code: classifyTransportError(error),
|
|
@@ -652,6 +705,7 @@ function createCodexNetworkTransport(options = {}) {
|
|
|
652
705
|
};
|
|
653
706
|
return Object.freeze({
|
|
654
707
|
run,
|
|
708
|
+
history: evidence.snapshot,
|
|
655
709
|
fetch: (area, input, init) => run(area, () => globalThis.fetch(input, init)),
|
|
656
710
|
snapshot: () => Object.fromEntries([...attempts].map(([area, value]) => [area, { ...value }]))
|
|
657
711
|
});
|
|
@@ -1316,6 +1370,21 @@ function createSubagentBackendSwitcher({ entries, prepare, persist }) {
|
|
|
1316
1370
|
backgroundMode: "one-shot",
|
|
1317
1371
|
maxDepth: "provider-managed"
|
|
1318
1372
|
});
|
|
1373
|
+
const ownedFields = [
|
|
1374
|
+
"provider",
|
|
1375
|
+
"modelSelectionSettings",
|
|
1376
|
+
"backgroundMode",
|
|
1377
|
+
"maxDepth"
|
|
1378
|
+
];
|
|
1379
|
+
const restore = (current, original) => {
|
|
1380
|
+
const result = { ...current }, applied = convert(original);
|
|
1381
|
+
for (const key of ownedFields) {
|
|
1382
|
+
if (current[key] !== applied[key]) continue;
|
|
1383
|
+
if (Object.hasOwn(original, key)) result[key] = original[key];
|
|
1384
|
+
else delete result[key];
|
|
1385
|
+
}
|
|
1386
|
+
return result;
|
|
1387
|
+
};
|
|
1319
1388
|
const configure = (fiber, config) => {
|
|
1320
1389
|
if (!standard(fiber.entry, config)) return config;
|
|
1321
1390
|
if (!originals.has(fiber)) originals.set(fiber, { ...config });
|
|
@@ -1345,7 +1414,8 @@ function createSubagentBackendSwitcher({ entries, prepare, persist }) {
|
|
|
1345
1414
|
fiber,
|
|
1346
1415
|
before
|
|
1347
1416
|
});
|
|
1348
|
-
|
|
1417
|
+
if (mode === "codex" && before.provider !== "codex-subscription-subagent") originals.set(fiber, { ...before });
|
|
1418
|
+
await fiber.update(mode === "codex" ? convert(before) : restore(before, original), true);
|
|
1349
1419
|
}
|
|
1350
1420
|
await persist?.(mode);
|
|
1351
1421
|
} catch (error) {
|
|
@@ -1364,7 +1434,7 @@ function createSubagentBackendSwitcher({ entries, prepare, persist }) {
|
|
|
1364
1434
|
await tail.catch(() => {});
|
|
1365
1435
|
disposed = true;
|
|
1366
1436
|
selected = "dsh";
|
|
1367
|
-
for (const [fiber, original] of originals) if (fiber.config?.provider === "codex-subscription-subagent") await fiber.update(original, true);
|
|
1437
|
+
for (const [fiber, original] of originals) if (fiber.config?.provider === "codex-subscription-subagent") await fiber.update(restore(fiber.config, original), true);
|
|
1368
1438
|
originals.clear();
|
|
1369
1439
|
}
|
|
1370
1440
|
};
|
|
@@ -2860,8 +2930,28 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
|
|
|
2860
2930
|
}
|
|
2861
2931
|
Object.freeze(["0.82.1", "0.85.1"]);
|
|
2862
2932
|
//#endregion
|
|
2933
|
+
//#region src/subscription-credentials.js
|
|
2934
|
+
async function readSubscriptionCredentials(getAuth, readCredential, signal) {
|
|
2935
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
2936
|
+
const auth = await getAuth({ signal });
|
|
2937
|
+
signal?.throwIfAborted();
|
|
2938
|
+
if (typeof auth?.auth?.apiKey !== "string" || !auth.auth.apiKey) break;
|
|
2939
|
+
const credential = await readCredential({ signal });
|
|
2940
|
+
signal?.throwIfAborted();
|
|
2941
|
+
if (credential?.type !== "oauth") break;
|
|
2942
|
+
if (credential.access === auth.auth.apiKey) return {
|
|
2943
|
+
access: credential.access,
|
|
2944
|
+
accountId: credential.accountId
|
|
2945
|
+
};
|
|
2946
|
+
}
|
|
2947
|
+
return {
|
|
2948
|
+
access: void 0,
|
|
2949
|
+
accountId: void 0
|
|
2950
|
+
};
|
|
2951
|
+
}
|
|
2952
|
+
//#endregion
|
|
2863
2953
|
//#region src/version.js
|
|
2864
|
-
const PACKAGE_VERSION = "2.2.
|
|
2954
|
+
const PACKAGE_VERSION = "2.2.4";
|
|
2865
2955
|
const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
|
|
2866
2956
|
//#endregion
|
|
2867
2957
|
//#region src/model-catalog.js
|
|
@@ -2986,12 +3076,8 @@ function createOfficialModelCatalog(options = {}) {
|
|
|
2986
3076
|
let timer;
|
|
2987
3077
|
const timeoutError = /* @__PURE__ */ new Error("Codex model catalog refresh timed out");
|
|
2988
3078
|
const work = (async () => {
|
|
2989
|
-
const
|
|
2990
|
-
if (currentGeneration !== generation || requestSignal.aborted) return false;
|
|
2991
|
-
const credential = await options.readCredential({ signal: requestSignal });
|
|
3079
|
+
const { access, accountId } = await readSubscriptionCredentials(options.getAuth, options.readCredential, requestSignal);
|
|
2992
3080
|
if (currentGeneration !== generation || requestSignal.aborted) return false;
|
|
2993
|
-
const access = auth?.auth?.apiKey;
|
|
2994
|
-
const accountId = credential?.type === "oauth" ? credential.accountId : void 0;
|
|
2995
3081
|
if (typeof access !== "string" || access.length === 0 || typeof accountId !== "string" || accountId.length === 0) return false;
|
|
2996
3082
|
const headers = {
|
|
2997
3083
|
authorization: `Bearer ${access}`,
|
|
@@ -3148,10 +3234,7 @@ function createCodexSearchProvider(options) {
|
|
|
3148
3234
|
signal?.throwIfAborted();
|
|
3149
3235
|
const preferences = readCapabilitySettings(options.resolvePreferences?.());
|
|
3150
3236
|
if (preferences.searchMode === "disabled") throw new WebError("Codex search is disabled in subscription settings", "WEB_PROVIDER_UNAVAILABLE");
|
|
3151
|
-
const
|
|
3152
|
-
const credential = await options.readCredential({ signal });
|
|
3153
|
-
const access = auth?.auth?.apiKey;
|
|
3154
|
-
const accountId = credential?.type === "oauth" ? credential.accountId : void 0;
|
|
3237
|
+
const { access, accountId } = await readSubscriptionCredentials(options.getAuth, options.readCredential, signal);
|
|
3155
3238
|
if (typeof access !== "string" || access.length === 0 || typeof accountId !== "string" || accountId.length === 0) throw new WebError("ChatGPT subscription is not signed in", "WEB_PROVIDER_CREDENTIAL_MISSING");
|
|
3156
3239
|
const model = nonEmpty$1(options.resolveModel?.()) ?? DEFAULT_MODEL;
|
|
3157
3240
|
const id = nonEmpty$1(options.resolveSessionId?.()) ?? randomUUID();
|
|
@@ -3662,10 +3745,7 @@ function createCodexImageTool(options) {
|
|
|
3662
3745
|
const prompt = nonEmpty(args.prompt);
|
|
3663
3746
|
if (prompt === void 0) throw new Error("prompt must be a non-empty string");
|
|
3664
3747
|
const imageOptions = normalizeImageOptions(args);
|
|
3665
|
-
const
|
|
3666
|
-
const credential = await options.readCredential({ signal: exec.signal });
|
|
3667
|
-
const access = auth?.auth?.apiKey;
|
|
3668
|
-
const accountId = credential?.type === "oauth" ? credential.accountId : void 0;
|
|
3748
|
+
const { access, accountId } = await readSubscriptionCredentials(options.getAuth, options.readCredential, exec.signal);
|
|
3669
3749
|
if (typeof access !== "string" || access.length === 0 || typeof accountId !== "string" || accountId.length === 0) throw new Error("ChatGPT subscription is not signed in");
|
|
3670
3750
|
if (!attachments.imageLimits.mediaTypes.includes("image/png")) throw new Error("This DSH installation does not accept PNG image attachments");
|
|
3671
3751
|
const maximumBytes = Math.min(attachments.imageLimits.maxImageBytes, attachments.imageLimits.maxMessageImageBytes);
|
|
@@ -3907,6 +3987,272 @@ var OriginalImageStore = class {
|
|
|
3907
3987
|
}
|
|
3908
3988
|
};
|
|
3909
3989
|
//#endregion
|
|
3990
|
+
//#region src/diagnostic-checks.js
|
|
3991
|
+
const states = /* @__PURE__ */ new Set([
|
|
3992
|
+
"pass",
|
|
3993
|
+
"fail",
|
|
3994
|
+
"warn",
|
|
3995
|
+
"unknown",
|
|
3996
|
+
"not-applicable"
|
|
3997
|
+
]);
|
|
3998
|
+
/** Adapters return bounded reason codes, never exceptions or raw service data. */
|
|
3999
|
+
async function collectChecks(definitions, { timeoutMs = 1500, now = Date.now, source = "server", scope = "plugin-process" } = {}) {
|
|
4000
|
+
return Promise.all(definitions.map(async ({ id, capability, run }) => {
|
|
4001
|
+
const startedAt = now();
|
|
4002
|
+
let timer;
|
|
4003
|
+
const controller = new AbortController();
|
|
4004
|
+
const base = {
|
|
4005
|
+
id,
|
|
4006
|
+
capability,
|
|
4007
|
+
source,
|
|
4008
|
+
scope
|
|
4009
|
+
};
|
|
4010
|
+
try {
|
|
4011
|
+
if (!run) return {
|
|
4012
|
+
...base,
|
|
4013
|
+
status: "unknown",
|
|
4014
|
+
reason: "not-instrumented",
|
|
4015
|
+
observedAt: now()
|
|
4016
|
+
};
|
|
4017
|
+
const result = await Promise.race([Promise.resolve().then(() => run(controller.signal)), new Promise((resolve) => {
|
|
4018
|
+
timer = setTimeout(() => {
|
|
4019
|
+
controller.abort();
|
|
4020
|
+
resolve({
|
|
4021
|
+
status: "unknown",
|
|
4022
|
+
reason: "inspection-timeout"
|
|
4023
|
+
});
|
|
4024
|
+
}, timeoutMs);
|
|
4025
|
+
})]);
|
|
4026
|
+
const valid = states.has(result?.status) && /^[a-z][a-z0-9-]{0,63}$/u.test(result?.reason ?? "");
|
|
4027
|
+
return {
|
|
4028
|
+
...base,
|
|
4029
|
+
status: valid ? result.status : "unknown",
|
|
4030
|
+
reason: valid ? result.reason : "invalid-inspection-result",
|
|
4031
|
+
observedAt: now(),
|
|
4032
|
+
elapsedMs: Math.max(0, now() - startedAt)
|
|
4033
|
+
};
|
|
4034
|
+
} catch {
|
|
4035
|
+
return {
|
|
4036
|
+
...base,
|
|
4037
|
+
status: "unknown",
|
|
4038
|
+
reason: "inspection-failed",
|
|
4039
|
+
observedAt: now(),
|
|
4040
|
+
elapsedMs: Math.max(0, now() - startedAt)
|
|
4041
|
+
};
|
|
4042
|
+
} finally {
|
|
4043
|
+
clearTimeout(timer);
|
|
4044
|
+
}
|
|
4045
|
+
}));
|
|
4046
|
+
}
|
|
4047
|
+
const diagnosticCapabilities = Object.freeze([
|
|
4048
|
+
"account",
|
|
4049
|
+
"accounts",
|
|
4050
|
+
"settings",
|
|
4051
|
+
"models",
|
|
4052
|
+
"quota",
|
|
4053
|
+
"search",
|
|
4054
|
+
"images",
|
|
4055
|
+
"sketch",
|
|
4056
|
+
"subagents",
|
|
4057
|
+
"compaction",
|
|
4058
|
+
"transport",
|
|
4059
|
+
"storage",
|
|
4060
|
+
"host-ui"
|
|
4061
|
+
]);
|
|
4062
|
+
const areas = {
|
|
4063
|
+
catalog: "models",
|
|
4064
|
+
quota: "quota",
|
|
4065
|
+
search: "search",
|
|
4066
|
+
image: "images",
|
|
4067
|
+
model: "transport",
|
|
4068
|
+
login: "account",
|
|
4069
|
+
"quota-reset": "quota"
|
|
4070
|
+
};
|
|
4071
|
+
function diagnosticEvidence({ operations, history }, now) {
|
|
4072
|
+
return [...(operations?.events ?? []).map((e) => ({
|
|
4073
|
+
capability: e.capability,
|
|
4074
|
+
action: e.action,
|
|
4075
|
+
source: e.source,
|
|
4076
|
+
status: e.status,
|
|
4077
|
+
observedAt: e.observedAt
|
|
4078
|
+
})), ...(history?.events ?? []).map((e) => ({
|
|
4079
|
+
capability: areas[e.area],
|
|
4080
|
+
action: e.area,
|
|
4081
|
+
source: "network",
|
|
4082
|
+
status: e.status === "ok" ? "completed" : "failed",
|
|
4083
|
+
observedAt: e.observedAt
|
|
4084
|
+
}))].filter((e) => Number.isSafeInteger(e.observedAt) && now >= e.observedAt && now - e.observedAt <= 9e5).sort((a, b) => a.observedAt - b.observedAt);
|
|
4085
|
+
}
|
|
4086
|
+
function unresolvedFailures(events) {
|
|
4087
|
+
const failed = /* @__PURE__ */ new Map();
|
|
4088
|
+
for (const event of events) {
|
|
4089
|
+
const key = `${event.source}:${event.action}`;
|
|
4090
|
+
if (event.status === "failed") failed.set(key, event);
|
|
4091
|
+
else if (event.status === "completed") failed.delete(key);
|
|
4092
|
+
}
|
|
4093
|
+
return [...failed.values()];
|
|
4094
|
+
}
|
|
4095
|
+
//#endregion
|
|
4096
|
+
//#region src/diagnostic-capabilities.js
|
|
4097
|
+
function capabilityCoverage({ account, preference, runtime, catalog, tools, storage, checks, operations, history, now = Date.now() }) {
|
|
4098
|
+
const disabled = {
|
|
4099
|
+
images: preference.imageGeneration === false && preference.imageEditing === false,
|
|
4100
|
+
sketch: preference.imageSketch === false || preference.imageEditing === false,
|
|
4101
|
+
search: preference.searchMode === "disabled",
|
|
4102
|
+
compaction: preference.compactionMode === "dsh",
|
|
4103
|
+
subagents: preference.subagentBackend === "dsh"
|
|
4104
|
+
};
|
|
4105
|
+
const observed = diagnosticEvidence({
|
|
4106
|
+
operations,
|
|
4107
|
+
history
|
|
4108
|
+
}, now);
|
|
4109
|
+
return diagnosticCapabilities.map((id) => {
|
|
4110
|
+
let readiness = "unknown", reason = "no-readiness-check", blockedBy;
|
|
4111
|
+
if (disabled[id]) {
|
|
4112
|
+
readiness = "not-applicable";
|
|
4113
|
+
reason = "disabled-or-host-owned";
|
|
4114
|
+
} else if ([
|
|
4115
|
+
"models",
|
|
4116
|
+
"quota",
|
|
4117
|
+
"search",
|
|
4118
|
+
"images",
|
|
4119
|
+
"compaction"
|
|
4120
|
+
].includes(id) && account.status === "signed-out") {
|
|
4121
|
+
readiness = "warn";
|
|
4122
|
+
reason = "sign-in-required";
|
|
4123
|
+
blockedBy = "account";
|
|
4124
|
+
} else if (id === "account") {
|
|
4125
|
+
readiness = account.status === "signed-in" ? "pass" : "unknown";
|
|
4126
|
+
reason = account.status === "signed-in" ? "local-sign-in-present" : "sign-in-unverified";
|
|
4127
|
+
} else if (id === "settings" && typeof preference.writable === "boolean") {
|
|
4128
|
+
readiness = preference.writable ? "pass" : "warn";
|
|
4129
|
+
reason = preference.writable ? "settings-writable" : "settings-readonly";
|
|
4130
|
+
} else if (id === "subagents" && runtime) {
|
|
4131
|
+
readiness = runtime.installed && !runtime.restartRequired ? "pass" : "warn";
|
|
4132
|
+
reason = runtime.restartRequired ? "restart-required" : runtime.installed ? "runtime-present" : "runtime-missing";
|
|
4133
|
+
} else if (id === "models" && catalog) {
|
|
4134
|
+
readiness = catalog.source === "online" ? "pass" : "warn";
|
|
4135
|
+
reason = catalog.source === "online" ? "catalog-online" : "catalog-fallback";
|
|
4136
|
+
} else if (id === "storage" && storage?.readable) {
|
|
4137
|
+
readiness = "pass";
|
|
4138
|
+
reason = "storage-readable";
|
|
4139
|
+
} else if (tools && (id === "images" || id === "sketch" && preference.imageSketchAgent === true)) {
|
|
4140
|
+
readiness = tools[id] ? "pass" : "warn";
|
|
4141
|
+
reason = tools[id] ? "tool-registered" : "tool-missing";
|
|
4142
|
+
}
|
|
4143
|
+
const evidence = observed.filter((event) => event.capability === id || id === "transport" && event.source === "network");
|
|
4144
|
+
const failures = unresolvedFailures(evidence);
|
|
4145
|
+
const recent = evidence.at(-1);
|
|
4146
|
+
const relatedChecks = checks.filter((check) => check.capability === id || ["images", "sketch"].includes(id) && check.id === "tools");
|
|
4147
|
+
const collectionIssue = relatedChecks.find((check) => ["inspection-failed", "inspection-timeout"].includes(check.reason));
|
|
4148
|
+
if (collectionIssue && readiness === "unknown") reason = collectionIssue.reason;
|
|
4149
|
+
return {
|
|
4150
|
+
id,
|
|
4151
|
+
readiness,
|
|
4152
|
+
reason,
|
|
4153
|
+
...blockedBy ? { blockedBy } : {},
|
|
4154
|
+
checks: relatedChecks.map((check) => check.id),
|
|
4155
|
+
execution: recent ? "observed" : "not-verified",
|
|
4156
|
+
...failures.length ? { unresolved: failures } : {},
|
|
4157
|
+
...recent ? { latest: {
|
|
4158
|
+
action: recent.action,
|
|
4159
|
+
source: recent.source,
|
|
4160
|
+
status: recent.status,
|
|
4161
|
+
observedAt: recent.observedAt
|
|
4162
|
+
} } : {}
|
|
4163
|
+
};
|
|
4164
|
+
});
|
|
4165
|
+
}
|
|
4166
|
+
//#endregion
|
|
4167
|
+
//#region src/diagnostic-operations.js
|
|
4168
|
+
const actions = Object.freeze({
|
|
4169
|
+
"login/start": "account",
|
|
4170
|
+
"login/submit": "account",
|
|
4171
|
+
"login/cancel": "account",
|
|
4172
|
+
logout: "account",
|
|
4173
|
+
"account/select": "accounts",
|
|
4174
|
+
"account/remove": "accounts",
|
|
4175
|
+
"preferences/update": "settings",
|
|
4176
|
+
"account/cleanup": "accounts",
|
|
4177
|
+
usage: "quota",
|
|
4178
|
+
"preferences/models": "models",
|
|
4179
|
+
"storage/status": "storage",
|
|
4180
|
+
"storage/clear-forecast": "storage",
|
|
4181
|
+
"runtime/install": "subagents",
|
|
4182
|
+
"runtime/remove": "subagents",
|
|
4183
|
+
"runtime/cancel": "subagents",
|
|
4184
|
+
codex_image_generate: "images",
|
|
4185
|
+
codex_sketch: "sketch"
|
|
4186
|
+
});
|
|
4187
|
+
function safeOperations(raw) {
|
|
4188
|
+
if (!Array.isArray(raw?.events)) return void 0;
|
|
4189
|
+
return {
|
|
4190
|
+
scope: "plugin-process",
|
|
4191
|
+
capacity: 32,
|
|
4192
|
+
dropped: (Number.isSafeInteger(raw.dropped) && raw.dropped >= 0 ? raw.dropped : 0) + Math.max(0, raw.events.length - 32),
|
|
4193
|
+
events: raw.events.slice(-32).flatMap((value) => {
|
|
4194
|
+
if (!Object.hasOwn(actions, value?.action ?? "") || ![
|
|
4195
|
+
"completed",
|
|
4196
|
+
"failed",
|
|
4197
|
+
"cancelled"
|
|
4198
|
+
].includes(value.status) || !["rpc", "tool"].includes(value.source) || !Number.isSafeInteger(value.observedAt) || value.observedAt < 0) return [];
|
|
4199
|
+
return [{
|
|
4200
|
+
capability: actions[value.action],
|
|
4201
|
+
action: value.action,
|
|
4202
|
+
status: value.status,
|
|
4203
|
+
source: value.source,
|
|
4204
|
+
observedAt: value.observedAt
|
|
4205
|
+
}];
|
|
4206
|
+
})
|
|
4207
|
+
};
|
|
4208
|
+
}
|
|
4209
|
+
function createDiagnosticOperations({ now = Date.now } = {}) {
|
|
4210
|
+
const events = [];
|
|
4211
|
+
let sequence = 0, dropped = 0;
|
|
4212
|
+
const record = (action, status, source = "rpc") => {
|
|
4213
|
+
if (!Object.hasOwn(actions, action) || ![
|
|
4214
|
+
"completed",
|
|
4215
|
+
"failed",
|
|
4216
|
+
"cancelled"
|
|
4217
|
+
].includes(status) || !["rpc", "tool"].includes(source)) return;
|
|
4218
|
+
events.push({
|
|
4219
|
+
sequence: ++sequence,
|
|
4220
|
+
capability: actions[action],
|
|
4221
|
+
action,
|
|
4222
|
+
source,
|
|
4223
|
+
status,
|
|
4224
|
+
observedAt: now()
|
|
4225
|
+
});
|
|
4226
|
+
if (events.length > 32) {
|
|
4227
|
+
events.shift();
|
|
4228
|
+
dropped++;
|
|
4229
|
+
}
|
|
4230
|
+
};
|
|
4231
|
+
return {
|
|
4232
|
+
record,
|
|
4233
|
+
wrap: (handler) => async (endpoint, payload, signal) => {
|
|
4234
|
+
try {
|
|
4235
|
+
const result = await handler(endpoint, payload, signal);
|
|
4236
|
+
record(endpoint, result?.ok === true ? "completed" : "failed");
|
|
4237
|
+
return result;
|
|
4238
|
+
} catch (error) {
|
|
4239
|
+
record(endpoint, signal?.aborted ? "cancelled" : "failed");
|
|
4240
|
+
throw error;
|
|
4241
|
+
}
|
|
4242
|
+
},
|
|
4243
|
+
tool: (exec, result) => {
|
|
4244
|
+
if (!["codex_image_generate", "codex_sketch"].includes(exec?.name)) return;
|
|
4245
|
+
record(exec.name, exec.signal?.aborted ? "cancelled" : result?.isError === true ? "failed" : result?.isError === false ? "completed" : "failed", "tool");
|
|
4246
|
+
},
|
|
4247
|
+
snapshot: () => ({
|
|
4248
|
+
scope: "plugin-process",
|
|
4249
|
+
capacity: 32,
|
|
4250
|
+
dropped,
|
|
4251
|
+
events: events.map((value) => ({ ...value }))
|
|
4252
|
+
})
|
|
4253
|
+
};
|
|
4254
|
+
}
|
|
4255
|
+
//#endregion
|
|
3910
4256
|
//#region src/diagnostics.js
|
|
3911
4257
|
const requestAreas = /* @__PURE__ */ new Set([
|
|
3912
4258
|
"login",
|
|
@@ -3939,6 +4285,26 @@ const elapsedBuckets = /* @__PURE__ */ new Set([
|
|
|
3939
4285
|
"5-15s",
|
|
3940
4286
|
"over-15s"
|
|
3941
4287
|
]);
|
|
4288
|
+
function safeHistory(raw) {
|
|
4289
|
+
if (!raw || !Array.isArray(raw.events)) return void 0;
|
|
4290
|
+
const events = raw.events.slice(-32).flatMap((value) => {
|
|
4291
|
+
if (!value || !requestAreas.has(value.area) || !statuses.has(value.status) || !Number.isSafeInteger(value.sequence) || value.sequence < 1 || !Number.isSafeInteger(value.observedAt) || value.observedAt < 0) return [];
|
|
4292
|
+
return [{
|
|
4293
|
+
area: value.area,
|
|
4294
|
+
status: value.status,
|
|
4295
|
+
sequence: value.sequence,
|
|
4296
|
+
observedAt: value.observedAt,
|
|
4297
|
+
...codes.has(value.code) ? { code: value.code } : {},
|
|
4298
|
+
...Number.isInteger(value.httpStatus) && value.httpStatus >= 100 && value.httpStatus <= 599 ? { httpStatus: value.httpStatus } : {}
|
|
4299
|
+
}];
|
|
4300
|
+
});
|
|
4301
|
+
return {
|
|
4302
|
+
scope: "plugin-process",
|
|
4303
|
+
capacity: 32,
|
|
4304
|
+
dropped: (Number.isSafeInteger(raw.dropped) && raw.dropped >= 0 ? raw.dropped : 0) + Math.max(0, raw.events.length - 32),
|
|
4305
|
+
events
|
|
4306
|
+
};
|
|
4307
|
+
}
|
|
3942
4308
|
function safeRequests(network) {
|
|
3943
4309
|
const raw = network?.snapshot?.() ?? {};
|
|
3944
4310
|
const result = {};
|
|
@@ -3957,17 +4323,113 @@ function safeRequests(network) {
|
|
|
3957
4323
|
return result;
|
|
3958
4324
|
}
|
|
3959
4325
|
/** Build a support report that deliberately excludes OAuth and account metadata. */
|
|
3960
|
-
async function createSubscriptionDiagnostics({ auth, preferences, login = { phase: "idle" }, network, modelCatalog, connection, compaction }) {
|
|
4326
|
+
async function createSubscriptionDiagnostics({ auth, preferences, login = { phase: "idle" }, network, modelCatalog, connection, compaction, inspectionOptions, operations, runtimeManagement, storage, tools }) {
|
|
4327
|
+
const collected = {};
|
|
4328
|
+
const checks = await collectChecks([
|
|
4329
|
+
[
|
|
4330
|
+
"account",
|
|
4331
|
+
"account",
|
|
4332
|
+
() => auth.status()
|
|
4333
|
+
],
|
|
4334
|
+
[
|
|
4335
|
+
"preferences",
|
|
4336
|
+
"settings",
|
|
4337
|
+
() => preferences.status()
|
|
4338
|
+
],
|
|
4339
|
+
[
|
|
4340
|
+
"catalog",
|
|
4341
|
+
"models",
|
|
4342
|
+
() => modelCatalog?.status?.()
|
|
4343
|
+
],
|
|
4344
|
+
[
|
|
4345
|
+
"gaps",
|
|
4346
|
+
"models",
|
|
4347
|
+
() => modelCatalog?.capabilityGaps?.()
|
|
4348
|
+
],
|
|
4349
|
+
[
|
|
4350
|
+
"requests",
|
|
4351
|
+
"transport",
|
|
4352
|
+
() => network?.snapshot ? safeRequests(network) : void 0
|
|
4353
|
+
],
|
|
4354
|
+
[
|
|
4355
|
+
"history",
|
|
4356
|
+
"transport",
|
|
4357
|
+
() => safeHistory(network?.history?.())
|
|
4358
|
+
],
|
|
4359
|
+
[
|
|
4360
|
+
"websocket",
|
|
4361
|
+
"transport",
|
|
4362
|
+
() => connection ? safeCounters(connection, [
|
|
4363
|
+
"requests",
|
|
4364
|
+
"connectionsCreated",
|
|
4365
|
+
"connectionsReused",
|
|
4366
|
+
"deltaRequests",
|
|
4367
|
+
"websocketFailures",
|
|
4368
|
+
"sseFallbacks"
|
|
4369
|
+
]) : void 0
|
|
4370
|
+
],
|
|
4371
|
+
[
|
|
4372
|
+
"compaction",
|
|
4373
|
+
"compaction",
|
|
4374
|
+
() => compaction ? safeCounters(compaction, [
|
|
4375
|
+
"requests",
|
|
4376
|
+
"checkpointsSaved",
|
|
4377
|
+
"checkpointsReused"
|
|
4378
|
+
]) : void 0
|
|
4379
|
+
],
|
|
4380
|
+
[
|
|
4381
|
+
"operations",
|
|
4382
|
+
"transport",
|
|
4383
|
+
() => safeOperations(operations?.snapshot?.())
|
|
4384
|
+
],
|
|
4385
|
+
[
|
|
4386
|
+
"runtime",
|
|
4387
|
+
"subagents",
|
|
4388
|
+
async () => {
|
|
4389
|
+
const value = await runtimeManagement?.status?.();
|
|
4390
|
+
return value ? Object.fromEntries([
|
|
4391
|
+
"available",
|
|
4392
|
+
"installed",
|
|
4393
|
+
"restartRequired"
|
|
4394
|
+
].filter((key) => typeof value[key] === "boolean").map((key) => [key, value[key]])) : void 0;
|
|
4395
|
+
}
|
|
4396
|
+
],
|
|
4397
|
+
[
|
|
4398
|
+
"storage",
|
|
4399
|
+
"storage",
|
|
4400
|
+
async () => typeof storage === "function" ? (await storage(), { readable: true }) : void 0
|
|
4401
|
+
],
|
|
4402
|
+
[
|
|
4403
|
+
"tools",
|
|
4404
|
+
"host-ui",
|
|
4405
|
+
() => typeof tools?.get === "function" ? {
|
|
4406
|
+
images: !!tools.get("codex_image_generate"),
|
|
4407
|
+
sketch: !!tools.get("codex_sketch")
|
|
4408
|
+
} : void 0
|
|
4409
|
+
]
|
|
4410
|
+
].map(([id, capability, read]) => ({
|
|
4411
|
+
id,
|
|
4412
|
+
capability,
|
|
4413
|
+
run: read ? async (signal) => {
|
|
4414
|
+
const value = await read();
|
|
4415
|
+
if (value === void 0) return {
|
|
4416
|
+
status: "unknown",
|
|
4417
|
+
reason: "not-instrumented"
|
|
4418
|
+
};
|
|
4419
|
+
if (!signal.aborted) collected[id] = value;
|
|
4420
|
+
return {
|
|
4421
|
+
status: "pass",
|
|
4422
|
+
reason: "inspection-completed"
|
|
4423
|
+
};
|
|
4424
|
+
} : void 0
|
|
4425
|
+
})), inspectionOptions);
|
|
3961
4426
|
let account = { status: "unknown" };
|
|
3962
4427
|
const issues = [];
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
const preference = preferences.status();
|
|
3969
|
-
const catalog = modelCatalog?.status?.();
|
|
3970
|
-
const gaps = (modelCatalog?.capabilityGaps?.() ?? []).slice(0, 20).flatMap((value) => {
|
|
4428
|
+
if (collected.account) account = { status: collected.account.authenticated === true ? "signed-in" : "signed-out" };
|
|
4429
|
+
else issues.push({ code: "account-status-unavailable" });
|
|
4430
|
+
const preference = collected.preferences ?? {};
|
|
4431
|
+
const catalog = collected.catalog;
|
|
4432
|
+
const gaps = (Array.isArray(collected.gaps) ? collected.gaps : []).slice(0, 20).flatMap((value) => {
|
|
3971
4433
|
if (!value || typeof value.model !== "string" || !/^[a-z][a-z0-9._-]{0,79}$/u.test(value.model)) return [];
|
|
3972
4434
|
const fields = Object.fromEntries([
|
|
3973
4435
|
"reasoning",
|
|
@@ -3985,6 +4447,23 @@ async function createSubscriptionDiagnostics({ auth, preferences, login = { phas
|
|
|
3985
4447
|
if (gaps.length) issues.push({ code: "catalog-capabilities-not-adapted" });
|
|
3986
4448
|
return {
|
|
3987
4449
|
schemaVersion: 3,
|
|
4450
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4451
|
+
inspection: {
|
|
4452
|
+
schemaVersion: 1,
|
|
4453
|
+
meaning: "collection-success-is-not-feature-success",
|
|
4454
|
+
checks,
|
|
4455
|
+
capabilities: capabilityCoverage({
|
|
4456
|
+
account,
|
|
4457
|
+
preference,
|
|
4458
|
+
runtime: collected.runtime,
|
|
4459
|
+
catalog,
|
|
4460
|
+
tools: collected.tools,
|
|
4461
|
+
storage: collected.storage,
|
|
4462
|
+
checks,
|
|
4463
|
+
operations: collected.operations,
|
|
4464
|
+
history: collected.history
|
|
4465
|
+
})
|
|
4466
|
+
},
|
|
3988
4467
|
package: "dsh-codex-subscription",
|
|
3989
4468
|
version: PACKAGE_VERSION,
|
|
3990
4469
|
runtime: {
|
|
@@ -3994,20 +4473,11 @@ async function createSubscriptionDiagnostics({ auth, preferences, login = { phas
|
|
|
3994
4473
|
},
|
|
3995
4474
|
account,
|
|
3996
4475
|
login,
|
|
3997
|
-
requests:
|
|
3998
|
-
...
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
"deltaRequests",
|
|
4003
|
-
"websocketFailures",
|
|
4004
|
-
"sseFallbacks"
|
|
4005
|
-
]) } : {},
|
|
4006
|
-
...compaction ? { compaction: safeCounters(compaction, [
|
|
4007
|
-
"requests",
|
|
4008
|
-
"checkpointsSaved",
|
|
4009
|
-
"checkpointsReused"
|
|
4010
|
-
]) } : {},
|
|
4476
|
+
requests: collected.requests ?? {},
|
|
4477
|
+
...collected.history ? { requestHistory: collected.history } : {},
|
|
4478
|
+
...collected.operations ? { operations: collected.operations } : {},
|
|
4479
|
+
...collected.websocket ? { websocket: collected.websocket } : {},
|
|
4480
|
+
...collected.compaction ? { compaction: collected.compaction } : {},
|
|
4011
4481
|
...catalog && ["fallback", "online"].includes(catalog.source) && [
|
|
4012
4482
|
"idle",
|
|
4013
4483
|
"refreshing",
|
|
@@ -4025,7 +4495,7 @@ async function createSubscriptionDiagnostics({ auth, preferences, login = { phas
|
|
|
4025
4495
|
...typeof preference.outputVerbosity === "string" ? { outputVerbosity: preference.outputVerbosity } : {},
|
|
4026
4496
|
searchProvider: preference.searchProvider,
|
|
4027
4497
|
speedMode: preference.speedMode,
|
|
4028
|
-
writable: preference.writable
|
|
4498
|
+
...typeof preference.writable === "boolean" ? { writable: preference.writable } : {}
|
|
4029
4499
|
},
|
|
4030
4500
|
issues
|
|
4031
4501
|
};
|
|
@@ -4192,10 +4662,7 @@ function createCodexUsageReader(options) {
|
|
|
4192
4662
|
let inFlight;
|
|
4193
4663
|
let generation = 0;
|
|
4194
4664
|
const load = async (signal) => {
|
|
4195
|
-
const
|
|
4196
|
-
const credential = await readCredential({ signal });
|
|
4197
|
-
const access = auth?.auth?.apiKey;
|
|
4198
|
-
const accountId = credential?.type === "oauth" ? credential.accountId : void 0;
|
|
4665
|
+
const { access, accountId } = await readSubscriptionCredentials(getAuth, readCredential, signal);
|
|
4199
4666
|
if (typeof access !== "string" || access.length === 0 || typeof accountId !== "string" || accountId.length === 0) throw new Error("ChatGPT subscription is not signed in");
|
|
4200
4667
|
const response = await fetchUsage(CODEX_USAGE_URL, {
|
|
4201
4668
|
method: "GET",
|
|
@@ -4851,9 +5318,7 @@ const requestSignal = (signal, timeoutMs) => {
|
|
|
4851
5318
|
function safeCopy(value) {
|
|
4852
5319
|
return typeof value === "string" && value.length > 0 ? value.slice(0, MAX_COPY_LENGTH) : void 0;
|
|
4853
5320
|
}
|
|
4854
|
-
function credentialsOf(
|
|
4855
|
-
const access = auth?.auth?.apiKey;
|
|
4856
|
-
const accountId = credential?.type === "oauth" ? credential.accountId : void 0;
|
|
5321
|
+
function credentialsOf({ access, accountId }) {
|
|
4857
5322
|
if (typeof access !== "string" || access.length === 0 || typeof accountId !== "string" || accountId.length === 0) throw new Error("ChatGPT subscription is not signed in");
|
|
4858
5323
|
return {
|
|
4859
5324
|
access,
|
|
@@ -4938,7 +5403,7 @@ function createCodexResetCreditService(options) {
|
|
|
4938
5403
|
...credit.title === void 0 ? {} : { name: credit.title },
|
|
4939
5404
|
...credit.creditExpiresAt === void 0 ? {} : { expiresAt: credit.creditExpiresAt }
|
|
4940
5405
|
});
|
|
4941
|
-
const resolveCredentials = async (signal) => credentialsOf(await getAuth
|
|
5406
|
+
const resolveCredentials = async (signal) => credentialsOf(await readSubscriptionCredentials(getAuth, readCredential, signal));
|
|
4942
5407
|
const readDetails = async (signal, credentials) => {
|
|
4943
5408
|
const { access, accountId } = credentials ?? await resolveCredentials(signal);
|
|
4944
5409
|
const response = await fetchReset(CODEX_RESET_CREDITS_URL, {
|
|
@@ -5129,7 +5594,7 @@ const publicError = (code, message) => ({
|
|
|
5129
5594
|
details: { issues: [] }
|
|
5130
5595
|
}
|
|
5131
5596
|
});
|
|
5132
|
-
function createSubscriptionRpcHandler({ authHandler, usageReader, resetCreditService, preferences, runtimeManagement, diagnosticsReader, modelCatalog, originalImages, resolveInheritedOriginal, closeConnections, onAccountChanged }) {
|
|
5597
|
+
function createSubscriptionRpcHandler({ authHandler, usageReader, resetCreditService, preferences, runtimeManagement, diagnosticsReader, modelCatalog, originalImages, resolveInheritedOriginal, closeConnections, onAccountChanged, onCleanupFailure }) {
|
|
5133
5598
|
return async (endpoint, payload, signal) => {
|
|
5134
5599
|
if (endpoint === "storage/status" || endpoint === "storage/clear-forecast") try {
|
|
5135
5600
|
signal.throwIfAborted();
|
|
@@ -5287,23 +5752,20 @@ function createSubscriptionRpcHandler({ authHandler, usageReader, resetCreditSer
|
|
|
5287
5752
|
return publicError("internal", message);
|
|
5288
5753
|
}
|
|
5289
5754
|
const result = await authHandler(endpoint, payload, signal);
|
|
5290
|
-
if (result.ok === true &&
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
modelCatalog?.clear();
|
|
5305
|
-
onAccountChanged?.();
|
|
5306
|
-
modelCatalog?.refresh({ signal: void 0 }).catch(() => {});
|
|
5755
|
+
if (result.ok === true && (endpoint === "logout" || endpoint === "account/select" || endpoint === "account/remove" || endpoint === "login/status" && result.value?.authenticated === true)) {
|
|
5756
|
+
const tasks = [
|
|
5757
|
+
() => closeConnections?.(),
|
|
5758
|
+
() => usageReader.clearCache(),
|
|
5759
|
+
() => resetCreditService.clear(),
|
|
5760
|
+
() => modelCatalog?.clear(),
|
|
5761
|
+
() => onAccountChanged?.()
|
|
5762
|
+
];
|
|
5763
|
+
if (endpoint === "logout") tasks.push(() => usageReader.clear());
|
|
5764
|
+
if (endpoint === "account/remove" && typeof payload?.id === "string") tasks.push(() => usageReader.clearScope(payload.id));
|
|
5765
|
+
if ((await Promise.allSettled(tasks.map((task) => Promise.resolve().then(task)))).some((value) => value.status === "rejected")) try {
|
|
5766
|
+
onCleanupFailure?.();
|
|
5767
|
+
} catch {}
|
|
5768
|
+
if (endpoint !== "logout") Promise.resolve().then(() => modelCatalog?.refresh({ signal: void 0 })).catch(() => {});
|
|
5307
5769
|
} else if (result.ok === true && (endpoint === "status" || result.value?.authenticated === true)) modelCatalog?.refresh({ signal: void 0 }).catch(() => {});
|
|
5308
5770
|
return result;
|
|
5309
5771
|
};
|
|
@@ -5381,6 +5843,8 @@ function apply(ctx, config = {}) {
|
|
|
5381
5843
|
const settings = createSettingsAdapter(ctx, z.object(settingsFields), config, SETTINGS_NAMESPACE);
|
|
5382
5844
|
const searchProvider = createSearchProviderSwitcher(ctx.loader);
|
|
5383
5845
|
const network = createCodexNetworkTransport();
|
|
5846
|
+
const diagnosticOperations = createDiagnosticOperations();
|
|
5847
|
+
ctx.effect(() => ctx.on?.("tools/result", (exec, result) => diagnosticOperations.tool(exec, result)), "codex-subscription: operation evidence");
|
|
5384
5848
|
const originalImages = new OriginalImageStore();
|
|
5385
5849
|
const accountVault = ACCOUNT_VAULT_KEY !== void 0 && typeof ctx.credentials.readRecord === "function" && typeof ctx.credentials.modifyRecord === "function" && typeof ctx.credentials.deleteRecord === "function" ? new DshOAuthAccountVault(ctx.credentials, {
|
|
5386
5850
|
key: ACCOUNT_VAULT_KEY,
|
|
@@ -5714,14 +6178,19 @@ function apply(ctx, config = {}) {
|
|
|
5714
6178
|
network,
|
|
5715
6179
|
modelCatalog,
|
|
5716
6180
|
connection,
|
|
5717
|
-
compaction
|
|
6181
|
+
compaction,
|
|
6182
|
+
operations: diagnosticOperations,
|
|
6183
|
+
runtimeManagement,
|
|
6184
|
+
storage: () => usageReader.storage(),
|
|
6185
|
+
tools: ctx.tools
|
|
5718
6186
|
}),
|
|
6187
|
+
onCleanupFailure: () => diagnosticOperations.record("account/cleanup", "failed"),
|
|
5719
6188
|
modelCatalog,
|
|
5720
6189
|
closeConnections: () => connection.dispose(),
|
|
5721
6190
|
originalImages,
|
|
5722
6191
|
resolveInheritedOriginal: (sessionId, assetId) => inheritedOriginalImageRef(ctx.get?.("sessions")?.get?.(sessionId), assetId)
|
|
5723
6192
|
});
|
|
5724
|
-
const handler = (endpoint, payload, signal) => endpoint.startsWith("sketch/") ? sketchBridge.rpc(endpoint, payload) : subscriptionHandler(endpoint, payload, signal);
|
|
6193
|
+
const handler = diagnosticOperations.wrap((endpoint, payload, signal) => endpoint.startsWith("sketch/") ? sketchBridge.rpc(endpoint, payload) : subscriptionHandler(endpoint, payload, signal));
|
|
5725
6194
|
ctx.effect(() => {
|
|
5726
6195
|
modelCatalog.refresh().catch((error) => ctx.logger?.debug?.("could not refresh Codex model catalog: %s", error.message));
|
|
5727
6196
|
}, "codex-subscription: official model catalog");
|