@odla-ai/harness 0.11.12 → 0.11.14
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/dist/{chunk-INL642J5.js → chunk-6T26HEWI.js} +7 -3
- package/dist/chunk-6T26HEWI.js.map +1 -0
- package/dist/{chunk-6QILNLBY.js → chunk-ZXUN2STV.js} +36 -29
- package/dist/chunk-ZXUN2STV.js.map +1 -0
- package/dist/code-runtime-cli.cjs +51 -41
- package/dist/code-runtime-cli.cjs.map +1 -1
- package/dist/code-runtime-cli.js +2 -2
- package/dist/index.cjs +6 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/node.cjs +53 -41
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +5 -1
- package/dist/node.d.ts +5 -1
- package/dist/node.js +4 -2
- package/dist/node.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-6QILNLBY.js.map +0 -1
- package/dist/chunk-INL642J5.js.map +0 -1
|
@@ -82,7 +82,8 @@ function codeToolRequestPresentation(request) {
|
|
|
82
82
|
}
|
|
83
83
|
function codeToolResultPresentation(request, response) {
|
|
84
84
|
const started = codeToolRequestPresentation(request);
|
|
85
|
-
if (!started
|
|
85
|
+
if (!started) return void 0;
|
|
86
|
+
if (!response.ok && started.kind !== "recipe") return started;
|
|
86
87
|
const details = record(response.details);
|
|
87
88
|
if (started.kind === "read") {
|
|
88
89
|
return {
|
|
@@ -129,7 +130,10 @@ function toolFailureReason(response) {
|
|
|
129
130
|
if (response.ok) return void 0;
|
|
130
131
|
const supplied = response.details?.failureReason;
|
|
131
132
|
const reason = typeof supplied === "string" && supplied || DEFAULT_FAILURE_REASON[response.content] || response.content || "tool request failed; inspect the tool input and workspace state";
|
|
132
|
-
|
|
133
|
+
if (reason.length <= MAX_FAILURE_REASON) return reason;
|
|
134
|
+
const head = reason.slice(0, 60);
|
|
135
|
+
const gap = " \u2026 ";
|
|
136
|
+
return `${head}${gap}${reason.slice(-(MAX_FAILURE_REASON - head.length - gap.length))}`;
|
|
133
137
|
}
|
|
134
138
|
var DEFAULT_FAILURE_REASON = {
|
|
135
139
|
"tool denied by CaMeL policy": "tool denied by CaMeL policy",
|
|
@@ -172,4 +176,4 @@ export {
|
|
|
172
176
|
toolFailureReason,
|
|
173
177
|
observedBroker
|
|
174
178
|
};
|
|
175
|
-
//# sourceMappingURL=chunk-
|
|
179
|
+
//# sourceMappingURL=chunk-6T26HEWI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/code-tool-presentation.ts","../src/code-runtime-observer.ts"],"sourcesContent":["import type {\n CodeToolLocationPreview, CodeToolPresentation, HarnessToolRequest, HarnessToolResponse,\n} from \"./types\";\n\nconst text = (value: unknown, maximum: number): string | undefined => {\n if (typeof value !== \"string\") return undefined;\n const bounded = value.replace(/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]/g, \" \").trim();\n return bounded ? bounded.slice(0, maximum) : undefined;\n};\nconst integer = (value: unknown): number | undefined =>\n Number.isSafeInteger(value) && Number(value) >= 0 ? Number(value) : undefined;\nconst record = (value: unknown): Record<string, unknown> | undefined =>\n value && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown> : undefined;\nconst excerpt = (value: unknown, tail = false): string | undefined => {\n if (typeof value !== \"string\") return undefined;\n const safe = value.replace(/[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]/g, \" \");\n const source = (tail ? safe.slice(-10_000) : safe.slice(0, 10_000)).trim();\n if (!source) return undefined;\n const lines = source.split(\"\\n\").filter((line) => line.trim()).map((line) => line.slice(0, 240));\n const selected = tail ? lines.slice(-10) : lines.slice(0, 10);\n return text(selected.join(\"\\n\"), 2_400);\n};\nconst paths = (value: unknown): string[] | undefined => {\n if (!Array.isArray(value)) return undefined;\n const items = value.flatMap((item) => {\n const path = text(item, 1_024);\n return path ? [path] : [];\n }).slice(0, 12);\n return items.length ? items : undefined;\n};\n\nfunction patchStats(value: unknown): { additions?: number; deletions?: number } {\n if (typeof value !== \"string\") return {};\n let additions = 0;\n let deletions = 0;\n for (const line of value.slice(0, 262_144).split(\"\\n\")) {\n if (line.startsWith(\"+++\") || line.startsWith(\"---\")) continue;\n if (line.startsWith(\"+\")) additions += 1;\n else if (line.startsWith(\"-\")) deletions += 1;\n }\n return { ...(additions ? { additions } : {}), ...(deletions ? { deletions } : {}) };\n}\n\nfunction searchResults(value: unknown): CodeToolLocationPreview[] | undefined {\n if (typeof value !== \"string\") return undefined;\n const results = value.split(\"\\n\").flatMap((line) => {\n const match = /^([^:\\n]{1,1024}):(\\d+):\\s?(.*)$/.exec(line);\n if (!match) return [];\n const lineNumber = Number(match[2]);\n const itemText = text(match[3], 240);\n if (!Number.isSafeInteger(lineNumber) || lineNumber < 1) return [];\n return [{ path: match[1]!, line: lineNumber, ...(itemText ? { text: itemText } : {}) }];\n }).slice(0, 5);\n return results.length ? results : undefined;\n}\n\n/** Produce the bounded presentation available as soon as a broker call starts. */\nexport function codeToolRequestPresentation(request: HarnessToolRequest): CodeToolPresentation | undefined {\n const input = request.input;\n if (request.tool === \"sandbox.read\") {\n const path = text(input.path, 1_024);\n if (!path) return undefined;\n const startLine = integer(input.startLine);\n const endLine = integer(input.endLine);\n return { kind: \"read\", path, ...(startLine ? { startLine } : {}), ...(endLine ? { endLine } : {}) };\n }\n if (request.tool === \"sandbox.list\") {\n const scope = text(input.prefix, 1_024);\n return { kind: \"list\", ...(scope ? { scope } : {}) };\n }\n if (request.tool === \"sandbox.search\" || request.tool === \"sandbox.overview\"\n || request.tool === \"sandbox.where_is\" || request.tool === \"sandbox.who_imports\"\n || request.tool === \"sandbox.who_touches\") {\n const query = text(input.query, 512);\n const scope = request.tool === \"sandbox.search\" ? text(input.prefix, 1_024) : undefined;\n if (request.tool === \"sandbox.search\" && !query) return undefined;\n return { kind: \"query\", ...(query ? { query } : {}), ...(scope ? { scope } : {}) };\n }\n if (request.tool === \"sandbox.apply_patch\") {\n return { kind: \"patch\", ...patchStats(input.patch) };\n }\n if (request.tool === \"sandbox.edit\") {\n const lines = (value: unknown) => (typeof value === \"string\" ? value.slice(0, 262_144).split(\"\\n\").length : 0);\n return { kind: \"patch\", additions: lines(input.newText), deletions: lines(input.oldText) };\n }\n if (request.tool === \"sandbox.write\") {\n const path = text(input.path, 1_024);\n const additions = typeof input.content === \"string\" ? input.content.slice(0, 262_144).split(\"\\n\").length : 0;\n return { kind: \"patch\", additions, ...(path ? { paths: [path] } : {}) };\n }\n const recipeId = text(input.recipeId, 120);\n return recipeId ? { kind: \"recipe\", recipeId } : undefined;\n}\n\n/** Enrich a started presentation with only the broker's bounded result shape. */\nexport function codeToolResultPresentation(\n request: HarnessToolRequest,\n response: HarnessToolResponse,\n): CodeToolPresentation | undefined {\n const started = codeToolRequestPresentation(request);\n if (!started) return undefined;\n // A failed read or search has nothing to show but its reason; a failed\n // recipe is the one result whose output matters most, and a bounded reason\n // showed nothing of a red test run (bug eff741ee).\n if (!response.ok && started.kind !== \"recipe\") return started;\n const details = record(response.details);\n if (started.kind === \"read\") {\n return {\n ...started,\n ...(integer(details?.startLine) ? { startLine: integer(details?.startLine) } : {}),\n ...(integer(details?.endLine) ? { endLine: integer(details?.endLine) } : {}),\n ...(excerpt(response.content) ? { excerpt: excerpt(response.content) } : {}),\n };\n }\n if (started.kind === \"list\") {\n const listed = response.content.split(\"\\n\")\n .filter((line) => line && !line.startsWith(\"…\") && !line.startsWith(\"Workspace \"))\n .map((line) => text(line, 1_024)).filter((line): line is string => Boolean(line)).slice(0, 8);\n return {\n ...started,\n ...(integer(details?.count) !== undefined ? { count: integer(details?.count) } : {}),\n ...(listed.length ? { paths: listed } : {}),\n };\n }\n if (started.kind === \"query\") {\n const results = request.tool === \"sandbox.search\" ? searchResults(response.content) : undefined;\n const resultExcerpt = request.tool === \"sandbox.search\" ? undefined : excerpt(response.content);\n return {\n ...started,\n ...(integer(details?.count) !== undefined ? { count: integer(details?.count) } : {}),\n ...(results ? { results } : {}),\n ...(resultExcerpt ? { excerpt: resultExcerpt } : {}),\n };\n }\n if (started.kind === \"patch\") {\n return { ...started, ...(paths(details?.paths) ? { paths: paths(details?.paths) } : {}) };\n }\n const output = response.content.replace(/^Recipe [^\\n]*\\.?\\s*/u, \"\");\n return {\n ...started,\n ...(integer(details?.exitCode) !== undefined ? { exitCode: integer(details?.exitCode) } : {}),\n ...(typeof details?.timedOut === \"boolean\" ? { timedOut: details.timedOut } : {}),\n ...(typeof details?.outputLimitExceeded === \"boolean\"\n ? { outputLimitExceeded: details.outputLimitExceeded } : {}),\n ...(excerpt(output, true) ? { excerpt: excerpt(output, true) } : {}),\n };\n}\n","// Reporting a brokered tool effect onto the session event stream.\n//\n// Split out of code-runtime-engine.ts, which was one line under the 250 LOC cap\n// and so could not absorb the failure reason below (PM bug c775485c: the same\n// two lines left PR #684 red and unlandable). The seam is real rather than\n// convenient — this is the only code in the engine that translates a broker\n// call into what a watcher sees, and it is the only code that needs to know how\n// a failure is described.\n\nimport { codeToolRequestPresentation, codeToolResultPresentation } from \"./code-tool-presentation\";\nimport type { CodeSessionEventData, HarnessToolBroker, HarnessToolResponse } from \"./types\";\n\n/** Longest failure reason forwarded onto a session event. A reason is a short\n * diagnostic for a human or an agent reading the stream, never a transcript. */\nexport const MAX_FAILURE_REASON = 240;\n\n/** The bounded reason a failed tool response carries, if it carries one.\n *\n * Only `response.ok` used to reach the stream, so a watcher saw that a call\n * failed and could never see why — which is what made an 84% apply_patch\n * failure rate undiagnosable (PM bugs 515655ec and 38d92f1d). */\nexport function toolFailureReason(response: HarnessToolResponse): string | undefined {\n if (response.ok) return undefined;\n // Guaranteed here rather than only where the response is built, because this\n // is the boundary that emits the event: a failure reaching the stream without\n // a reason is the defect, whoever constructed the response.\n const supplied = response.details?.failureReason;\n const reason = (typeof supplied === \"string\" && supplied)\n || DEFAULT_FAILURE_REASON[response.content]\n || response.content\n || \"tool request failed; inspect the tool input and workspace state\";\n if (reason.length <= MAX_FAILURE_REASON) return reason;\n // A test runner states its verdict last, so a reason that must be cut keeps\n // its first line and its tail rather than a head that ends mid-preamble.\n const head = reason.slice(0, 60); const gap = \" … \";\n return `${head}${gap}${reason.slice(-(MAX_FAILURE_REASON - head.length - gap.length))}`;\n}\n\n/** Reasons for the two refusals the broker states as bare content. */\nconst DEFAULT_FAILURE_REASON: Record<string, string> = {\n \"tool denied by CaMeL policy\": \"tool denied by CaMeL policy\",\n \"review sessions are read-only\": \"review session is read-only; workspace changes are not permitted\",\n};\n\n/** Wrap `broker` so every effect reports its start and its finish.\n *\n * `emit` is the engine's own event sink; it already swallows its own errors, so\n * reporting can never fail the effect it is reporting on.\n */\nexport function observedBroker(input: {\n broker: HarnessToolBroker;\n operationIdFor: (requestId: string) => string;\n emit: (event: CodeSessionEventData) => Promise<void>;\n now?: () => number;\n}): HarnessToolBroker {\n const now = input.now ?? Date.now;\n return {\n execute: async (context, request) => {\n const startedAt = now();\n // Stable and opaque: an older container may choose any bounded request\n // id, while the owner stream admits only a closed printable id shape.\n const operationId = input.operationIdFor(request.requestId);\n const startedPresentation = codeToolRequestPresentation(request);\n await input.emit({\n type: \"tool\", phase: \"started\", tool: request.tool, operationId,\n ...(startedPresentation ? { presentation: startedPresentation } : {}),\n });\n const response = await input.broker.execute(context, request);\n const completedPresentation = codeToolResultPresentation(request, response);\n const failureReason = toolFailureReason(response);\n await input.emit({\n type: \"tool\", phase: \"completed\", tool: request.tool,\n ok: response.ok, durationMs: now() - startedAt, operationId,\n ...(failureReason ? { failureReason } : {}),\n ...(completedPresentation ? { presentation: completedPresentation } : {}),\n });\n return response;\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
observedBroker
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6T26HEWI.js";
|
|
4
4
|
import {
|
|
5
5
|
SECRET_WORKSPACE_FILE,
|
|
6
6
|
SKIP_WORKSPACE_DIRS,
|
|
@@ -1040,6 +1040,10 @@ function parseMemory(value) {
|
|
|
1040
1040
|
function execute(engine, args, name, recipe2, signal) {
|
|
1041
1041
|
return runContainerCommand(engine, args, name, { timeoutMs: recipe2.timeoutMs, maxOutputBytes: recipe2.maxOutputBytes }, signal);
|
|
1042
1042
|
}
|
|
1043
|
+
var CONTAINER_PROGRESS = /^\[\d+\/\d+\] .*$/gm;
|
|
1044
|
+
function recipeOutput(engine, stderr) {
|
|
1045
|
+
return engine === "container" ? stderr.replace(CONTAINER_PROGRESS, "").replace(/^\n+/, "") : stderr;
|
|
1046
|
+
}
|
|
1043
1047
|
function runContainerCommand(engine, args, name, recipe2, signal) {
|
|
1044
1048
|
return new Promise((accept, reject) => {
|
|
1045
1049
|
const started = Date.now();
|
|
@@ -1082,7 +1086,7 @@ function runContainerCommand(engine, args, name, recipe2, signal) {
|
|
|
1082
1086
|
accept({
|
|
1083
1087
|
exitCode: code ?? 1,
|
|
1084
1088
|
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
1085
|
-
stderr: Buffer.concat(stderr).toString("utf8"),
|
|
1089
|
+
stderr: recipeOutput(engine, Buffer.concat(stderr).toString("utf8")),
|
|
1086
1090
|
durationMs: Date.now() - started,
|
|
1087
1091
|
outputLimitExceeded,
|
|
1088
1092
|
timedOut
|
|
@@ -3625,7 +3629,7 @@ function describeProofRecipes(proven, proof, envelope) {
|
|
|
3625
3629
|
function createCodeRuntimeToolBroker(input, lease, role) {
|
|
3626
3630
|
const broker = createCodeToolBroker({
|
|
3627
3631
|
recipes: input.recipes,
|
|
3628
|
-
recipeExecutor: createContainerRecipeExecutor(input.engine),
|
|
3632
|
+
recipeExecutor: input.recipeExecutor ?? createContainerRecipeExecutor(input.engine),
|
|
3629
3633
|
recipeAuthorization: input.recipeAuthorization ?? "registered_recipe",
|
|
3630
3634
|
readerId: `code-session:${lease.task.taskId}`,
|
|
3631
3635
|
readOnlyPrefixes: [".odla-references"]
|
|
@@ -3643,6 +3647,19 @@ function createCodeRuntimeToolBroker(input, lease, role) {
|
|
|
3643
3647
|
return role === "coding" ? broker : { execute: (context, request) => reviewTools.has(request.tool) ? broker.execute(context, request) : Promise.resolve({ requestId: request.requestId, ok: false, content: "review sessions are read-only" }) };
|
|
3644
3648
|
}
|
|
3645
3649
|
|
|
3650
|
+
// src/code-runtime-engine-report.ts
|
|
3651
|
+
async function recordSessionFailure(options, command, active, value) {
|
|
3652
|
+
active.failure = value.slice(0, 2e3);
|
|
3653
|
+
if (active.acknowledged) {
|
|
3654
|
+
await options.control.reportSessionFailure(command.sessionId, active.failure).catch(() => void 0);
|
|
3655
|
+
}
|
|
3656
|
+
}
|
|
3657
|
+
async function recordDiagnostic(options, command, active, value) {
|
|
3658
|
+
const detail = value.trim().slice(0, 2e3) || "Theseus runtime failed";
|
|
3659
|
+
options.onDiagnostic?.(detail);
|
|
3660
|
+
await appendCodeRuntimeEvent(options.control, command, { type: "diagnostic", level: "error", message: detail }, active.conversationRefs).catch(() => void 0);
|
|
3661
|
+
}
|
|
3662
|
+
|
|
3646
3663
|
// src/code-runtime-goal.ts
|
|
3647
3664
|
var POSITIVE = (value) => Number.isFinite(value) && Number(value) > 0 ? Number(value) : void 0;
|
|
3648
3665
|
function codeGoalSpec(payload) {
|
|
@@ -3878,10 +3895,11 @@ var TheseusRuntimeEngine = class {
|
|
|
3878
3895
|
this.options = options;
|
|
3879
3896
|
this.#attempt = options.runAgentAttempt ?? runCodeAgentAttempt;
|
|
3880
3897
|
this.#buildPolicyDigest = digestRuntimeValue(JSON.stringify(options.recipes));
|
|
3898
|
+
this.#recipeExecutor = options.recipeExecutor ?? createContainerRecipeExecutor(options.engine, { dependencies: options.recipeDependencies ?? null });
|
|
3881
3899
|
this.#checkpoints = new CodeRuntimeCheckpointManager({
|
|
3882
3900
|
control: options.control,
|
|
3883
3901
|
recipes: options.recipes,
|
|
3884
|
-
recipeExecutor:
|
|
3902
|
+
recipeExecutor: this.#recipeExecutor,
|
|
3885
3903
|
fallbackPolicyDigest: this.#buildPolicyDigest,
|
|
3886
3904
|
event: (command, event, refs) => this.#event(command, event, refs)
|
|
3887
3905
|
});
|
|
@@ -3891,6 +3909,8 @@ var TheseusRuntimeEngine = class {
|
|
|
3891
3909
|
#attempt;
|
|
3892
3910
|
#buildPolicyDigest;
|
|
3893
3911
|
#checkpoints;
|
|
3912
|
+
/** One executor for the session broker, the verifier and goal pursuit, built with the host's dependency tree. */
|
|
3913
|
+
#recipeExecutor;
|
|
3894
3914
|
execute(command) {
|
|
3895
3915
|
if (command.kind === "checkpoint_stop") return this.#checkpoint(command);
|
|
3896
3916
|
if (command.kind === "pursue") return this.#pursue(command);
|
|
@@ -3963,9 +3983,9 @@ var TheseusRuntimeEngine = class {
|
|
|
3963
3983
|
active.done = startGate.ready.then((run) => run ? this.#runAttempt(command, metadata, active) : null).catch(async (cause) => {
|
|
3964
3984
|
const detail = runtimeErrorMessage(cause);
|
|
3965
3985
|
await this.#event(command, { type: "message", actor: "system", body: detail }, conversationRefs).catch(() => void 0);
|
|
3966
|
-
await this
|
|
3986
|
+
await recordDiagnostic(this.options, command, active, detail);
|
|
3967
3987
|
await this.#event(command, { type: "status", status: "failed" }, conversationRefs).catch(() => void 0);
|
|
3968
|
-
await this
|
|
3988
|
+
await recordSessionFailure(this.options, command, active, detail);
|
|
3969
3989
|
return null;
|
|
3970
3990
|
});
|
|
3971
3991
|
return {
|
|
@@ -3989,7 +4009,7 @@ var TheseusRuntimeEngine = class {
|
|
|
3989
4009
|
active.done = startGoalPursuit({
|
|
3990
4010
|
spec,
|
|
3991
4011
|
recipes: active.recipes,
|
|
3992
|
-
recipeExecutor: this
|
|
4012
|
+
recipeExecutor: this.#recipeExecutor,
|
|
3993
4013
|
workspace: active.workspace,
|
|
3994
4014
|
baseCommitSha: active.baseCommitSha,
|
|
3995
4015
|
trustedBaseDigest: active.trustedBaseDigest,
|
|
@@ -4011,8 +4031,8 @@ var TheseusRuntimeEngine = class {
|
|
|
4011
4031
|
}, active)
|
|
4012
4032
|
}).catch(async (cause) => {
|
|
4013
4033
|
const detail = runtimeErrorMessage(cause);
|
|
4014
|
-
await this
|
|
4015
|
-
await this
|
|
4034
|
+
await recordDiagnostic(this.options, command, active, detail);
|
|
4035
|
+
await recordSessionFailure(this.options, command, active, detail);
|
|
4016
4036
|
return { status: "failed", finalText: "", error: detail };
|
|
4017
4037
|
});
|
|
4018
4038
|
return { status: "running", message: `Pursuing the goal, up to ${spec.budget.maxAttempts} attempt(s)` };
|
|
@@ -4059,9 +4079,9 @@ var TheseusRuntimeEngine = class {
|
|
|
4059
4079
|
{ type: "message", actor: "system", body: detail },
|
|
4060
4080
|
active.conversationRefs
|
|
4061
4081
|
).catch(() => void 0);
|
|
4062
|
-
await this
|
|
4082
|
+
await recordDiagnostic(this.options, command, active, detail);
|
|
4063
4083
|
await this.#event(command, { type: "status", status: "failed" }, active.conversationRefs).catch(() => void 0);
|
|
4064
|
-
await this
|
|
4084
|
+
await recordSessionFailure(this.options, command, active, detail);
|
|
4065
4085
|
return null;
|
|
4066
4086
|
});
|
|
4067
4087
|
return { status: "running", message: "Theseus accepted the owner prompt" };
|
|
@@ -4071,6 +4091,7 @@ var TheseusRuntimeEngine = class {
|
|
|
4071
4091
|
const broker = this.#observed(command, active, createCodeRuntimeToolBroker({
|
|
4072
4092
|
recipes: active.recipes,
|
|
4073
4093
|
engine: this.options.engine,
|
|
4094
|
+
recipeExecutor: this.#recipeExecutor,
|
|
4074
4095
|
recipeAuthorization: this.options.recipeAuthorization
|
|
4075
4096
|
}, lease, metadata.role));
|
|
4076
4097
|
const startedAt = Date.now();
|
|
@@ -4113,8 +4134,8 @@ var TheseusRuntimeEngine = class {
|
|
|
4113
4134
|
durationMs: Date.now() - startedAt
|
|
4114
4135
|
}, active.conversationRefs).catch(() => void 0);
|
|
4115
4136
|
if (!completed) {
|
|
4116
|
-
await this
|
|
4117
|
-
await this
|
|
4137
|
+
await recordDiagnostic(this.options, command, active, detail);
|
|
4138
|
+
await recordSessionFailure(this.options, command, active, detail);
|
|
4118
4139
|
}
|
|
4119
4140
|
return {
|
|
4120
4141
|
...result,
|
|
@@ -4139,21 +4160,6 @@ var TheseusRuntimeEngine = class {
|
|
|
4139
4160
|
this.#active.delete(command.sessionId);
|
|
4140
4161
|
return result;
|
|
4141
4162
|
}
|
|
4142
|
-
async #failure(command, active, value) {
|
|
4143
|
-
active.failure = value.slice(0, 2e3);
|
|
4144
|
-
if (active.acknowledged) {
|
|
4145
|
-
await this.options.control.reportSessionFailure(command.sessionId, active.failure).catch(() => void 0);
|
|
4146
|
-
}
|
|
4147
|
-
}
|
|
4148
|
-
async #diagnostic(command, active, value) {
|
|
4149
|
-
const detail = value.trim().slice(0, 2e3) || "Theseus runtime failed";
|
|
4150
|
-
this.options.onDiagnostic?.(detail);
|
|
4151
|
-
await this.#event(
|
|
4152
|
-
command,
|
|
4153
|
-
{ type: "diagnostic", level: "error", message: detail },
|
|
4154
|
-
active.conversationRefs
|
|
4155
|
-
).catch(() => void 0);
|
|
4156
|
-
}
|
|
4157
4163
|
async #event(command, event, refs) {
|
|
4158
4164
|
await appendCodeRuntimeEvent(this.options.control, command, event, refs);
|
|
4159
4165
|
}
|
|
@@ -4189,6 +4195,7 @@ export {
|
|
|
4189
4195
|
buildRecipeContainerArgs,
|
|
4190
4196
|
createContainerRecipeExecutor,
|
|
4191
4197
|
assertCodeBuildRecipe,
|
|
4198
|
+
recipeOutput,
|
|
4192
4199
|
runContainerCommand,
|
|
4193
4200
|
verifyCodeCandidate,
|
|
4194
4201
|
prepareRuntimeCheckpoint,
|
|
@@ -4227,4 +4234,4 @@ export {
|
|
|
4227
4234
|
withProofRecipes,
|
|
4228
4235
|
TheseusRuntimeEngine
|
|
4229
4236
|
};
|
|
4230
|
-
//# sourceMappingURL=chunk-
|
|
4237
|
+
//# sourceMappingURL=chunk-ZXUN2STV.js.map
|