@odla-ai/harness 0.11.13 → 0.11.15

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.
@@ -2803,7 +2803,8 @@ function codeToolRequestPresentation(request) {
2803
2803
  }
2804
2804
  function codeToolResultPresentation(request, response2) {
2805
2805
  const started = codeToolRequestPresentation(request);
2806
- if (!started || !response2.ok) return started;
2806
+ if (!started) return void 0;
2807
+ if (!response2.ok && started.kind !== "recipe") return started;
2807
2808
  const details = record3(response2.details);
2808
2809
  if (started.kind === "read") {
2809
2810
  return {
@@ -3623,6 +3624,19 @@ async function graphQuery(context, request, options, policy, registry) {
3623
3624
  return response(request, true, renderWhoTouches(graphs, query));
3624
3625
  }
3625
3626
 
3627
+ // src/code-tool-recipe-output.ts
3628
+ var RECIPE_OUTPUT_HEAD = 4e3;
3629
+ var RECIPE_OUTPUT_TAIL = 24e3;
3630
+ var ANSI = /\u001b\[[0-9;?]*[A-Za-z]/g;
3631
+ function boundedRecipeOutput(output) {
3632
+ const plain = output.replace(ANSI, "");
3633
+ if (plain.length <= RECIPE_OUTPUT_HEAD + RECIPE_OUTPUT_TAIL) return plain;
3634
+ const omitted = plain.length - RECIPE_OUTPUT_HEAD - RECIPE_OUTPUT_TAIL;
3635
+ return `${plain.slice(0, RECIPE_OUTPUT_HEAD)}
3636
+ \u2026 [${omitted} characters omitted; the last ${RECIPE_OUTPUT_TAIL} follow] \u2026
3637
+ ${plain.slice(-RECIPE_OUTPUT_TAIL)}`;
3638
+ }
3639
+
3626
3640
  // src/code-tool-broker.ts
3627
3641
  function createCodeToolBroker(options) {
3628
3642
  validateOptions(options);
@@ -3722,8 +3736,9 @@ async function recipe(context, request, options, recipes, policy) {
3722
3736
  const output = [result.stdout, result.stderr].filter(Boolean).join("\n");
3723
3737
  const ok = result.exitCode === 0 && !result.outputLimitExceeded && !result.timedOut;
3724
3738
  const status = result.timedOut ? "timed out" : result.outputLimitExceeded ? "exceeded output limit" : ok ? "passed" : `failed with exit ${result.exitCode}`;
3725
- return response(request, ok, `Recipe ${recipeId} ${status}.${output ? `
3726
- ${output}` : ""}`, {
3739
+ const shown = boundedRecipeOutput(output);
3740
+ return response(request, ok, `Recipe ${recipeId} ${status}.${shown ? `
3741
+ ${shown}` : ""}`, {
3727
3742
  recipeId,
3728
3743
  exitCode: result.exitCode,
3729
3744
  durationMs: result.durationMs,
@@ -3748,7 +3763,7 @@ function validateOptions(options) {
3748
3763
  function createCodeRuntimeToolBroker(input, lease, role) {
3749
3764
  const broker = createCodeToolBroker({
3750
3765
  recipes: input.recipes,
3751
- recipeExecutor: createContainerRecipeExecutor(input.engine),
3766
+ recipeExecutor: input.recipeExecutor ?? createContainerRecipeExecutor(input.engine),
3752
3767
  recipeAuthorization: input.recipeAuthorization ?? "registered_recipe",
3753
3768
  readerId: `code-session:${lease.task.taskId}`,
3754
3769
  readOnlyPrefixes: [".odla-references"]
@@ -3766,6 +3781,31 @@ function createCodeRuntimeToolBroker(input, lease, role) {
3766
3781
  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" }) };
3767
3782
  }
3768
3783
 
3784
+ // src/code-runtime-events.ts
3785
+ var import_node_crypto4 = require("crypto");
3786
+ async function appendCodeRuntimeEvent(control, command, event, refs) {
3787
+ const eventId = `${command.commandId.slice(0, 45)}:${refs.length + 1}`;
3788
+ refs.push(eventId);
3789
+ const attributed = { ...event, interactionId: command.commandId };
3790
+ const bounded = attributed.type === "message" ? { ...attributed, body: attributed.body.trim().slice(0, 2e4) || `${attributed.actor} event` } : attributed;
3791
+ await control.appendSessionEvent(command.sessionId, eventId, bounded);
3792
+ }
3793
+ var digestRuntimeValue = (value) => `sha256:${(0, import_node_crypto4.createHash)("sha256").update(value).digest("hex")}`;
3794
+ var runtimeErrorMessage = (value) => value instanceof Error ? value.message : String(value);
3795
+
3796
+ // src/code-runtime-engine-report.ts
3797
+ async function recordSessionFailure(options, command, active, value) {
3798
+ active.failure = value.slice(0, 2e3);
3799
+ if (active.acknowledged) {
3800
+ await options.control.reportSessionFailure(command.sessionId, active.failure).catch(() => void 0);
3801
+ }
3802
+ }
3803
+ async function recordDiagnostic(options, command, active, value) {
3804
+ const detail = value.trim().slice(0, 2e3) || "Theseus runtime failed";
3805
+ options.onDiagnostic?.(detail);
3806
+ await appendCodeRuntimeEvent(options.control, command, { type: "diagnostic", level: "error", message: detail }, active.conversationRefs).catch(() => void 0);
3807
+ }
3808
+
3769
3809
  // src/code-memory.ts
3770
3810
  var import_graph2 = require("@odla-ai/graph");
3771
3811
  var MAX_MEMORY_BODY = 4e3;
@@ -4054,18 +4094,6 @@ async function startGoalPursuit(input) {
4054
4094
  return { status: run.met ? "completed" : "failed", finalText: "" };
4055
4095
  }
4056
4096
 
4057
- // src/code-runtime-events.ts
4058
- var import_node_crypto4 = require("crypto");
4059
- async function appendCodeRuntimeEvent(control, command, event, refs) {
4060
- const eventId = `${command.commandId.slice(0, 45)}:${refs.length + 1}`;
4061
- refs.push(eventId);
4062
- const attributed = { ...event, interactionId: command.commandId };
4063
- const bounded = attributed.type === "message" ? { ...attributed, body: attributed.body.trim().slice(0, 2e4) || `${attributed.actor} event` } : attributed;
4064
- await control.appendSessionEvent(command.sessionId, eventId, bounded);
4065
- }
4066
- var digestRuntimeValue = (value) => `sha256:${(0, import_node_crypto4.createHash)("sha256").update(value).digest("hex")}`;
4067
- var runtimeErrorMessage = (value) => value instanceof Error ? value.message : String(value);
4068
-
4069
4097
  // src/code-runtime-acknowledgement-gate.ts
4070
4098
  function codeRuntimeAcknowledgementGate(signal) {
4071
4099
  let settle;
@@ -4253,10 +4281,11 @@ var TheseusRuntimeEngine = class {
4253
4281
  this.options = options;
4254
4282
  this.#attempt = options.runAgentAttempt ?? runCodeAgentAttempt;
4255
4283
  this.#buildPolicyDigest = digestRuntimeValue(JSON.stringify(options.recipes));
4284
+ this.#recipeExecutor = options.recipeExecutor ?? createContainerRecipeExecutor(options.engine, { dependencies: options.recipeDependencies ?? null });
4256
4285
  this.#checkpoints = new CodeRuntimeCheckpointManager({
4257
4286
  control: options.control,
4258
4287
  recipes: options.recipes,
4259
- recipeExecutor: options.recipeExecutor ?? createContainerRecipeExecutor(options.engine, { dependencies: options.recipeDependencies ?? null }),
4288
+ recipeExecutor: this.#recipeExecutor,
4260
4289
  fallbackPolicyDigest: this.#buildPolicyDigest,
4261
4290
  event: (command, event, refs) => this.#event(command, event, refs)
4262
4291
  });
@@ -4266,6 +4295,8 @@ var TheseusRuntimeEngine = class {
4266
4295
  #attempt;
4267
4296
  #buildPolicyDigest;
4268
4297
  #checkpoints;
4298
+ /** One executor for the session broker, the verifier and goal pursuit, built with the host's dependency tree. */
4299
+ #recipeExecutor;
4269
4300
  execute(command) {
4270
4301
  if (command.kind === "checkpoint_stop") return this.#checkpoint(command);
4271
4302
  if (command.kind === "pursue") return this.#pursue(command);
@@ -4338,9 +4369,9 @@ var TheseusRuntimeEngine = class {
4338
4369
  active.done = startGate.ready.then((run) => run ? this.#runAttempt(command, metadata, active) : null).catch(async (cause) => {
4339
4370
  const detail = runtimeErrorMessage(cause);
4340
4371
  await this.#event(command, { type: "message", actor: "system", body: detail }, conversationRefs).catch(() => void 0);
4341
- await this.#diagnostic(command, active, detail);
4372
+ await recordDiagnostic(this.options, command, active, detail);
4342
4373
  await this.#event(command, { type: "status", status: "failed" }, conversationRefs).catch(() => void 0);
4343
- await this.#failure(command, active, detail);
4374
+ await recordSessionFailure(this.options, command, active, detail);
4344
4375
  return null;
4345
4376
  });
4346
4377
  return {
@@ -4364,7 +4395,7 @@ var TheseusRuntimeEngine = class {
4364
4395
  active.done = startGoalPursuit({
4365
4396
  spec,
4366
4397
  recipes: active.recipes,
4367
- recipeExecutor: this.options.recipeExecutor ?? createContainerRecipeExecutor(this.options.engine, { dependencies: this.options.recipeDependencies ?? null }),
4398
+ recipeExecutor: this.#recipeExecutor,
4368
4399
  workspace: active.workspace,
4369
4400
  baseCommitSha: active.baseCommitSha,
4370
4401
  trustedBaseDigest: active.trustedBaseDigest,
@@ -4386,8 +4417,8 @@ var TheseusRuntimeEngine = class {
4386
4417
  }, active)
4387
4418
  }).catch(async (cause) => {
4388
4419
  const detail = runtimeErrorMessage(cause);
4389
- await this.#diagnostic(command, active, detail);
4390
- await this.#failure(command, active, detail);
4420
+ await recordDiagnostic(this.options, command, active, detail);
4421
+ await recordSessionFailure(this.options, command, active, detail);
4391
4422
  return { status: "failed", finalText: "", error: detail };
4392
4423
  });
4393
4424
  return { status: "running", message: `Pursuing the goal, up to ${spec.budget.maxAttempts} attempt(s)` };
@@ -4434,9 +4465,9 @@ var TheseusRuntimeEngine = class {
4434
4465
  { type: "message", actor: "system", body: detail },
4435
4466
  active.conversationRefs
4436
4467
  ).catch(() => void 0);
4437
- await this.#diagnostic(command, active, detail);
4468
+ await recordDiagnostic(this.options, command, active, detail);
4438
4469
  await this.#event(command, { type: "status", status: "failed" }, active.conversationRefs).catch(() => void 0);
4439
- await this.#failure(command, active, detail);
4470
+ await recordSessionFailure(this.options, command, active, detail);
4440
4471
  return null;
4441
4472
  });
4442
4473
  return { status: "running", message: "Theseus accepted the owner prompt" };
@@ -4446,6 +4477,7 @@ var TheseusRuntimeEngine = class {
4446
4477
  const broker = this.#observed(command, active, createCodeRuntimeToolBroker({
4447
4478
  recipes: active.recipes,
4448
4479
  engine: this.options.engine,
4480
+ recipeExecutor: this.#recipeExecutor,
4449
4481
  recipeAuthorization: this.options.recipeAuthorization
4450
4482
  }, lease, metadata.role));
4451
4483
  const startedAt = Date.now();
@@ -4488,8 +4520,8 @@ var TheseusRuntimeEngine = class {
4488
4520
  durationMs: Date.now() - startedAt
4489
4521
  }, active.conversationRefs).catch(() => void 0);
4490
4522
  if (!completed) {
4491
- await this.#diagnostic(command, active, detail);
4492
- await this.#failure(command, active, detail);
4523
+ await recordDiagnostic(this.options, command, active, detail);
4524
+ await recordSessionFailure(this.options, command, active, detail);
4493
4525
  }
4494
4526
  return {
4495
4527
  ...result,
@@ -4514,21 +4546,6 @@ var TheseusRuntimeEngine = class {
4514
4546
  this.#active.delete(command.sessionId);
4515
4547
  return result;
4516
4548
  }
4517
- async #failure(command, active, value) {
4518
- active.failure = value.slice(0, 2e3);
4519
- if (active.acknowledged) {
4520
- await this.options.control.reportSessionFailure(command.sessionId, active.failure).catch(() => void 0);
4521
- }
4522
- }
4523
- async #diagnostic(command, active, value) {
4524
- const detail = value.trim().slice(0, 2e3) || "Theseus runtime failed";
4525
- this.options.onDiagnostic?.(detail);
4526
- await this.#event(
4527
- command,
4528
- { type: "diagnostic", level: "error", message: detail },
4529
- active.conversationRefs
4530
- ).catch(() => void 0);
4531
- }
4532
4549
  async #event(command, event, refs) {
4533
4550
  await appendCodeRuntimeEvent(this.options.control, command, event, refs);
4534
4551
  }