@karlorz/codexhost-cli-win32-arm64 0.13.3-7 → 0.14.0-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/app/codexhost-distribution.json +1 -1
- package/app/console-server.mjs +55 -4
- package/app/console-web.js +344 -54
- package/app/cpa-live-voice-hook.js +55 -4
- package/app/desktop-controller.mjs +69 -8
- package/app/host-runtime.mjs +743 -230
- package/app/plugins/antigravity/plugin.mjs +88 -12
- package/app/plugins/claude-code/plugin.mjs +397 -21
- package/app/plugins/codebuddy/plugin.mjs +107 -17
- package/app/plugins/codex-usage/plugin.mjs +67 -7
- package/app/plugins/copilot/assets/icon.png +0 -0
- package/app/plugins/copilot/manifest.json +26 -0
- package/app/plugins/copilot/plugin.mjs +34645 -0
- package/app/plugins/cursor-cli/plugin.mjs +88 -6
- package/app/plugins/deepseek-harness/plugin.mjs +73 -6
- package/app/plugins/enabled.json +1 -0
- package/app/plugins/grok/plugin.mjs +272 -60
- package/app/plugins/hermes/plugin.mjs +70 -4
- package/app/plugins/kimi-code/plugin.mjs +73 -6
- package/app/plugins/kiro-cli/plugin.mjs +73 -6
- package/app/plugins/omp/plugin.mjs +73 -112
- package/app/plugins/opencode/plugin.mjs +75 -6
- package/app/plugins/pi/plugin.mjs +204 -44
- package/app/plugins/qoder/plugin.mjs +73 -6
- package/app/plugins/qoder-cn/plugin.mjs +73 -6
- package/app/plugins/workbuddy/plugin.mjs +368 -41
- package/app/plugins/zcode/plugin.mjs +74 -6
- package/app/renderer-extension.js +749 -157
- 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
|
@@ -6155,9 +6155,9 @@ function floatSafeRemainder(val, step) {
|
|
|
6155
6155
|
return ratio - roundedRatio;
|
|
6156
6156
|
}
|
|
6157
6157
|
var EVALUATING = /* @__PURE__ */ Symbol("evaluating");
|
|
6158
|
-
function defineLazy(
|
|
6158
|
+
function defineLazy(object10, key, getter) {
|
|
6159
6159
|
let value2 = void 0;
|
|
6160
|
-
Object.defineProperty(
|
|
6160
|
+
Object.defineProperty(object10, key, {
|
|
6161
6161
|
get() {
|
|
6162
6162
|
if (value2 === EVALUATING) {
|
|
6163
6163
|
return void 0;
|
|
@@ -6169,7 +6169,7 @@ function defineLazy(object9, key, getter) {
|
|
|
6169
6169
|
return value2;
|
|
6170
6170
|
},
|
|
6171
6171
|
set(v) {
|
|
6172
|
-
Object.defineProperty(
|
|
6172
|
+
Object.defineProperty(object10, key, {
|
|
6173
6173
|
value: v
|
|
6174
6174
|
// configurable: true,
|
|
6175
6175
|
});
|
|
@@ -20094,10 +20094,19 @@ var model = external_exports.string().min(1).max(512);
|
|
|
20094
20094
|
var project = external_exports.string().min(1).max(4096);
|
|
20095
20095
|
var usageStatisticsParamsSchema = external_exports.strictObject({
|
|
20096
20096
|
range: external_exports.enum(USAGE_STATISTICS_RANGES),
|
|
20097
|
+
/** Display timezone for ranges, dates and hourly buckets; omitted means the Host's local zone. */
|
|
20098
|
+
timeZone: external_exports.string().min(1).max(128).refine((value2) => {
|
|
20099
|
+
try {
|
|
20100
|
+
new Intl.DateTimeFormat("en", { timeZone: value2 });
|
|
20101
|
+
return true;
|
|
20102
|
+
} catch {
|
|
20103
|
+
return false;
|
|
20104
|
+
}
|
|
20105
|
+
}, "Unsupported usage statistics timezone").optional(),
|
|
20097
20106
|
harness: harness.optional(),
|
|
20098
20107
|
model: model.nullable().optional(),
|
|
20099
20108
|
project: project.nullable().optional(),
|
|
20100
|
-
/** One
|
|
20109
|
+
/** One date in the query timezone inside the range. */
|
|
20101
20110
|
date: localDate.optional()
|
|
20102
20111
|
});
|
|
20103
20112
|
var usageStatisticsTotalsSchema = external_exports.strictObject({
|
|
@@ -20133,7 +20142,7 @@ var usageStatisticsSessionSchema = external_exports.strictObject({
|
|
|
20133
20142
|
});
|
|
20134
20143
|
var usageStatisticsResultSchema = external_exports.strictObject({
|
|
20135
20144
|
range: external_exports.enum(USAGE_STATISTICS_RANGES),
|
|
20136
|
-
/** First
|
|
20145
|
+
/** First date in the query timezone (Host local when omitted); null for all time. */
|
|
20137
20146
|
from: localDate.nullable(),
|
|
20138
20147
|
to: localDate,
|
|
20139
20148
|
/** The filters these figures apply, echoed so a late answer to older filters is recognised. */
|
|
@@ -20173,7 +20182,7 @@ var usageStatisticsResultSchema = external_exports.strictObject({
|
|
|
20173
20182
|
totals: usageStatisticsTotalsSchema,
|
|
20174
20183
|
/** Each date and Harness of the range: every filter except the day. */
|
|
20175
20184
|
daily: external_exports.array(external_exports.strictObject({ date: localDate, harness, ...totals })).max(2e5),
|
|
20176
|
-
/**
|
|
20185
|
+
/** Weekday (0 = Sunday) and hour in the query timezone, all filters applied. */
|
|
20177
20186
|
hourly: external_exports.array(external_exports.strictObject({
|
|
20178
20187
|
weekday: external_exports.number().int().min(0).max(6),
|
|
20179
20188
|
hour: external_exports.number().int().min(0).max(23),
|
|
@@ -20286,6 +20295,8 @@ var CONSOLE_HOST_METHODS = Object.freeze([
|
|
|
20286
20295
|
"codexhost/harness/display-settings/set",
|
|
20287
20296
|
"codexhost/harness/inspect",
|
|
20288
20297
|
"codexhost/harness/installation",
|
|
20298
|
+
"codexhost/harness/installation/start",
|
|
20299
|
+
"codexhost/harness/installation/status",
|
|
20289
20300
|
"codexhost/harness/launch-settings/get",
|
|
20290
20301
|
"codexhost/harness/launch-settings/set",
|
|
20291
20302
|
"codexhost/harness/grok-computer-use/get",
|
|
@@ -20369,7 +20380,18 @@ var threadManualCompactionStartedSchema = external_exports.strictObject({
|
|
|
20369
20380
|
var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
|
|
20370
20381
|
var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
|
|
20371
20382
|
var cacheHitRatePercentSchema = external_exports.number().finite().min(0).max(100);
|
|
20383
|
+
var indicatorTextSchema = (maximum) => harnessLocalizedTextSchema.refine((entries) => Object.values(entries).every((text) => text.length <= maximum));
|
|
20384
|
+
var composerIndicatorsSchema = external_exports.array(external_exports.object({
|
|
20385
|
+
kind: external_exports.literal("countdown"),
|
|
20386
|
+
id: external_exports.string().min(1).max(64),
|
|
20387
|
+
expiresAtUnix: nonNegativeSafeIntegerSchema,
|
|
20388
|
+
label: indicatorTextSchema(256).optional(),
|
|
20389
|
+
tooltip: indicatorTextSchema(1024).optional()
|
|
20390
|
+
}).strict()).max(2).refine((entries) => new Set(entries.map(({ id: id2 }) => id2)).size === entries.length, {
|
|
20391
|
+
message: "Composer indicator IDs must be unique"
|
|
20392
|
+
});
|
|
20372
20393
|
var threadUsageSnapshotSchema = external_exports.object({
|
|
20394
|
+
composerIndicators: composerIndicatorsSchema.optional(),
|
|
20373
20395
|
inputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
20374
20396
|
cachedInputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
20375
20397
|
cacheWriteInputTokens: nonNegativeSafeIntegerSchema.optional(),
|
|
@@ -20785,7 +20807,9 @@ var harnessSessionCapabilitiesSchema = external_exports.object({
|
|
|
20785
20807
|
}).strict().optional(),
|
|
20786
20808
|
autonomousTurns: external_exports.object({
|
|
20787
20809
|
observe: external_exports.boolean()
|
|
20788
|
-
}).strict().optional()
|
|
20810
|
+
}).strict().optional(),
|
|
20811
|
+
/** True only when `turn.steer` delivers input into the active Turn through a native primitive. */
|
|
20812
|
+
steer: external_exports.boolean().optional()
|
|
20789
20813
|
}).strict();
|
|
20790
20814
|
var harnessConfigurationStateSchema = external_exports.object({
|
|
20791
20815
|
effectiveModel: harnessModelRefSchema.optional(),
|
|
@@ -20918,6 +20942,16 @@ var threadOwnershipListResultSchema = external_exports.object({
|
|
|
20918
20942
|
seen.add(thread.threadId);
|
|
20919
20943
|
}
|
|
20920
20944
|
});
|
|
20945
|
+
var threadSteeringInspectParamsSchema = external_exports.object({
|
|
20946
|
+
threadId: hostThreadIdSchema,
|
|
20947
|
+
/** The text about to be steered; a Harness command always stops and restarts. */
|
|
20948
|
+
text: external_exports.string().optional()
|
|
20949
|
+
}).strict();
|
|
20950
|
+
var THREAD_STEER_DELIVERY_PARAM = "codexhostSteerDelivery";
|
|
20951
|
+
var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
|
|
20952
|
+
var threadSteeringInspectResultSchema = external_exports.object({
|
|
20953
|
+
delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
|
|
20954
|
+
}).strict();
|
|
20921
20955
|
|
|
20922
20956
|
// packages/shared-contracts/dist/harness-plugins.js
|
|
20923
20957
|
var HARNESS_PLUGIN_API_VERSION = 1;
|
|
@@ -21060,6 +21094,8 @@ var grokComputerUseSettingsSchema = external_exports.object({
|
|
|
21060
21094
|
|
|
21061
21095
|
// packages/shared-contracts/dist/harness-installation.js
|
|
21062
21096
|
var HARNESS_INSTALLATION_METHOD = "codexhost/harness/installation";
|
|
21097
|
+
var HARNESS_INSTALLATION_START_METHOD = "codexhost/harness/installation/start";
|
|
21098
|
+
var HARNESS_INSTALLATION_STATUS_METHOD = "codexhost/harness/installation/status";
|
|
21063
21099
|
var harnessInstallationParamsSchema = external_exports.object({
|
|
21064
21100
|
harnessId: harnessIdSchema,
|
|
21065
21101
|
action: external_exports.enum(["check", "update", "install"])
|
|
@@ -21069,6 +21105,10 @@ var harnessInstallationStateSchema = external_exports.object({
|
|
|
21069
21105
|
latestVersion: external_exports.string().min(1).max(128),
|
|
21070
21106
|
updateAvailable: external_exports.boolean(),
|
|
21071
21107
|
canUpdate: external_exports.boolean(),
|
|
21108
|
+
/** Defaults to CLI; some Harnesses ship only inside a desktop application. */
|
|
21109
|
+
versionKind: external_exports.enum(["cli", "application"]).optional(),
|
|
21110
|
+
/** Official download opened by the user; does not imply an automatic installation. */
|
|
21111
|
+
manualUpdateUrl: external_exports.url().max(2048).refine((value2) => /^https:\/\/[^/?#@]+(?:[/?#]|$)/iu.test(value2), "Manual updates require a credential-free HTTPS URL").optional(),
|
|
21072
21112
|
// Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
|
|
21073
21113
|
message: external_exports.string().max(2048).optional(),
|
|
21074
21114
|
messageCode: external_exports.string().min(1).max(128).optional(),
|
|
@@ -21076,6 +21116,20 @@ var harnessInstallationStateSchema = external_exports.object({
|
|
|
21076
21116
|
notice: harnessLocalizedTextSchema.optional(),
|
|
21077
21117
|
latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
|
|
21078
21118
|
}).strict();
|
|
21119
|
+
var harnessInstallationTaskParamsSchema = external_exports.object({ taskId: external_exports.string().uuid() }).strict();
|
|
21120
|
+
var harnessInstallationTaskSchema = external_exports.discriminatedUnion("status", [
|
|
21121
|
+
external_exports.object({ taskId: external_exports.string().uuid(), status: external_exports.literal("running") }).strict(),
|
|
21122
|
+
external_exports.object({
|
|
21123
|
+
taskId: external_exports.string().uuid(),
|
|
21124
|
+
status: external_exports.literal("succeeded"),
|
|
21125
|
+
result: harnessInstallationStateSchema
|
|
21126
|
+
}).strict(),
|
|
21127
|
+
external_exports.object({
|
|
21128
|
+
taskId: external_exports.string().uuid(),
|
|
21129
|
+
status: external_exports.literal("failed"),
|
|
21130
|
+
error: external_exports.object({ code: external_exports.number().int(), message: external_exports.string().min(1).max(2048) }).strict()
|
|
21131
|
+
}).strict()
|
|
21132
|
+
]);
|
|
21079
21133
|
|
|
21080
21134
|
// packages/shared-contracts/dist/codex-accounts.js
|
|
21081
21135
|
var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
|
|
@@ -23918,9 +23972,13 @@ function requestManagerFromHookState(value2, hostId2) {
|
|
|
23918
23972
|
const direct = manager(value2) ?? manager(value2.manager);
|
|
23919
23973
|
if (direct)
|
|
23920
23974
|
return direct;
|
|
23921
|
-
if (!hostId2 || typeof value2.addManager !== "function" || typeof value2.getForHostId !== "function"
|
|
23975
|
+
if (!hostId2 || typeof value2.addManager !== "function" || typeof value2.getForHostId !== "function")
|
|
23922
23976
|
return null;
|
|
23923
|
-
|
|
23977
|
+
try {
|
|
23978
|
+
return manager(value2.getForHostId(hostId2));
|
|
23979
|
+
} catch {
|
|
23980
|
+
return null;
|
|
23981
|
+
}
|
|
23924
23982
|
}
|
|
23925
23983
|
function discoverRendererHosts(root, ancestors = committedReactAncestors, managerFrom = requestManagerFromHookState) {
|
|
23926
23984
|
const editors = [
|
|
@@ -23956,7 +24014,7 @@ function discoverRendererHosts(root, ancestors = committedReactAncestors, manage
|
|
|
23956
24014
|
const manager = managerFrom(value2);
|
|
23957
24015
|
if (manager)
|
|
23958
24016
|
managers.add(manager);
|
|
23959
|
-
if (value2 && typeof value2 === "object" && "addManager" in value2 && typeof value2.addManager === "function" && "getForHostId" in value2 && typeof value2.getForHostId === "function"
|
|
24017
|
+
if (value2 && typeof value2 === "object" && "addManager" in value2 && typeof value2.addManager === "function" && "getForHostId" in value2 && typeof value2.getForHostId === "function") {
|
|
23960
24018
|
registries.add(value2);
|
|
23961
24019
|
}
|
|
23962
24020
|
hook = hook.next && typeof hook.next === "object" ? hook.next : null;
|
|
@@ -23972,7 +24030,13 @@ function discoverRendererHosts(root, ancestors = committedReactAncestors, manage
|
|
|
23972
24030
|
function resolveRendererHostManager(discovery, hostId2, managerFrom = requestManagerFromHookState) {
|
|
23973
24031
|
if (!hostId2)
|
|
23974
24032
|
return null;
|
|
23975
|
-
const candidates = discovery.registries.length ? discovery.registries.
|
|
24033
|
+
const candidates = discovery.registries.length ? discovery.registries.flatMap((registry2) => {
|
|
24034
|
+
try {
|
|
24035
|
+
return [managerFrom(registry2.getForHostId(hostId2))];
|
|
24036
|
+
} catch {
|
|
24037
|
+
return [];
|
|
24038
|
+
}
|
|
24039
|
+
}) : discovery.managers;
|
|
23976
24040
|
const matching = new Set(candidates.filter((manager) => manager && (manager.getHostId?.() ?? manager.requestClient.hostId) === hostId2 && (manager.requestClient.hostId === void 0 || manager.requestClient.hostId === hostId2)));
|
|
23977
24041
|
return matching.size === 1 ? matching.values().next().value ?? null : null;
|
|
23978
24042
|
}
|
|
@@ -25091,6 +25155,36 @@ var ExternalVoice = class {
|
|
|
25091
25155
|
}
|
|
25092
25156
|
};
|
|
25093
25157
|
|
|
25158
|
+
// packages/host-runtime/src/external-voice-presentation.ts
|
|
25159
|
+
var INLINE_MARKDOWN = "::codex-realtime-inline{}\n";
|
|
25160
|
+
var inlineMarker = /^::codex-realtime-inline\{\}\r?\n/u;
|
|
25161
|
+
function externalVoiceContentText(text) {
|
|
25162
|
+
return text.replace(inlineMarker, "");
|
|
25163
|
+
}
|
|
25164
|
+
function object5(value2) {
|
|
25165
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
25166
|
+
}
|
|
25167
|
+
function presentItem(item) {
|
|
25168
|
+
if (!object5(item) || item.type !== "agentMessage" || typeof item.text !== "string") return item;
|
|
25169
|
+
if (!item.text.trim() || inlineMarker.test(item.text)) return item;
|
|
25170
|
+
return { ...item, text: INLINE_MARKDOWN + item.text };
|
|
25171
|
+
}
|
|
25172
|
+
function presentExternalVoiceTurn(turn) {
|
|
25173
|
+
if (!Array.isArray(turn.items)) return turn;
|
|
25174
|
+
return { ...turn, items: turn.items.map(presentItem) };
|
|
25175
|
+
}
|
|
25176
|
+
function presentExternalVoiceMessage(message2) {
|
|
25177
|
+
const params = message2.params;
|
|
25178
|
+
if (!object5(params)) return message2;
|
|
25179
|
+
if ((message2.method === "item/started" || message2.method === "item/completed") && params.item) {
|
|
25180
|
+
return { ...message2, params: { ...params, item: presentItem(params.item) } };
|
|
25181
|
+
}
|
|
25182
|
+
if ((message2.method === "turn/started" || message2.method === "turn/completed") && object5(params.turn)) {
|
|
25183
|
+
return { ...message2, params: { ...params, turn: presentExternalVoiceTurn(params.turn) } };
|
|
25184
|
+
}
|
|
25185
|
+
return message2;
|
|
25186
|
+
}
|
|
25187
|
+
|
|
25094
25188
|
// packages/host-runtime/src/external-voice-session-input.ts
|
|
25095
25189
|
var MAX_MESSAGES = 32;
|
|
25096
25190
|
var MAX_MESSAGE_CHARS = 2e3;
|
|
@@ -25129,7 +25223,7 @@ function voiceSessionInputFromTurns(turns) {
|
|
|
25129
25223
|
const text = userMessageText(item);
|
|
25130
25224
|
if (text) messages.push(liveMessage("user", text));
|
|
25131
25225
|
} else if (item.type === "agentMessage" && item.phase !== "commentary") {
|
|
25132
|
-
const text = typeof item.text === "string" ? item.text.trim() : "";
|
|
25226
|
+
const text = typeof item.text === "string" ? externalVoiceContentText(item.text).trim() : "";
|
|
25133
25227
|
if (text) messages.push(liveMessage("assistant", text));
|
|
25134
25228
|
}
|
|
25135
25229
|
}
|
|
@@ -25159,7 +25253,7 @@ function speakableFromProjectedTurn(turn) {
|
|
|
25159
25253
|
function speakableFromItems(items) {
|
|
25160
25254
|
const values = [...items];
|
|
25161
25255
|
const finals = values.filter((item) => item.phase === "final_answer");
|
|
25162
|
-
const text = (finals.length ? finals : values.filter((item) => item.phase !== "commentary").slice(-1)).map((item) => item.text).join("\n").trim();
|
|
25256
|
+
const text = (finals.length ? finals : values.filter((item) => item.phase !== "commentary").slice(-1)).map((item) => externalVoiceContentText(item.text)).join("\n").trim();
|
|
25163
25257
|
return text.length > 0 ? text : void 0;
|
|
25164
25258
|
}
|
|
25165
25259
|
var ExternalVoiceResults = class {
|
|
@@ -25259,7 +25353,7 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
|
25259
25353
|
var wrapper_default = import_websocket.default;
|
|
25260
25354
|
|
|
25261
25355
|
// packages/host-runtime/src/external-voice-gateway.ts
|
|
25262
|
-
function
|
|
25356
|
+
function object6(value2) {
|
|
25263
25357
|
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
25264
25358
|
}
|
|
25265
25359
|
function configuredExternalVoiceGateway(environment) {
|
|
@@ -25342,7 +25436,7 @@ function configuredExternalVoiceGateway(environment) {
|
|
|
25342
25436
|
if (closed || input.signal.aborted) return;
|
|
25343
25437
|
try {
|
|
25344
25438
|
const event = JSON.parse(String(raw));
|
|
25345
|
-
if (
|
|
25439
|
+
if (object6(event) && typeof event.type === "string")
|
|
25346
25440
|
input.onEvent(event);
|
|
25347
25441
|
} catch {
|
|
25348
25442
|
input.onError();
|
|
@@ -25962,6 +26056,64 @@ async function handleHarnessInstallation(params, adapters) {
|
|
|
25962
26056
|
}
|
|
25963
26057
|
}
|
|
25964
26058
|
|
|
26059
|
+
// packages/host-runtime/src/harness-installation-tasks.ts
|
|
26060
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
26061
|
+
var HarnessInstallationTasks = class {
|
|
26062
|
+
#tasks = /* @__PURE__ */ new Map();
|
|
26063
|
+
#active = /* @__PURE__ */ new Map();
|
|
26064
|
+
#prune() {
|
|
26065
|
+
const cutoff = Date.now() - 15 * 6e4;
|
|
26066
|
+
for (const [id2, task] of this.#tasks) {
|
|
26067
|
+
if (task.finishedAt !== void 0 && task.finishedAt < cutoff) this.#tasks.delete(id2);
|
|
26068
|
+
}
|
|
26069
|
+
}
|
|
26070
|
+
start(params, adapters) {
|
|
26071
|
+
const parsed2 = harnessInstallationParamsSchema.safeParse(params);
|
|
26072
|
+
if (!parsed2.success)
|
|
26073
|
+
throw new HarnessInstallationError(-32602, "Invalid Harness installation request");
|
|
26074
|
+
this.#prune();
|
|
26075
|
+
const key = JSON.stringify([parsed2.data.harnessId, parsed2.data.action]);
|
|
26076
|
+
const activeId = this.#active.get(key);
|
|
26077
|
+
const active = activeId ? this.#tasks.get(activeId) : void 0;
|
|
26078
|
+
if (active) return active.state;
|
|
26079
|
+
const taskId = randomUUID5();
|
|
26080
|
+
const task = {
|
|
26081
|
+
state: { taskId, status: "running" }
|
|
26082
|
+
};
|
|
26083
|
+
this.#tasks.set(taskId, task);
|
|
26084
|
+
this.#active.set(key, taskId);
|
|
26085
|
+
void handleHarnessInstallation(parsed2.data, adapters).then(
|
|
26086
|
+
(result) => {
|
|
26087
|
+
task.state = { taskId, status: "succeeded", result };
|
|
26088
|
+
},
|
|
26089
|
+
(error51) => {
|
|
26090
|
+
task.state = {
|
|
26091
|
+
taskId,
|
|
26092
|
+
status: "failed",
|
|
26093
|
+
error: error51 instanceof HarnessInstallationError ? { code: error51.code, message: error51.message } : { code: -32077, message: "Harness version management failed" }
|
|
26094
|
+
};
|
|
26095
|
+
}
|
|
26096
|
+
).finally(() => {
|
|
26097
|
+
task.finishedAt = Date.now();
|
|
26098
|
+
this.#active.delete(key);
|
|
26099
|
+
});
|
|
26100
|
+
return task.state;
|
|
26101
|
+
}
|
|
26102
|
+
status(params) {
|
|
26103
|
+
const parsed2 = harnessInstallationTaskParamsSchema.safeParse(params);
|
|
26104
|
+
if (!parsed2.success)
|
|
26105
|
+
throw new HarnessInstallationError(-32602, "Invalid Harness installation task request");
|
|
26106
|
+
this.#prune();
|
|
26107
|
+
const task = this.#tasks.get(parsed2.data.taskId);
|
|
26108
|
+
if (!task)
|
|
26109
|
+
throw new HarnessInstallationError(
|
|
26110
|
+
-32079,
|
|
26111
|
+
"Harness installation task is unavailable on this Host"
|
|
26112
|
+
);
|
|
26113
|
+
return task.state;
|
|
26114
|
+
}
|
|
26115
|
+
};
|
|
26116
|
+
|
|
25965
26117
|
// packages/host-runtime/src/account/codex-credential-export.ts
|
|
25966
26118
|
import { createHash as createHash3 } from "node:crypto";
|
|
25967
26119
|
import { readFile as readFile10 } from "node:fs/promises";
|
|
@@ -26054,7 +26206,7 @@ async function listOthers(adapter) {
|
|
|
26054
26206
|
}
|
|
26055
26207
|
|
|
26056
26208
|
// packages/host-runtime/src/harness-display-settings.ts
|
|
26057
|
-
import { randomUUID as
|
|
26209
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
26058
26210
|
import { link, mkdir as mkdir8, readFile as readFile11, rename as rename5, rm as rm7, writeFile as writeFile7 } from "node:fs/promises";
|
|
26059
26211
|
import os5 from "node:os";
|
|
26060
26212
|
import path16 from "node:path";
|
|
@@ -26079,7 +26231,7 @@ var HarnessDisplaySettingsStore = class {
|
|
|
26079
26231
|
async set(input) {
|
|
26080
26232
|
const entries = harnessDisplayEntriesSchema.parse(input.entries);
|
|
26081
26233
|
await mkdir8(path16.dirname(this.#file), { recursive: true, mode: 448 });
|
|
26082
|
-
const temporary = `${this.#file}.${
|
|
26234
|
+
const temporary = `${this.#file}.${randomUUID6()}.tmp`;
|
|
26083
26235
|
try {
|
|
26084
26236
|
await writeFile7(temporary, `${JSON.stringify(entries)}
|
|
26085
26237
|
`, { mode: 384, flag: "wx" });
|
|
@@ -26100,7 +26252,7 @@ var HarnessDisplaySettingsStore = class {
|
|
|
26100
26252
|
};
|
|
26101
26253
|
|
|
26102
26254
|
// packages/host-runtime/src/model-price-overrides-file.ts
|
|
26103
|
-
import { randomUUID as
|
|
26255
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
26104
26256
|
import { mkdir as mkdir10, readFile as readFile13, rename as rename7, rm as rm8, writeFile as writeFile9 } from "node:fs/promises";
|
|
26105
26257
|
import path18 from "node:path";
|
|
26106
26258
|
|
|
@@ -26675,7 +26827,7 @@ async function updateModelPriceOverridesFile(file2, change) {
|
|
|
26675
26827
|
const updated = { ...document, models: next };
|
|
26676
26828
|
parseModelPriceOverrides(updated);
|
|
26677
26829
|
await mkdir10(path18.dirname(file2), { recursive: true });
|
|
26678
|
-
const temporary = `${file2}.${
|
|
26830
|
+
const temporary = `${file2}.${randomUUID7()}.tmp`;
|
|
26679
26831
|
try {
|
|
26680
26832
|
await writeFile9(temporary, `${JSON.stringify(updated, null, 2)}
|
|
26681
26833
|
`, { flag: "wx" });
|
|
@@ -26711,7 +26863,7 @@ async function handleModelPriceOverridesRequest(catalog, method, params) {
|
|
|
26711
26863
|
}
|
|
26712
26864
|
|
|
26713
26865
|
// packages/host-runtime/src/delegation-skill.ts
|
|
26714
|
-
import { createHash as createHash4, randomUUID as
|
|
26866
|
+
import { createHash as createHash4, randomUUID as randomUUID8 } from "node:crypto";
|
|
26715
26867
|
import { mkdir as mkdir11, open as open4, readFile as readFile14, rename as rename8, rm as rm9, stat as stat5 } from "node:fs/promises";
|
|
26716
26868
|
import os7 from "node:os";
|
|
26717
26869
|
import path19 from "node:path";
|
|
@@ -26811,7 +26963,7 @@ async function readOptional(filePath) {
|
|
|
26811
26963
|
}
|
|
26812
26964
|
async function atomicWrite(filePath, content) {
|
|
26813
26965
|
await mkdir11(path19.dirname(filePath), { recursive: true, mode: 448 });
|
|
26814
|
-
const temporaryPath = path19.join(path19.dirname(filePath), `.SKILL.md.${
|
|
26966
|
+
const temporaryPath = path19.join(path19.dirname(filePath), `.SKILL.md.${randomUUID8()}.tmp`);
|
|
26815
26967
|
const handle = await open4(temporaryPath, "wx", 384);
|
|
26816
26968
|
try {
|
|
26817
26969
|
await handle.writeFile(content, "utf8");
|
|
@@ -27048,6 +27200,7 @@ var usageFields = /* @__PURE__ */ new Set([
|
|
|
27048
27200
|
...safeIntegerFields,
|
|
27049
27201
|
...percentFields,
|
|
27050
27202
|
"sessionCacheUsage",
|
|
27203
|
+
"composerIndicators",
|
|
27051
27204
|
"totalCostUsd",
|
|
27052
27205
|
"totalCredits",
|
|
27053
27206
|
"contextUsagePercent",
|
|
@@ -27070,6 +27223,7 @@ function parseHostUsage(value2) {
|
|
|
27070
27223
|
throw new Error(`Harness Usage contains unknown field '${key}'`);
|
|
27071
27224
|
}
|
|
27072
27225
|
}
|
|
27226
|
+
const indicators = value2.composerIndicators === void 0 ? {} : { composerIndicators: composerIndicatorsSchema.parse(value2.composerIndicators) };
|
|
27073
27227
|
for (const field of [
|
|
27074
27228
|
"totalCredits",
|
|
27075
27229
|
"contextUsagePercent",
|
|
@@ -27140,9 +27294,9 @@ function parseHostUsage(value2) {
|
|
|
27140
27294
|
if (value2.costSource !== "publicPrice") {
|
|
27141
27295
|
throw new Error("Harness Usage 'unpricedModels' must be provided with a 'publicPrice' cost");
|
|
27142
27296
|
}
|
|
27143
|
-
return { ...value2, unpricedModels: [...models] };
|
|
27297
|
+
return { ...value2, ...indicators, unpricedModels: [...models] };
|
|
27144
27298
|
}
|
|
27145
|
-
return { ...value2 };
|
|
27299
|
+
return { ...value2, ...indicators };
|
|
27146
27300
|
}
|
|
27147
27301
|
var requestTokenFields = [
|
|
27148
27302
|
"inputTokens",
|
|
@@ -27293,7 +27447,7 @@ var packageMetadata = {
|
|
|
27293
27447
|
|
|
27294
27448
|
// packages/mapping-store/dist/mapping-store.js
|
|
27295
27449
|
import { execFileSync } from "node:child_process";
|
|
27296
|
-
import { randomUUID as
|
|
27450
|
+
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
27297
27451
|
import { constants as constants3 } from "node:fs";
|
|
27298
27452
|
import { copyFile as copyFile3, mkdir as mkdir13, open as open7, readFile as readFile17, readdir as readdir4, rename as rename11, rm as rm12, stat as stat6 } from "node:fs/promises";
|
|
27299
27453
|
import path21 from "node:path";
|
|
@@ -27309,7 +27463,9 @@ var isoDateSchema = external_exports.string().refine((value2) => !Number.isNaN(D
|
|
|
27309
27463
|
var storedTurnMappingV1Schema = external_exports.object({
|
|
27310
27464
|
hostTurnId: hostTurnIdSchema,
|
|
27311
27465
|
nativeTurnRef: nativeTurnRefSchema,
|
|
27312
|
-
nativeCheckpointRef: nativeCheckpointRefSchema.optional()
|
|
27466
|
+
nativeCheckpointRef: nativeCheckpointRefSchema.optional(),
|
|
27467
|
+
/** Desktop presentation for work completed during an external voice call. */
|
|
27468
|
+
realtimeInline: external_exports.literal(true).optional()
|
|
27313
27469
|
}).strict();
|
|
27314
27470
|
var storedGitInfoV1Schema = external_exports.object({
|
|
27315
27471
|
branch: nonBlankTextSchema6.max(4096).optional(),
|
|
@@ -27449,7 +27605,7 @@ var storedDelegationRecordV1Schema = external_exports.object({
|
|
|
27449
27605
|
});
|
|
27450
27606
|
|
|
27451
27607
|
// packages/mapping-store/dist/section-placements.js
|
|
27452
|
-
import { randomUUID as
|
|
27608
|
+
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
27453
27609
|
import { constants } from "node:fs";
|
|
27454
27610
|
import { open as open5, readFile as readFile15, rename as rename9, rm as rm10 } from "node:fs/promises";
|
|
27455
27611
|
var threadIdSchema = external_exports.string().min(1).max(1024);
|
|
@@ -27501,7 +27657,7 @@ async function readSectionPlacementsFile(file2) {
|
|
|
27501
27657
|
}
|
|
27502
27658
|
async function writeSectionPlacementsFile(file2, placements) {
|
|
27503
27659
|
const parsed2 = parseSectionPlacements({ formatVersion: 1, placements });
|
|
27504
|
-
const temp = `${file2}.tmp-${
|
|
27660
|
+
const temp = `${file2}.tmp-${randomUUID9()}`;
|
|
27505
27661
|
let handle = null;
|
|
27506
27662
|
try {
|
|
27507
27663
|
handle = await open5(temp, "wx", constants.S_IRUSR | constants.S_IWUSR);
|
|
@@ -27520,7 +27676,7 @@ async function writeSectionPlacementsFile(file2, placements) {
|
|
|
27520
27676
|
}
|
|
27521
27677
|
|
|
27522
27678
|
// packages/mapping-store/dist/superseded-sessions.js
|
|
27523
|
-
import { randomUUID as
|
|
27679
|
+
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
27524
27680
|
import { constants as constants2 } from "node:fs";
|
|
27525
27681
|
import { mkdir as mkdir12, open as open6, readFile as readFile16, rename as rename10, rm as rm11 } from "node:fs/promises";
|
|
27526
27682
|
import path20 from "node:path";
|
|
@@ -27555,7 +27711,7 @@ async function writeSupersededSessionsFile(file2, sessions) {
|
|
|
27555
27711
|
formatVersion: 1,
|
|
27556
27712
|
sessions: sessions.slice(-SUPERSEDED_SESSIONS_MAX)
|
|
27557
27713
|
}).sessions;
|
|
27558
|
-
const temp = `${file2}.tmp-${
|
|
27714
|
+
const temp = `${file2}.tmp-${randomUUID10()}`;
|
|
27559
27715
|
let handle = null;
|
|
27560
27716
|
try {
|
|
27561
27717
|
await mkdir12(path20.dirname(file2), { recursive: true });
|
|
@@ -27810,7 +27966,7 @@ var MappingStore = class {
|
|
|
27810
27966
|
this.#sectionsDirectory = path21.join(this.#directory, "sections");
|
|
27811
27967
|
this.#metadataDirectory = path21.join(this.#directory, "thread-metadata");
|
|
27812
27968
|
this.#lockPath = path21.join(this.#directory, "store.lock");
|
|
27813
|
-
this.#instanceId = options2.instanceId ??
|
|
27969
|
+
this.#instanceId = options2.instanceId ?? randomUUID11();
|
|
27814
27970
|
this.#now = options2.now ?? (() => /* @__PURE__ */ new Date());
|
|
27815
27971
|
this.#beforeReplace = options2.beforeReplace;
|
|
27816
27972
|
}
|
|
@@ -28318,6 +28474,8 @@ var MappingStore = class {
|
|
|
28318
28474
|
if (!hostMatch.nativeCheckpointRef && update.nativeCheckpointRef) {
|
|
28319
28475
|
hostMatch.nativeCheckpointRef = update.nativeCheckpointRef;
|
|
28320
28476
|
}
|
|
28477
|
+
if (update.realtimeInline)
|
|
28478
|
+
hostMatch.realtimeInline = true;
|
|
28321
28479
|
continue;
|
|
28322
28480
|
}
|
|
28323
28481
|
const added = { ...update };
|
|
@@ -28334,7 +28492,7 @@ var MappingStore = class {
|
|
|
28334
28492
|
this.#rebuildIndexes();
|
|
28335
28493
|
}
|
|
28336
28494
|
async #replaceFile(target, record4, preserveBackup) {
|
|
28337
|
-
const temp = `${target}.tmp-${
|
|
28495
|
+
const temp = `${target}.tmp-${randomUUID11()}`;
|
|
28338
28496
|
let handle = null;
|
|
28339
28497
|
try {
|
|
28340
28498
|
await this.#beforeReplace?.(cloneRecord(record4));
|
|
@@ -28361,7 +28519,7 @@ var MappingStore = class {
|
|
|
28361
28519
|
/** Atomically patches owned metadata fields, retaining unknown fields on disk. */
|
|
28362
28520
|
async #writeMetadataFile(hostThreadId, metadata) {
|
|
28363
28521
|
const target = this.#metadataPath(hostThreadId);
|
|
28364
|
-
const temp = `${target}.tmp-${
|
|
28522
|
+
const temp = `${target}.tmp-${randomUUID11()}`;
|
|
28365
28523
|
let handle = null;
|
|
28366
28524
|
try {
|
|
28367
28525
|
const retained = Object.fromEntries(Object.entries(await this.#readMetadata(hostThreadId) ?? {}).filter(([name]) => !["formatVersion", "hostThreadId", ...THREAD_METADATA_FIELDS].includes(name)));
|
|
@@ -28408,7 +28566,7 @@ var MappingStore = class {
|
|
|
28408
28566
|
}
|
|
28409
28567
|
async #replaceDelegationFile(record4) {
|
|
28410
28568
|
const target = this.#delegationPath(record4.delegationId);
|
|
28411
|
-
const temp = `${target}.tmp-${
|
|
28569
|
+
const temp = `${target}.tmp-${randomUUID11()}`;
|
|
28412
28570
|
let handle = null;
|
|
28413
28571
|
try {
|
|
28414
28572
|
handle = await open7(temp, "wx", constants3.S_IRUSR | constants3.S_IWUSR);
|
|
@@ -30100,8 +30258,18 @@ function projectSubagentActivities(item) {
|
|
|
30100
30258
|
];
|
|
30101
30259
|
});
|
|
30102
30260
|
}
|
|
30261
|
+
function projectUserMessage(item, clientId) {
|
|
30262
|
+
return {
|
|
30263
|
+
id: item.itemId,
|
|
30264
|
+
type: "userMessage",
|
|
30265
|
+
clientId,
|
|
30266
|
+
content: item.input.map(({ text }) => ({ type: "text", text, text_elements: [] }))
|
|
30267
|
+
};
|
|
30268
|
+
}
|
|
30103
30269
|
function projectItem(item, outcome, defaultCwd, includeCommandOutput = true) {
|
|
30104
30270
|
switch (item.type) {
|
|
30271
|
+
case "userMessage":
|
|
30272
|
+
return projectUserMessage(item, null);
|
|
30105
30273
|
case "agentMessage":
|
|
30106
30274
|
return {
|
|
30107
30275
|
id: item.itemId,
|
|
@@ -30307,6 +30475,7 @@ var CodexTurnProjector = class {
|
|
|
30307
30475
|
#interactions = /* @__PURE__ */ new Map();
|
|
30308
30476
|
#items = /* @__PURE__ */ new Map();
|
|
30309
30477
|
#wireItemOrder = [];
|
|
30478
|
+
#userMessageClientIds = /* @__PURE__ */ new Map();
|
|
30310
30479
|
#startedAt;
|
|
30311
30480
|
#startedAtMs;
|
|
30312
30481
|
#threadId;
|
|
@@ -30348,6 +30517,10 @@ var CodexTurnProjector = class {
|
|
|
30348
30517
|
}
|
|
30349
30518
|
return items;
|
|
30350
30519
|
}
|
|
30520
|
+
/** Associate steered input with the Desktop message that submitted it, before it is published. */
|
|
30521
|
+
bindUserMessageClientId(itemId, clientId) {
|
|
30522
|
+
this.#userMessageClientIds.set(itemId, clientId);
|
|
30523
|
+
}
|
|
30351
30524
|
pendingTurn(startedAt = null) {
|
|
30352
30525
|
return {
|
|
30353
30526
|
id: this.#turnId,
|
|
@@ -30358,6 +30531,8 @@ var CodexTurnProjector = class {
|
|
|
30358
30531
|
const projected = this.#items.get(itemId);
|
|
30359
30532
|
if (!projected?.wireStarted)
|
|
30360
30533
|
return [];
|
|
30534
|
+
if (projected.item.type === "userMessage")
|
|
30535
|
+
return [this.#projectItem(projected.item)];
|
|
30361
30536
|
if (projected.item.type === "agentMessage") {
|
|
30362
30537
|
return [projectItem(projected.item, projected.outcome, this.#cwd)];
|
|
30363
30538
|
}
|
|
@@ -30690,7 +30865,7 @@ var CodexTurnProjector = class {
|
|
|
30690
30865
|
};
|
|
30691
30866
|
}
|
|
30692
30867
|
const messages = [
|
|
30693
|
-
completedItem(projectItem(projected.item, projected.outcome,
|
|
30868
|
+
completedItem(this.#projectItem(projected.item, projected.outcome, !projected.streamedCommandOutput))
|
|
30694
30869
|
];
|
|
30695
30870
|
if (projected.item.type === "reasoning") {
|
|
30696
30871
|
const reasoning = projected.item;
|
|
@@ -30755,6 +30930,8 @@ var CodexTurnProjector = class {
|
|
|
30755
30930
|
projectReasoningTranscriptItem(reasoning, projected.outcome, this.#cwd, projected.durationMs ?? null)
|
|
30756
30931
|
];
|
|
30757
30932
|
}
|
|
30933
|
+
if (projected.item.type === "userMessage")
|
|
30934
|
+
return [this.#projectItem(projected.item)];
|
|
30758
30935
|
if (projected.item.type === "agentMessage") {
|
|
30759
30936
|
return [projectItem(projected.item, projected.outcome, this.#cwd)];
|
|
30760
30937
|
}
|
|
@@ -30853,10 +31030,13 @@ var CodexTurnProjector = class {
|
|
|
30853
31030
|
threadId: this.#threadId,
|
|
30854
31031
|
turnId: this.#turnId,
|
|
30855
31032
|
startedAtMs,
|
|
30856
|
-
item: projectItem(item, null
|
|
31033
|
+
item: this.#projectItem(item, null)
|
|
30857
31034
|
}
|
|
30858
31035
|
};
|
|
30859
31036
|
}
|
|
31037
|
+
#projectItem(item, outcome = null, includeCommandOutput = true) {
|
|
31038
|
+
return item.type === "userMessage" ? projectUserMessage(item, this.#userMessageClientIds.get(item.itemId) ?? null) : projectItem(item, outcome, this.#cwd, includeCommandOutput);
|
|
31039
|
+
}
|
|
30860
31040
|
#startReasoningTranscript(item, startedAtMs) {
|
|
30861
31041
|
return {
|
|
30862
31042
|
method: "item/started",
|
|
@@ -32008,7 +32188,7 @@ var AccountRateLimits = class {
|
|
|
32008
32188
|
};
|
|
32009
32189
|
|
|
32010
32190
|
// packages/host-runtime/src/native-account-observer.ts
|
|
32011
|
-
var
|
|
32191
|
+
var object7 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
32012
32192
|
var NativeAccountObserver = class {
|
|
32013
32193
|
constructor(input) {
|
|
32014
32194
|
this.input = input;
|
|
@@ -32031,7 +32211,7 @@ var NativeAccountObserver = class {
|
|
|
32031
32211
|
}
|
|
32032
32212
|
/** Called after forwarding the native frame. Identity read failure cannot alter its outcome. */
|
|
32033
32213
|
observe(value2) {
|
|
32034
|
-
if (!
|
|
32214
|
+
if (!object7(value2) || value2.method !== "account/updated" && value2.method !== "account/login/completed" || !this.input.control.refresh || !this.#ready())
|
|
32035
32215
|
return;
|
|
32036
32216
|
this.#collectRequested = true;
|
|
32037
32217
|
if (this.#collecting) return;
|
|
@@ -32070,13 +32250,13 @@ var NativeAccountObserver = class {
|
|
|
32070
32250
|
const generation = scope.owner.generation;
|
|
32071
32251
|
this.#lastGeneration = generation;
|
|
32072
32252
|
const response = await scope.owner.controlRequest("account/read", { refreshToken: false });
|
|
32073
|
-
if (response.error || !
|
|
32253
|
+
if (response.error || !object7(response.result))
|
|
32074
32254
|
throw new Error("Invalid native Account response");
|
|
32075
32255
|
const account = response.result.account;
|
|
32076
32256
|
let params;
|
|
32077
32257
|
if (account === null) params = { authMode: null, planType: null };
|
|
32078
32258
|
else {
|
|
32079
|
-
if (!
|
|
32259
|
+
if (!object7(account) || account.type !== "chatgpt")
|
|
32080
32260
|
throw new Error("Invalid native Account response");
|
|
32081
32261
|
params = {
|
|
32082
32262
|
authMode: "chatgpt",
|
|
@@ -32248,7 +32428,7 @@ var HarnessAccountInspectionCache = class {
|
|
|
32248
32428
|
};
|
|
32249
32429
|
|
|
32250
32430
|
// packages/host-runtime/src/app-server-host.ts
|
|
32251
|
-
import { createHash as createHash9, randomUUID as
|
|
32431
|
+
import { createHash as createHash9, randomUUID as randomUUID18 } from "node:crypto";
|
|
32252
32432
|
import os9 from "node:os";
|
|
32253
32433
|
import path28 from "node:path";
|
|
32254
32434
|
|
|
@@ -32256,12 +32436,12 @@ import path28 from "node:path";
|
|
|
32256
32436
|
import nodePath from "node:path";
|
|
32257
32437
|
|
|
32258
32438
|
// packages/host-runtime/src/external-thread-repository.ts
|
|
32259
|
-
import { randomUUID as
|
|
32439
|
+
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
32260
32440
|
import os8 from "node:os";
|
|
32261
32441
|
import path25 from "node:path";
|
|
32262
32442
|
|
|
32263
32443
|
// packages/host-runtime/src/external-subagent-threads.ts
|
|
32264
|
-
import { createHash as createHash6, randomUUID as
|
|
32444
|
+
import { createHash as createHash6, randomUUID as randomUUID12 } from "node:crypto";
|
|
32265
32445
|
function childCreateRequest(parent, nativeRef, id2) {
|
|
32266
32446
|
const key = createHash6("sha256").update(JSON.stringify([parent.hostThreadId, parent.harnessId, nativeRef.nativeSessionId, id2])).digest("hex");
|
|
32267
32447
|
return `subagent:${key}`;
|
|
@@ -32343,7 +32523,7 @@ function subagentMaterializer(store, parent, previousParent) {
|
|
|
32343
32523
|
return configured(await rebind(existing, parent));
|
|
32344
32524
|
}
|
|
32345
32525
|
const provisional = existing ?? await store.createProvisional({
|
|
32346
|
-
hostThreadId: hostThreadIdSchema.parse(
|
|
32526
|
+
hostThreadId: hostThreadIdSchema.parse(randomUUID12()),
|
|
32347
32527
|
createRequestId,
|
|
32348
32528
|
harnessId: parent.harnessId,
|
|
32349
32529
|
cwd: parent.cwd,
|
|
@@ -32386,14 +32566,13 @@ async function projectExternalSnapshot(store, record4, snapshot2, previousParent
|
|
|
32386
32566
|
return { ...entry, item: { ...entry.item, subagents } };
|
|
32387
32567
|
})
|
|
32388
32568
|
);
|
|
32389
|
-
|
|
32390
|
-
|
|
32391
|
-
|
|
32392
|
-
|
|
32393
|
-
|
|
32394
|
-
|
|
32395
|
-
|
|
32396
|
-
);
|
|
32569
|
+
const projected = projectHistoricalTurn({
|
|
32570
|
+
threadId: record4.hostThreadId,
|
|
32571
|
+
turnId: mapping.hostTurnId,
|
|
32572
|
+
cwd: record4.cwd,
|
|
32573
|
+
snapshot: { ...turn, items }
|
|
32574
|
+
});
|
|
32575
|
+
turns.push(mapping.realtimeInline ? presentExternalVoiceTurn(projected) : projected);
|
|
32397
32576
|
}
|
|
32398
32577
|
return turns;
|
|
32399
32578
|
}
|
|
@@ -32497,7 +32676,7 @@ var ExternalThreadRepository = class {
|
|
|
32497
32676
|
removeThread(hostThreadId) {
|
|
32498
32677
|
return this.store.removeThread(hostThreadId);
|
|
32499
32678
|
}
|
|
32500
|
-
async persistTurn(record4, hostTurnId, nativeTurnRef, nativeCheckpointRef) {
|
|
32679
|
+
async persistTurn(record4, hostTurnId, nativeTurnRef, nativeCheckpointRef, realtimeInline) {
|
|
32501
32680
|
if (record4.state !== "ready" || !record4.nativeSessionRef || nativeTurnRef.harnessId !== record4.harnessId || nativeTurnRef.nativeSessionId !== record4.nativeSessionRef.nativeSessionId || nativeCheckpointRef && (nativeCheckpointRef.harnessId !== record4.harnessId || nativeCheckpointRef.nativeSessionId !== record4.nativeSessionRef.nativeSessionId)) {
|
|
32502
32681
|
throw new Error("Live Turn identity does not belong to the stored Thread");
|
|
32503
32682
|
}
|
|
@@ -32505,7 +32684,8 @@ var ExternalThreadRepository = class {
|
|
|
32505
32684
|
{
|
|
32506
32685
|
hostTurnId,
|
|
32507
32686
|
nativeTurnRef,
|
|
32508
|
-
...nativeCheckpointRef ? { nativeCheckpointRef } : {}
|
|
32687
|
+
...nativeCheckpointRef ? { nativeCheckpointRef } : {},
|
|
32688
|
+
...realtimeInline ? { realtimeInline } : {}
|
|
32509
32689
|
}
|
|
32510
32690
|
]);
|
|
32511
32691
|
}
|
|
@@ -32518,7 +32698,7 @@ var ExternalThreadRepository = class {
|
|
|
32518
32698
|
throw new Error("Derived Snapshot identity does not belong to its Native Session");
|
|
32519
32699
|
}
|
|
32520
32700
|
return {
|
|
32521
|
-
hostTurnId: hostTurnIdSchema.parse(
|
|
32701
|
+
hostTurnId: hostTurnIdSchema.parse(randomUUID13()),
|
|
32522
32702
|
nativeTurnRef: turn.nativeTurnRef,
|
|
32523
32703
|
...turn.checkpoint ? { nativeCheckpointRef: turn.checkpoint } : {}
|
|
32524
32704
|
};
|
|
@@ -32558,6 +32738,7 @@ var ExternalThreadRepository = class {
|
|
|
32558
32738
|
}
|
|
32559
32739
|
return {
|
|
32560
32740
|
hostTurnId: previous.hostTurnId,
|
|
32741
|
+
...previous.realtimeInline ? { realtimeInline: true } : {},
|
|
32561
32742
|
nativeTurnRef: turn.nativeTurnRef,
|
|
32562
32743
|
...turn.checkpoint ? { nativeCheckpointRef: turn.checkpoint } : {}
|
|
32563
32744
|
};
|
|
@@ -32589,6 +32770,7 @@ var ExternalThreadRepository = class {
|
|
|
32589
32770
|
}
|
|
32590
32771
|
return {
|
|
32591
32772
|
hostTurnId: previous.hostTurnId,
|
|
32773
|
+
...previous.realtimeInline ? { realtimeInline: true } : {},
|
|
32592
32774
|
nativeTurnRef: turn.nativeTurnRef,
|
|
32593
32775
|
...turn.checkpoint ? { nativeCheckpointRef: turn.checkpoint } : {}
|
|
32594
32776
|
};
|
|
@@ -32641,14 +32823,15 @@ var ExternalThreadRepository = class {
|
|
|
32641
32823
|
const aligned = snapshot2.turns.map((turn) => {
|
|
32642
32824
|
const existing = mappingsByNative.get(nativeTurnKey2(turn.nativeTurnRef));
|
|
32643
32825
|
const mapping = existing ?? {
|
|
32644
|
-
hostTurnId: hostTurnIdSchema.parse(
|
|
32826
|
+
hostTurnId: hostTurnIdSchema.parse(randomUUID13()),
|
|
32645
32827
|
nativeTurnRef: turn.nativeTurnRef,
|
|
32646
32828
|
...turn.checkpoint ? { nativeCheckpointRef: turn.checkpoint } : {}
|
|
32647
32829
|
};
|
|
32648
32830
|
return {
|
|
32649
32831
|
snapshot: turn,
|
|
32650
32832
|
mapping: {
|
|
32651
|
-
|
|
32833
|
+
hostTurnId: mapping.hostTurnId,
|
|
32834
|
+
...mapping.realtimeInline ? { realtimeInline: true } : {},
|
|
32652
32835
|
nativeTurnRef: turn.nativeTurnRef,
|
|
32653
32836
|
...turn.checkpoint ? { nativeCheckpointRef: turn.checkpoint } : {}
|
|
32654
32837
|
}
|
|
@@ -32668,8 +32851,8 @@ var ExternalThreadRepository = class {
|
|
|
32668
32851
|
};
|
|
32669
32852
|
function createExternalThreadRecordInput(input) {
|
|
32670
32853
|
return {
|
|
32671
|
-
hostThreadId: input.hostThreadId ?? hostThreadIdSchema.parse(
|
|
32672
|
-
createRequestId: input.createRequestId ??
|
|
32854
|
+
hostThreadId: input.hostThreadId ?? hostThreadIdSchema.parse(randomUUID13()),
|
|
32855
|
+
createRequestId: input.createRequestId ?? randomUUID13(),
|
|
32673
32856
|
harnessId: input.harnessId,
|
|
32674
32857
|
cwd: input.cwd,
|
|
32675
32858
|
...input.title ? { title: input.title } : {},
|
|
@@ -32791,6 +32974,15 @@ async function executeExternalThreadFork(input) {
|
|
|
32791
32974
|
boundaryIndex = mappings.length - 1;
|
|
32792
32975
|
}
|
|
32793
32976
|
const boundary = mappings[boundaryIndex];
|
|
32977
|
+
if (boundary && source.steeredTurnIds.has(boundary.hostTurnId)) {
|
|
32978
|
+
return {
|
|
32979
|
+
ok: false,
|
|
32980
|
+
error: {
|
|
32981
|
+
code: -32080,
|
|
32982
|
+
message: "This Turn took steered input; reopen the Thread before forking from it"
|
|
32983
|
+
}
|
|
32984
|
+
};
|
|
32985
|
+
}
|
|
32794
32986
|
if (boundaryIndex < 0 || !boundary?.nativeCheckpointRef) {
|
|
32795
32987
|
return {
|
|
32796
32988
|
ok: false,
|
|
@@ -33547,6 +33739,16 @@ async function executeExternalThreadRollback(input) {
|
|
|
33547
33739
|
if (derived.running) {
|
|
33548
33740
|
return { ok: false, error: { code: -32072, message: "External Thread has an active Turn" } };
|
|
33549
33741
|
}
|
|
33742
|
+
const undone = derived.record.turnMappings.slice(-rollback.numTurns);
|
|
33743
|
+
if (undone.some((mapping) => derived.steeredTurnIds.has(mapping.hostTurnId))) {
|
|
33744
|
+
return {
|
|
33745
|
+
ok: false,
|
|
33746
|
+
error: {
|
|
33747
|
+
code: -32080,
|
|
33748
|
+
message: "A Turn here took steered input; reopen the Thread before undoing Turns"
|
|
33749
|
+
}
|
|
33750
|
+
};
|
|
33751
|
+
}
|
|
33550
33752
|
const refreshError = await runtime.refresh(derived);
|
|
33551
33753
|
if (refreshError) return { ok: false, error: refreshError };
|
|
33552
33754
|
if (expectedLastTurnId !== void 0 && derived.record.turnMappings.at(-1)?.hostTurnId !== expectedLastTurnId) {
|
|
@@ -34346,6 +34548,7 @@ var ExternalThreadRuntime = class {
|
|
|
34346
34548
|
#repository;
|
|
34347
34549
|
#lifecycle = new ExternalThreadLifecycle();
|
|
34348
34550
|
#hasRunningDescendants;
|
|
34551
|
+
#steeredTurnIds = /* @__PURE__ */ new Map();
|
|
34349
34552
|
#subagentRunning;
|
|
34350
34553
|
#threads = /* @__PURE__ */ new Map();
|
|
34351
34554
|
constructor(input) {
|
|
@@ -34359,7 +34562,8 @@ var ExternalThreadRuntime = class {
|
|
|
34359
34562
|
this.idleRelease = new ExternalThreadIdleRelease({
|
|
34360
34563
|
threads: () => this.values(),
|
|
34361
34564
|
get: (id2) => this.get(id2),
|
|
34362
|
-
|
|
34565
|
+
// Idle release detaches only the Native Session. Host Thread state survives restoration.
|
|
34566
|
+
remove: (id2) => this.#detach(id2),
|
|
34363
34567
|
queue: input.idleRelease?.queue ?? new DesktopRequestQueue(),
|
|
34364
34568
|
canRelease: (thread) => !thread.sessionUnavailable && !this.#lifecycle.busy(thread.id) && (input.idleRelease?.canRelease(thread) ?? false),
|
|
34365
34569
|
...input.idleRelease?.onClosed ? { onClosed: input.idleRelease.onClosed } : {},
|
|
@@ -34369,14 +34573,21 @@ var ExternalThreadRuntime = class {
|
|
|
34369
34573
|
get(threadId2) {
|
|
34370
34574
|
return this.#threads.get(threadId2);
|
|
34371
34575
|
}
|
|
34576
|
+
#detach(threadId2) {
|
|
34577
|
+
const thread = this.#threads.get(threadId2);
|
|
34578
|
+
this.#threads.delete(threadId2);
|
|
34579
|
+
if (!thread || thread.steeredTurnIds.size === 0) this.#steeredTurnIds.delete(threadId2);
|
|
34580
|
+
}
|
|
34372
34581
|
values() {
|
|
34373
34582
|
return [...this.#threads.values()];
|
|
34374
34583
|
}
|
|
34375
34584
|
remove(threadId2) {
|
|
34376
34585
|
this.#threads.delete(threadId2);
|
|
34586
|
+
this.#steeredTurnIds.delete(threadId2);
|
|
34377
34587
|
}
|
|
34378
34588
|
clear() {
|
|
34379
34589
|
this.#threads.clear();
|
|
34590
|
+
this.#steeredTurnIds.clear();
|
|
34380
34591
|
}
|
|
34381
34592
|
drain() {
|
|
34382
34593
|
return this.#lifecycle.drain();
|
|
@@ -34433,6 +34644,11 @@ var ExternalThreadRuntime = class {
|
|
|
34433
34644
|
...effectivePermissionModeId ? { effectivePermissionModeId } : {}
|
|
34434
34645
|
};
|
|
34435
34646
|
const running = this.#subagentRunning(input.record.hostThreadId);
|
|
34647
|
+
let steeredTurnIds = this.#steeredTurnIds.get(input.record.hostThreadId);
|
|
34648
|
+
if (!steeredTurnIds) {
|
|
34649
|
+
steeredTurnIds = /* @__PURE__ */ new Set();
|
|
34650
|
+
this.#steeredTurnIds.set(input.record.hostThreadId, steeredTurnIds);
|
|
34651
|
+
}
|
|
34436
34652
|
const externalThread = {
|
|
34437
34653
|
id: input.record.hostThreadId,
|
|
34438
34654
|
cwd: input.record.cwd,
|
|
@@ -34457,11 +34673,13 @@ var ExternalThreadRuntime = class {
|
|
|
34457
34673
|
usageTurnId: null,
|
|
34458
34674
|
projectedTurns: /* @__PURE__ */ new Map(),
|
|
34459
34675
|
responseGates: /* @__PURE__ */ new Map(),
|
|
34676
|
+
pendingSteerProjections: /* @__PURE__ */ new Set(),
|
|
34460
34677
|
ephemeralTurnIds: /* @__PURE__ */ new Set(),
|
|
34461
34678
|
persistenceError: null,
|
|
34462
34679
|
projectedTerminalTurnId: null,
|
|
34463
34680
|
ignoredInteractionIds: /* @__PURE__ */ new Set(),
|
|
34464
|
-
sessionUnavailable: false
|
|
34681
|
+
sessionUnavailable: false,
|
|
34682
|
+
steeredTurnIds
|
|
34465
34683
|
};
|
|
34466
34684
|
this.idleRelease.touch(externalThread);
|
|
34467
34685
|
externalThread.outputTask = this.#consumeOutputs(externalThread);
|
|
@@ -34518,13 +34736,13 @@ var ExternalThreadRuntime = class {
|
|
|
34518
34736
|
const retire = async () => {
|
|
34519
34737
|
if (this.#threads.get(parentId) !== parent || this.#threads.get(child.id) !== child) return;
|
|
34520
34738
|
if (bestEffort) {
|
|
34521
|
-
this
|
|
34739
|
+
this.remove(child.id);
|
|
34522
34740
|
await child.session.close();
|
|
34523
34741
|
await child.outputTask;
|
|
34524
34742
|
} else {
|
|
34525
34743
|
child.sessionUnavailable = true;
|
|
34526
34744
|
await this.#lifecycle.release(child.id, child.session, child.outputTask);
|
|
34527
|
-
if (this.#threads.get(child.id) === child) this
|
|
34745
|
+
if (this.#threads.get(child.id) === child) this.remove(child.id);
|
|
34528
34746
|
}
|
|
34529
34747
|
};
|
|
34530
34748
|
if (bestEffort) await retire().catch(this.#diagnose);
|
|
@@ -34761,7 +34979,8 @@ var ExternalThreadRuntime = class {
|
|
|
34761
34979
|
thread.record,
|
|
34762
34980
|
event.turnId,
|
|
34763
34981
|
event.nativeTurnRef,
|
|
34764
|
-
event.outcome.checkpoint
|
|
34982
|
+
event.outcome.checkpoint,
|
|
34983
|
+
thread.projectedTurns.get(event.turnId)?.realtimeInline
|
|
34765
34984
|
);
|
|
34766
34985
|
return null;
|
|
34767
34986
|
} catch (error51) {
|
|
@@ -34897,6 +35116,71 @@ var ExternalThreadRuntime = class {
|
|
|
34897
35116
|
};
|
|
34898
35117
|
|
|
34899
35118
|
// packages/host-runtime/src/external-turn-steering.ts
|
|
35119
|
+
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
35120
|
+
|
|
35121
|
+
// packages/host-runtime/src/external-command-routing.ts
|
|
35122
|
+
var ExternalCommandError = class extends Error {
|
|
35123
|
+
constructor(code, message2) {
|
|
35124
|
+
super(message2);
|
|
35125
|
+
this.code = code;
|
|
35126
|
+
}
|
|
35127
|
+
code;
|
|
35128
|
+
};
|
|
35129
|
+
function isExternalCommandCandidate(text) {
|
|
35130
|
+
return /^\/[^\s/]+(?:\s|$)/u.test(text.trimStart());
|
|
35131
|
+
}
|
|
35132
|
+
async function inspectLiveCommandCatalog(commands, timeoutMs = 1e3) {
|
|
35133
|
+
let timeout;
|
|
35134
|
+
try {
|
|
35135
|
+
const result = await Promise.race([
|
|
35136
|
+
commands.list(),
|
|
35137
|
+
new Promise((resolve) => {
|
|
35138
|
+
timeout = setTimeout(() => resolve(null), timeoutMs);
|
|
35139
|
+
})
|
|
35140
|
+
]);
|
|
35141
|
+
return result?.ok ? harnessCommandCatalogSchema.parse(result.value) : null;
|
|
35142
|
+
} catch {
|
|
35143
|
+
return null;
|
|
35144
|
+
} finally {
|
|
35145
|
+
if (timeout !== void 0) clearTimeout(timeout);
|
|
35146
|
+
}
|
|
35147
|
+
}
|
|
35148
|
+
async function resolveExternalCommand(commands, text, options2 = {}) {
|
|
35149
|
+
const catalog = await commands.list();
|
|
35150
|
+
if (!catalog.ok) throw new ExternalCommandError(-32073, catalog.error.message);
|
|
35151
|
+
const commandText = text.trim();
|
|
35152
|
+
const matched = catalog.value.commands.toSorted((left, right) => right.invocation.length - left.invocation.length).find((command) => {
|
|
35153
|
+
if (commandText === command.invocation) return true;
|
|
35154
|
+
return command.argumentMode === "text" && commandText.startsWith(`${command.invocation} `);
|
|
35155
|
+
});
|
|
35156
|
+
if (!matched) {
|
|
35157
|
+
const name = /^\/(\S+)/u.exec(commandText)?.[1] ?? "";
|
|
35158
|
+
if (name && !isExcludedLiveCommand(name, "command") && options2.liveCatalogPending?.(catalog.value)) {
|
|
35159
|
+
return null;
|
|
35160
|
+
}
|
|
35161
|
+
throw new ExternalCommandError(
|
|
35162
|
+
-32078,
|
|
35163
|
+
"External Harness does not expose the requested command"
|
|
35164
|
+
);
|
|
35165
|
+
}
|
|
35166
|
+
const argumentText = commandText.slice(matched.invocation.length).trimStart();
|
|
35167
|
+
return {
|
|
35168
|
+
descriptor: matched,
|
|
35169
|
+
...argumentText.length > 0 ? { arguments: { text: argumentText } } : {}
|
|
35170
|
+
};
|
|
35171
|
+
}
|
|
35172
|
+
|
|
35173
|
+
// packages/host-runtime/src/external-turn-steering.ts
|
|
35174
|
+
function isHarnessCommand(thread, text) {
|
|
35175
|
+
return thread.session.commands !== void 0 && isExternalCommandCandidate(restoreHarnessCommandMentions(text));
|
|
35176
|
+
}
|
|
35177
|
+
function externalSteeringDelivery(thread, text) {
|
|
35178
|
+
if (text !== void 0 && isHarnessCommand(thread, text)) return "newTurn";
|
|
35179
|
+
if (thread.session.readCapabilities) {
|
|
35180
|
+
return thread.session.readCapabilities().then((capabilities) => capabilities.steer === true ? "activeTurn" : "newTurn");
|
|
35181
|
+
}
|
|
35182
|
+
return thread.session.capabilities.steer === true ? "activeTurn" : "newTurn";
|
|
35183
|
+
}
|
|
34900
35184
|
var ExternalSteerError = class extends Error {
|
|
34901
35185
|
constructor(code, message2) {
|
|
34902
35186
|
super(message2);
|
|
@@ -34904,6 +35188,11 @@ var ExternalSteerError = class extends Error {
|
|
|
34904
35188
|
}
|
|
34905
35189
|
code;
|
|
34906
35190
|
};
|
|
35191
|
+
var ExternalSteerNotTakenError = class extends ExternalSteerError {
|
|
35192
|
+
constructor(message2) {
|
|
35193
|
+
super(-32074, message2);
|
|
35194
|
+
}
|
|
35195
|
+
};
|
|
34907
35196
|
function parseInput(params) {
|
|
34908
35197
|
if (typeof params.expectedTurnId !== "string" || !params.expectedTurnId.trim()) {
|
|
34909
35198
|
throw new ExternalSteerError(-32602, "External steering requires expectedTurnId");
|
|
@@ -34920,12 +35209,47 @@ function parseInput(params) {
|
|
|
34920
35209
|
if (clientUserMessageId != null && (typeof clientUserMessageId !== "string" || !clientUserMessageId.trim())) {
|
|
34921
35210
|
throw new ExternalSteerError(-32602, "External steering message identity is invalid");
|
|
34922
35211
|
}
|
|
35212
|
+
const delivery = params[THREAD_STEER_DELIVERY_PARAM];
|
|
35213
|
+
const parsedDelivery = delivery == null ? void 0 : threadSteerDeliverySchema.safeParse(delivery);
|
|
35214
|
+
if (parsedDelivery && !parsedDelivery.success) {
|
|
35215
|
+
throw new ExternalSteerError(-32602, "External steering delivery is invalid");
|
|
35216
|
+
}
|
|
34923
35217
|
return {
|
|
34924
35218
|
expectedTurnId: params.expectedTurnId,
|
|
34925
35219
|
text,
|
|
34926
|
-
...typeof clientUserMessageId === "string" ? { clientUserMessageId } : {}
|
|
35220
|
+
...typeof clientUserMessageId === "string" ? { clientUserMessageId } : {},
|
|
35221
|
+
...parsedDelivery ? { delivery: parsedDelivery.data } : {}
|
|
34927
35222
|
};
|
|
34928
35223
|
}
|
|
35224
|
+
async function insertNativeSteer(thread, input, host) {
|
|
35225
|
+
const restored = restoreHarnessCommandMentions(input.text);
|
|
35226
|
+
const steered = [{ type: "text", text: rewriteDelegationMentionText(restored) }];
|
|
35227
|
+
const displayed = [{ type: "text", text: restored }];
|
|
35228
|
+
const projectionDone = Promise.withResolvers();
|
|
35229
|
+
thread.pendingSteerProjections.add(projectionDone.promise);
|
|
35230
|
+
try {
|
|
35231
|
+
const result = await thread.session.execute({
|
|
35232
|
+
type: "turn.steer",
|
|
35233
|
+
turnId: input.turnId,
|
|
35234
|
+
input: steered
|
|
35235
|
+
});
|
|
35236
|
+
if (!result.ok) throw new ExternalSteerNotTakenError(result.error.message);
|
|
35237
|
+
thread.steeredTurnIds.add(input.turnId);
|
|
35238
|
+
const item = {
|
|
35239
|
+
type: "userMessage",
|
|
35240
|
+
itemId: hostItemIdSchema.parse(randomUUID14()),
|
|
35241
|
+
input: displayed
|
|
35242
|
+
};
|
|
35243
|
+
try {
|
|
35244
|
+
await host.project(input.turnId, item, input.clientUserMessageId);
|
|
35245
|
+
} catch (error51) {
|
|
35246
|
+
host.diagnose(error51);
|
|
35247
|
+
}
|
|
35248
|
+
} finally {
|
|
35249
|
+
projectionDone.resolve(void 0);
|
|
35250
|
+
thread.pendingSteerProjections.delete(projectionDone.promise);
|
|
35251
|
+
}
|
|
35252
|
+
}
|
|
34929
35253
|
var ExternalTurnSteering = class {
|
|
34930
35254
|
constructor(timeoutMs = 2e4) {
|
|
34931
35255
|
this.timeoutMs = timeoutMs;
|
|
@@ -34937,7 +35261,7 @@ var ExternalTurnSteering = class {
|
|
|
34937
35261
|
hasPending(threadId2) {
|
|
34938
35262
|
return threadId2 === void 0 ? this.#pending.size > 0 : this.#pending.has(threadId2);
|
|
34939
35263
|
}
|
|
34940
|
-
run(thread, params, start) {
|
|
35264
|
+
run(thread, params, start, insert) {
|
|
34941
35265
|
try {
|
|
34942
35266
|
const input = parseInput(params);
|
|
34943
35267
|
if (this.#closed)
|
|
@@ -34959,7 +35283,7 @@ var ExternalTurnSteering = class {
|
|
|
34959
35283
|
if (!thread.running || thread.activeTurnId !== input.expectedTurnId) {
|
|
34960
35284
|
throw new ExternalSteerError(-32074, "External steering must reference the active Turn");
|
|
34961
35285
|
}
|
|
34962
|
-
const result = this.#
|
|
35286
|
+
const result = this.#deliver(thread, input, start, insert);
|
|
34963
35287
|
if (key) {
|
|
34964
35288
|
const receipt2 = { fingerprint, result, settled: false };
|
|
34965
35289
|
this.#receipts.set(key, receipt2);
|
|
@@ -34982,6 +35306,56 @@ var ExternalTurnSteering = class {
|
|
|
34982
35306
|
return Promise.reject(error51);
|
|
34983
35307
|
}
|
|
34984
35308
|
}
|
|
35309
|
+
/**
|
|
35310
|
+
* A Renderer that already presented a delivery gets exactly that one. Otherwise native delivery
|
|
35311
|
+
* is tried only when the Session can take the input now, and input the Harness did not take
|
|
35312
|
+
* falls back to stopping and restarting, so no case is worse than the stop-then-start path.
|
|
35313
|
+
*/
|
|
35314
|
+
#deliver(thread, input, start, insert) {
|
|
35315
|
+
const delivery = input.delivery === "newTurn" || isHarnessCommand(thread, input.text) ? "newTurn" : input.delivery ?? externalSteeringDelivery(thread);
|
|
35316
|
+
const deliver = (mode) => {
|
|
35317
|
+
if (this.#closed || !thread.running || thread.activeTurnId !== input.expectedTurnId) {
|
|
35318
|
+
throw new ExternalSteerError(-32074, "External steering target is no longer active");
|
|
35319
|
+
}
|
|
35320
|
+
if (this.hasPending(thread.id))
|
|
35321
|
+
throw new ExternalSteerError(-32072, "External Thread is already changing direction");
|
|
35322
|
+
if (mode === "newTurn") return this.#replace(thread, input, start);
|
|
35323
|
+
const native = insert({
|
|
35324
|
+
turnId: thread.activeTurnId,
|
|
35325
|
+
text: input.text,
|
|
35326
|
+
...input.clientUserMessageId ? { clientUserMessageId: input.clientUserMessageId } : {}
|
|
35327
|
+
}).then((admitted) => ({ ...admitted, delivery: "activeTurn" }));
|
|
35328
|
+
if (input.delivery === "activeTurn") return native;
|
|
35329
|
+
return native.catch(async (error51) => {
|
|
35330
|
+
if (!(error51 instanceof ExternalSteerNotTakenError)) throw error51;
|
|
35331
|
+
if (thread.running || thread.activeTurnId) return deliver("newTurn");
|
|
35332
|
+
const assertActive = () => {
|
|
35333
|
+
if (this.#closed)
|
|
35334
|
+
throw new ExternalSteerError(-32074, "External steering connection is closed");
|
|
35335
|
+
};
|
|
35336
|
+
return { ...await start(input.text, assertActive), delivery: "newTurn" };
|
|
35337
|
+
});
|
|
35338
|
+
};
|
|
35339
|
+
if (typeof delivery === "string") return deliver(delivery);
|
|
35340
|
+
const failure = Promise.withResolvers();
|
|
35341
|
+
let failureReason = null;
|
|
35342
|
+
const pending = {
|
|
35343
|
+
turnId: input.expectedTurnId,
|
|
35344
|
+
resolve: () => void 0,
|
|
35345
|
+
reject(error51) {
|
|
35346
|
+
failureReason ??= error51;
|
|
35347
|
+
failure.reject(error51);
|
|
35348
|
+
}
|
|
35349
|
+
};
|
|
35350
|
+
this.#pending.set(thread.id, pending);
|
|
35351
|
+
return Promise.race([delivery, failure.promise]).then((mode) => {
|
|
35352
|
+
if (failureReason) throw failureReason;
|
|
35353
|
+
if (this.#pending.get(thread.id) === pending) this.#pending.delete(thread.id);
|
|
35354
|
+
return deliver(mode);
|
|
35355
|
+
}).finally(() => {
|
|
35356
|
+
if (this.#pending.get(thread.id) === pending) this.#pending.delete(thread.id);
|
|
35357
|
+
});
|
|
35358
|
+
}
|
|
34985
35359
|
terminal(threadId2, turnId, outcome) {
|
|
34986
35360
|
const pending = this.#pending.get(threadId2);
|
|
34987
35361
|
if (pending?.turnId === turnId) pending.resolve(outcome);
|
|
@@ -35036,7 +35410,9 @@ var ExternalTurnSteering = class {
|
|
|
35036
35410
|
thread.session.execute({ type: "turn.cancel", turnId }),
|
|
35037
35411
|
failure.promise
|
|
35038
35412
|
]);
|
|
35039
|
-
if (!cancelled.ok
|
|
35413
|
+
if (!cancelled.ok && cancelled.error.code !== "invalidState") {
|
|
35414
|
+
throw new ExternalSteerError(-32074, cancelled.error.message);
|
|
35415
|
+
}
|
|
35040
35416
|
const outcome = await Promise.race([terminal3.promise, failure.promise]);
|
|
35041
35417
|
clearTimeout(timeout);
|
|
35042
35418
|
const assertActive = () => {
|
|
@@ -35054,7 +35430,7 @@ var ExternalTurnSteering = class {
|
|
|
35054
35430
|
if (thread.running || thread.activeTurnId) {
|
|
35055
35431
|
throw new ExternalSteerError(-32072, "Another External Turn started before replacement");
|
|
35056
35432
|
}
|
|
35057
|
-
return await start(input.text, assertActive);
|
|
35433
|
+
return { ...await start(input.text, assertActive), delivery: "newTurn" };
|
|
35058
35434
|
} finally {
|
|
35059
35435
|
clearTimeout(timeout);
|
|
35060
35436
|
if (this.#pending.get(thread.id) === pending) this.#pending.delete(thread.id);
|
|
@@ -35062,58 +35438,6 @@ var ExternalTurnSteering = class {
|
|
|
35062
35438
|
}
|
|
35063
35439
|
};
|
|
35064
35440
|
|
|
35065
|
-
// packages/host-runtime/src/external-command-routing.ts
|
|
35066
|
-
var ExternalCommandError = class extends Error {
|
|
35067
|
-
constructor(code, message2) {
|
|
35068
|
-
super(message2);
|
|
35069
|
-
this.code = code;
|
|
35070
|
-
}
|
|
35071
|
-
code;
|
|
35072
|
-
};
|
|
35073
|
-
function isExternalCommandCandidate(text) {
|
|
35074
|
-
return /^\/[^\s/]+(?:\s|$)/u.test(text.trimStart());
|
|
35075
|
-
}
|
|
35076
|
-
async function inspectLiveCommandCatalog(commands, timeoutMs = 1e3) {
|
|
35077
|
-
let timeout;
|
|
35078
|
-
try {
|
|
35079
|
-
const result = await Promise.race([
|
|
35080
|
-
commands.list(),
|
|
35081
|
-
new Promise((resolve) => {
|
|
35082
|
-
timeout = setTimeout(() => resolve(null), timeoutMs);
|
|
35083
|
-
})
|
|
35084
|
-
]);
|
|
35085
|
-
return result?.ok ? harnessCommandCatalogSchema.parse(result.value) : null;
|
|
35086
|
-
} catch {
|
|
35087
|
-
return null;
|
|
35088
|
-
} finally {
|
|
35089
|
-
if (timeout !== void 0) clearTimeout(timeout);
|
|
35090
|
-
}
|
|
35091
|
-
}
|
|
35092
|
-
async function resolveExternalCommand(commands, text, options2 = {}) {
|
|
35093
|
-
const catalog = await commands.list();
|
|
35094
|
-
if (!catalog.ok) throw new ExternalCommandError(-32073, catalog.error.message);
|
|
35095
|
-
const commandText = text.trim();
|
|
35096
|
-
const matched = catalog.value.commands.toSorted((left, right) => right.invocation.length - left.invocation.length).find((command) => {
|
|
35097
|
-
if (commandText === command.invocation) return true;
|
|
35098
|
-
return command.argumentMode === "text" && commandText.startsWith(`${command.invocation} `);
|
|
35099
|
-
});
|
|
35100
|
-
if (!matched) {
|
|
35101
|
-
const name = /^\/(\S+)/u.exec(commandText)?.[1] ?? "";
|
|
35102
|
-
if (name && !isExcludedLiveCommand(name, "command") && options2.liveCatalogPending?.(catalog.value)) {
|
|
35103
|
-
return null;
|
|
35104
|
-
}
|
|
35105
|
-
throw new ExternalCommandError(
|
|
35106
|
-
-32078,
|
|
35107
|
-
"External Harness does not expose the requested command"
|
|
35108
|
-
);
|
|
35109
|
-
}
|
|
35110
|
-
const argumentText = commandText.slice(matched.invocation.length).trimStart();
|
|
35111
|
-
return {
|
|
35112
|
-
descriptor: matched,
|
|
35113
|
-
...argumentText.length > 0 ? { arguments: { text: argumentText } } : {}
|
|
35114
|
-
};
|
|
35115
|
-
}
|
|
35116
|
-
|
|
35117
35441
|
// packages/host-runtime/src/live-command-catalog-cache.ts
|
|
35118
35442
|
import path26 from "node:path";
|
|
35119
35443
|
var MAX_ENTRIES = 64;
|
|
@@ -35145,7 +35469,7 @@ function sameWorkspace(left, right) {
|
|
|
35145
35469
|
}
|
|
35146
35470
|
|
|
35147
35471
|
// packages/host-runtime/src/harness-delegation-coordinator.ts
|
|
35148
|
-
import { createHash as createHash8, randomUUID as
|
|
35472
|
+
import { createHash as createHash8, randomUUID as randomUUID15 } from "node:crypto";
|
|
35149
35473
|
import path27 from "node:path";
|
|
35150
35474
|
|
|
35151
35475
|
// packages/host-runtime/src/delegation-snapshot.ts
|
|
@@ -35449,10 +35773,10 @@ var HarnessDelegationCoordinator = class {
|
|
|
35449
35773
|
});
|
|
35450
35774
|
this.#validateConfiguration(inspected.inspection, input.model, input.thinkingOptionId);
|
|
35451
35775
|
}
|
|
35452
|
-
const delegationId = hostThreadIdSchema.parse(
|
|
35453
|
-
const childThreadId = hostThreadIdSchema.parse(
|
|
35454
|
-
const turnId = hostTurnIdSchema.parse(
|
|
35455
|
-
const createRequestId = input.requestId ? `delegation:${input.requestId}` :
|
|
35776
|
+
const delegationId = hostThreadIdSchema.parse(randomUUID15());
|
|
35777
|
+
const childThreadId = hostThreadIdSchema.parse(randomUUID15());
|
|
35778
|
+
const turnId = hostTurnIdSchema.parse(randomUUID15());
|
|
35779
|
+
const createRequestId = input.requestId ? `delegation:${input.requestId}` : randomUUID15();
|
|
35456
35780
|
let record4 = await this.#repository.createProvisional(
|
|
35457
35781
|
createExternalThreadRecordInput({
|
|
35458
35782
|
hostThreadId: childThreadId,
|
|
@@ -35606,7 +35930,7 @@ var HarnessDelegationCoordinator = class {
|
|
|
35606
35930
|
if (this.#externalThreadBusy(thread) || thread.activeTurnId) {
|
|
35607
35931
|
throw new DelegationControlError("THREAD_BUSY", "Thread already has an active Turn");
|
|
35608
35932
|
}
|
|
35609
|
-
const turnId = hostTurnIdSchema.parse(
|
|
35933
|
+
const turnId = hostTurnIdSchema.parse(randomUUID15());
|
|
35610
35934
|
try {
|
|
35611
35935
|
await this.#startExternalTurn(thread, input.message, turnId);
|
|
35612
35936
|
} catch (error51) {
|
|
@@ -35880,8 +36204,8 @@ import { pathToFileURL } from "node:url";
|
|
|
35880
36204
|
function isNullable(value2) {
|
|
35881
36205
|
return value2 === null || value2 === void 0;
|
|
35882
36206
|
}
|
|
35883
|
-
function defineProperty(
|
|
35884
|
-
return Object.defineProperty(
|
|
36207
|
+
function defineProperty(object10, key, value2) {
|
|
36208
|
+
return Object.defineProperty(object10, key, {
|
|
35885
36209
|
writable: true,
|
|
35886
36210
|
value: value2,
|
|
35887
36211
|
enumerable: false
|
|
@@ -37420,8 +37744,8 @@ var Fiber = class {
|
|
|
37420
37744
|
});
|
|
37421
37745
|
}
|
|
37422
37746
|
};
|
|
37423
|
-
function isApplicable(
|
|
37424
|
-
return
|
|
37747
|
+
function isApplicable(object10) {
|
|
37748
|
+
return object10 && typeof object10 === "object" && typeof object10.apply === "function";
|
|
37425
37749
|
}
|
|
37426
37750
|
function Inject(name, config2) {
|
|
37427
37751
|
return function(value2, decorator) {
|
|
@@ -38256,10 +38580,10 @@ var SingleNativeCodexAccount = class {
|
|
|
38256
38580
|
};
|
|
38257
38581
|
|
|
38258
38582
|
// packages/host-runtime/src/codex-runtime/official-runtime-owner.ts
|
|
38259
|
-
import { randomUUID as
|
|
38583
|
+
import { randomUUID as randomUUID17 } from "node:crypto";
|
|
38260
38584
|
|
|
38261
38585
|
// packages/host-runtime/src/official-request-broker.ts
|
|
38262
|
-
import { randomUUID as
|
|
38586
|
+
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
38263
38587
|
var INTERNAL_REQUEST_PREFIX = "codexhost:official:";
|
|
38264
38588
|
var MAX_RETIRED_IDS = 1024;
|
|
38265
38589
|
function isRecord17(value2) {
|
|
@@ -38275,7 +38599,7 @@ var OfficialRequestBroker = class {
|
|
|
38275
38599
|
constructor(input) {
|
|
38276
38600
|
this.#send = input.send;
|
|
38277
38601
|
this.#timeoutMs = input.timeoutMs ?? 3e4;
|
|
38278
|
-
this.#nextId = input.nextId ?? (() => `${INTERNAL_REQUEST_PREFIX}${
|
|
38602
|
+
this.#nextId = input.nextId ?? (() => `${INTERNAL_REQUEST_PREFIX}${randomUUID16()}`);
|
|
38279
38603
|
}
|
|
38280
38604
|
get pendingCount() {
|
|
38281
38605
|
return this.#pending.size;
|
|
@@ -38484,7 +38808,7 @@ var OfficialWorkGate = class {
|
|
|
38484
38808
|
};
|
|
38485
38809
|
|
|
38486
38810
|
// packages/host-runtime/src/codex-runtime/official-runtime-owner.ts
|
|
38487
|
-
var
|
|
38811
|
+
var object8 = (value2) => typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
38488
38812
|
var requestKey = (id2) => JSON.stringify([typeof id2, id2]);
|
|
38489
38813
|
var RESUME_FIELDS = /* @__PURE__ */ new Set([
|
|
38490
38814
|
"model",
|
|
@@ -38629,7 +38953,7 @@ var OfficialRuntimeOwner = class {
|
|
|
38629
38953
|
}
|
|
38630
38954
|
#attach(role, output, onBackendStopped) {
|
|
38631
38955
|
const client = {
|
|
38632
|
-
id:
|
|
38956
|
+
id: randomUUID17(),
|
|
38633
38957
|
role,
|
|
38634
38958
|
output,
|
|
38635
38959
|
...onBackendStopped ? { onBackendStopped } : {},
|
|
@@ -38749,7 +39073,7 @@ var OfficialRuntimeOwner = class {
|
|
|
38749
39073
|
if (value2.method === "initialized") return;
|
|
38750
39074
|
if (typeof value2.id !== "string" && typeof value2.id !== "number")
|
|
38751
39075
|
throw new Error("Official methods require a request ID");
|
|
38752
|
-
const params =
|
|
39076
|
+
const params = object8(value2.params) ? value2.params : {};
|
|
38753
39077
|
this.#checkMethod(value2.method);
|
|
38754
39078
|
const finish = this.gate.admit();
|
|
38755
39079
|
let pendingKey;
|
|
@@ -38784,10 +39108,10 @@ var OfficialRuntimeOwner = class {
|
|
|
38784
39108
|
if (!this.#clients.has(client) || event.generation !== this.#generation || !["running", "starting"].includes(this.#phase))
|
|
38785
39109
|
return;
|
|
38786
39110
|
const value2 = event.value;
|
|
38787
|
-
if (!
|
|
39111
|
+
if (!object8(value2)) return client.output(event);
|
|
38788
39112
|
if (typeof value2.id === "string" || typeof value2.id === "number") {
|
|
38789
39113
|
if (typeof value2.method === "string") {
|
|
38790
|
-
const id2 = `codexhost:server:${client.id}:${event.generation}:${
|
|
39114
|
+
const id2 = `codexhost:server:${client.id}:${event.generation}:${randomUUID17()}`;
|
|
38791
39115
|
client.serverRequests.set(id2, value2.id);
|
|
38792
39116
|
const projected = { ...value2, id: id2 };
|
|
38793
39117
|
return client.output({
|
|
@@ -38810,7 +39134,7 @@ var OfficialRuntimeOwner = class {
|
|
|
38810
39134
|
if (response.error) return;
|
|
38811
39135
|
if (["thread/archive", "thread/unsubscribe"].includes(method) && typeof params.threadId === "string")
|
|
38812
39136
|
client.threads.delete(params.threadId);
|
|
38813
|
-
if (!["thread/start", "thread/resume", "thread/fork"].includes(method) || !
|
|
39137
|
+
if (!["thread/start", "thread/resume", "thread/fork"].includes(method) || !object8(response.result) || !object8(response.result.thread))
|
|
38814
39138
|
return;
|
|
38815
39139
|
const id2 = response.result.thread.id;
|
|
38816
39140
|
if (typeof id2 !== "string") return;
|
|
@@ -38832,7 +39156,7 @@ var OfficialRuntimeOwner = class {
|
|
|
38832
39156
|
const restoring = (async () => {
|
|
38833
39157
|
const resume = subscription.params;
|
|
38834
39158
|
const response = await runtime.request("thread/resume", resume);
|
|
38835
|
-
if (response.error || !
|
|
39159
|
+
if (response.error || !object8(response.result) || !object8(response.result.thread) || response.result.thread.id !== params.threadId)
|
|
38836
39160
|
throw new Error("Official Thread restoration failed");
|
|
38837
39161
|
if (client.runtime !== runtime || runtime.generation !== this.#generation)
|
|
38838
39162
|
throw new OfficialAdmissionError("unavailable");
|
|
@@ -38980,16 +39304,16 @@ var OfficialRuntimeScope = class {
|
|
|
38980
39304
|
#scheduleRecovery() {
|
|
38981
39305
|
if (!this.#recovery || this.#closed || this.#recoveryTimer || this.#starting) return;
|
|
38982
39306
|
const { delaysMs } = this.#recovery;
|
|
38983
|
-
const
|
|
39307
|
+
const delay8 = delaysMs[Math.min(this.#recoveryAttempt, delaysMs.length - 1)] ?? 0;
|
|
38984
39308
|
this.#recoveryAttempt++;
|
|
38985
39309
|
this.#diagnosticOutput.write(
|
|
38986
|
-
`codexhost: official Codex is unavailable; restarting in ${String(
|
|
39310
|
+
`codexhost: official Codex is unavailable; restarting in ${String(delay8)}ms
|
|
38987
39311
|
`
|
|
38988
39312
|
);
|
|
38989
39313
|
const timer = setTimeout(() => {
|
|
38990
39314
|
this.#recoveryTimer = void 0;
|
|
38991
39315
|
this.start().catch(() => void 0);
|
|
38992
|
-
},
|
|
39316
|
+
}, delay8);
|
|
38993
39317
|
timer.unref();
|
|
38994
39318
|
this.#recoveryTimer = timer;
|
|
38995
39319
|
}
|
|
@@ -40075,6 +40399,7 @@ var AppServerHost = class {
|
|
|
40075
40399
|
#plugins;
|
|
40076
40400
|
#launchSettings;
|
|
40077
40401
|
#accountInspections = new HarnessAccountInspectionCache();
|
|
40402
|
+
#installationTasks = new HarnessInstallationTasks();
|
|
40078
40403
|
#externalRuntime;
|
|
40079
40404
|
#executionHosts = /* @__PURE__ */ new WeakMap();
|
|
40080
40405
|
#externalPrewarms = new ExternalThreadPrewarms();
|
|
@@ -40110,7 +40435,7 @@ var AppServerHost = class {
|
|
|
40110
40435
|
#sectionMoves = Promise.resolve();
|
|
40111
40436
|
#writer;
|
|
40112
40437
|
/** Console requests share Desktop handling; their replies return to the console. */
|
|
40113
|
-
#consoleRequestPrefix = `codexhost-console:${
|
|
40438
|
+
#consoleRequestPrefix = `codexhost-console:${randomUUID18()}:`;
|
|
40114
40439
|
#consoleReplies = /* @__PURE__ */ new Map();
|
|
40115
40440
|
#nextConsoleRequest = 0;
|
|
40116
40441
|
#subagentThreadStatuses = /* @__PURE__ */ new Map();
|
|
@@ -40948,11 +41273,11 @@ var AppServerHost = class {
|
|
|
40948
41273
|
this.#dispatchDesktopReply(request, () => this.#inspectHarness(request));
|
|
40949
41274
|
return;
|
|
40950
41275
|
}
|
|
40951
|
-
if (request.method === HARNESS_INSTALLATION_METHOD) {
|
|
41276
|
+
if (request.method === HARNESS_INSTALLATION_METHOD || request.method === HARNESS_INSTALLATION_START_METHOD || request.method === HARNESS_INSTALLATION_STATUS_METHOD) {
|
|
40952
41277
|
this.#dispatchDesktopReply(request, async () => {
|
|
40953
|
-
await this.#waitForPlugins();
|
|
40954
41278
|
try {
|
|
40955
|
-
|
|
41279
|
+
if (request.method !== HARNESS_INSTALLATION_STATUS_METHOD) await this.#waitForPlugins();
|
|
41280
|
+
const result = request.method === HARNESS_INSTALLATION_START_METHOD ? this.#installationTasks.start(request.params, this.#externalAdapters) : request.method === HARNESS_INSTALLATION_STATUS_METHOD ? this.#installationTasks.status(request.params) : await handleHarnessInstallation(request.params, this.#externalAdapters);
|
|
40956
41281
|
await this.#writer.json(rpcEnvelope(request, { result: jsonValueSchema.parse(result) }));
|
|
40957
41282
|
} catch (error51) {
|
|
40958
41283
|
await this.#writer.json(
|
|
@@ -41057,6 +41382,10 @@ var AppServerHost = class {
|
|
|
41057
41382
|
await this.#listThreadOwnership(request);
|
|
41058
41383
|
return;
|
|
41059
41384
|
}
|
|
41385
|
+
if (request.method === "codexhost/thread/steering/inspect") {
|
|
41386
|
+
await this.#inspectThreadSteering(request);
|
|
41387
|
+
return;
|
|
41388
|
+
}
|
|
41060
41389
|
if (request.method === "codexhost/thread/model/select") {
|
|
41061
41390
|
await this.#selectThreadModel(request);
|
|
41062
41391
|
return;
|
|
@@ -41830,7 +42159,7 @@ var AppServerHost = class {
|
|
|
41830
42159
|
throw error51;
|
|
41831
42160
|
}
|
|
41832
42161
|
this.#activeOfficialTurns.set(threadId2, turnId);
|
|
41833
|
-
const delegationId = hostThreadIdSchema.parse(
|
|
42162
|
+
const delegationId = hostThreadIdSchema.parse(randomUUID18());
|
|
41834
42163
|
try {
|
|
41835
42164
|
const source = await this.#repository.find(input.parentThreadId);
|
|
41836
42165
|
const pendingTerminal = this.#pendingOfficialTerminalStatuses.get(threadId2);
|
|
@@ -42018,7 +42347,7 @@ var AppServerHost = class {
|
|
|
42018
42347
|
async #listDelegationThreads(input) {
|
|
42019
42348
|
const [sortKey, sortDirection2] = input.sort.split("-");
|
|
42020
42349
|
const request = {
|
|
42021
|
-
id: `codexhost:delegation-list:${
|
|
42350
|
+
id: `codexhost:delegation-list:${randomUUID18()}`,
|
|
42022
42351
|
method: "thread/list",
|
|
42023
42352
|
params: {
|
|
42024
42353
|
cwd: input.cwd ? [input.cwd] : null,
|
|
@@ -42561,6 +42890,28 @@ var AppServerHost = class {
|
|
|
42561
42890
|
);
|
|
42562
42891
|
}
|
|
42563
42892
|
}
|
|
42893
|
+
/** Read the same delivery decision that Desktop `turn/steer` will follow. */
|
|
42894
|
+
async #inspectThreadSteering(request) {
|
|
42895
|
+
const params = threadSteeringInspectParamsSchema.safeParse(request.params);
|
|
42896
|
+
if (!params.success) {
|
|
42897
|
+
await this.#writer.json(rpcError(request, -32602, "Invalid Thread steering params"));
|
|
42898
|
+
return;
|
|
42899
|
+
}
|
|
42900
|
+
let delivery;
|
|
42901
|
+
try {
|
|
42902
|
+
const location = await this.#locateExternalThread(params.data.threadId);
|
|
42903
|
+
if (await this.#writeResolutionError(request, location)) return;
|
|
42904
|
+
const thread = location.kind === "external" ? this.#externalRuntime.get(params.data.threadId) : void 0;
|
|
42905
|
+
delivery = location.kind !== "external" ? "official" : thread ? await externalSteeringDelivery(thread, params.data.text) : "newTurn";
|
|
42906
|
+
} catch {
|
|
42907
|
+
await this.#writer.json(
|
|
42908
|
+
rpcError(request, -32081, "Thread steering metadata could not be read")
|
|
42909
|
+
);
|
|
42910
|
+
return;
|
|
42911
|
+
}
|
|
42912
|
+
const result = threadSteeringInspectResultSchema.parse({ delivery });
|
|
42913
|
+
await this.#writer.json(rpcEnvelope(request, { result: jsonValueSchema.parse(result) }));
|
|
42914
|
+
}
|
|
42564
42915
|
async #inspectThreadCommands(request) {
|
|
42565
42916
|
const params = threadCommandsInspectParamsSchema.safeParse(request.params);
|
|
42566
42917
|
if (!params.success) {
|
|
@@ -42724,7 +43075,7 @@ var AppServerHost = class {
|
|
|
42724
43075
|
if (thread.running || thread.activeTurnId) {
|
|
42725
43076
|
throw new ExternalCommandError(-32072, "External Thread already has an active operation");
|
|
42726
43077
|
}
|
|
42727
|
-
const turnId = requestedTurnId ?? hostTurnIdSchema.parse(
|
|
43078
|
+
const turnId = requestedTurnId ?? hostTurnIdSchema.parse(randomUUID18());
|
|
42728
43079
|
const projection = {
|
|
42729
43080
|
projector: new CodexTurnProjector({
|
|
42730
43081
|
threadId: thread.id,
|
|
@@ -43161,9 +43512,20 @@ var AppServerHost = class {
|
|
|
43161
43512
|
await this.#writer.json(rpcError(request, resolution.error.code, resolution.error.message));
|
|
43162
43513
|
return true;
|
|
43163
43514
|
}
|
|
43515
|
+
/** Refresh history before Desktop acts on native Turn boundaries. */
|
|
43164
43516
|
#refreshExternalThread(thread) {
|
|
43165
43517
|
return this.#externalRuntime.refresh(thread);
|
|
43166
43518
|
}
|
|
43519
|
+
#markExternalHistoryRead(thread, turns) {
|
|
43520
|
+
if (!thread.historyHydrated) return;
|
|
43521
|
+
for (const turnId of thread.steeredTurnIds) {
|
|
43522
|
+
if (turnId !== thread.activeTurnId && turns.some(
|
|
43523
|
+
(turn) => turn.id === turnId && (turn.status === "completed" || turn.status === "failed" || turn.status === "interrupted")
|
|
43524
|
+
)) {
|
|
43525
|
+
thread.steeredTurnIds.delete(turnId);
|
|
43526
|
+
}
|
|
43527
|
+
}
|
|
43528
|
+
}
|
|
43167
43529
|
#persistTerminalIdentity(thread, event) {
|
|
43168
43530
|
return this.#externalRuntime.persistTerminalIdentity(thread, event);
|
|
43169
43531
|
}
|
|
@@ -43363,17 +43725,19 @@ var AppServerHost = class {
|
|
|
43363
43725
|
return;
|
|
43364
43726
|
}
|
|
43365
43727
|
}
|
|
43728
|
+
const readTurns = includeTurns ? [...this.#externalHistoryTurns(thread)] : [];
|
|
43366
43729
|
await this.#writer.json(
|
|
43367
43730
|
rpcEnvelope(request, {
|
|
43368
43731
|
result: {
|
|
43369
43732
|
thread: {
|
|
43370
43733
|
...thread.thread,
|
|
43371
43734
|
...await this.#externalSectionFields(thread.record.hostThreadId),
|
|
43372
|
-
turns:
|
|
43735
|
+
turns: readTurns
|
|
43373
43736
|
}
|
|
43374
43737
|
}
|
|
43375
43738
|
})
|
|
43376
43739
|
);
|
|
43740
|
+
if (includeTurns) this.#markExternalHistoryRead(thread, readTurns);
|
|
43377
43741
|
await this.#replayExternalUsage(thread);
|
|
43378
43742
|
}
|
|
43379
43743
|
async #listExternalHistory(request, thread, params, historyFresh) {
|
|
@@ -43390,6 +43754,9 @@ var AppServerHost = class {
|
|
|
43390
43754
|
const turns = this.#externalHistoryTurns(thread);
|
|
43391
43755
|
const result = request.method === "thread/turns/list" ? listExternalTurns(turns, params) : listExternalItems(turns, params);
|
|
43392
43756
|
await this.#writer.json(rpcEnvelope(request, { result }));
|
|
43757
|
+
if (request.method === "thread/turns/list") {
|
|
43758
|
+
this.#markExternalHistoryRead(thread, result.data);
|
|
43759
|
+
}
|
|
43393
43760
|
} catch (error51) {
|
|
43394
43761
|
await this.#writer.json(
|
|
43395
43762
|
rpcError(
|
|
@@ -43408,7 +43775,7 @@ var AppServerHost = class {
|
|
|
43408
43775
|
return;
|
|
43409
43776
|
}
|
|
43410
43777
|
}
|
|
43411
|
-
const turns = this.#externalHistoryTurns(thread);
|
|
43778
|
+
const turns = [...this.#externalHistoryTurns(thread)];
|
|
43412
43779
|
const responseThread = {
|
|
43413
43780
|
...await this.#withExternalSection(thread.thread),
|
|
43414
43781
|
turns: params.excludeTurns === true ? [] : turns
|
|
@@ -43442,6 +43809,8 @@ var AppServerHost = class {
|
|
|
43442
43809
|
}
|
|
43443
43810
|
})
|
|
43444
43811
|
);
|
|
43812
|
+
if (params.excludeTurns !== true) this.#markExternalHistoryRead(thread, turns);
|
|
43813
|
+
else if (initialTurnsPage) this.#markExternalHistoryRead(thread, initialTurnsPage.data);
|
|
43445
43814
|
} catch (error51) {
|
|
43446
43815
|
await this.#writer.json(
|
|
43447
43816
|
rpcError(
|
|
@@ -43630,10 +43999,15 @@ var AppServerHost = class {
|
|
|
43630
43999
|
assertActive,
|
|
43631
44000
|
typeof requestObject(request).clientUserMessageId === "string" ? requestObject(request).clientUserMessageId : void 0,
|
|
43632
44001
|
requestObject(request)[THREAD_REFERENCE_SOURCE_HOST_PARAM]
|
|
43633
|
-
)
|
|
44002
|
+
),
|
|
44003
|
+
(input) => this.#insertExternalInput(thread, input)
|
|
43634
44004
|
);
|
|
43635
44005
|
try {
|
|
43636
|
-
await this.#writer.json(
|
|
44006
|
+
await this.#writer.json(
|
|
44007
|
+
rpcEnvelope(request, {
|
|
44008
|
+
result: { turnId: started.turnId, delivery: started.delivery }
|
|
44009
|
+
})
|
|
44010
|
+
);
|
|
43637
44011
|
} finally {
|
|
43638
44012
|
started.gate.resolve();
|
|
43639
44013
|
}
|
|
@@ -43649,6 +44023,34 @@ var AppServerHost = class {
|
|
|
43649
44023
|
this.#signalActiveWorkChanged();
|
|
43650
44024
|
}
|
|
43651
44025
|
}
|
|
44026
|
+
/** Native same-Turn input; `insertNativeSteer` owns the delivery and its fallback signal. */
|
|
44027
|
+
async #insertExternalInput(thread, input) {
|
|
44028
|
+
await insertNativeSteer(thread, input, {
|
|
44029
|
+
project: async (turnId, item, clientUserMessageId) => {
|
|
44030
|
+
const projection = this.#projectedTurn(thread, turnId);
|
|
44031
|
+
if (clientUserMessageId) {
|
|
44032
|
+
projection.projector.bindUserMessageClientId(item.itemId, clientUserMessageId);
|
|
44033
|
+
}
|
|
44034
|
+
await this.#projectHarnessOutput(thread, {
|
|
44035
|
+
kind: "event",
|
|
44036
|
+
event: { type: "item.started", turnId, item }
|
|
44037
|
+
});
|
|
44038
|
+
await this.#projectHarnessOutput(thread, {
|
|
44039
|
+
kind: "event",
|
|
44040
|
+
event: {
|
|
44041
|
+
type: "item.completed",
|
|
44042
|
+
turnId,
|
|
44043
|
+
snapshot: { item, outcome: { status: "succeeded" } }
|
|
44044
|
+
}
|
|
44045
|
+
});
|
|
44046
|
+
},
|
|
44047
|
+
diagnose: (error51) => this.#diagnose(error51)
|
|
44048
|
+
});
|
|
44049
|
+
return {
|
|
44050
|
+
turnId: input.turnId,
|
|
44051
|
+
gate: { promise: Promise.resolve(), resolve: () => void 0 }
|
|
44052
|
+
};
|
|
44053
|
+
}
|
|
43652
44054
|
/** Keep command restoration and dispatch identical for start and steer submissions. */
|
|
43653
44055
|
async #beginExternalInputTurn(thread, inputText, assertActive, clientUserMessageId, sourceHostId) {
|
|
43654
44056
|
const text = restoreHarnessCommandMentions(inputText);
|
|
@@ -43706,7 +44108,7 @@ var AppServerHost = class {
|
|
|
43706
44108
|
if (thread.running || thread.activeTurnId || this.#pendingExternalCommandRequests.has(thread.id)) {
|
|
43707
44109
|
throw new ExternalSteerError(-32072, "External Thread already has an active Turn");
|
|
43708
44110
|
}
|
|
43709
|
-
const turnId = hostTurnIdSchema.parse(
|
|
44111
|
+
const turnId = hostTurnIdSchema.parse(randomUUID18());
|
|
43710
44112
|
const startedAtMs = Date.now();
|
|
43711
44113
|
const projection = {
|
|
43712
44114
|
projector: new CodexTurnProjector({
|
|
@@ -44000,8 +44402,14 @@ var AppServerHost = class {
|
|
|
44000
44402
|
}
|
|
44001
44403
|
return;
|
|
44002
44404
|
}
|
|
44405
|
+
if (event.type === "turn.completed" && thread.pendingSteerProjections.size > 0) {
|
|
44406
|
+
await Promise.allSettled([...thread.pendingSteerProjections]);
|
|
44407
|
+
}
|
|
44003
44408
|
const projection = this.#projectedTurn(thread, event.turnId);
|
|
44004
44409
|
await this.#waitForTurnResponse(thread, event.turnId);
|
|
44410
|
+
if (event.type === "item.completed" && event.snapshot.item.type === "agentMessage" && this.#externalVoice.has(thread.id)) {
|
|
44411
|
+
projection.realtimeInline = true;
|
|
44412
|
+
}
|
|
44005
44413
|
if (event.type === "interaction.closed" && thread.ignoredInteractionIds.delete(event.interactionId)) {
|
|
44006
44414
|
return;
|
|
44007
44415
|
}
|
|
@@ -44041,7 +44449,9 @@ var AppServerHost = class {
|
|
|
44041
44449
|
thread.ephemeralTurnIds.delete(event.turnId);
|
|
44042
44450
|
this.#manualCompactionTurns.delete(thread);
|
|
44043
44451
|
} else {
|
|
44044
|
-
thread.turns.push(
|
|
44452
|
+
thread.turns.push(
|
|
44453
|
+
projection.realtimeInline ? presentExternalVoiceTurn(result.completedTurn) : result.completedTurn
|
|
44454
|
+
);
|
|
44045
44455
|
thread.projectedTerminalTurnId = event.turnId;
|
|
44046
44456
|
thread.thread.updatedAt = completedAt;
|
|
44047
44457
|
thread.thread.recencyAt = completedAt;
|
|
@@ -44051,6 +44461,7 @@ var AppServerHost = class {
|
|
|
44051
44461
|
thread.activeTurnId = null;
|
|
44052
44462
|
if (!projection.projector.hasOpenDetachedItems) thread.projectedTurns.delete(event.turnId);
|
|
44053
44463
|
thread.responseGates.delete(event.turnId);
|
|
44464
|
+
thread.pendingSteerProjections.clear();
|
|
44054
44465
|
this.#signalActiveWorkChanged();
|
|
44055
44466
|
const delegation = await this.#repository.getDelegationByChild(thread.record.hostThreadId);
|
|
44056
44467
|
if (delegation) {
|
|
@@ -44067,7 +44478,11 @@ var AppServerHost = class {
|
|
|
44067
44478
|
if (event.type === "item.completed" && projection.projector.completed && !projection.projector.hasOpenDetachedItems) {
|
|
44068
44479
|
thread.projectedTurns.delete(event.turnId);
|
|
44069
44480
|
}
|
|
44070
|
-
for (const message2 of result.messages)
|
|
44481
|
+
for (const message2 of result.messages) {
|
|
44482
|
+
await this.#writer.json(
|
|
44483
|
+
projection.realtimeInline ? presentExternalVoiceMessage(message2) : message2
|
|
44484
|
+
);
|
|
44485
|
+
}
|
|
44071
44486
|
this.#externalVoiceResults.observe(
|
|
44072
44487
|
thread.id,
|
|
44073
44488
|
event,
|
|
@@ -44355,7 +44770,7 @@ var AppServerHost = class {
|
|
|
44355
44770
|
try {
|
|
44356
44771
|
result = projection.projector.projectQuestion(
|
|
44357
44772
|
interaction,
|
|
44358
|
-
hostItemIdSchema.parse(
|
|
44773
|
+
hostItemIdSchema.parse(randomUUID18())
|
|
44359
44774
|
);
|
|
44360
44775
|
} catch (error51) {
|
|
44361
44776
|
this.#diagnose(error51);
|
|
@@ -44583,7 +44998,7 @@ import path30 from "node:path";
|
|
|
44583
44998
|
import { PassThrough } from "node:stream";
|
|
44584
44999
|
|
|
44585
45000
|
// packages/host-runtime/src/remote-socket-lock.ts
|
|
44586
|
-
import { randomUUID as
|
|
45001
|
+
import { randomUUID as randomUUID19 } from "node:crypto";
|
|
44587
45002
|
import { chmod as chmod3, lstat as lstat5, mkdir as mkdir14, open as open9, readFile as readFile18, readdir as readdir5, rename as rename12, rm as rm13 } from "node:fs/promises";
|
|
44588
45003
|
import { uptime } from "node:os";
|
|
44589
45004
|
import path29 from "node:path";
|
|
@@ -44709,7 +45124,7 @@ async function preparePrivateLockDirectory(lockDirectory) {
|
|
|
44709
45124
|
await chmod3(lockDirectory, 448);
|
|
44710
45125
|
}
|
|
44711
45126
|
async function writeLockRecordAtomic(lockDirectory, entryPath, record4) {
|
|
44712
|
-
const temporary = path29.join(lockDirectory, `.tmp-${record4.ownerToken}-${
|
|
45127
|
+
const temporary = path29.join(lockDirectory, `.tmp-${record4.ownerToken}-${randomUUID19()}`);
|
|
44713
45128
|
const handle = await open9(temporary, "wx", 384);
|
|
44714
45129
|
try {
|
|
44715
45130
|
await handle.writeFile(`${JSON.stringify(record4)}
|
|
@@ -44784,7 +45199,7 @@ async function withRemoteAppServerSocketInitializationLock(socketPath, action) {
|
|
|
44784
45199
|
const legacyPath = `${socketPath}.initializing`;
|
|
44785
45200
|
const lockDirectory = `${socketPath}.initializers`;
|
|
44786
45201
|
await preparePrivateLockDirectory(lockDirectory);
|
|
44787
|
-
const ownerToken =
|
|
45202
|
+
const ownerToken = randomUUID19();
|
|
44788
45203
|
const entryPath = path29.join(lockDirectory, lockEntryName(ownerToken));
|
|
44789
45204
|
const baseRecord = {
|
|
44790
45205
|
version: 2,
|
|
@@ -45295,12 +45710,12 @@ function createRemoteAppServerWebSocketListener(input) {
|
|
|
45295
45710
|
|
|
45296
45711
|
// packages/host-runtime/src/remote-official-app-server.ts
|
|
45297
45712
|
import { spawn as spawn5 } from "node:child_process";
|
|
45298
|
-
import { randomUUID as
|
|
45713
|
+
import { randomUUID as randomUUID20 } from "node:crypto";
|
|
45299
45714
|
import { lstat as lstat7, rm as rm15, stat as stat7 } from "node:fs/promises";
|
|
45300
45715
|
import path31 from "node:path";
|
|
45301
45716
|
var DEFAULT_CLOSE_TIMEOUT_MS = 2e3;
|
|
45302
45717
|
var DEFAULT_LISTEN_TIMEOUT_MS = 1e4;
|
|
45303
|
-
function remoteOfficialAppServerSocketPath(desktopControlSocketPath, token =
|
|
45718
|
+
function remoteOfficialAppServerSocketPath(desktopControlSocketPath, token = randomUUID20()) {
|
|
45304
45719
|
if (!path31.posix.isAbsolute(desktopControlSocketPath)) {
|
|
45305
45720
|
throw new Error("Desktop control socket path must be absolute");
|
|
45306
45721
|
}
|
|
@@ -46586,12 +47001,12 @@ async function readRemoteDelegationThread(environment, input) {
|
|
|
46586
47001
|
}
|
|
46587
47002
|
|
|
46588
47003
|
// packages/host-runtime/src/shared-thread-owner.ts
|
|
46589
|
-
import { randomUUID as
|
|
47004
|
+
import { randomUUID as randomUUID22 } from "node:crypto";
|
|
46590
47005
|
import { PassThrough as PassThrough3 } from "node:stream";
|
|
46591
47006
|
|
|
46592
47007
|
// packages/host-runtime/src/shared-thread-peer.ts
|
|
46593
|
-
import { randomUUID as
|
|
46594
|
-
function
|
|
47008
|
+
import { randomUUID as randomUUID21 } from "node:crypto";
|
|
47009
|
+
function object9(value2) {
|
|
46595
47010
|
return value2 !== null && typeof value2 === "object" && !Array.isArray(value2);
|
|
46596
47011
|
}
|
|
46597
47012
|
var StreamThreadPeer = class {
|
|
@@ -46604,7 +47019,7 @@ var StreamThreadPeer = class {
|
|
|
46604
47019
|
input;
|
|
46605
47020
|
output;
|
|
46606
47021
|
stop;
|
|
46607
|
-
#prefix = `shared:${
|
|
47022
|
+
#prefix = `shared:${randomUUID21()}:`;
|
|
46608
47023
|
#pending = /* @__PURE__ */ new Map();
|
|
46609
47024
|
#listeners = /* @__PURE__ */ new Set();
|
|
46610
47025
|
#ended = Promise.withResolvers();
|
|
@@ -46647,7 +47062,7 @@ var StreamThreadPeer = class {
|
|
|
46647
47062
|
async #read() {
|
|
46648
47063
|
for await (const frame of readLfFrames(this.input)) {
|
|
46649
47064
|
const message2 = parseJsonFrame(frame);
|
|
46650
|
-
if (!
|
|
47065
|
+
if (!object9(message2)) throw new Error("Invalid shared Thread response");
|
|
46651
47066
|
if (typeof message2.method !== "string") {
|
|
46652
47067
|
const pending = typeof message2.id === "string" ? this.#pending.get(message2.id) : void 0;
|
|
46653
47068
|
if (pending) {
|
|
@@ -46682,7 +47097,7 @@ var SharedThreadOwner = class {
|
|
|
46682
47097
|
input = new PassThrough3();
|
|
46683
47098
|
output = new PassThrough3();
|
|
46684
47099
|
#peer = new StreamThreadPeer(this.output, this.input, () => this.input.end());
|
|
46685
|
-
#prefix = `shared-interaction:${
|
|
47100
|
+
#prefix = `shared-interaction:${randomUUID22()}:`;
|
|
46686
47101
|
#interactions = /* @__PURE__ */ new Map();
|
|
46687
47102
|
#listeners = /* @__PURE__ */ new Set();
|
|
46688
47103
|
#receipts = /* @__PURE__ */ new Map();
|
|
@@ -46693,7 +47108,7 @@ var SharedThreadOwner = class {
|
|
|
46693
47108
|
const id2 = `${this.#prefix}${message2.id}`;
|
|
46694
47109
|
event = { ...message2, id: id2 };
|
|
46695
47110
|
this.#interactions.set(id2, { nativeId: message2.id, message: event });
|
|
46696
|
-
} else if (message2.method === "serverRequest/resolved" &&
|
|
47111
|
+
} else if (message2.method === "serverRequest/resolved" && object9(message2.params)) {
|
|
46697
47112
|
const id2 = `${this.#prefix}${message2.params.requestId}`;
|
|
46698
47113
|
this.#interactions.delete(id2);
|
|
46699
47114
|
event = { ...message2, params: { ...message2.params, requestId: id2 } };
|
|
@@ -46788,7 +47203,7 @@ var SharedThreadOwner = class {
|
|
|
46788
47203
|
const parsed2 = jsonRpcRequestSchema.safeParse(message2);
|
|
46789
47204
|
if (parsed2.success) {
|
|
46790
47205
|
const request = parsed2.data;
|
|
46791
|
-
void peer.request(request.method,
|
|
47206
|
+
void peer.request(request.method, object9(request.params) ? request.params : {}).then(
|
|
46792
47207
|
(reply2) => send({ ...reply2, id: request.id }),
|
|
46793
47208
|
() => send({
|
|
46794
47209
|
id: request.id,
|
|
@@ -46798,7 +47213,7 @@ var SharedThreadOwner = class {
|
|
|
46798
47213
|
}
|
|
46799
47214
|
})
|
|
46800
47215
|
);
|
|
46801
|
-
} else if (
|
|
47216
|
+
} else if (object9(message2) && rpcId(message2.id)) {
|
|
46802
47217
|
await peer.respond(message2);
|
|
46803
47218
|
}
|
|
46804
47219
|
}
|
|
@@ -46883,8 +47298,8 @@ var SharedThreadBridge = class {
|
|
|
46883
47298
|
}
|
|
46884
47299
|
this.#peer = peer;
|
|
46885
47300
|
peer.subscribe((message2) => {
|
|
46886
|
-
const params =
|
|
46887
|
-
if (
|
|
47301
|
+
const params = object9(message2.params) ? message2.params : {};
|
|
47302
|
+
if (object9(params.thread) && params.thread.modelProvider === "codexhost" && typeof params.thread.id === "string") {
|
|
46888
47303
|
this.#known.add(params.thread.id);
|
|
46889
47304
|
}
|
|
46890
47305
|
this.#publish(message2);
|
|
@@ -46928,7 +47343,7 @@ var SharedThreadBridge = class {
|
|
|
46928
47343
|
return owners;
|
|
46929
47344
|
}
|
|
46930
47345
|
async route(request) {
|
|
46931
|
-
const params =
|
|
47346
|
+
const params = object9(request.params) ? request.params : {};
|
|
46932
47347
|
const create = this.options.delegateCreates ? classifyCreateRequestRoute(request) : null;
|
|
46933
47348
|
let shared = create !== null && create.selectedHarness !== "codex";
|
|
46934
47349
|
if (!shared && typeof params.threadId === "string") {
|
|
@@ -46945,10 +47360,10 @@ var SharedThreadBridge = class {
|
|
|
46945
47360
|
const seen = /* @__PURE__ */ new Set();
|
|
46946
47361
|
do {
|
|
46947
47362
|
const reply2 = await peer.request("thread/list", { ...params, cursor, limit: 200 });
|
|
46948
|
-
if (!
|
|
47363
|
+
if (!object9(reply2.result) || !Array.isArray(reply2.result.data))
|
|
46949
47364
|
throw new Error("Shared Thread list failed");
|
|
46950
47365
|
for (const row of reply2.result.data) {
|
|
46951
|
-
if (!
|
|
47366
|
+
if (!object9(row) || typeof row.id !== "string")
|
|
46952
47367
|
throw new Error("Invalid shared Thread row");
|
|
46953
47368
|
rows.push(row);
|
|
46954
47369
|
this.#known.add(row.id);
|
|
@@ -46977,7 +47392,7 @@ var SharedThreadBridge = class {
|
|
|
46977
47392
|
return storedSectionPlacementV1Schema.array().parse(reply2.result);
|
|
46978
47393
|
}
|
|
46979
47394
|
async respond(message2) {
|
|
46980
|
-
if (!
|
|
47395
|
+
if (!object9(message2) || typeof message2.method === "string" || typeof message2.id !== "string" || !message2.id.startsWith("shared-interaction:"))
|
|
46981
47396
|
return false;
|
|
46982
47397
|
if (!this.#peer) throw new Error("Shared Thread Host is disconnected");
|
|
46983
47398
|
await this.#peer.respond(message2);
|
|
@@ -46992,7 +47407,7 @@ var SharedThreadBridge = class {
|
|
|
46992
47407
|
};
|
|
46993
47408
|
|
|
46994
47409
|
// packages/host-runtime/src/remote-control-app-server.ts
|
|
46995
|
-
import { randomUUID as
|
|
47410
|
+
import { randomUUID as randomUUID23 } from "node:crypto";
|
|
46996
47411
|
import { mkdir as mkdir17, open as open10, rename as rename13, rm as rm17 } from "node:fs/promises";
|
|
46997
47412
|
import path37 from "node:path";
|
|
46998
47413
|
var REMOTE_CONTROL_BRIDGE_PIPE_ENV = "CODEXHOST_REMOTE_CONTROL_BRIDGE_PIPE";
|
|
@@ -47013,7 +47428,7 @@ function nodeCompatibleWindowsPath(value2) {
|
|
|
47013
47428
|
if (value2.startsWith("\\\\?\\")) return value2.slice(4);
|
|
47014
47429
|
return value2;
|
|
47015
47430
|
}
|
|
47016
|
-
function remoteControlBridgePipePath(processId = process.pid, instanceId =
|
|
47431
|
+
function remoteControlBridgePipePath(processId = process.pid, instanceId = randomUUID23()) {
|
|
47017
47432
|
const safeInstance = instanceId.replaceAll(/[^a-zA-Z0-9-]/gu, "");
|
|
47018
47433
|
if (!safeInstance) throw new Error("Remote Control bridge instance ID is invalid");
|
|
47019
47434
|
return `\\\\.\\pipe\\codexhost-remote-control-${processId}-${safeInstance}`;
|
|
@@ -47028,7 +47443,7 @@ async function publishRemoteControlAppServerDescriptor(plan) {
|
|
|
47028
47443
|
await mkdir17(directory, { recursive: true, mode: 448 });
|
|
47029
47444
|
const temporaryPath = path37.join(
|
|
47030
47445
|
directory,
|
|
47031
|
-
`.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${
|
|
47446
|
+
`.${REMOTE_CONTROL_BRIDGE_DESCRIPTOR_FILE}.${plan.descriptor.ownerPid}.${randomUUID23()}.tmp`
|
|
47032
47447
|
);
|
|
47033
47448
|
const handle = await open10(temporaryPath, "wx", 384);
|
|
47034
47449
|
try {
|
|
@@ -47569,12 +47984,19 @@ function createHostUpdateCoordinator(options2) {
|
|
|
47569
47984
|
}
|
|
47570
47985
|
|
|
47571
47986
|
// packages/host-runtime/src/usage-statistics.ts
|
|
47572
|
-
import { randomUUID as
|
|
47987
|
+
import { randomUUID as randomUUID24 } from "node:crypto";
|
|
47573
47988
|
import { mkdir as mkdir19, readFile as readFile20, readdir as readdir6, rename as rename15, rm as rm19, writeFile as writeFile11 } from "node:fs/promises";
|
|
47574
47989
|
import path40 from "node:path";
|
|
47575
47990
|
import { setImmediate as yieldToEventLoop } from "node:timers/promises";
|
|
47576
47991
|
|
|
47577
47992
|
// packages/harness-adapter/dist/usage-statistics.js
|
|
47993
|
+
var HarnessUsageSourceChangedError = class extends Error {
|
|
47994
|
+
code = "HARNESS_USAGE_SOURCE_CHANGED";
|
|
47995
|
+
/** Plugins may bundle their own copy of this contract, so instanceof is insufficient. */
|
|
47996
|
+
static is(error51) {
|
|
47997
|
+
return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "HARNESS_USAGE_SOURCE_CHANGED";
|
|
47998
|
+
}
|
|
47999
|
+
};
|
|
47578
48000
|
var MAX_SESSION_ID_LENGTH = 512;
|
|
47579
48001
|
var MAX_CWD_LENGTH = 4096;
|
|
47580
48002
|
var MAX_SESSION_TITLE_LENGTH = 200;
|
|
@@ -47677,6 +48099,95 @@ function withHostSessionTitles(result, records) {
|
|
|
47677
48099
|
};
|
|
47678
48100
|
}
|
|
47679
48101
|
|
|
48102
|
+
// packages/host-runtime/src/usage-statistics-sources.ts
|
|
48103
|
+
import { setTimeout as delay7 } from "node:timers/promises";
|
|
48104
|
+
async function* readUsageStatisticsSources(capability, sources, signal) {
|
|
48105
|
+
let pending = sources;
|
|
48106
|
+
for (let attempt = 0; ; attempt++) {
|
|
48107
|
+
const changed = [];
|
|
48108
|
+
for (const source of pending) {
|
|
48109
|
+
signal.throwIfAborted();
|
|
48110
|
+
try {
|
|
48111
|
+
const entries = (await capability.readSource(source.id, signal)).map(parseHarnessUsageEntry).filter((entry) => entry !== null);
|
|
48112
|
+
yield { source, entries };
|
|
48113
|
+
} catch (error51) {
|
|
48114
|
+
signal.throwIfAborted();
|
|
48115
|
+
if (HarnessUsageSourceChangedError.is(error51) && attempt < 2) changed.push(source);
|
|
48116
|
+
else yield { source, error: error51 };
|
|
48117
|
+
}
|
|
48118
|
+
}
|
|
48119
|
+
if (!changed.length) return;
|
|
48120
|
+
await delay7(50 * (attempt + 1), void 0, { signal });
|
|
48121
|
+
let current;
|
|
48122
|
+
try {
|
|
48123
|
+
current = new Map(
|
|
48124
|
+
(await capability.listSources(signal)).map((source) => [source.id, source])
|
|
48125
|
+
);
|
|
48126
|
+
} catch (error51) {
|
|
48127
|
+
signal.throwIfAborted();
|
|
48128
|
+
for (const source of changed) yield { source, error: error51 };
|
|
48129
|
+
return;
|
|
48130
|
+
}
|
|
48131
|
+
const next = [];
|
|
48132
|
+
for (const source of changed) {
|
|
48133
|
+
const fresh = current.get(source.id);
|
|
48134
|
+
if (fresh) next.push(fresh);
|
|
48135
|
+
else yield { source, removed: true };
|
|
48136
|
+
}
|
|
48137
|
+
pending = next;
|
|
48138
|
+
}
|
|
48139
|
+
}
|
|
48140
|
+
|
|
48141
|
+
// packages/host-runtime/src/usage-statistics-calendar.ts
|
|
48142
|
+
function dateKey(year, month, day) {
|
|
48143
|
+
return `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
|
48144
|
+
}
|
|
48145
|
+
function createUsageStatisticsCalendar(timeZone) {
|
|
48146
|
+
const localZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
48147
|
+
const zone = timeZone ?? localZone;
|
|
48148
|
+
if (zone === localZone) {
|
|
48149
|
+
return {
|
|
48150
|
+
timeZone: zone,
|
|
48151
|
+
at(ms) {
|
|
48152
|
+
const date5 = new Date(ms);
|
|
48153
|
+
return {
|
|
48154
|
+
date: dateKey(date5.getFullYear(), date5.getMonth() + 1, date5.getDate()),
|
|
48155
|
+
weekday: date5.getDay(),
|
|
48156
|
+
hour: date5.getHours()
|
|
48157
|
+
};
|
|
48158
|
+
}
|
|
48159
|
+
};
|
|
48160
|
+
}
|
|
48161
|
+
const format = new Intl.DateTimeFormat("en-US", {
|
|
48162
|
+
timeZone: zone,
|
|
48163
|
+
calendar: "gregory",
|
|
48164
|
+
numberingSystem: "latn",
|
|
48165
|
+
year: "numeric",
|
|
48166
|
+
month: "2-digit",
|
|
48167
|
+
day: "2-digit",
|
|
48168
|
+
hour: "2-digit",
|
|
48169
|
+
hourCycle: "h23"
|
|
48170
|
+
});
|
|
48171
|
+
return {
|
|
48172
|
+
timeZone: zone,
|
|
48173
|
+
at(ms) {
|
|
48174
|
+
const parts = format.formatToParts(ms);
|
|
48175
|
+
const part = (type) => Number(parts.find((value2) => value2.type === type)?.value);
|
|
48176
|
+
const year = part("year"), month = part("month"), day = part("day");
|
|
48177
|
+
return {
|
|
48178
|
+
date: dateKey(year, month, day),
|
|
48179
|
+
weekday: new Date(Date.UTC(year, month - 1, day)).getUTCDay(),
|
|
48180
|
+
hour: part("hour")
|
|
48181
|
+
};
|
|
48182
|
+
}
|
|
48183
|
+
};
|
|
48184
|
+
}
|
|
48185
|
+
function shiftUsageDate(date5, days) {
|
|
48186
|
+
const value2 = /* @__PURE__ */ new Date(`${date5}T12:00:00Z`);
|
|
48187
|
+
value2.setUTCDate(value2.getUTCDate() + days);
|
|
48188
|
+
return dateKey(value2.getUTCFullYear(), value2.getUTCMonth() + 1, value2.getUTCDate());
|
|
48189
|
+
}
|
|
48190
|
+
|
|
47680
48191
|
// packages/host-runtime/src/usage-statistics.ts
|
|
47681
48192
|
var CACHE_VERSION = 7;
|
|
47682
48193
|
var STALE_AFTER_MS = 1e4;
|
|
@@ -47737,17 +48248,6 @@ function expand(value2, intern) {
|
|
|
47737
48248
|
function message(error51) {
|
|
47738
48249
|
return error51 instanceof Error ? error51.message : String(error51);
|
|
47739
48250
|
}
|
|
47740
|
-
function localDate2(ms) {
|
|
47741
|
-
const date5 = new Date(ms);
|
|
47742
|
-
const month = String(date5.getMonth() + 1).padStart(2, "0");
|
|
47743
|
-
const day = String(date5.getDate()).padStart(2, "0");
|
|
47744
|
-
return `${date5.getFullYear()}-${month}-${day}`;
|
|
47745
|
-
}
|
|
47746
|
-
function shiftDate(date5, days) {
|
|
47747
|
-
const value2 = /* @__PURE__ */ new Date(`${date5}T12:00:00`);
|
|
47748
|
-
value2.setDate(value2.getDate() + days);
|
|
47749
|
-
return localDate2(value2.getTime());
|
|
47750
|
-
}
|
|
47751
48251
|
var SESSIONS_PER_MEASURE = 50;
|
|
47752
48252
|
var MODELS_PER_SESSION = 16;
|
|
47753
48253
|
function emptyTotals() {
|
|
@@ -47934,23 +48434,27 @@ var UsageStatistics = class {
|
|
|
47934
48434
|
}
|
|
47935
48435
|
for (const { harness: harness2, capability, ids } of listed) {
|
|
47936
48436
|
const cache = this.#cache(harness2);
|
|
47937
|
-
const present =
|
|
48437
|
+
const present = new Set(ids.map(({ id: id2 }) => id2));
|
|
47938
48438
|
let failed = null;
|
|
47939
|
-
|
|
47940
|
-
|
|
47941
|
-
|
|
47942
|
-
|
|
47943
|
-
|
|
47944
|
-
|
|
48439
|
+
const pending = ids.filter(
|
|
48440
|
+
({ id: id2, fingerprint }) => cache.sources.get(id2)?.fingerprint !== fingerprint
|
|
48441
|
+
);
|
|
48442
|
+
this.#progress.read += ids.length - pending.length;
|
|
48443
|
+
try {
|
|
48444
|
+
for await (const result of readUsageStatisticsSources(capability, pending, signal)) {
|
|
48445
|
+
const { id: id2, fingerprint } = result.source;
|
|
48446
|
+
if ("entries" in result) {
|
|
48447
|
+
cache.sources.set(id2, { fingerprint, entries: result.entries });
|
|
47945
48448
|
cache.dirty = true;
|
|
47946
48449
|
this.#generation += 1;
|
|
47947
|
-
}
|
|
47948
|
-
|
|
47949
|
-
|
|
47950
|
-
}
|
|
48450
|
+
} else if ("error" in result) failed ??= message(result.error);
|
|
48451
|
+
else present.delete(id2);
|
|
48452
|
+
this.#progress.read += 1;
|
|
47951
48453
|
await yieldToEventLoop();
|
|
47952
48454
|
}
|
|
47953
|
-
|
|
48455
|
+
} catch (error51) {
|
|
48456
|
+
if (signal.aborted) return;
|
|
48457
|
+
throw error51;
|
|
47954
48458
|
}
|
|
47955
48459
|
for (const id2 of cache.sources.keys()) {
|
|
47956
48460
|
if (!present.has(id2)) {
|
|
@@ -48015,7 +48519,7 @@ var UsageStatistics = class {
|
|
|
48015
48519
|
async #persist(harness2, cache) {
|
|
48016
48520
|
if (!cache.dirty || this.#now() - cache.persistedAtMs < PERSIST_INTERVAL_MS) return;
|
|
48017
48521
|
const file2 = this.#file(harness2);
|
|
48018
|
-
const temporary = `${file2}.${
|
|
48522
|
+
const temporary = `${file2}.${randomUUID24()}.tmp`;
|
|
48019
48523
|
try {
|
|
48020
48524
|
await mkdir19(this.#directory, { recursive: true });
|
|
48021
48525
|
const sources = [...cache.sources].map(([id2, source]) => [
|
|
@@ -48033,9 +48537,10 @@ var UsageStatistics = class {
|
|
|
48033
48537
|
await rm19(temporary, { force: true });
|
|
48034
48538
|
}
|
|
48035
48539
|
}
|
|
48036
|
-
/** Every request once, per Harness in source order,
|
|
48037
|
-
#indexed() {
|
|
48038
|
-
if (this.#index?.generation === this.#generation
|
|
48540
|
+
/** Every request once, per Harness in source order, in the requested calendar. */
|
|
48541
|
+
#indexed(calendar) {
|
|
48542
|
+
if (this.#index?.generation === this.#generation && this.#index.timeZone === calendar.timeZone)
|
|
48543
|
+
return this.#index.entries;
|
|
48039
48544
|
const entries = [];
|
|
48040
48545
|
for (const [harness2, cache] of this.#caches) {
|
|
48041
48546
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -48043,26 +48548,20 @@ var UsageStatistics = class {
|
|
|
48043
48548
|
for (const entry of parsed2) {
|
|
48044
48549
|
if (seen.has(entry.id)) continue;
|
|
48045
48550
|
seen.add(entry.id);
|
|
48046
|
-
|
|
48047
|
-
entries.push({
|
|
48048
|
-
harness: harness2,
|
|
48049
|
-
entry,
|
|
48050
|
-
date: localDate2(entry.occurredAtMs),
|
|
48051
|
-
weekday: at.getDay(),
|
|
48052
|
-
hour: at.getHours()
|
|
48053
|
-
});
|
|
48551
|
+
entries.push({ harness: harness2, entry, ...calendar.at(entry.occurredAtMs) });
|
|
48054
48552
|
}
|
|
48055
48553
|
}
|
|
48056
48554
|
}
|
|
48057
|
-
this.#index = { generation: this.#generation, entries };
|
|
48555
|
+
this.#index = { generation: this.#generation, timeZone: calendar.timeZone, entries };
|
|
48058
48556
|
return entries;
|
|
48059
48557
|
}
|
|
48060
48558
|
#aggregate(params, now, lookup) {
|
|
48061
48559
|
const { range } = params;
|
|
48062
48560
|
const days = RANGE_DAYS[range];
|
|
48063
|
-
const
|
|
48561
|
+
const calendar = createUsageStatisticsCalendar(params.timeZone);
|
|
48562
|
+
const to = calendar.at(now).date;
|
|
48064
48563
|
let from = null;
|
|
48065
|
-
if (days !== null) from =
|
|
48564
|
+
if (days !== null) from = shiftUsageDate(to, -days + 1);
|
|
48066
48565
|
const inRange = (date5) => (from === null || date5 >= from) && date5 <= to;
|
|
48067
48566
|
const day = params.date !== void 0 && inRange(params.date) ? params.date : null;
|
|
48068
48567
|
const harnessFilter = params.harness ?? null;
|
|
@@ -48103,7 +48602,7 @@ var UsageStatistics = class {
|
|
|
48103
48602
|
const harnessPriced = /* @__PURE__ */ new Map();
|
|
48104
48603
|
const byProject = /* @__PURE__ */ new Map();
|
|
48105
48604
|
const sessions = /* @__PURE__ */ new Map();
|
|
48106
|
-
for (const indexed of this.#indexed()) {
|
|
48605
|
+
for (const indexed of this.#indexed(calendar)) {
|
|
48107
48606
|
const { harness: harness2, entry, date: date5 } = indexed;
|
|
48108
48607
|
if (!inRange(date5)) continue;
|
|
48109
48608
|
const model2 = entry.model ?? null;
|
|
@@ -48636,7 +49135,7 @@ async function runHostRuntime(input) {
|
|
|
48636
49135
|
}
|
|
48637
49136
|
|
|
48638
49137
|
// packages/host-runtime/src/remote-host-install.ts
|
|
48639
|
-
import { createHash as createHash12, randomUUID as
|
|
49138
|
+
import { createHash as createHash12, randomUUID as randomUUID25 } from "node:crypto";
|
|
48640
49139
|
import { constants as fsConstants } from "node:fs";
|
|
48641
49140
|
import {
|
|
48642
49141
|
access as access4,
|
|
@@ -48735,7 +49234,7 @@ async function writeAtomic(filePath, contents, mode) {
|
|
|
48735
49234
|
await mkdir20(path42.dirname(filePath), { recursive: true, mode: 448 });
|
|
48736
49235
|
const temporary = path42.join(
|
|
48737
49236
|
path42.dirname(filePath),
|
|
48738
|
-
`.${path42.basename(filePath)}.${process.pid}.${
|
|
49237
|
+
`.${path42.basename(filePath)}.${process.pid}.${randomUUID25()}.tmp`
|
|
48739
49238
|
);
|
|
48740
49239
|
try {
|
|
48741
49240
|
if (typeof contents === "string") {
|
|
@@ -48759,7 +49258,7 @@ async function writeAtomicExecutable(filePath, sourcePath) {
|
|
|
48759
49258
|
await mkdir20(path42.dirname(filePath), { recursive: true, mode: 448 });
|
|
48760
49259
|
const temporary = path42.join(
|
|
48761
49260
|
path42.dirname(filePath),
|
|
48762
|
-
`.${path42.basename(filePath)}.${process.pid}.${
|
|
49261
|
+
`.${path42.basename(filePath)}.${process.pid}.${randomUUID25()}.tmp`
|
|
48763
49262
|
);
|
|
48764
49263
|
try {
|
|
48765
49264
|
await copyFile4(sourcePath, temporary);
|
|
@@ -49500,6 +49999,7 @@ var harnessBrokerMethodSchema = external_exports.enum([
|
|
|
49500
49999
|
"adapter.open",
|
|
49501
50000
|
"adapter.subagent.readSnapshot",
|
|
49502
50001
|
"session.readSnapshot",
|
|
50002
|
+
"session.readCapabilities",
|
|
49503
50003
|
"session.refreshUsage",
|
|
49504
50004
|
"session.execute",
|
|
49505
50005
|
"session.commands.list",
|
|
@@ -49682,6 +50182,11 @@ var turnStartSchema = external_exports.object({
|
|
|
49682
50182
|
turnId: hostTurnIdSchema,
|
|
49683
50183
|
input: external_exports.array(textInputSchema)
|
|
49684
50184
|
}).strict();
|
|
50185
|
+
var turnSteerSchema = external_exports.object({
|
|
50186
|
+
type: external_exports.literal("turn.steer"),
|
|
50187
|
+
turnId: hostTurnIdSchema,
|
|
50188
|
+
input: external_exports.array(textInputSchema)
|
|
50189
|
+
}).strict();
|
|
49685
50190
|
var turnCancelSchema = external_exports.object({ type: external_exports.literal("turn.cancel"), turnId: hostTurnIdSchema }).strict();
|
|
49686
50191
|
var interactionResponseSchema = external_exports.union([
|
|
49687
50192
|
external_exports.object({
|
|
@@ -49707,6 +50212,7 @@ var permissionSelectSchema = external_exports.object({
|
|
|
49707
50212
|
}).strict();
|
|
49708
50213
|
var brokerHostCommandSchema = external_exports.discriminatedUnion("type", [
|
|
49709
50214
|
turnStartSchema,
|
|
50215
|
+
turnSteerSchema,
|
|
49710
50216
|
turnCancelSchema,
|
|
49711
50217
|
interactionRespondSchema,
|
|
49712
50218
|
modelSelectSchema,
|
|
@@ -49841,7 +50347,7 @@ var harnessOutputSchema = external_exports.custom((value2) => {
|
|
|
49841
50347
|
});
|
|
49842
50348
|
|
|
49843
50349
|
// packages/harness-broker/dist/server.js
|
|
49844
|
-
import { randomBytes as randomBytes5, randomUUID as
|
|
50350
|
+
import { randomBytes as randomBytes5, randomUUID as randomUUID26 } from "node:crypto";
|
|
49845
50351
|
import { chmod as chmod6, lstat as lstat10, mkdir as mkdir21, open as open11, readFile as readFile22, rename as rename17, rm as rm21 } from "node:fs/promises";
|
|
49846
50352
|
import net4, {} from "node:net";
|
|
49847
50353
|
import path45 from "node:path";
|
|
@@ -49900,7 +50406,7 @@ async function assertNoLiveDescriptor(descriptorPath) {
|
|
|
49900
50406
|
}
|
|
49901
50407
|
}
|
|
49902
50408
|
async function publishDescriptor(descriptorPath, descriptor) {
|
|
49903
|
-
const temporary = `${descriptorPath}.${process.pid}.${
|
|
50409
|
+
const temporary = `${descriptorPath}.${process.pid}.${randomUUID26()}.tmp`;
|
|
49904
50410
|
const handle = await open11(temporary, "wx", 384);
|
|
49905
50411
|
try {
|
|
49906
50412
|
await handle.writeFile(`${JSON.stringify(descriptor)}
|
|
@@ -49925,6 +50431,7 @@ function sessionMetadata(record4) {
|
|
|
49925
50431
|
sessionId: record4.id,
|
|
49926
50432
|
sessionGeneration: record4.generation,
|
|
49927
50433
|
capabilities: record4.session.capabilities,
|
|
50434
|
+
readCapabilities: true,
|
|
49928
50435
|
initialState: {
|
|
49929
50436
|
...initialState,
|
|
49930
50437
|
...record4.nativeRef ? { nativeRef: record4.nativeRef } : {},
|
|
@@ -49977,7 +50484,7 @@ async function startHarnessBrokerServer(input) {
|
|
|
49977
50484
|
await assertNoLiveDescriptor(input.descriptorPath);
|
|
49978
50485
|
if (process.platform !== "win32")
|
|
49979
50486
|
await prepareUnixSocketPath(input.socketPath);
|
|
49980
|
-
const generation = input.generation ??
|
|
50487
|
+
const generation = input.generation ?? randomUUID26();
|
|
49981
50488
|
const token = input.token ?? randomBytes5(32).toString("hex");
|
|
49982
50489
|
const descriptor = {
|
|
49983
50490
|
schemaVersion: 1,
|
|
@@ -50018,7 +50525,7 @@ async function startHarnessBrokerServer(input) {
|
|
|
50018
50525
|
};
|
|
50019
50526
|
const server = net4.createServer((socket) => {
|
|
50020
50527
|
const state = {
|
|
50021
|
-
id:
|
|
50528
|
+
id: randomUUID26(),
|
|
50022
50529
|
socket,
|
|
50023
50530
|
authenticated: false,
|
|
50024
50531
|
inputSequence: 0,
|
|
@@ -50256,7 +50763,7 @@ async function startHarnessBrokerServer(input) {
|
|
|
50256
50763
|
}
|
|
50257
50764
|
};
|
|
50258
50765
|
}
|
|
50259
|
-
const openReservation =
|
|
50766
|
+
const openReservation = randomUUID26();
|
|
50260
50767
|
if (sourceKey)
|
|
50261
50768
|
nativeWriters.set(sourceKey, openReservation);
|
|
50262
50769
|
const provisionalReservation = openInput.kind === "create" ? openReservation : void 0;
|
|
@@ -50400,6 +50907,8 @@ async function startHarnessBrokerServer(input) {
|
|
|
50400
50907
|
let result;
|
|
50401
50908
|
if (command.type === "turn.start")
|
|
50402
50909
|
result = await record5.session.execute(command);
|
|
50910
|
+
else if (command.type === "turn.steer")
|
|
50911
|
+
result = await record5.session.execute(command);
|
|
50403
50912
|
else if (command.type === "turn.cancel")
|
|
50404
50913
|
result = await record5.session.execute(command);
|
|
50405
50914
|
else if (command.type === "interaction.respond") {
|
|
@@ -50431,6 +50940,10 @@ async function startHarnessBrokerServer(input) {
|
|
|
50431
50940
|
}
|
|
50432
50941
|
return result;
|
|
50433
50942
|
}
|
|
50943
|
+
if (request.method === "session.readCapabilities") {
|
|
50944
|
+
const session = requireSession(request.params).session;
|
|
50945
|
+
return session.readCapabilities ? session.readCapabilities() : session.capabilities;
|
|
50946
|
+
}
|
|
50434
50947
|
if (request.method === "session.readSnapshot") {
|
|
50435
50948
|
return requireSession(request.params).session.readSnapshot();
|
|
50436
50949
|
}
|
|
@@ -50557,7 +51070,7 @@ async function startHarnessBrokerServer(input) {
|
|
|
50557
51070
|
}
|
|
50558
51071
|
state.authenticated = true;
|
|
50559
51072
|
state.inputSequence = 1;
|
|
50560
|
-
await send({ kind: "response", id:
|
|
51073
|
+
await send({ kind: "response", id: randomUUID26(), ok: true, value: { ready: true } });
|
|
50561
51074
|
return;
|
|
50562
51075
|
}
|
|
50563
51076
|
const parsed2 = harnessBrokerRequestSchema.safeParse(raw);
|