@karlorz/codexhost-cli-win32-arm64 0.13.3-1 → 0.13.3-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.md +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/console-web.js +63 -0
- package/app/cpa-live-voice-hook.js +6 -9
- package/app/host-runtime.mjs +372 -205
- package/app/plugins/grok/plugin.mjs +281 -178
- package/app/renderer-extension.js +211 -5
- package/bin/codexhost.exe +0 -0
- package/libexec/codexhost-node-repl.exe +0 -0
- package/libexec/codexhost-shim.exe +0 -0
- package/libexec/codexhost-updater.exe +0 -0
- package/package.json +1 -1
package/app/host-runtime.mjs
CHANGED
|
@@ -22330,7 +22330,7 @@ function retainRendererHostResponses(client, hostId2, target) {
|
|
|
22330
22330
|
if (typeof client.addRequestLifecycleListener !== "function" || typeof target.addEventListener !== "function" || typeof target.removeEventListener !== "function")
|
|
22331
22331
|
return () => {
|
|
22332
22332
|
};
|
|
22333
|
-
const
|
|
22333
|
+
const isRecord21 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
22334
22334
|
const pending = /* @__PURE__ */ new Set();
|
|
22335
22335
|
let retired = false;
|
|
22336
22336
|
let unsubscribe = () => {
|
|
@@ -22346,15 +22346,15 @@ function retainRendererHostResponses(client, hostId2, target) {
|
|
|
22346
22346
|
const ownOrigin = target.location?.origin;
|
|
22347
22347
|
if (source === target && ownOrigin && ownOrigin !== "null" && origin !== ownOrigin)
|
|
22348
22348
|
return;
|
|
22349
|
-
if (!
|
|
22349
|
+
if (!isRecord21(data) || data.type !== "mcp-response" || data.hostId !== hostId2)
|
|
22350
22350
|
return;
|
|
22351
22351
|
const message2 = data.message;
|
|
22352
|
-
if (!
|
|
22352
|
+
if (!isRecord21(message2))
|
|
22353
22353
|
return;
|
|
22354
22354
|
const id2 = message2.id;
|
|
22355
22355
|
if (typeof id2 !== "string" && typeof id2 !== "number" || !pending.has(id2))
|
|
22356
22356
|
return;
|
|
22357
|
-
const hasError =
|
|
22357
|
+
const hasError = isRecord21(message2.error);
|
|
22358
22358
|
if (!hasError && !Object.prototype.hasOwnProperty.call(message2, "result"))
|
|
22359
22359
|
return;
|
|
22360
22360
|
queueMicrotask(() => {
|
|
@@ -22368,7 +22368,7 @@ function retainRendererHostResponses(client, hostId2, target) {
|
|
|
22368
22368
|
};
|
|
22369
22369
|
target.addEventListener("message", receive);
|
|
22370
22370
|
unsubscribe = client.addRequestLifecycleListener((event) => {
|
|
22371
|
-
if (!
|
|
22371
|
+
if (!isRecord21(event) || event.hostId !== hostId2)
|
|
22372
22372
|
return;
|
|
22373
22373
|
const id2 = event.id;
|
|
22374
22374
|
if (typeof id2 !== "string" && typeof id2 !== "number")
|
|
@@ -22398,13 +22398,13 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22398
22398
|
let selectedModel = null;
|
|
22399
22399
|
let prewarmGeneration = 0;
|
|
22400
22400
|
const externalPrewarms = /* @__PURE__ */ new Set();
|
|
22401
|
-
const
|
|
22401
|
+
const isRecord21 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
22402
22402
|
const isUnsupportedPosixBridgeSpawn = (value2) => {
|
|
22403
22403
|
const marker = "AbsolutePathBuf deserialized without a base path";
|
|
22404
22404
|
if (typeof value2 === "string") {
|
|
22405
22405
|
return value2.startsWith("Invalid request:") && value2.includes(marker);
|
|
22406
22406
|
}
|
|
22407
|
-
if (!
|
|
22407
|
+
if (!isRecord21(value2))
|
|
22408
22408
|
return false;
|
|
22409
22409
|
if (typeof value2.message === "string" && value2.message.includes(marker)) {
|
|
22410
22410
|
if (value2.code === -32600 || value2.message.startsWith("Invalid request:"))
|
|
@@ -22497,7 +22497,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22497
22497
|
bridgeState = "idle";
|
|
22498
22498
|
};
|
|
22499
22499
|
const rememberExternalThread = (value2) => {
|
|
22500
|
-
if (!
|
|
22500
|
+
if (!isRecord21(value2) || typeof value2.id !== "string")
|
|
22501
22501
|
return;
|
|
22502
22502
|
if (value2.modelProvider === "codexhost" || value2.cliVersion === "codexhost") {
|
|
22503
22503
|
knownExternalThreadIds.add(value2.id);
|
|
@@ -22505,7 +22505,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22505
22505
|
}
|
|
22506
22506
|
};
|
|
22507
22507
|
const observeBridgeResult = (request, result) => {
|
|
22508
|
-
if (!request || !
|
|
22508
|
+
if (!request || !isRecord21(result))
|
|
22509
22509
|
return;
|
|
22510
22510
|
if (request.method === "thread/list" && Array.isArray(result.data)) {
|
|
22511
22511
|
for (const thread of result.data)
|
|
@@ -22516,7 +22516,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22516
22516
|
rememberExternalThread(result.thread);
|
|
22517
22517
|
return;
|
|
22518
22518
|
}
|
|
22519
|
-
if (request.method === "codexhost/thread/inspect" &&
|
|
22519
|
+
if (request.method === "codexhost/thread/inspect" && isRecord21(request.parameters) && typeof request.parameters.threadId === "string") {
|
|
22520
22520
|
if (result.owner === "external") {
|
|
22521
22521
|
knownExternalThreadIds.add(request.parameters.threadId);
|
|
22522
22522
|
knownOfficialThreadIds.delete(request.parameters.threadId);
|
|
@@ -22526,18 +22526,18 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22526
22526
|
}
|
|
22527
22527
|
return;
|
|
22528
22528
|
}
|
|
22529
|
-
if (request.method === "thread/delete" &&
|
|
22529
|
+
if (request.method === "thread/delete" && isRecord21(request.parameters) && typeof request.parameters.threadId === "string") {
|
|
22530
22530
|
knownExternalThreadIds.delete(request.parameters.threadId);
|
|
22531
22531
|
knownOfficialThreadIds.delete(request.parameters.threadId);
|
|
22532
22532
|
}
|
|
22533
22533
|
};
|
|
22534
22534
|
const handleBridgeFrame = (value2) => {
|
|
22535
|
-
if (!
|
|
22535
|
+
if (!isRecord21(value2)) {
|
|
22536
22536
|
failBridge("received a non-object app-server frame");
|
|
22537
22537
|
return;
|
|
22538
22538
|
}
|
|
22539
22539
|
if (value2.method === bridgeReadyMethod && value2.id === void 0) {
|
|
22540
|
-
if (
|
|
22540
|
+
if (isRecord21(value2.params) && value2.params.protocolVersion === 1) {
|
|
22541
22541
|
bridgeState = "ready";
|
|
22542
22542
|
if (bridgeReadyTimeout !== null)
|
|
22543
22543
|
globalThis.clearTimeout(bridgeReadyTimeout);
|
|
@@ -22551,7 +22551,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22551
22551
|
return;
|
|
22552
22552
|
}
|
|
22553
22553
|
if (typeof value2.method === "string" && value2.id === void 0) {
|
|
22554
|
-
if (value2.method === "thread/started" &&
|
|
22554
|
+
if (value2.method === "thread/started" && isRecord21(value2.params)) {
|
|
22555
22555
|
rememberExternalThread(value2.params.thread);
|
|
22556
22556
|
}
|
|
22557
22557
|
originalOnNotification.call(manager, value2.method, value2.params);
|
|
@@ -22602,13 +22602,13 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22602
22602
|
}
|
|
22603
22603
|
};
|
|
22604
22604
|
const handleOuterNotification = (method, parameters) => {
|
|
22605
|
-
if (method === "process/exited" &&
|
|
22605
|
+
if (method === "process/exited" && isRecord21(parameters) && parameters.processHandle === bridgeProcessHandle) {
|
|
22606
22606
|
const exitCode = typeof parameters.exitCode === "number" ? parameters.exitCode : "unknown";
|
|
22607
22607
|
const stderr = typeof parameters.stderr === "string" ? parameters.stderr.trim() : "";
|
|
22608
22608
|
failBridge(`process exited unexpectedly with code ${exitCode}${stderr ? `: ${stderr}` : ""}`, false);
|
|
22609
22609
|
return true;
|
|
22610
22610
|
}
|
|
22611
|
-
if (method !== "process/outputDelta" || !
|
|
22611
|
+
if (method !== "process/outputDelta" || !isRecord21(parameters) || parameters.processHandle !== bridgeProcessHandle || parameters.stream !== "stdout" && parameters.stream !== "stderr" || typeof parameters.deltaBase64 !== "string") {
|
|
22612
22612
|
return false;
|
|
22613
22613
|
}
|
|
22614
22614
|
if (parameters.capReached === true) {
|
|
@@ -22712,7 +22712,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22712
22712
|
return bridgeInitialization;
|
|
22713
22713
|
};
|
|
22714
22714
|
const threadIdFromParameters = (parameters) => {
|
|
22715
|
-
if (!
|
|
22715
|
+
if (!isRecord21(parameters))
|
|
22716
22716
|
return null;
|
|
22717
22717
|
const value2 = parameters.threadId ?? parameters.conversationId;
|
|
22718
22718
|
return typeof value2 === "string" ? value2 : null;
|
|
@@ -22729,9 +22729,9 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22729
22729
|
const resolution = initializeBridge().then(() => enqueueBridgeRequest("codexhost/thread/ownership/list", {
|
|
22730
22730
|
threadIds: [threadId2]
|
|
22731
22731
|
})).then((value2) => {
|
|
22732
|
-
const ownerships =
|
|
22732
|
+
const ownerships = isRecord21(value2) && Array.isArray(value2.threads) ? value2.threads : null;
|
|
22733
22733
|
const ownership = ownerships?.[0];
|
|
22734
|
-
if (!ownerships || !
|
|
22734
|
+
if (!ownerships || !isRecord21(ownership) || ownerships.length !== 1 || ownership.threadId !== threadId2 || ownership.owner !== "external" && ownership.owner !== "codex") {
|
|
22735
22735
|
throw transportError("Thread ownership lookup returned an invalid result");
|
|
22736
22736
|
}
|
|
22737
22737
|
if (ownership.owner === "external") {
|
|
@@ -22770,7 +22770,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22770
22770
|
if (method === "thread/list")
|
|
22771
22771
|
return true;
|
|
22772
22772
|
if (method === "thread/start") {
|
|
22773
|
-
return
|
|
22773
|
+
return isRecord21(parameters) && typeof parameters.model === "string" && parameters.model.startsWith("codexhost/");
|
|
22774
22774
|
}
|
|
22775
22775
|
const threadId2 = threadIdFromParameters(parameters);
|
|
22776
22776
|
if (threadId2 && knownExternalThreadIds.has(threadId2))
|
|
@@ -22780,7 +22780,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22780
22780
|
return selectedModel !== null && (method.startsWith("thread/") || method.startsWith("turn/") || method.startsWith("review/"));
|
|
22781
22781
|
};
|
|
22782
22782
|
const routeThreadStart = (parameters) => {
|
|
22783
|
-
if (!
|
|
22783
|
+
if (!isRecord21(parameters) || parameters.ephemeral === true) {
|
|
22784
22784
|
return parameters;
|
|
22785
22785
|
}
|
|
22786
22786
|
return {
|
|
@@ -22813,12 +22813,12 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22813
22813
|
return shouldUseBridge(method, routedParameters) ? sendBridged() : sendDirect();
|
|
22814
22814
|
};
|
|
22815
22815
|
const publishDraftWorkspace = (parameters) => {
|
|
22816
|
-
if (!
|
|
22816
|
+
if (!isRecord21(parameters) || parameters.ephemeral === true)
|
|
22817
22817
|
return;
|
|
22818
22818
|
const cwd = parameters.cwd;
|
|
22819
22819
|
if (typeof cwd !== "string" || cwd.length === 0)
|
|
22820
22820
|
return;
|
|
22821
|
-
const drafts =
|
|
22821
|
+
const drafts = isRecord21(target.__codexhostDraftWorkspacesV1) ? target.__codexhostDraftWorkspacesV1 : {};
|
|
22822
22822
|
drafts[hostId2] = cwd;
|
|
22823
22823
|
Object.defineProperty(target, "__codexhostDraftWorkspacesV1", {
|
|
22824
22824
|
configurable: true,
|
|
@@ -22841,16 +22841,16 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22841
22841
|
};
|
|
22842
22842
|
const routedPrewarm = (parameters, options2) => {
|
|
22843
22843
|
const routed = routeThreadStart(parameters);
|
|
22844
|
-
const external =
|
|
22844
|
+
const external = isRecord21(routed) && routed.ephemeral !== true && typeof routed.model === "string" && routed.model.startsWith("codexhost/");
|
|
22845
22845
|
const routedParameters = external ? { ...routed, codexhostPrewarm: true } : routed;
|
|
22846
22846
|
const generation = prewarmGeneration;
|
|
22847
22847
|
publishDraftWorkspace(routedParameters);
|
|
22848
22848
|
const pending = shouldUseBridge("thread/start", routedParameters) ? routedSend("thread/start", routedParameters, options2) : options2 === void 0 ? originalPrewarm.call(bridge, routedParameters) : originalPrewarm.call(bridge, routedParameters, options2);
|
|
22849
|
-
if (
|
|
22849
|
+
if (isRecord21(parameters) && parameters.ephemeral === true || typeof pending !== "object" && typeof pending !== "function" || pending === null || typeof Reflect.get(pending, "then") !== "function") {
|
|
22850
22850
|
return pending;
|
|
22851
22851
|
}
|
|
22852
22852
|
return Promise.resolve(pending).then((result) => {
|
|
22853
|
-
const threadId2 = external &&
|
|
22853
|
+
const threadId2 = external && isRecord21(result) && isRecord21(result.thread) && typeof result.thread.id === "string" ? result.thread.id : null;
|
|
22854
22854
|
if (disposed || generation !== prewarmGeneration) {
|
|
22855
22855
|
if (threadId2)
|
|
22856
22856
|
discardExternalPrewarm(threadId2);
|
|
@@ -22866,7 +22866,7 @@ function createDraftPrewarmPolicyBridge(manager, bridge, hostId2, target, prewar
|
|
|
22866
22866
|
bridge.prewarmThreadStart = routedPrewarm;
|
|
22867
22867
|
const routedWindowMessage = (event) => {
|
|
22868
22868
|
const message2 = event.data;
|
|
22869
|
-
if (!
|
|
22869
|
+
if (!isRecord21(message2) || message2.type !== "mcp-notification" || message2.hostId !== hostId2 || typeof message2.method !== "string") {
|
|
22870
22870
|
return;
|
|
22871
22871
|
}
|
|
22872
22872
|
handleOuterNotification(message2.method, message2.params);
|
|
@@ -23883,6 +23883,15 @@ var voices = /* @__PURE__ */ new Set([
|
|
|
23883
23883
|
"sol",
|
|
23884
23884
|
"cove"
|
|
23885
23885
|
]);
|
|
23886
|
+
function protocolId(value2) {
|
|
23887
|
+
return typeof value2 === "string" && value2.length > 0 && value2.length <= 256 ? value2 : void 0;
|
|
23888
|
+
}
|
|
23889
|
+
function userTurnId(event, turn) {
|
|
23890
|
+
return protocolId(turn.id) ?? protocolId(event.event_id);
|
|
23891
|
+
}
|
|
23892
|
+
function delegationTurnId(event, item) {
|
|
23893
|
+
return protocolId(item.user_bidi_turn_id) ?? protocolId(item.turn_id) ?? protocolId(item.turnId) ?? protocolId(event.turn_id) ?? (object3(event.turn) ? protocolId(event.turn.id) : void 0);
|
|
23894
|
+
}
|
|
23886
23895
|
var ExternalVoice = class {
|
|
23887
23896
|
constructor(options2) {
|
|
23888
23897
|
this.options = options2;
|
|
@@ -23892,7 +23901,7 @@ var ExternalVoice = class {
|
|
|
23892
23901
|
has(threadId2) {
|
|
23893
23902
|
return this.#sessions.has(threadId2);
|
|
23894
23903
|
}
|
|
23895
|
-
async start(threadId2, params) {
|
|
23904
|
+
async start(threadId2, params, conversation) {
|
|
23896
23905
|
if (this.has(threadId2)) throw new Error("This chat already has a voice call");
|
|
23897
23906
|
if (!object3(params.transport) || params.transport.type !== "webrtc" || typeof params.transport.sdp !== "string" || !params.transport.sdp.startsWith("v=0") || params.transport.sdp.length > 256e3 || params.outputModality !== "audio") {
|
|
23898
23907
|
throw new Error("External voice requires the native WebRTC audio call transport");
|
|
@@ -23900,7 +23909,12 @@ var ExternalVoice = class {
|
|
|
23900
23909
|
if (params.voice != null && (typeof params.voice !== "string" || !voices.has(params.voice))) {
|
|
23901
23910
|
throw new Error("Selected voice is unavailable for the external live-call protocol");
|
|
23902
23911
|
}
|
|
23903
|
-
const session = {
|
|
23912
|
+
const session = {
|
|
23913
|
+
controller: new AbortController(),
|
|
23914
|
+
seen: /* @__PURE__ */ new Set(),
|
|
23915
|
+
tasks: /* @__PURE__ */ new Map(),
|
|
23916
|
+
pendingHandles: []
|
|
23917
|
+
};
|
|
23904
23918
|
this.#sessions.set(threadId2, session);
|
|
23905
23919
|
const requireActive = () => {
|
|
23906
23920
|
if (session.controller.signal.aborted || this.#sessions.get(threadId2) !== session)
|
|
@@ -23910,6 +23924,7 @@ var ExternalVoice = class {
|
|
|
23910
23924
|
session.creation = this.options.createCall({
|
|
23911
23925
|
sdp: params.transport.sdp,
|
|
23912
23926
|
...typeof params.voice === "string" ? { voice: params.voice } : {},
|
|
23927
|
+
...conversation && conversation.length > 0 ? { input: conversation } : {},
|
|
23913
23928
|
signal: session.controller.signal,
|
|
23914
23929
|
onEvent: (event) => {
|
|
23915
23930
|
void this.#event(threadId2, session, event).catch(() => this.#fail(threadId2, session));
|
|
@@ -24004,6 +24019,7 @@ var ExternalVoice = class {
|
|
|
24004
24019
|
return;
|
|
24005
24020
|
}
|
|
24006
24021
|
if (event.type === "turn.done" && object3(event.turn)) {
|
|
24022
|
+
const userTask = String(event.turn.role) === "user" && typeof event.turn.transcript === "string" ? this.#registerTask(session, userTurnId(event, event.turn), event.turn.transcript) : void 0;
|
|
24007
24023
|
if (["user", "assistant"].includes(String(event.turn.role)) && typeof event.turn.transcript === "string") {
|
|
24008
24024
|
await this.options.notify("thread/realtime/transcript/done", {
|
|
24009
24025
|
threadId: threadId2,
|
|
@@ -24011,43 +24027,167 @@ var ExternalVoice = class {
|
|
|
24011
24027
|
text: event.turn.transcript
|
|
24012
24028
|
});
|
|
24013
24029
|
}
|
|
24030
|
+
if (userTask) await this.#startTask(threadId2, session, userTask);
|
|
24014
24031
|
return;
|
|
24015
24032
|
}
|
|
24016
24033
|
if (event.type !== "delegation.created" || !object3(event.item)) return;
|
|
24017
24034
|
const item = event.item;
|
|
24018
|
-
|
|
24019
|
-
|
|
24020
|
-
if (session.seen.has(
|
|
24035
|
+
const delegationId = protocolId(item.id);
|
|
24036
|
+
if (item.type !== "delegation" || item.target !== "client" || !delegationId) return;
|
|
24037
|
+
if (session.seen.has(delegationId)) return;
|
|
24021
24038
|
if (session.seen.size >= 512) {
|
|
24022
24039
|
await this.#fail(threadId2, session);
|
|
24023
24040
|
return;
|
|
24024
24041
|
}
|
|
24025
|
-
session.seen.add(
|
|
24026
|
-
const
|
|
24027
|
-
if (
|
|
24028
|
-
|
|
24042
|
+
session.seen.add(delegationId);
|
|
24043
|
+
const turnId = delegationTurnId(event, item);
|
|
24044
|
+
if (turnId) this.#attachHandle(session, turnId, delegationId);
|
|
24045
|
+
const text = Array.isArray(item.content) ? item.content.filter(object3).map(
|
|
24046
|
+
(part) => part.type === "input_text" && typeof part.text === "string" ? part.text : ""
|
|
24047
|
+
).filter(Boolean).join("\n") : "";
|
|
24048
|
+
if (turnId && text) {
|
|
24049
|
+
const task = this.#registerTask(session, turnId, text);
|
|
24050
|
+
if (task) await this.#startTask(threadId2, session, task);
|
|
24051
|
+
}
|
|
24052
|
+
}
|
|
24053
|
+
#attachHandle(session, turnId, delegationId) {
|
|
24054
|
+
const byId = session.tasks.get(turnId);
|
|
24055
|
+
if (byId) {
|
|
24056
|
+
if (!byId.delegationId) {
|
|
24057
|
+
byId.delegationId = delegationId;
|
|
24058
|
+
if (byId.result) this.#speak(session, byId);
|
|
24059
|
+
}
|
|
24060
|
+
return;
|
|
24061
|
+
}
|
|
24062
|
+
if (session.pendingHandles.length < 512)
|
|
24063
|
+
session.pendingHandles.push({ id: delegationId, turnId });
|
|
24064
|
+
}
|
|
24065
|
+
#takePendingHandle(session, task) {
|
|
24066
|
+
if (task.delegationId) return;
|
|
24067
|
+
const byTurn = session.pendingHandles.findIndex((handle2) => handle2.turnId === task.id);
|
|
24068
|
+
if (byTurn < 0) return;
|
|
24069
|
+
const [handle] = session.pendingHandles.splice(byTurn, 1);
|
|
24070
|
+
if (handle) task.delegationId = handle.id;
|
|
24071
|
+
}
|
|
24072
|
+
#registerTask(session, turnId, text) {
|
|
24073
|
+
const transcript = text.trim();
|
|
24074
|
+
if (!transcript || transcript.length > 32e3) return;
|
|
24075
|
+
const id2 = turnId ?? `user-turn:${randomUUID2()}`;
|
|
24076
|
+
if (session.tasks.has(id2) || session.tasks.size >= 512) return;
|
|
24077
|
+
const task = { id: id2, text: transcript };
|
|
24078
|
+
session.tasks.set(id2, task);
|
|
24079
|
+
this.#takePendingHandle(session, task);
|
|
24080
|
+
return task;
|
|
24081
|
+
}
|
|
24082
|
+
async #startTask(threadId2, session, task) {
|
|
24083
|
+
if (session.controller.signal.aborted || this.#sessions.get(threadId2) !== session) return;
|
|
24029
24084
|
let result;
|
|
24030
24085
|
try {
|
|
24031
|
-
result = await this.options.runTask(threadId2, text, session.controller.signal);
|
|
24086
|
+
result = await this.options.runTask(threadId2, task.text, session.controller.signal);
|
|
24032
24087
|
} catch {
|
|
24033
24088
|
result = "The selected agent could not complete this request. No completion is confirmed. Check the chat for its current task status.";
|
|
24034
24089
|
}
|
|
24090
|
+
task.result = result;
|
|
24035
24091
|
if (session.controller.signal.aborted || this.#sessions.get(threadId2) !== session) return;
|
|
24036
|
-
|
|
24092
|
+
this.#speak(session, task);
|
|
24093
|
+
}
|
|
24094
|
+
#speak(session, task) {
|
|
24095
|
+
const result = task.result;
|
|
24037
24096
|
const call = session.call;
|
|
24038
|
-
if (!call) return;
|
|
24097
|
+
if (!result || !call) return;
|
|
24098
|
+
const spokenFor = task.delegationId ?? null;
|
|
24099
|
+
if (task.spokenFor === spokenFor) return;
|
|
24100
|
+
task.spokenFor = spokenFor;
|
|
24101
|
+
const characters = [...result].slice(0, 8e3);
|
|
24102
|
+
const delegationId = task.delegationId;
|
|
24039
24103
|
for (let offset = 0; offset < characters.length; offset += 120) {
|
|
24040
|
-
|
|
24041
|
-
|
|
24042
|
-
|
|
24043
|
-
|
|
24044
|
-
|
|
24045
|
-
|
|
24104
|
+
const chunk = characters.slice(offset, offset + 120).join("");
|
|
24105
|
+
call.send(
|
|
24106
|
+
delegationId ? {
|
|
24107
|
+
type: "delegation.context.append",
|
|
24108
|
+
delegation_item_id: delegationId,
|
|
24109
|
+
channel: "speakable",
|
|
24110
|
+
content: [{ type: "input_text", text: chunk }]
|
|
24111
|
+
} : {
|
|
24112
|
+
type: "session.context.append",
|
|
24113
|
+
content: [{ type: "input_text", text: chunk }]
|
|
24114
|
+
}
|
|
24115
|
+
);
|
|
24046
24116
|
}
|
|
24047
24117
|
}
|
|
24048
24118
|
};
|
|
24049
24119
|
|
|
24120
|
+
// packages/host-runtime/src/external-voice-session-input.ts
|
|
24121
|
+
var MAX_MESSAGES = 32;
|
|
24122
|
+
var MAX_MESSAGE_CHARS = 2e3;
|
|
24123
|
+
var MAX_TOTAL_CHARS = 12e3;
|
|
24124
|
+
function isRecord3(value2) {
|
|
24125
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
24126
|
+
}
|
|
24127
|
+
function userMessageText(item) {
|
|
24128
|
+
if (!Array.isArray(item.content)) return "";
|
|
24129
|
+
return item.content.filter(isRecord3).map((part) => part.type === "text" && typeof part.text === "string" ? part.text.trim() : "").filter((text) => text.length > 0).join("\n");
|
|
24130
|
+
}
|
|
24131
|
+
function clip(text) {
|
|
24132
|
+
return text.length <= MAX_MESSAGE_CHARS ? text : text.slice(0, MAX_MESSAGE_CHARS);
|
|
24133
|
+
}
|
|
24134
|
+
function liveMessage(role, text) {
|
|
24135
|
+
return {
|
|
24136
|
+
type: "message",
|
|
24137
|
+
role,
|
|
24138
|
+
content: [{ type: role === "user" ? "input_text" : "output_text", text: clip(text) }]
|
|
24139
|
+
};
|
|
24140
|
+
}
|
|
24141
|
+
function messageChars(message2) {
|
|
24142
|
+
const content = message2.content;
|
|
24143
|
+
if (!Array.isArray(content) || !isRecord3(content[0]) || typeof content[0].text !== "string") {
|
|
24144
|
+
return 0;
|
|
24145
|
+
}
|
|
24146
|
+
return content[0].text.length;
|
|
24147
|
+
}
|
|
24148
|
+
function voiceSessionInputFromTurns(turns) {
|
|
24149
|
+
const messages = [];
|
|
24150
|
+
for (const turn of turns) {
|
|
24151
|
+
if (!isRecord3(turn) || !Array.isArray(turn.items)) continue;
|
|
24152
|
+
for (const item of turn.items) {
|
|
24153
|
+
if (!isRecord3(item)) continue;
|
|
24154
|
+
if (item.type === "userMessage") {
|
|
24155
|
+
const text = userMessageText(item);
|
|
24156
|
+
if (text) messages.push(liveMessage("user", text));
|
|
24157
|
+
} else if (item.type === "agentMessage" && item.phase !== "commentary") {
|
|
24158
|
+
const text = typeof item.text === "string" ? item.text.trim() : "";
|
|
24159
|
+
if (text) messages.push(liveMessage("assistant", text));
|
|
24160
|
+
}
|
|
24161
|
+
}
|
|
24162
|
+
}
|
|
24163
|
+
const selected = [];
|
|
24164
|
+
let total = 0;
|
|
24165
|
+
for (const message2 of messages.slice(-MAX_MESSAGES).reverse()) {
|
|
24166
|
+
const size = messageChars(message2);
|
|
24167
|
+
if (total + size > MAX_TOTAL_CHARS) break;
|
|
24168
|
+
total += size;
|
|
24169
|
+
selected.push(message2);
|
|
24170
|
+
}
|
|
24171
|
+
return selected.reverse();
|
|
24172
|
+
}
|
|
24173
|
+
|
|
24050
24174
|
// packages/host-runtime/src/external-voice-results.ts
|
|
24175
|
+
function isRecord4(value2) {
|
|
24176
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
24177
|
+
}
|
|
24178
|
+
function speakableFromProjectedTurn(turn) {
|
|
24179
|
+
if (!isRecord4(turn) || !Array.isArray(turn.items)) return void 0;
|
|
24180
|
+
const messages = turn.items.filter(
|
|
24181
|
+
(item) => isRecord4(item) && item.type === "agentMessage" && typeof item.text === "string"
|
|
24182
|
+
);
|
|
24183
|
+
return speakableFromItems(messages);
|
|
24184
|
+
}
|
|
24185
|
+
function speakableFromItems(items) {
|
|
24186
|
+
const values = [...items];
|
|
24187
|
+
const finals = values.filter((item) => item.phase === "final_answer");
|
|
24188
|
+
const text = (finals.length ? finals : values.filter((item) => item.phase !== "commentary").slice(-1)).map((item) => item.text).join("\n").trim();
|
|
24189
|
+
return text.length > 0 ? text : void 0;
|
|
24190
|
+
}
|
|
24051
24191
|
var ExternalVoiceResults = class {
|
|
24052
24192
|
#pending = /* @__PURE__ */ new Map();
|
|
24053
24193
|
watch(threadId2, turnId, signal) {
|
|
@@ -24067,7 +24207,7 @@ var ExternalVoiceResults = class {
|
|
|
24067
24207
|
});
|
|
24068
24208
|
});
|
|
24069
24209
|
}
|
|
24070
|
-
observe(threadId2, event) {
|
|
24210
|
+
observe(threadId2, event, projectedTurn) {
|
|
24071
24211
|
if (event.type === "session.faulted") {
|
|
24072
24212
|
for (const [turnId, pending2] of this.#pending) {
|
|
24073
24213
|
if (pending2.threadId !== threadId2) continue;
|
|
@@ -24080,6 +24220,16 @@ var ExternalVoiceResults = class {
|
|
|
24080
24220
|
if (!("turnId" in event)) return;
|
|
24081
24221
|
const pending = this.#pending.get(event.turnId);
|
|
24082
24222
|
if (!pending || pending.threadId !== threadId2) return;
|
|
24223
|
+
if (event.type === "item.started" && event.item.type === "agentMessage") {
|
|
24224
|
+
pending.items.set(event.item.itemId, {
|
|
24225
|
+
text: event.item.text,
|
|
24226
|
+
...event.item.phase ? { phase: event.item.phase } : {}
|
|
24227
|
+
});
|
|
24228
|
+
}
|
|
24229
|
+
if (event.type === "item.updated" && event.update.type === "text.append") {
|
|
24230
|
+
const item = pending.items.get(event.itemId);
|
|
24231
|
+
if (item) item.text += event.update.text;
|
|
24232
|
+
}
|
|
24083
24233
|
if (event.type === "item.completed" && event.snapshot.item.type === "agentMessage" && event.snapshot.outcome.status === "succeeded") {
|
|
24084
24234
|
const item = event.snapshot.item;
|
|
24085
24235
|
pending.items.set(item.itemId, {
|
|
@@ -24094,9 +24244,7 @@ var ExternalVoiceResults = class {
|
|
|
24094
24244
|
pending.reject(new Error("External agent task did not complete"));
|
|
24095
24245
|
return;
|
|
24096
24246
|
}
|
|
24097
|
-
const
|
|
24098
|
-
const finals = items.filter((item) => item.phase === "final_answer");
|
|
24099
|
-
const text = (finals.length ? finals : items.filter((item) => item.phase !== "commentary").slice(-1)).map((item) => item.text).join("\n").trim();
|
|
24247
|
+
const text = speakableFromItems(pending.items.values()) ?? speakableFromProjectedTurn(projectedTurn);
|
|
24100
24248
|
if (!text) {
|
|
24101
24249
|
pending.reject(new Error("External agent returned no spoken result"));
|
|
24102
24250
|
return;
|
|
@@ -24810,7 +24958,8 @@ function configuredExternalVoiceGateway(environment) {
|
|
|
24810
24958
|
model: typeof config2.experimental_realtime_ws_model === "string" ? config2.experimental_realtime_ws_model : "gpt-realtime",
|
|
24811
24959
|
instructions: "Use natural Hong Kong Cantonese. Delegate every user question and task to the client, including simple arithmetic. The client agent owns all reasoning and task execution. Do not answer questions yourself or invent task results. Speak only verified client results; do not read private reasoning or machine identifiers.",
|
|
24812
24960
|
audio: { output: { voice: input.voice ?? "cove" } },
|
|
24813
|
-
delegation: { type: "client", ack_filler: false }
|
|
24961
|
+
delegation: { type: "client", ack_filler: false },
|
|
24962
|
+
...input.input && input.input.length > 0 ? { initial_items: input.input } : {}
|
|
24814
24963
|
})
|
|
24815
24964
|
);
|
|
24816
24965
|
const response = await fetch(`${url2.href.replace(/\/$/u, "")}/realtime/calls`, {
|
|
@@ -25400,20 +25549,20 @@ var CHECK_EVERY_MS = HOUR_MS;
|
|
|
25400
25549
|
var MISSING_AFTER_MS = 6 * HOUR_MS;
|
|
25401
25550
|
var FETCH_TIMEOUT_MS = 3e4;
|
|
25402
25551
|
var MINIMUM_PRICED_MODELS = 1e3;
|
|
25403
|
-
function
|
|
25552
|
+
function isRecord5(value2) {
|
|
25404
25553
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
25405
25554
|
}
|
|
25406
25555
|
function price(value2) {
|
|
25407
25556
|
return typeof value2 === "number" && Number.isFinite(value2) && value2 >= 0 ? value2 : null;
|
|
25408
25557
|
}
|
|
25409
25558
|
function compactModelsDev(api) {
|
|
25410
|
-
if (!
|
|
25559
|
+
if (!isRecord5(api)) throw new Error("models.dev catalog must be an object");
|
|
25411
25560
|
const providers = {};
|
|
25412
25561
|
let count2 = 0;
|
|
25413
25562
|
for (const [providerId, provider] of Object.entries(api)) {
|
|
25414
|
-
if (!
|
|
25563
|
+
if (!isRecord5(provider) || !isRecord5(provider.models)) continue;
|
|
25415
25564
|
for (const [modelId, model2] of Object.entries(provider.models)) {
|
|
25416
|
-
if (!
|
|
25565
|
+
if (!isRecord5(model2) || !isRecord5(model2.cost)) continue;
|
|
25417
25566
|
const input = price(model2.cost.input);
|
|
25418
25567
|
const output = price(model2.cost.output);
|
|
25419
25568
|
if (input === null || output === null) continue;
|
|
@@ -25440,22 +25589,22 @@ function isEntry(value2) {
|
|
|
25440
25589
|
return value2.length < 5 || value2[4] === true || typeof value2[4] === "string";
|
|
25441
25590
|
}
|
|
25442
25591
|
function parseModelPriceTable(value2) {
|
|
25443
|
-
if (!
|
|
25592
|
+
if (!isRecord5(value2) || !isRecord5(value2.providers)) return null;
|
|
25444
25593
|
if (typeof value2.fetchedAtMs !== "number" || !Number.isSafeInteger(value2.fetchedAtMs)) {
|
|
25445
25594
|
return null;
|
|
25446
25595
|
}
|
|
25447
25596
|
for (const models of Object.values(value2.providers)) {
|
|
25448
|
-
if (!
|
|
25597
|
+
if (!isRecord5(models) || !Object.values(models).every(isEntry)) return null;
|
|
25449
25598
|
}
|
|
25450
25599
|
return value2;
|
|
25451
25600
|
}
|
|
25452
25601
|
function parseModelPriceOverrides(value2) {
|
|
25453
|
-
if (!
|
|
25602
|
+
if (!isRecord5(value2) || !isRecord5(value2.models)) {
|
|
25454
25603
|
throw new Error("Price overrides must contain a 'models' object");
|
|
25455
25604
|
}
|
|
25456
25605
|
const overrides = /* @__PURE__ */ new Map();
|
|
25457
25606
|
for (const [key, entry] of Object.entries(value2.models)) {
|
|
25458
|
-
if (key.length === 0 || !
|
|
25607
|
+
if (key.length === 0 || !isRecord5(entry)) {
|
|
25459
25608
|
throw new Error(`Price override '${key}' is invalid`);
|
|
25460
25609
|
}
|
|
25461
25610
|
for (const field of Object.keys(entry)) {
|
|
@@ -25811,7 +25960,7 @@ var ModelPriceCatalog = class {
|
|
|
25811
25960
|
function errorMessage2(error51) {
|
|
25812
25961
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
25813
25962
|
}
|
|
25814
|
-
function
|
|
25963
|
+
function isRecord6(value2) {
|
|
25815
25964
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
25816
25965
|
}
|
|
25817
25966
|
async function readDocument(file2) {
|
|
@@ -25852,7 +26001,7 @@ async function updateModelPriceOverridesFile(file2, change) {
|
|
|
25852
26001
|
);
|
|
25853
26002
|
}
|
|
25854
26003
|
const document = current.document ?? { models: {} };
|
|
25855
|
-
const models =
|
|
26004
|
+
const models = isRecord6(document.models) ? document.models : {};
|
|
25856
26005
|
const { key, price: price2, previousKey } = change;
|
|
25857
26006
|
if (previousKey !== void 0 && !Object.hasOwn(models, previousKey)) {
|
|
25858
26007
|
throw new ModelPriceOverridesError(`Custom price '${previousKey}' no longer exists`);
|
|
@@ -26118,7 +26267,7 @@ function rewriteDelegationMentionText(text) {
|
|
|
26118
26267
|
const { text: stripped, mentions } = stripDelegationMentions(text);
|
|
26119
26268
|
return mentions.length === 0 ? text : appendInstruction(stripped, mentions);
|
|
26120
26269
|
}
|
|
26121
|
-
function
|
|
26270
|
+
function isRecord7(value2) {
|
|
26122
26271
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
26123
26272
|
}
|
|
26124
26273
|
function rewriteDelegationMentionInput(input, skill) {
|
|
@@ -26126,7 +26275,7 @@ function rewriteDelegationMentionInput(input, skill) {
|
|
|
26126
26275
|
const seen = /* @__PURE__ */ new Set();
|
|
26127
26276
|
let lastTextIndex = -1;
|
|
26128
26277
|
const rewritten = input.map((item, index) => {
|
|
26129
|
-
if (!
|
|
26278
|
+
if (!isRecord7(item) || item.type !== "text" || typeof item.text !== "string") return item;
|
|
26130
26279
|
lastTextIndex = index;
|
|
26131
26280
|
const result = stripDelegationMentions(item.text);
|
|
26132
26281
|
for (const mention of result.mentions) {
|
|
@@ -26138,14 +26287,14 @@ function rewriteDelegationMentionInput(input, skill) {
|
|
|
26138
26287
|
});
|
|
26139
26288
|
if (mentions.length === 0) return null;
|
|
26140
26289
|
const target = rewritten[lastTextIndex];
|
|
26141
|
-
if (
|
|
26290
|
+
if (isRecord7(target) && typeof target.text === "string") {
|
|
26142
26291
|
rewritten[lastTextIndex] = {
|
|
26143
26292
|
...target,
|
|
26144
26293
|
text: appendInstruction(target.text, mentions)
|
|
26145
26294
|
};
|
|
26146
26295
|
}
|
|
26147
26296
|
const hasSkill = rewritten.some(
|
|
26148
|
-
(item) =>
|
|
26297
|
+
(item) => isRecord7(item) && item.type === "skill" && item.name === skill?.name
|
|
26149
26298
|
);
|
|
26150
26299
|
if (skill && !hasSkill) rewritten.push({ type: "skill", name: skill.name, path: skill.path });
|
|
26151
26300
|
return rewritten;
|
|
@@ -26251,11 +26400,11 @@ var usageFields = /* @__PURE__ */ new Set([
|
|
|
26251
26400
|
"costSource",
|
|
26252
26401
|
"unpricedModels"
|
|
26253
26402
|
]);
|
|
26254
|
-
function
|
|
26403
|
+
function isRecord8(value2) {
|
|
26255
26404
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
26256
26405
|
}
|
|
26257
26406
|
function parseHostUsage(value2) {
|
|
26258
|
-
if (!
|
|
26407
|
+
if (!isRecord8(value2))
|
|
26259
26408
|
throw new Error("Harness Usage must be an object");
|
|
26260
26409
|
const keys = Object.keys(value2);
|
|
26261
26410
|
if (keys.length === 0)
|
|
@@ -26301,7 +26450,7 @@ function parseHostUsage(value2) {
|
|
|
26301
26450
|
}
|
|
26302
26451
|
if (value2.sessionCacheUsage !== void 0) {
|
|
26303
26452
|
const totals2 = value2.sessionCacheUsage;
|
|
26304
|
-
if (!
|
|
26453
|
+
if (!isRecord8(totals2) || Object.keys(totals2).some((key) => key !== "inputTokens" && key !== "cachedInputTokens") || typeof totals2.inputTokens !== "number" || !Number.isSafeInteger(totals2.inputTokens) || totals2.inputTokens < 0 || typeof totals2.cachedInputTokens !== "number" || !Number.isSafeInteger(totals2.cachedInputTokens) || totals2.cachedInputTokens < 0 || totals2.cachedInputTokens > totals2.inputTokens) {
|
|
26305
26454
|
throw new Error("Harness Usage 'sessionCacheUsage' must contain complete bounded token totals");
|
|
26306
26455
|
}
|
|
26307
26456
|
}
|
|
@@ -26357,7 +26506,7 @@ var requestFields = /* @__PURE__ */ new Set([
|
|
|
26357
26506
|
"provider"
|
|
26358
26507
|
]);
|
|
26359
26508
|
function parseHostUsageRequest(value2) {
|
|
26360
|
-
if (!
|
|
26509
|
+
if (!isRecord8(value2))
|
|
26361
26510
|
throw new Error("Harness Usage request must be an object");
|
|
26362
26511
|
for (const key of Object.keys(value2)) {
|
|
26363
26512
|
if (!requestFields.has(key)) {
|
|
@@ -27764,7 +27913,7 @@ var TITLE_MAX_LENGTH = 150;
|
|
|
27764
27913
|
var DESCRIPTION_MAX_LENGTH = 500;
|
|
27765
27914
|
var SERVER_NAME_MAX_LENGTH = 80;
|
|
27766
27915
|
var ELLIPSIS = "…";
|
|
27767
|
-
function
|
|
27916
|
+
function isRecord9(value2) {
|
|
27768
27917
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
27769
27918
|
}
|
|
27770
27919
|
function boundedText(value2, field, maxLength) {
|
|
@@ -27818,7 +27967,7 @@ function responseError(message2) {
|
|
|
27818
27967
|
function responsePersist(value2) {
|
|
27819
27968
|
if (value2 === void 0 || value2 === null)
|
|
27820
27969
|
return null;
|
|
27821
|
-
if (!
|
|
27970
|
+
if (!isRecord9(value2) || Object.keys(value2).length !== 1 || value2.persist !== "session" && value2.persist !== "always") {
|
|
27822
27971
|
throw responseError("contains malformed persist metadata");
|
|
27823
27972
|
}
|
|
27824
27973
|
return value2.persist;
|
|
@@ -27864,7 +28013,7 @@ function projectCodexApprovalRequest(input) {
|
|
|
27864
28013
|
},
|
|
27865
28014
|
denyResponse,
|
|
27866
28015
|
parseResponse(result) {
|
|
27867
|
-
if (!
|
|
28016
|
+
if (!isRecord9(result) || typeof result.action !== "string") {
|
|
27868
28017
|
throw responseError("missing action");
|
|
27869
28018
|
}
|
|
27870
28019
|
if (Object.keys(result).some((key) => key !== "action" && key !== "content" && key !== "_meta")) {
|
|
@@ -27872,7 +28021,7 @@ function projectCodexApprovalRequest(input) {
|
|
|
27872
28021
|
}
|
|
27873
28022
|
const selectedPersist = responsePersist(result._meta);
|
|
27874
28023
|
if (result.action === "accept") {
|
|
27875
|
-
if ("content" in result && (!
|
|
28024
|
+
if ("content" in result && (!isRecord9(result.content) || Object.keys(result.content).length !== 0)) {
|
|
27876
28025
|
throw responseError("contains non-empty accepted content");
|
|
27877
28026
|
}
|
|
27878
28027
|
if (selectedPersist === "session") {
|
|
@@ -27932,7 +28081,7 @@ function projectApprovalChoices(input) {
|
|
|
27932
28081
|
},
|
|
27933
28082
|
denyResponse,
|
|
27934
28083
|
parseResponse(result) {
|
|
27935
|
-
if (!
|
|
28084
|
+
if (!isRecord9(result) || typeof result.action !== "string")
|
|
27936
28085
|
throw responseError("missing action");
|
|
27937
28086
|
if (Object.keys(result).some((key) => !["action", "content", "_meta"].includes(key))) {
|
|
27938
28087
|
throw responseError("contains unreviewed fields");
|
|
@@ -27947,7 +28096,7 @@ function projectApprovalChoices(input) {
|
|
|
27947
28096
|
return denyResponse;
|
|
27948
28097
|
}
|
|
27949
28098
|
const content = result.content;
|
|
27950
|
-
if (result.action !== "accept" || !
|
|
28099
|
+
if (result.action !== "accept" || !isRecord9(content) || Object.keys(content).length !== 1 || !interaction.actions.some(({ id: id2 }) => id2 === content.actionId)) {
|
|
27951
28100
|
throw responseError("contains an undeclared approval choice");
|
|
27952
28101
|
}
|
|
27953
28102
|
return { type: "approval", actionId: content.actionId };
|
|
@@ -27956,7 +28105,7 @@ function projectApprovalChoices(input) {
|
|
|
27956
28105
|
}
|
|
27957
28106
|
|
|
27958
28107
|
// packages/protocol-core/dist/codex-question.js
|
|
27959
|
-
function
|
|
28108
|
+
function isRecord10(value2) {
|
|
27960
28109
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
27961
28110
|
}
|
|
27962
28111
|
function responseError2(message2) {
|
|
@@ -28025,7 +28174,7 @@ function projectCodexQuestionRequest(input) {
|
|
|
28025
28174
|
}
|
|
28026
28175
|
},
|
|
28027
28176
|
parseResponse(result) {
|
|
28028
|
-
if (!
|
|
28177
|
+
if (!isRecord10(result) || !isRecord10(result.answers)) {
|
|
28029
28178
|
throw responseError2("missing answers object");
|
|
28030
28179
|
}
|
|
28031
28180
|
const rawAnswers = result.answers;
|
|
@@ -28038,7 +28187,7 @@ function projectCodexQuestionRequest(input) {
|
|
|
28038
28187
|
const question = interaction.questions.find(({ id: id2 }) => id2 === questionId);
|
|
28039
28188
|
if (!question)
|
|
28040
28189
|
throw responseError2("contains an unknown Question ID");
|
|
28041
|
-
if (!
|
|
28190
|
+
if (!isRecord10(answerValue) || !Array.isArray(answerValue.answers)) {
|
|
28042
28191
|
throw responseError2("answer entry has no answers array");
|
|
28043
28192
|
}
|
|
28044
28193
|
const values = answerValue.answers;
|
|
@@ -28120,7 +28269,7 @@ function projectCodexThreadUsage(input) {
|
|
|
28120
28269
|
}
|
|
28121
28270
|
|
|
28122
28271
|
// packages/protocol-core/dist/codex-native-usage.js
|
|
28123
|
-
function
|
|
28272
|
+
function isRecord11(value2) {
|
|
28124
28273
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
28125
28274
|
}
|
|
28126
28275
|
function nonNegativeSafeInteger(value2) {
|
|
@@ -28133,7 +28282,7 @@ function optionalReset(value2) {
|
|
|
28133
28282
|
return nonNegativeSafeInteger(value2);
|
|
28134
28283
|
}
|
|
28135
28284
|
function parseRateLimitWindow(value2) {
|
|
28136
|
-
if (!
|
|
28285
|
+
if (!isRecord11(value2))
|
|
28137
28286
|
return null;
|
|
28138
28287
|
const usedPercent = finitePercent(value2.usedPercent);
|
|
28139
28288
|
const windowDurationMins = nonNegativeSafeInteger(value2.windowDurationMins);
|
|
@@ -28144,7 +28293,7 @@ function parseRateLimitWindow(value2) {
|
|
|
28144
28293
|
return { usedPercent, windowDurationMins, ...resetsAt !== void 0 ? { resetsAt } : {} };
|
|
28145
28294
|
}
|
|
28146
28295
|
function parseRateLimitCandidate(value2, options2 = {}) {
|
|
28147
|
-
if (!
|
|
28296
|
+
if (!isRecord11(value2))
|
|
28148
28297
|
return null;
|
|
28149
28298
|
if (options2.genericOnly && value2.limitId !== void 0 && value2.limitId !== null && value2.limitId !== "codex") {
|
|
28150
28299
|
return null;
|
|
@@ -28154,16 +28303,16 @@ function parseRateLimitCandidate(value2, options2 = {}) {
|
|
|
28154
28303
|
return primary || secondary ? { primary, secondary } : null;
|
|
28155
28304
|
}
|
|
28156
28305
|
function rateLimitCandidates(value2) {
|
|
28157
|
-
if (!
|
|
28306
|
+
if (!isRecord11(value2))
|
|
28158
28307
|
return [];
|
|
28159
|
-
const result =
|
|
28160
|
-
if (!
|
|
28308
|
+
const result = isRecord11(value2.result) ? value2.result : value2;
|
|
28309
|
+
if (!isRecord11(result))
|
|
28161
28310
|
return [];
|
|
28162
28311
|
const candidates = [];
|
|
28163
28312
|
const base = parseRateLimitCandidate(result.rateLimits, { genericOnly: true });
|
|
28164
28313
|
if (base)
|
|
28165
28314
|
candidates.push(base);
|
|
28166
|
-
const notificationParams =
|
|
28315
|
+
const notificationParams = isRecord11(value2.params) ? value2.params : void 0;
|
|
28167
28316
|
const notificationSnapshot = parseRateLimitCandidate(notificationParams?.rateLimits, {
|
|
28168
28317
|
genericOnly: true
|
|
28169
28318
|
});
|
|
@@ -28207,14 +28356,14 @@ function parseAvailableCount(value2) {
|
|
|
28207
28356
|
return void 0;
|
|
28208
28357
|
}
|
|
28209
28358
|
function rateLimitResetCreditsSummary(value2) {
|
|
28210
|
-
if (!
|
|
28359
|
+
if (!isRecord11(value2))
|
|
28211
28360
|
return null;
|
|
28212
|
-
const result =
|
|
28213
|
-
const fromResult =
|
|
28361
|
+
const result = isRecord11(value2.result) ? value2.result : value2;
|
|
28362
|
+
const fromResult = isRecord11(result) && isRecord11(result.rateLimitResetCredits) ? result.rateLimitResetCredits : null;
|
|
28214
28363
|
if (fromResult)
|
|
28215
28364
|
return fromResult;
|
|
28216
|
-
const params =
|
|
28217
|
-
return
|
|
28365
|
+
const params = isRecord11(value2.params) ? value2.params : void 0;
|
|
28366
|
+
return isRecord11(params?.rateLimitResetCredits) ? params.rateLimitResetCredits : null;
|
|
28218
28367
|
}
|
|
28219
28368
|
function observeCodexRateLimitResetCredits(value2) {
|
|
28220
28369
|
const summary = rateLimitResetCreditsSummary(value2);
|
|
@@ -28226,7 +28375,7 @@ function observeCodexRateLimitResetCredits(value2) {
|
|
|
28226
28375
|
const expiresAtUnix = [];
|
|
28227
28376
|
if (Array.isArray(summary.credits)) {
|
|
28228
28377
|
for (const credit of summary.credits) {
|
|
28229
|
-
if (!
|
|
28378
|
+
if (!isRecord11(credit))
|
|
28230
28379
|
continue;
|
|
28231
28380
|
if (credit.status !== void 0 && credit.status !== "available")
|
|
28232
28381
|
continue;
|
|
@@ -28985,11 +29134,11 @@ function itemStatus(outcome) {
|
|
|
28985
29134
|
return "inProgress";
|
|
28986
29135
|
return outcome.status === "succeeded" ? "completed" : "failed";
|
|
28987
29136
|
}
|
|
28988
|
-
function
|
|
29137
|
+
function isRecord12(value2) {
|
|
28989
29138
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
28990
29139
|
}
|
|
28991
29140
|
function nestedString(value2, keys, preserveText = false) {
|
|
28992
|
-
if (!
|
|
29141
|
+
if (!isRecord12(value2))
|
|
28993
29142
|
return void 0;
|
|
28994
29143
|
for (const key of keys) {
|
|
28995
29144
|
const field = value2[key];
|
|
@@ -29152,7 +29301,7 @@ function planFromTodoValue(value2) {
|
|
|
29152
29301
|
const record4 = unwrapToolRecord(value2);
|
|
29153
29302
|
if (!record4)
|
|
29154
29303
|
return planFromChecklistText(typeof value2 === "string" ? value2 : null);
|
|
29155
|
-
if (
|
|
29304
|
+
if (isRecord12(record4.TodosUpdated)) {
|
|
29156
29305
|
const nested = planFromTodoValue(record4.TodosUpdated);
|
|
29157
29306
|
if (nested)
|
|
29158
29307
|
return nested;
|
|
@@ -29167,7 +29316,7 @@ function planFromTodoValue(value2) {
|
|
|
29167
29316
|
plan.push({ step: entry.trim(), status: "pending" });
|
|
29168
29317
|
continue;
|
|
29169
29318
|
}
|
|
29170
|
-
if (!
|
|
29319
|
+
if (!isRecord12(entry))
|
|
29171
29320
|
continue;
|
|
29172
29321
|
const step = nestedString(entry, ["content", "step", "text", "title", "description", "task"]);
|
|
29173
29322
|
if (!step)
|
|
@@ -29222,7 +29371,7 @@ function unwrapToolRecord(value2) {
|
|
|
29222
29371
|
}
|
|
29223
29372
|
if (Array.isArray(value2))
|
|
29224
29373
|
return { todos: value2 };
|
|
29225
|
-
if (!
|
|
29374
|
+
if (!isRecord12(value2))
|
|
29226
29375
|
return null;
|
|
29227
29376
|
for (const wrapper of ["input", "arguments", "params"]) {
|
|
29228
29377
|
if (value2[wrapper] === void 0)
|
|
@@ -29339,6 +29488,18 @@ function projectItem(item, outcome, defaultCwd, includeCommandOutput = true, sen
|
|
|
29339
29488
|
changes: projectFileChanges(item.changes),
|
|
29340
29489
|
status: itemStatus(outcome)
|
|
29341
29490
|
};
|
|
29491
|
+
case "generatedImage":
|
|
29492
|
+
return {
|
|
29493
|
+
id: item.itemId,
|
|
29494
|
+
type: "imageGeneration",
|
|
29495
|
+
status: itemStatus(outcome),
|
|
29496
|
+
savedPath: item.savedPath,
|
|
29497
|
+
result: "",
|
|
29498
|
+
revisedPrompt: item.revisedPrompt ?? null,
|
|
29499
|
+
inputImages: [],
|
|
29500
|
+
failure: null,
|
|
29501
|
+
transparentBackground: null
|
|
29502
|
+
};
|
|
29342
29503
|
case "subagentDelegation": {
|
|
29343
29504
|
const primary = item.subagents[0];
|
|
29344
29505
|
const sameConfiguration = item.subagents.every((subagent) => subagent.model === primary?.model && subagent.reasoningEffort === primary?.reasoningEffort);
|
|
@@ -30132,7 +30293,7 @@ var CodexTurnProjector = class {
|
|
|
30132
30293
|
};
|
|
30133
30294
|
|
|
30134
30295
|
// packages/protocol-core/dist/thread-fork.js
|
|
30135
|
-
function
|
|
30296
|
+
function isRecord13(value2) {
|
|
30136
30297
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
30137
30298
|
}
|
|
30138
30299
|
function optionalText2(params, name, options2 = {}) {
|
|
@@ -30155,7 +30316,7 @@ function optionalBoolean(params, name) {
|
|
|
30155
30316
|
function decodeThreadForkRequest(request) {
|
|
30156
30317
|
if (request.method !== "thread/fork")
|
|
30157
30318
|
return null;
|
|
30158
|
-
if (!
|
|
30319
|
+
if (!isRecord13(request.params))
|
|
30159
30320
|
throw new Error("thread/fork params must be an object");
|
|
30160
30321
|
const params = request.params;
|
|
30161
30322
|
const threadId2 = optionalText2(params, "threadId");
|
|
@@ -30191,7 +30352,7 @@ function decodeThreadForkRequest(request) {
|
|
|
30191
30352
|
function decodeThreadRevertRequest(request) {
|
|
30192
30353
|
if (request.method !== "thread/revert")
|
|
30193
30354
|
return null;
|
|
30194
|
-
if (!
|
|
30355
|
+
if (!isRecord13(request.params))
|
|
30195
30356
|
throw new Error("thread/revert params must be an object");
|
|
30196
30357
|
const { threadId: threadId2, beforeTurnId } = request.params;
|
|
30197
30358
|
if (typeof threadId2 !== "string" || threadId2.length === 0) {
|
|
@@ -30205,7 +30366,7 @@ function decodeThreadRevertRequest(request) {
|
|
|
30205
30366
|
function decodeThreadRollbackRequest(request) {
|
|
30206
30367
|
if (request.method !== "thread/rollback")
|
|
30207
30368
|
return null;
|
|
30208
|
-
if (!
|
|
30369
|
+
if (!isRecord13(request.params))
|
|
30209
30370
|
throw new Error("thread/rollback params must be an object");
|
|
30210
30371
|
const { threadId: threadId2, numTurns } = request.params;
|
|
30211
30372
|
if (typeof threadId2 !== "string" || threadId2.length === 0) {
|
|
@@ -30306,13 +30467,13 @@ var THREAD_SOURCE_KINDS = /* @__PURE__ */ new Set([
|
|
|
30306
30467
|
"subAgentOther",
|
|
30307
30468
|
"unknown"
|
|
30308
30469
|
]);
|
|
30309
|
-
function
|
|
30470
|
+
function isRecord14(value2) {
|
|
30310
30471
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
30311
30472
|
}
|
|
30312
30473
|
function paramsObject(request, method) {
|
|
30313
30474
|
if (request.params === void 0 && method === "thread/list")
|
|
30314
30475
|
return {};
|
|
30315
|
-
if (!
|
|
30476
|
+
if (!isRecord14(request.params))
|
|
30316
30477
|
throw new Error(`${method} params must be an object`);
|
|
30317
30478
|
return request.params;
|
|
30318
30479
|
}
|
|
@@ -30384,7 +30545,7 @@ function cursorPayload(value2) {
|
|
|
30384
30545
|
};
|
|
30385
30546
|
}
|
|
30386
30547
|
function parseCursorPayload(value2) {
|
|
30387
|
-
if (!
|
|
30548
|
+
if (!isRecord14(value2) || value2.formatVersion !== 1)
|
|
30388
30549
|
throw new Error("Host cursor is invalid");
|
|
30389
30550
|
const { queryFingerprint: fingerprint, sortDirection: sortDirection2, officialCursor, officialDone } = value2;
|
|
30390
30551
|
const { externalAnchor: externalAnchor2, externalDone } = value2;
|
|
@@ -30393,7 +30554,7 @@ function parseCursorPayload(value2) {
|
|
|
30393
30554
|
}
|
|
30394
30555
|
let anchor = null;
|
|
30395
30556
|
if (externalAnchor2 !== null) {
|
|
30396
|
-
if (!
|
|
30557
|
+
if (!isRecord14(externalAnchor2) || !Number.isSafeInteger(externalAnchor2.timestamp) || typeof externalAnchor2.threadId !== "string" || externalAnchor2.threadId.length === 0) {
|
|
30397
30558
|
throw new Error("Host cursor is invalid");
|
|
30398
30559
|
}
|
|
30399
30560
|
anchor = {
|
|
@@ -30431,7 +30592,7 @@ function decodeHostThreadListCursor(value2, expected) {
|
|
|
30431
30592
|
return cursor;
|
|
30432
30593
|
}
|
|
30433
30594
|
function carriesHostThreadListCursor(request) {
|
|
30434
|
-
if (request.method !== "thread/list" || !
|
|
30595
|
+
if (request.method !== "thread/list" || !isRecord14(request.params))
|
|
30435
30596
|
return false;
|
|
30436
30597
|
const cursor = request.params.cursor;
|
|
30437
30598
|
return typeof cursor === "string" && (cursor.startsWith(HOST_CURSOR_PREFIX) || cursor.startsWith(SECTION_CURSOR_PREFIX));
|
|
@@ -30528,7 +30689,7 @@ function decodeSectionCursor(value2, queryFingerprint2) {
|
|
|
30528
30689
|
} catch {
|
|
30529
30690
|
throw new Error("thread/list cursor is invalid");
|
|
30530
30691
|
}
|
|
30531
|
-
if (!
|
|
30692
|
+
if (!isRecord14(decoded) || decoded.formatVersion !== 1 || !Number.isSafeInteger(decoded.offset) || decoded.offset <= 0) {
|
|
30532
30693
|
throw new Error("thread/list cursor is invalid");
|
|
30533
30694
|
}
|
|
30534
30695
|
if (decoded.queryFingerprint !== queryFingerprint2) {
|
|
@@ -30592,7 +30753,7 @@ function decodeThreadMetadataUpdateRequest(request) {
|
|
|
30592
30753
|
if (daybreakEnabled !== null)
|
|
30593
30754
|
decoded.daybreakEnabled = daybreakEnabled;
|
|
30594
30755
|
if (params.gitInfo !== void 0 && params.gitInfo !== null) {
|
|
30595
|
-
if (!
|
|
30756
|
+
if (!isRecord14(params.gitInfo)) {
|
|
30596
30757
|
throw new Error("thread/metadata/update params.gitInfo must be an object or null");
|
|
30597
30758
|
}
|
|
30598
30759
|
const gitInfo = {};
|
|
@@ -30612,10 +30773,10 @@ function decodeThreadMetadataUpdateRequest(request) {
|
|
|
30612
30773
|
return decoded;
|
|
30613
30774
|
}
|
|
30614
30775
|
function observeDeletedProject(value2) {
|
|
30615
|
-
if (!
|
|
30776
|
+
if (!isRecord14(value2) || value2.method !== "project/changed" || "id" in value2)
|
|
30616
30777
|
return null;
|
|
30617
30778
|
const params = value2.params;
|
|
30618
|
-
if (!
|
|
30779
|
+
if (!isRecord14(params) || params.changeType !== "deleted")
|
|
30619
30780
|
return null;
|
|
30620
30781
|
return typeof params.projectId === "string" && params.projectId.length > 0 ? params.projectId : null;
|
|
30621
30782
|
}
|
|
@@ -30627,7 +30788,7 @@ function optionalCursor(value2, name) {
|
|
|
30627
30788
|
return value2;
|
|
30628
30789
|
}
|
|
30629
30790
|
function decodeOfficialThreadListPage(value2) {
|
|
30630
|
-
if (!
|
|
30791
|
+
if (!isRecord14(value2) || !Array.isArray(value2.data) || value2.data.some((row) => !isRecord14(row))) {
|
|
30631
30792
|
throw new Error("Official thread/list response is invalid");
|
|
30632
30793
|
}
|
|
30633
30794
|
return {
|
|
@@ -34278,7 +34439,7 @@ import { createHash as createHash7 } from "node:crypto";
|
|
|
34278
34439
|
var CURSOR_PREFIX = "codexhost:thread-messages:v1:";
|
|
34279
34440
|
var DEFAULT_MESSAGE_LIMIT = 25;
|
|
34280
34441
|
var MAX_MESSAGE_LIMIT = 100;
|
|
34281
|
-
function
|
|
34442
|
+
function isRecord15(value2) {
|
|
34282
34443
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
34283
34444
|
}
|
|
34284
34445
|
function stringValue(value2) {
|
|
@@ -34287,12 +34448,12 @@ function stringValue(value2) {
|
|
|
34287
34448
|
function textFromUserItem(item) {
|
|
34288
34449
|
if (!Array.isArray(item.content)) return "";
|
|
34289
34450
|
return item.content.flatMap(
|
|
34290
|
-
(part) =>
|
|
34451
|
+
(part) => isRecord15(part) && part.type === "text" && typeof part.text === "string" ? [part.text] : []
|
|
34291
34452
|
).join("\n");
|
|
34292
34453
|
}
|
|
34293
34454
|
function threadStatus(value2, running) {
|
|
34294
34455
|
if (running) return "running";
|
|
34295
|
-
if (
|
|
34456
|
+
if (isRecord15(value2)) {
|
|
34296
34457
|
if (value2.type === "active") return "running";
|
|
34297
34458
|
}
|
|
34298
34459
|
return "completed";
|
|
@@ -34309,10 +34470,10 @@ function allVisibleMessages(turns) {
|
|
|
34309
34470
|
const turnId = stringValue(turn.id);
|
|
34310
34471
|
if (!turnId || !Array.isArray(turn.items)) continue;
|
|
34311
34472
|
const agentItems = turn.items.filter(
|
|
34312
|
-
(item) =>
|
|
34473
|
+
(item) => isRecord15(item) && item.type === "agentMessage"
|
|
34313
34474
|
);
|
|
34314
34475
|
for (const item of turn.items) {
|
|
34315
|
-
if (!
|
|
34476
|
+
if (!isRecord15(item)) continue;
|
|
34316
34477
|
const id2 = stringValue(item.id);
|
|
34317
34478
|
if (!id2) continue;
|
|
34318
34479
|
if (item.type === "userMessage") {
|
|
@@ -34387,7 +34548,7 @@ function projectDelegationThreadSnapshot(input) {
|
|
|
34387
34548
|
const progress = latestTurnMessages.filter((message2) => message2.phase !== "final" && message2.text.trim()).map(({ id: id2, turnId, text }) => ({ id: id2, turnId, text }));
|
|
34388
34549
|
const result = input.running ? { availability: "pending" } : final ? { availability: "available", text: final.text } : {
|
|
34389
34550
|
availability: "unavailable",
|
|
34390
|
-
...
|
|
34551
|
+
...isRecord15(latestTurn?.error) && typeof latestTurn.error.message === "string" ? { message: latestTurn.error.message } : {}
|
|
34391
34552
|
};
|
|
34392
34553
|
const offset = options2.view === "messages" ? decodeCursor(input.threadId, options2.cursor) : visible.length;
|
|
34393
34554
|
const page = options2.view === "messages" ? [] : void 0;
|
|
@@ -37321,11 +37482,11 @@ function spawnOfficialAppServerConnection(input) {
|
|
|
37321
37482
|
}
|
|
37322
37483
|
|
|
37323
37484
|
// packages/host-runtime/src/account/codex-account-control.ts
|
|
37324
|
-
function
|
|
37485
|
+
function isRecord16(value2) {
|
|
37325
37486
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
37326
37487
|
}
|
|
37327
37488
|
function currentCodexAccountFromOfficialRead(result) {
|
|
37328
|
-
if (!
|
|
37489
|
+
if (!isRecord16(result) || !isRecord16(result.account) || result.account.type !== "chatgpt") {
|
|
37329
37490
|
return null;
|
|
37330
37491
|
}
|
|
37331
37492
|
const email3 = external_exports.string().email().max(320).safeParse(result.account.email);
|
|
@@ -37361,7 +37522,7 @@ import { randomUUID as randomUUID14 } from "node:crypto";
|
|
|
37361
37522
|
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
37362
37523
|
var INTERNAL_REQUEST_PREFIX = "codexhost:official:";
|
|
37363
37524
|
var MAX_RETIRED_IDS = 1024;
|
|
37364
|
-
function
|
|
37525
|
+
function isRecord17(value2) {
|
|
37365
37526
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
37366
37527
|
}
|
|
37367
37528
|
var OfficialRequestBroker = class {
|
|
@@ -37404,7 +37565,7 @@ var OfficialRequestBroker = class {
|
|
|
37404
37565
|
});
|
|
37405
37566
|
}
|
|
37406
37567
|
handle(value2) {
|
|
37407
|
-
if (!
|
|
37568
|
+
if (!isRecord17(value2) || typeof value2.id !== "string") return false;
|
|
37408
37569
|
const pending = this.#pending.get(value2.id);
|
|
37409
37570
|
if (!pending) return this.#retired.has(value2.id);
|
|
37410
37571
|
clearTimeout(pending.timeout);
|
|
@@ -38165,11 +38326,11 @@ function createOwnedConnectionBackend(factory) {
|
|
|
38165
38326
|
}
|
|
38166
38327
|
|
|
38167
38328
|
// packages/host-runtime/src/route-observation.ts
|
|
38168
|
-
function
|
|
38329
|
+
function isRecord18(value2) {
|
|
38169
38330
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
38170
38331
|
}
|
|
38171
38332
|
function classifyThreadPurpose(request) {
|
|
38172
|
-
return
|
|
38333
|
+
return isRecord18(request.params) && request.params.ephemeral === true ? "ephemeral" : "conversation";
|
|
38173
38334
|
}
|
|
38174
38335
|
var RequestRouteObservationTracker = class {
|
|
38175
38336
|
#nextCreateOrdinal = 0;
|
|
@@ -38194,13 +38355,13 @@ var RequestRouteObservationTracker = class {
|
|
|
38194
38355
|
this.#createByThreadId.set(threadId2, tracked);
|
|
38195
38356
|
}
|
|
38196
38357
|
bindOfficialResponse(response) {
|
|
38197
|
-
if (!
|
|
38358
|
+
if (!isRecord18(response) || !("id" in response)) return;
|
|
38198
38359
|
const tracked = this.#pendingByRequestId.get(response.id);
|
|
38199
38360
|
if (!tracked) return;
|
|
38200
38361
|
this.#pendingByRequestId.delete(response.id);
|
|
38201
38362
|
const result = response.result;
|
|
38202
|
-
const thread =
|
|
38203
|
-
if (
|
|
38363
|
+
const thread = isRecord18(result) ? result.thread : null;
|
|
38364
|
+
if (isRecord18(thread) && typeof thread.id === "string") {
|
|
38204
38365
|
this.#createByThreadId.set(thread.id, tracked);
|
|
38205
38366
|
}
|
|
38206
38367
|
}
|
|
@@ -38418,11 +38579,11 @@ var OfficialThreadListError = class extends Error {
|
|
|
38418
38579
|
}
|
|
38419
38580
|
rpcError;
|
|
38420
38581
|
};
|
|
38421
|
-
function
|
|
38582
|
+
function isRecord19(value2) {
|
|
38422
38583
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
38423
38584
|
}
|
|
38424
38585
|
function officialThreadListPageFromResponse(response) {
|
|
38425
|
-
if (
|
|
38586
|
+
if (isRecord19(response.error)) {
|
|
38426
38587
|
if (!Number.isSafeInteger(response.error.code) || typeof response.error.message !== "string") {
|
|
38427
38588
|
throw new Error("Official thread/list error response is invalid");
|
|
38428
38589
|
}
|
|
@@ -38987,14 +39148,14 @@ var THREAD_USAGE_UPDATED_METHOD = "codexhost/thread/usage/updated";
|
|
|
38987
39148
|
function delay4(milliseconds) {
|
|
38988
39149
|
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
38989
39150
|
}
|
|
38990
|
-
function
|
|
39151
|
+
function isRecord20(value2) {
|
|
38991
39152
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
38992
39153
|
}
|
|
38993
39154
|
function officialThreadBusy(thread) {
|
|
38994
|
-
if (thread &&
|
|
39155
|
+
if (thread && isRecord20(thread.status) && thread.status.type === "active") return true;
|
|
38995
39156
|
const turns = thread && Array.isArray(thread.turns) ? thread.turns : [];
|
|
38996
39157
|
const latestTurn = turns.at(-1);
|
|
38997
|
-
return
|
|
39158
|
+
return isRecord20(latestTurn) && (latestTurn.status === "inProgress" || latestTurn.status === "running");
|
|
38998
39159
|
}
|
|
38999
39160
|
function errorMessage4(error51) {
|
|
39000
39161
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
@@ -39101,15 +39262,15 @@ function classifyCreateRequestRoute(request) {
|
|
|
39101
39262
|
};
|
|
39102
39263
|
}
|
|
39103
39264
|
function routingParams(request) {
|
|
39104
|
-
return
|
|
39265
|
+
return isRecord20(request.params) ? request.params : {};
|
|
39105
39266
|
}
|
|
39106
39267
|
function requestObject(request) {
|
|
39107
|
-
if (!
|
|
39268
|
+
if (!isRecord20(request.params)) throw new Error(`${request.method} params must be an object`);
|
|
39108
39269
|
return request.params;
|
|
39109
39270
|
}
|
|
39110
39271
|
function requestText(params) {
|
|
39111
39272
|
if (!Array.isArray(params.input)) throw new Error("turn/start input must be an array");
|
|
39112
|
-
const text = params.input.filter((item) =>
|
|
39273
|
+
const text = params.input.filter((item) => isRecord20(item) && item.type === "text").map((item) => item.text).filter((value2) => typeof value2 === "string").join("\n");
|
|
39113
39274
|
if (!text) throw new Error("turn/start must contain text input");
|
|
39114
39275
|
return text;
|
|
39115
39276
|
}
|
|
@@ -39544,19 +39705,19 @@ var AppServerHost = class {
|
|
|
39544
39705
|
for (const resolve of waiters) resolve();
|
|
39545
39706
|
}
|
|
39546
39707
|
#observeOfficialTurnStartResponse(value2) {
|
|
39547
|
-
if (!
|
|
39708
|
+
if (!isRecord20(value2) || !("id" in value2)) return;
|
|
39548
39709
|
const threadId2 = this.#pendingOfficialTurnStarts.get(value2.id);
|
|
39549
39710
|
if (!threadId2) return;
|
|
39550
39711
|
this.#pendingOfficialTurnStarts.delete(value2.id);
|
|
39551
|
-
const result =
|
|
39552
|
-
const turn = result &&
|
|
39712
|
+
const result = isRecord20(value2.result) ? value2.result : null;
|
|
39713
|
+
const turn = result && isRecord20(result.turn) ? result.turn : null;
|
|
39553
39714
|
if (turn && typeof turn.id === "string") {
|
|
39554
39715
|
this.#activeOfficialTurns.set(threadId2, turn.id);
|
|
39555
39716
|
}
|
|
39556
39717
|
this.#signalActiveWorkChanged();
|
|
39557
39718
|
}
|
|
39558
39719
|
#takeConsoleReply(value2) {
|
|
39559
|
-
if (!
|
|
39720
|
+
if (!isRecord20(value2) || typeof value2.id !== "string") return false;
|
|
39560
39721
|
const reply2 = this.#consoleReplies.get(value2.id);
|
|
39561
39722
|
if (!reply2) return false;
|
|
39562
39723
|
this.#consoleReplies.delete(value2.id);
|
|
@@ -39602,10 +39763,10 @@ var AppServerHost = class {
|
|
|
39602
39763
|
);
|
|
39603
39764
|
try {
|
|
39604
39765
|
const message2 = await reply2;
|
|
39605
|
-
if (
|
|
39766
|
+
if (isRecord20(message2) && "result" in message2) {
|
|
39606
39767
|
return { result: message2.result ?? null };
|
|
39607
39768
|
}
|
|
39608
|
-
const error51 =
|
|
39769
|
+
const error51 = isRecord20(message2) && isRecord20(message2.error) ? message2.error : void 0;
|
|
39609
39770
|
return {
|
|
39610
39771
|
error: {
|
|
39611
39772
|
code: typeof error51?.code === "number" ? error51.code : -32603,
|
|
@@ -39631,7 +39792,7 @@ var AppServerHost = class {
|
|
|
39631
39792
|
this.#diagnose(error51);
|
|
39632
39793
|
continue;
|
|
39633
39794
|
}
|
|
39634
|
-
if (
|
|
39795
|
+
if (isRecord20(parsed2) && parsed2.method === "initialized" && !("id" in parsed2)) {
|
|
39635
39796
|
continue;
|
|
39636
39797
|
}
|
|
39637
39798
|
if (await this.#handleDesktopApprovalResponse(parsed2)) continue;
|
|
@@ -39653,7 +39814,7 @@ var AppServerHost = class {
|
|
|
39653
39814
|
const options2 = this.#observedSessionUsage.requestOptions("initialize", params);
|
|
39654
39815
|
const nativeParams = options2 ? { ...params, ...options2 } : params;
|
|
39655
39816
|
const response = await this.#officialRuntime.initializeProtocol(nativeParams);
|
|
39656
|
-
if (!
|
|
39817
|
+
if (!isRecord20(response.error)) this.#observedSessionUsage.initialized(nativeParams);
|
|
39657
39818
|
await this.#writer.json({ ...response, id: request.id });
|
|
39658
39819
|
this.#nativeAccountObserver?.initialized(nativeGeneration);
|
|
39659
39820
|
} catch (error51) {
|
|
@@ -39661,7 +39822,7 @@ var AppServerHost = class {
|
|
|
39661
39822
|
}
|
|
39662
39823
|
continue;
|
|
39663
39824
|
}
|
|
39664
|
-
const threadId2 =
|
|
39825
|
+
const threadId2 = isRecord20(request.params) && typeof request.params.threadId === "string" ? request.params.threadId : void 0;
|
|
39665
39826
|
this.#dispatchDesktopRequest(
|
|
39666
39827
|
() => this.#desktopRequests.run(
|
|
39667
39828
|
threadId2,
|
|
@@ -39709,7 +39870,7 @@ var AppServerHost = class {
|
|
|
39709
39870
|
for (const guard of this.#replyGuards.get(id2) ?? []) guard.answered = true;
|
|
39710
39871
|
}
|
|
39711
39872
|
#noteDesktopReply(value2) {
|
|
39712
|
-
if (
|
|
39873
|
+
if (isRecord20(value2) && "id" in value2 && !("method" in value2)) {
|
|
39713
39874
|
this.#markDesktopRequestAnswered(value2.id);
|
|
39714
39875
|
}
|
|
39715
39876
|
}
|
|
@@ -40222,7 +40383,7 @@ var AppServerHost = class {
|
|
|
40222
40383
|
return;
|
|
40223
40384
|
}
|
|
40224
40385
|
if (request.method === "thread/fork") {
|
|
40225
|
-
const params =
|
|
40386
|
+
const params = isRecord20(request.params) ? request.params : {};
|
|
40226
40387
|
const resolution = typeof params.threadId === "string" ? await this.#resolveExternalThread(params.threadId) : { kind: "official" };
|
|
40227
40388
|
if (resolution.kind === "error") {
|
|
40228
40389
|
await this.#writer.json(rpcError(request, resolution.error.code, resolution.error.message));
|
|
@@ -40243,7 +40404,7 @@ var AppServerHost = class {
|
|
|
40243
40404
|
}
|
|
40244
40405
|
}
|
|
40245
40406
|
if (request.method === "thread/revert") {
|
|
40246
|
-
const params =
|
|
40407
|
+
const params = isRecord20(request.params) ? request.params : {};
|
|
40247
40408
|
const resolution = typeof params.threadId === "string" ? await this.#resolveExternalThread(params.threadId) : { kind: "official" };
|
|
40248
40409
|
if (resolution.kind === "error") {
|
|
40249
40410
|
await this.#writer.json(rpcError(request, resolution.error.code, resolution.error.message));
|
|
@@ -40264,7 +40425,7 @@ var AppServerHost = class {
|
|
|
40264
40425
|
}
|
|
40265
40426
|
}
|
|
40266
40427
|
if (request.method === "thread/rollback") {
|
|
40267
|
-
const params =
|
|
40428
|
+
const params = isRecord20(request.params) ? request.params : {};
|
|
40268
40429
|
const resolution = typeof params.threadId === "string" ? await this.#resolveExternalThread(params.threadId) : { kind: "official" };
|
|
40269
40430
|
if (resolution.kind === "error") {
|
|
40270
40431
|
await this.#writer.json(rpcError(request, resolution.error.code, resolution.error.message));
|
|
@@ -40422,7 +40583,7 @@ var AppServerHost = class {
|
|
|
40422
40583
|
return;
|
|
40423
40584
|
}
|
|
40424
40585
|
}
|
|
40425
|
-
if (request.method === "thread/backgroundTerminals/clean" &&
|
|
40586
|
+
if (request.method === "thread/backgroundTerminals/clean" && isRecord20(request.params) && typeof request.params.threadId === "string") {
|
|
40426
40587
|
const location = await this.#locateExternalThread(request.params.threadId);
|
|
40427
40588
|
if (await this.#writeResolutionError(request, location)) return;
|
|
40428
40589
|
if (location.kind === "external") {
|
|
@@ -40430,7 +40591,7 @@ var AppServerHost = class {
|
|
|
40430
40591
|
return;
|
|
40431
40592
|
}
|
|
40432
40593
|
}
|
|
40433
|
-
if (request.method.startsWith("thread/realtime/") &&
|
|
40594
|
+
if (request.method.startsWith("thread/realtime/") && isRecord20(request.params) && typeof request.params.threadId === "string") {
|
|
40434
40595
|
const resolution = await this.#resolveExternalThread(request.params.threadId);
|
|
40435
40596
|
if (await this.#writeResolutionError(request, resolution)) return;
|
|
40436
40597
|
if (resolution.kind === "external") {
|
|
@@ -40442,7 +40603,7 @@ var AppServerHost = class {
|
|
|
40442
40603
|
return;
|
|
40443
40604
|
}
|
|
40444
40605
|
}
|
|
40445
|
-
if (request.method.startsWith("thread/") && !EXPLICIT_EXTERNAL_THREAD_METHODS.has(request.method) &&
|
|
40606
|
+
if (request.method.startsWith("thread/") && !EXPLICIT_EXTERNAL_THREAD_METHODS.has(request.method) && isRecord20(request.params) && typeof request.params.threadId === "string") {
|
|
40446
40607
|
const location = await this.#locateExternalThread(request.params.threadId);
|
|
40447
40608
|
if (await this.#writeResolutionError(request, location)) return;
|
|
40448
40609
|
if (location.kind === "external") {
|
|
@@ -40461,10 +40622,10 @@ var AppServerHost = class {
|
|
|
40461
40622
|
/** Native Codex Turns: turn `#` delegation chips into an explicit Skill-backed request. */
|
|
40462
40623
|
async #rewriteOfficialDelegationMentions(request, frame) {
|
|
40463
40624
|
if (request.method !== "turn/start" && request.method !== "turn/steer") return frame;
|
|
40464
|
-
if (!
|
|
40625
|
+
if (!isRecord20(request.params) || !Array.isArray(request.params.input)) return frame;
|
|
40465
40626
|
const input = request.params.input;
|
|
40466
40627
|
if (!input.some(
|
|
40467
|
-
(item) =>
|
|
40628
|
+
(item) => isRecord20(item) && typeof item.text === "string" && item.text.includes(DELEGATION_MENTION_PATH_PREFIX)
|
|
40468
40629
|
)) {
|
|
40469
40630
|
return frame;
|
|
40470
40631
|
}
|
|
@@ -40477,7 +40638,7 @@ var AppServerHost = class {
|
|
|
40477
40638
|
}
|
|
40478
40639
|
async #forwardOfficialNonRequest(value2, frame) {
|
|
40479
40640
|
if (this.#options.externalOnly) return;
|
|
40480
|
-
const response =
|
|
40641
|
+
const response = isRecord20(value2) ? value2 : null;
|
|
40481
40642
|
const request = response && (typeof response.id === "string" || typeof response.id === "number") ? this.#officialServerRequests.get(response.id) : null;
|
|
40482
40643
|
if (request !== void 0 && response) {
|
|
40483
40644
|
this.#officialServerRequests.delete(response.id);
|
|
@@ -40497,13 +40658,13 @@ var AppServerHost = class {
|
|
|
40497
40658
|
return;
|
|
40498
40659
|
}
|
|
40499
40660
|
try {
|
|
40500
|
-
const options2 =
|
|
40661
|
+
const options2 = isRecord20(request.params) ? this.#observedSessionUsage.requestOptions(request.method, request.params) : null;
|
|
40501
40662
|
if (options2) {
|
|
40502
40663
|
const original = parseJsonFrame(frame);
|
|
40503
|
-
if (
|
|
40664
|
+
if (isRecord20(original))
|
|
40504
40665
|
frame = encodeJsonFrame({
|
|
40505
40666
|
...original,
|
|
40506
|
-
params: { ...
|
|
40667
|
+
params: { ...isRecord20(original.params) ? original.params : {}, ...options2 }
|
|
40507
40668
|
});
|
|
40508
40669
|
}
|
|
40509
40670
|
await this.#officialRuntime.sendFrame(frame);
|
|
@@ -40527,7 +40688,7 @@ var AppServerHost = class {
|
|
|
40527
40688
|
const observedAtMs = Date.now();
|
|
40528
40689
|
this.#observeOfficialTurnStartResponse(parsed2);
|
|
40529
40690
|
let forwarded = parsed2;
|
|
40530
|
-
if (
|
|
40691
|
+
if (isRecord20(parsed2) && typeof parsed2.method === "string" && "id" in parsed2) {
|
|
40531
40692
|
const originalId = parsed2.id;
|
|
40532
40693
|
if (typeof originalId === "string" || typeof originalId === "number") {
|
|
40533
40694
|
const forwardedId = `codexhost:official:${++this.#nextOfficialServerRequestId}`;
|
|
@@ -40535,7 +40696,7 @@ var AppServerHost = class {
|
|
|
40535
40696
|
forwarded = { ...parsed2, id: forwardedId };
|
|
40536
40697
|
}
|
|
40537
40698
|
}
|
|
40538
|
-
const accountScopedNotification =
|
|
40699
|
+
const accountScopedNotification = isRecord20(parsed2) && typeof parsed2.method === "string" && (parsed2.method === "account/updated" || parsed2.method.startsWith("account/rateLimits/"));
|
|
40539
40700
|
if (accountScopedNotification) {
|
|
40540
40701
|
if (parsed2.method === "account/updated") this.#officialRateLimits.reset(input.accountId);
|
|
40541
40702
|
}
|
|
@@ -40547,7 +40708,7 @@ var AppServerHost = class {
|
|
|
40547
40708
|
this.#diagnose(error51);
|
|
40548
40709
|
}
|
|
40549
40710
|
this.#routeObservationTracker.bindOfficialResponse(parsed2);
|
|
40550
|
-
const privateTelemetry =
|
|
40711
|
+
const privateTelemetry = isRecord20(parsed2) && typeof parsed2.method === "string" && !("id" in parsed2) && !this.#observedSessionUsage.shouldForwardNotification(parsed2);
|
|
40551
40712
|
if (!privateTelemetry) {
|
|
40552
40713
|
if (forwarded === parsed2) await this.#writer.frame(input.frame);
|
|
40553
40714
|
else await this.#writer.json(forwarded);
|
|
@@ -40613,10 +40774,10 @@ var AppServerHost = class {
|
|
|
40613
40774
|
}
|
|
40614
40775
|
}
|
|
40615
40776
|
async #observeOfficialTurnLifecycle(value2) {
|
|
40616
|
-
if (!
|
|
40777
|
+
if (!isRecord20(value2) || !isRecord20(value2.params)) return;
|
|
40617
40778
|
const params = value2.params;
|
|
40618
40779
|
if (value2.method === "turn/started" && typeof params.threadId === "string") {
|
|
40619
|
-
const turn =
|
|
40780
|
+
const turn = isRecord20(params.turn) ? params.turn : null;
|
|
40620
40781
|
if (turn && typeof turn.id === "string") {
|
|
40621
40782
|
this.#forgetPendingOfficialTurnStarts(params.threadId);
|
|
40622
40783
|
this.#activeOfficialTurns.set(params.threadId, turn.id);
|
|
@@ -40629,7 +40790,7 @@ var AppServerHost = class {
|
|
|
40629
40790
|
const delegation = await this.#repository.getDelegationByChild(
|
|
40630
40791
|
hostThreadIdSchema.parse(params.threadId)
|
|
40631
40792
|
);
|
|
40632
|
-
const turn =
|
|
40793
|
+
const turn = isRecord20(params.turn) ? params.turn : null;
|
|
40633
40794
|
const status2 = turn?.status === "failed" ? "failed" : turn?.status === "interrupted" || turn?.status === "cancelled" ? "interrupted" : "completed";
|
|
40634
40795
|
if (this.#pendingOfficialDelegationThreads.has(params.threadId)) {
|
|
40635
40796
|
this.#pendingOfficialTerminalStatuses.set(params.threadId, status2);
|
|
@@ -40662,28 +40823,28 @@ var AppServerHost = class {
|
|
|
40662
40823
|
}
|
|
40663
40824
|
async #readOfficialThreadCwd(threadId2) {
|
|
40664
40825
|
const response = await this.#requestOfficial("thread/read", { threadId: threadId2 });
|
|
40665
|
-
if (
|
|
40666
|
-
const result =
|
|
40667
|
-
const thread = result &&
|
|
40826
|
+
if (isRecord20(response.error)) return void 0;
|
|
40827
|
+
const result = isRecord20(response.result) ? response.result : null;
|
|
40828
|
+
const thread = result && isRecord20(result.thread) ? result.thread : null;
|
|
40668
40829
|
return thread && typeof thread.cwd === "string" && thread.cwd.trim() ? thread.cwd : void 0;
|
|
40669
40830
|
}
|
|
40670
40831
|
async #inspectOfficialDelegationTarget(input) {
|
|
40671
40832
|
const response = await this.#requestOfficial("model/list", {});
|
|
40672
|
-
if (
|
|
40833
|
+
if (isRecord20(response.error)) {
|
|
40673
40834
|
throw new DelegationControlError(
|
|
40674
40835
|
"DELEGATION_FAILED",
|
|
40675
40836
|
typeof response.error.message === "string" ? response.error.message : "Official Model catalog could not be read"
|
|
40676
40837
|
);
|
|
40677
40838
|
}
|
|
40678
|
-
const result =
|
|
40839
|
+
const result = isRecord20(response.result) ? response.result : null;
|
|
40679
40840
|
const data = result && Array.isArray(result.data) ? result.data : [];
|
|
40680
40841
|
const thinkingById = /* @__PURE__ */ new Map();
|
|
40681
40842
|
const models = data.flatMap((candidate) => {
|
|
40682
|
-
if (!
|
|
40843
|
+
if (!isRecord20(candidate) || typeof candidate.model !== "string" || !candidate.model.trim()) {
|
|
40683
40844
|
return [];
|
|
40684
40845
|
}
|
|
40685
40846
|
const supportedThinkingOptionIds = Array.isArray(candidate.supportedReasoningEfforts) ? candidate.supportedReasoningEfforts.flatMap((option) => {
|
|
40686
|
-
if (!
|
|
40847
|
+
if (!isRecord20(option) || typeof option.reasoningEffort !== "string" || !option.reasoningEffort.trim()) {
|
|
40687
40848
|
return [];
|
|
40688
40849
|
}
|
|
40689
40850
|
const id2 = harnessThinkingOptionIdSchema.safeParse(option.reasoningEffort);
|
|
@@ -40703,9 +40864,9 @@ var AppServerHost = class {
|
|
|
40703
40864
|
];
|
|
40704
40865
|
});
|
|
40705
40866
|
const defaultEntry = data.find(
|
|
40706
|
-
(candidate) =>
|
|
40867
|
+
(candidate) => isRecord20(candidate) && candidate.isDefault === true
|
|
40707
40868
|
);
|
|
40708
|
-
const defaultModel =
|
|
40869
|
+
const defaultModel = isRecord20(defaultEntry) && typeof defaultEntry.model === "string" ? encodeOfficialCodexModelRef(defaultEntry.model) : void 0;
|
|
40709
40870
|
return {
|
|
40710
40871
|
harnessId: input.harnessId,
|
|
40711
40872
|
inspection: {
|
|
@@ -40811,8 +40972,8 @@ var AppServerHost = class {
|
|
|
40811
40972
|
ephemeral: false,
|
|
40812
40973
|
historyMode: "paginated"
|
|
40813
40974
|
});
|
|
40814
|
-
const startedResult =
|
|
40815
|
-
const thread = startedResult &&
|
|
40975
|
+
const startedResult = isRecord20(started.result) ? started.result : null;
|
|
40976
|
+
const thread = startedResult && isRecord20(startedResult.thread) ? startedResult.thread : null;
|
|
40816
40977
|
const threadId2 = thread && typeof thread.id === "string" ? thread.id : null;
|
|
40817
40978
|
if (!threadId2) throw new Error("Official thread/start returned no Thread identity");
|
|
40818
40979
|
this.#pendingOfficialDelegationThreads.add(threadId2);
|
|
@@ -40824,8 +40985,8 @@ var AppServerHost = class {
|
|
|
40824
40985
|
...nativeModelId ? { model: nativeModelId } : {},
|
|
40825
40986
|
...input.thinkingOptionId ? { effort: input.thinkingOptionId } : {}
|
|
40826
40987
|
});
|
|
40827
|
-
const turnResult =
|
|
40828
|
-
const turnValue = turnResult &&
|
|
40988
|
+
const turnResult = isRecord20(turn.result) ? turn.result : null;
|
|
40989
|
+
const turnValue = turnResult && isRecord20(turnResult.turn) ? turnResult.turn : null;
|
|
40829
40990
|
const parsedTurnId = turnValue && typeof turnValue.id === "string" ? turnValue.id : null;
|
|
40830
40991
|
if (!parsedTurnId) throw new Error("Official turn/start returned no Turn identity");
|
|
40831
40992
|
turnId = parsedTurnId;
|
|
@@ -40895,11 +41056,11 @@ var AppServerHost = class {
|
|
|
40895
41056
|
threadId: input.threadId,
|
|
40896
41057
|
includeTurns: true
|
|
40897
41058
|
});
|
|
40898
|
-
if (
|
|
40899
|
-
if (!
|
|
41059
|
+
if (isRecord20(current.error)) throw officialThreadReadError(current.error);
|
|
41060
|
+
if (!isRecord20(current.result)) {
|
|
40900
41061
|
throw new DelegationControlError("INTERNAL_ERROR", "Official Thread read returned no result");
|
|
40901
41062
|
}
|
|
40902
|
-
const currentThread =
|
|
41063
|
+
const currentThread = isRecord20(current.result.thread) ? current.result.thread : null;
|
|
40903
41064
|
if (officialThreadBusy(currentThread)) {
|
|
40904
41065
|
throw new DelegationControlError("THREAD_BUSY", "Thread already has an active Turn");
|
|
40905
41066
|
}
|
|
@@ -40907,14 +41068,14 @@ var AppServerHost = class {
|
|
|
40907
41068
|
threadId: input.threadId,
|
|
40908
41069
|
excludeTurns: true
|
|
40909
41070
|
});
|
|
40910
|
-
if (
|
|
41071
|
+
if (isRecord20(resumed.error) || !isRecord20(resumed.result)) {
|
|
40911
41072
|
throw new DelegationControlError(
|
|
40912
41073
|
"DELEGATION_FAILED",
|
|
40913
|
-
|
|
41074
|
+
isRecord20(resumed.error) && typeof resumed.error.message === "string" ? resumed.error.message : "Official Thread resume failed",
|
|
40914
41075
|
{ notStarted: true }
|
|
40915
41076
|
);
|
|
40916
41077
|
}
|
|
40917
|
-
const resumedThread =
|
|
41078
|
+
const resumedThread = isRecord20(resumed.result.thread) ? resumed.result.thread : null;
|
|
40918
41079
|
if (!resumedThread || resumedThread.id !== input.threadId) {
|
|
40919
41080
|
throw new DelegationControlError(
|
|
40920
41081
|
"DELEGATION_FAILED",
|
|
@@ -40925,7 +41086,7 @@ var AppServerHost = class {
|
|
|
40925
41086
|
if (officialThreadBusy(resumedThread)) {
|
|
40926
41087
|
throw new DelegationControlError("THREAD_BUSY", "Thread already has an active Turn");
|
|
40927
41088
|
}
|
|
40928
|
-
if (!
|
|
41089
|
+
if (!isRecord20(resumedThread.status) || resumedThread.status.type !== "idle") {
|
|
40929
41090
|
throw new DelegationControlError(
|
|
40930
41091
|
"DELEGATION_FAILED",
|
|
40931
41092
|
"Official Thread is not idle after resume",
|
|
@@ -40936,15 +41097,15 @@ var AppServerHost = class {
|
|
|
40936
41097
|
threadId: input.threadId,
|
|
40937
41098
|
input: [{ type: "text", text: input.message }]
|
|
40938
41099
|
});
|
|
40939
|
-
if (
|
|
41100
|
+
if (isRecord20(response.error)) {
|
|
40940
41101
|
throw new DelegationControlError(
|
|
40941
41102
|
"DELEGATION_FAILED",
|
|
40942
41103
|
typeof response.error.message === "string" ? response.error.message : "Turn start failed",
|
|
40943
41104
|
{ notStarted: true }
|
|
40944
41105
|
);
|
|
40945
41106
|
}
|
|
40946
|
-
const result =
|
|
40947
|
-
const turn = result &&
|
|
41107
|
+
const result = isRecord20(response.result) ? response.result : null;
|
|
41108
|
+
const turn = result && isRecord20(result.turn) ? result.turn : null;
|
|
40948
41109
|
const turnId = turn && typeof turn.id === "string" ? turn.id : null;
|
|
40949
41110
|
if (!turnId) throw new Error("Official turn/start returned no Turn identity");
|
|
40950
41111
|
this.#activeOfficialTurns.set(input.threadId, turnId);
|
|
@@ -40966,13 +41127,13 @@ var AppServerHost = class {
|
|
|
40966
41127
|
threadId: input.threadId,
|
|
40967
41128
|
includeTurns: true
|
|
40968
41129
|
});
|
|
40969
|
-
if (
|
|
41130
|
+
if (isRecord20(current.error) || !isRecord20(current.result)) {
|
|
40970
41131
|
throw new DelegationControlError("THREAD_NOT_FOUND", "Official Thread was not found");
|
|
40971
41132
|
}
|
|
40972
|
-
const currentThread =
|
|
41133
|
+
const currentThread = isRecord20(current.result.thread) ? current.result.thread : null;
|
|
40973
41134
|
const currentTurns = currentThread && Array.isArray(currentThread.turns) ? currentThread.turns : [];
|
|
40974
41135
|
const latestTurn = currentTurns.at(-1);
|
|
40975
|
-
if (
|
|
41136
|
+
if (isRecord20(latestTurn) && typeof latestTurn.id === "string" && (latestTurn.status === "inProgress" || latestTurn.status === "running")) {
|
|
40976
41137
|
turnId = latestTurn.id;
|
|
40977
41138
|
this.#activeOfficialTurns.set(input.threadId, turnId);
|
|
40978
41139
|
} else {
|
|
@@ -40983,7 +41144,7 @@ var AppServerHost = class {
|
|
|
40983
41144
|
threadId: input.threadId,
|
|
40984
41145
|
turnId
|
|
40985
41146
|
});
|
|
40986
|
-
if (
|
|
41147
|
+
if (isRecord20(response.error)) {
|
|
40987
41148
|
throw new DelegationControlError(
|
|
40988
41149
|
"DELEGATION_FAILED",
|
|
40989
41150
|
typeof response.error.message === "string" ? response.error.message : "Turn cancel failed"
|
|
@@ -40996,13 +41157,13 @@ var AppServerHost = class {
|
|
|
40996
41157
|
threadId: input.threadId,
|
|
40997
41158
|
includeTurns: true
|
|
40998
41159
|
});
|
|
40999
|
-
if (
|
|
41000
|
-
const result =
|
|
41001
|
-
const thread = result &&
|
|
41160
|
+
if (isRecord20(response.error)) throw officialThreadReadError(response.error);
|
|
41161
|
+
const result = isRecord20(response.result) ? response.result : null;
|
|
41162
|
+
const thread = result && isRecord20(result.thread) ? result.thread : null;
|
|
41002
41163
|
if (!thread)
|
|
41003
41164
|
throw new DelegationControlError("INTERNAL_ERROR", "Official Thread read returned no Thread");
|
|
41004
|
-
const turns = Array.isArray(thread.turns) ? thread.turns.filter((turn) =>
|
|
41005
|
-
const running = this.#activeOfficialTurns.has(input.threadId) ||
|
|
41165
|
+
const turns = Array.isArray(thread.turns) ? thread.turns.filter((turn) => isRecord20(turn)) : [];
|
|
41166
|
+
const running = this.#activeOfficialTurns.has(input.threadId) || isRecord20(thread.status) && thread.status.type === "active";
|
|
41006
41167
|
const snapshot2 = projectDelegationThreadSnapshot({
|
|
41007
41168
|
threadId: input.threadId,
|
|
41008
41169
|
harnessId: "codex",
|
|
@@ -41050,7 +41211,7 @@ var AppServerHost = class {
|
|
|
41050
41211
|
threads: result.data.flatMap((entry) => {
|
|
41051
41212
|
if (typeof entry.id !== "string") return [];
|
|
41052
41213
|
const record4 = records.find((candidate) => candidate.hostThreadId === entry.id);
|
|
41053
|
-
const status2 =
|
|
41214
|
+
const status2 = isRecord20(entry.status) && entry.status.type === "active" ? "running" : "completed";
|
|
41054
41215
|
return [
|
|
41055
41216
|
{
|
|
41056
41217
|
threadId: entry.id,
|
|
@@ -41217,7 +41378,7 @@ var AppServerHost = class {
|
|
|
41217
41378
|
const exists2 = await this.#requestOfficial("project/read", {
|
|
41218
41379
|
projectId: update.projectId
|
|
41219
41380
|
}).then(
|
|
41220
|
-
(response) => !
|
|
41381
|
+
(response) => !isRecord20(response.error) && isRecord20(response.result) && isRecord20(response.result.project) && response.result.project.id === update.projectId,
|
|
41221
41382
|
() => false
|
|
41222
41383
|
);
|
|
41223
41384
|
if (!exists2) {
|
|
@@ -42407,10 +42568,10 @@ var AppServerHost = class {
|
|
|
42407
42568
|
...typeof params.serviceTier === "string" ? { serviceTier: params.serviceTier } : {}
|
|
42408
42569
|
});
|
|
42409
42570
|
try {
|
|
42410
|
-
if (params.initialTurnsPage !== void 0 && params.initialTurnsPage !== null && !
|
|
42571
|
+
if (params.initialTurnsPage !== void 0 && params.initialTurnsPage !== null && !isRecord20(params.initialTurnsPage)) {
|
|
42411
42572
|
throw new ExternalHistoryRequestError("initialTurnsPage must be an object");
|
|
42412
42573
|
}
|
|
42413
|
-
const initialPageParams =
|
|
42574
|
+
const initialPageParams = isRecord20(params.initialTurnsPage) ? params.initialTurnsPage : null;
|
|
42414
42575
|
const initialTurnsPage = initialPageParams ? listExternalTurns(turns, initialPageParams) : null;
|
|
42415
42576
|
const paginated = thread.record.historyMode === "paginated";
|
|
42416
42577
|
const turnsBackwardsCursor = paginated ? listExternalTurns(turns, { limit: 1, itemsView: "notLoaded" }).backwardsCursor : null;
|
|
@@ -42506,7 +42667,11 @@ var AppServerHost = class {
|
|
|
42506
42667
|
async #handleExternalVoiceRequest(request, thread) {
|
|
42507
42668
|
try {
|
|
42508
42669
|
if (request.method === "thread/realtime/start") {
|
|
42509
|
-
await this.#externalVoice.start(
|
|
42670
|
+
await this.#externalVoice.start(
|
|
42671
|
+
thread.id,
|
|
42672
|
+
requestObject(request),
|
|
42673
|
+
voiceSessionInputFromTurns(thread.turns)
|
|
42674
|
+
);
|
|
42510
42675
|
} else if (request.method === "thread/realtime/stop") {
|
|
42511
42676
|
await this.#externalVoice.stop(thread.id);
|
|
42512
42677
|
} else {
|
|
@@ -42751,9 +42916,7 @@ var AppServerHost = class {
|
|
|
42751
42916
|
if (typeof requestedTurnId === "string")
|
|
42752
42917
|
this.#externalSteering.interrupt(thread.id, requestedTurnId);
|
|
42753
42918
|
if (typeof requestedTurnId !== "string" || !thread.running || thread.activeTurnId !== requestedTurnId) {
|
|
42754
|
-
await this.#writer.json(
|
|
42755
|
-
rpcError(request, -32074, "External turn/interrupt must reference the active Turn")
|
|
42756
|
-
);
|
|
42919
|
+
await this.#writer.json(rpcEnvelope(request, { result: {} }));
|
|
42757
42920
|
return;
|
|
42758
42921
|
}
|
|
42759
42922
|
const turnId = thread.activeTurnId;
|
|
@@ -43038,7 +43201,11 @@ var AppServerHost = class {
|
|
|
43038
43201
|
thread.projectedTurns.delete(event.turnId);
|
|
43039
43202
|
}
|
|
43040
43203
|
for (const message2 of result.messages) await this.#writer.json(message2);
|
|
43041
|
-
this.#externalVoiceResults.observe(
|
|
43204
|
+
this.#externalVoiceResults.observe(
|
|
43205
|
+
thread.id,
|
|
43206
|
+
event,
|
|
43207
|
+
event.type === "turn.completed" ? result.completedTurn : void 0
|
|
43208
|
+
);
|
|
43042
43209
|
if (event.type === "turn.completed") {
|
|
43043
43210
|
await this.#setThreadStatus(
|
|
43044
43211
|
thread,
|
|
@@ -43083,7 +43250,7 @@ var AppServerHost = class {
|
|
|
43083
43250
|
const previousItems = new Map(
|
|
43084
43251
|
child.turns.flatMap(
|
|
43085
43252
|
(turn) => Array.isArray(turn.items) ? turn.items.flatMap(
|
|
43086
|
-
(item) =>
|
|
43253
|
+
(item) => isRecord20(item) && typeof item.id === "string" ? [[item.id, JSON.stringify(item)]] : []
|
|
43087
43254
|
) : []
|
|
43088
43255
|
)
|
|
43089
43256
|
);
|
|
@@ -43096,7 +43263,7 @@ var AppServerHost = class {
|
|
|
43096
43263
|
for (const turn of child.turns) {
|
|
43097
43264
|
if (typeof turn.id !== "string" || !Array.isArray(turn.items)) continue;
|
|
43098
43265
|
const changedItems = turn.items.filter(
|
|
43099
|
-
(item) =>
|
|
43266
|
+
(item) => isRecord20(item) && typeof item.id === "string" && previousItems.get(item.id) !== JSON.stringify(item)
|
|
43100
43267
|
);
|
|
43101
43268
|
if (changedItems.length > 0) {
|
|
43102
43269
|
await this.#writer.json({
|
|
@@ -43228,7 +43395,7 @@ var AppServerHost = class {
|
|
|
43228
43395
|
}
|
|
43229
43396
|
}
|
|
43230
43397
|
async #handleDesktopApprovalResponse(value2) {
|
|
43231
|
-
if (!
|
|
43398
|
+
if (!isRecord20(value2) || !isHostApprovalRequestId(value2.id)) return false;
|
|
43232
43399
|
const requestId = value2.id;
|
|
43233
43400
|
const pending = this.#pendingDesktopApprovals.get(requestId);
|
|
43234
43401
|
if (!pending) return true;
|
|
@@ -43357,7 +43524,7 @@ var AppServerHost = class {
|
|
|
43357
43524
|
}
|
|
43358
43525
|
}
|
|
43359
43526
|
async #handleDesktopQuestionResponse(value2) {
|
|
43360
|
-
if (!
|
|
43527
|
+
if (!isRecord20(value2) || !isHostQuestionRequestId(value2.id)) return false;
|
|
43361
43528
|
const requestId = value2.id;
|
|
43362
43529
|
const pending = this.#pendingDesktopQuestions.get(requestId);
|
|
43363
43530
|
if (!pending) return true;
|