@odla-ai/harness 0.5.1 → 0.6.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.
@@ -1384,6 +1384,9 @@ async function materializeCommandWorkspace(input) {
1384
1384
  }
1385
1385
  }
1386
1386
 
1387
+ // src/code-runtime-attempt.ts
1388
+ var import_ai2 = require("@odla-ai/ai");
1389
+
1387
1390
  // src/code-agent.ts
1388
1391
  var import_ai = require("@odla-ai/ai");
1389
1392
 
@@ -1435,7 +1438,12 @@ function codeSkill(opts) {
1435
1438
  { lease: opts.lease, workspaceDir: opts.workspaceDir, signal },
1436
1439
  { requestId: `bench-${tool}-${++seq}`, tool, input }
1437
1440
  );
1438
- opts.onToolCall?.({ tool, ok: response2.ok, durationMs: Date.now() - startedAt });
1441
+ opts.onToolCall?.({
1442
+ tool,
1443
+ ok: response2.ok,
1444
+ durationMs: Date.now() - startedAt,
1445
+ ...response2.ok ? {} : { error: String(response2.content).slice(0, 300) }
1446
+ });
1439
1447
  return { content: response2.content, isError: !response2.ok };
1440
1448
  };
1441
1449
  const read2 = {
@@ -1584,6 +1592,7 @@ async function runCodeAgent(options) {
1584
1592
  // src/code-runtime-attempt.ts
1585
1593
  async function runCodeAgentAttempt(options) {
1586
1594
  try {
1595
+ const surface = options.surface ?? "v2";
1587
1596
  const { run } = await runCodeAgent({
1588
1597
  inference: options.inference,
1589
1598
  broker: options.broker,
@@ -1593,17 +1602,31 @@ async function runCodeAgentAttempt(options) {
1593
1602
  // The brokered route resolves the real model from platform policy; this
1594
1603
  // id only labels the request the control plane is about to rewrite.
1595
1604
  model: "brokered",
1596
- surface: options.surface ?? "v2",
1605
+ surface,
1597
1606
  ...options.maxSteps === void 0 ? {} : { maxSteps: options.maxSteps },
1598
1607
  ...options.budget ? { budget: options.budget } : {},
1599
1608
  ...options.signal ? { signal: options.signal } : {},
1600
1609
  ...options.onToolCall ? { onToolCall: options.onToolCall } : {}
1601
1610
  });
1611
+ let finalText = run.finalText.trim();
1612
+ if (!finalText && run.stoppedReason !== "refusal") {
1613
+ const closing = await options.inference.chat({
1614
+ model: "brokered",
1615
+ system: `${SYSTEM_PROMPT_FOR[surface]}
1616
+
1617
+ Finish with a concise, non-empty answer to the owner. Do not call tools or promise future work.`,
1618
+ messages: [...run.messages, { role: "user", content: "Give the owner the closing answer now, grounded in the repository evidence and tool results above." }],
1619
+ maxTokens: 16384,
1620
+ ...options.signal ? { signal: options.signal } : {}
1621
+ });
1622
+ finalText = (0, import_ai2.extractText)(closing.content).trim();
1623
+ }
1624
+ const missingClosing = !finalText && run.stoppedReason !== "refusal";
1602
1625
  return {
1603
- status: run.stoppedReason === "refusal" ? "failed" : "completed",
1604
- finalText: run.finalText,
1626
+ status: run.stoppedReason === "refusal" || missingClosing ? "failed" : "completed",
1627
+ finalText,
1605
1628
  stoppedReason: run.stoppedReason,
1606
- ...run.stoppedReason === "refusal" ? { error: run.finalText || "the agent refused the task" } : {}
1629
+ ...run.stoppedReason === "refusal" ? { error: finalText || "the agent refused the task" } : missingClosing ? { error: "the Code agent did not produce a closing answer" } : {}
1607
1630
  };
1608
1631
  } catch (cause) {
1609
1632
  const error = (cause instanceof Error ? cause.message : String(cause)).slice(0, 2e3);
@@ -1613,31 +1636,7 @@ async function runCodeAgentAttempt(options) {
1613
1636
 
1614
1637
  // src/code-runtime-inference.ts
1615
1638
  async function handleCodeRuntimeInference(input) {
1616
- const { command, metadata, request, state } = input;
1617
- if (state.tokens >= metadata.maxTokensPerInteraction) {
1618
- if (!state.noticeEmitted) {
1619
- state.noticeEmitted = true;
1620
- await input.event({
1621
- type: "message",
1622
- actor: "system",
1623
- body: `The agent paused at the ${metadata.maxTokensPerInteraction.toLocaleString("en-US")}-token per-interaction limit. Send a new instruction to continue.`
1624
- }).catch(() => void 0);
1625
- }
1626
- return {
1627
- protocolVersion: HARNESS_PROTOCOL_VERSION,
1628
- type: "inference.response",
1629
- requestId: request.requestId,
1630
- response: {
1631
- id: `budget:${command.commandId}`,
1632
- provider: "openai",
1633
- model: "interaction-budget",
1634
- role: "assistant",
1635
- content: [{ type: "text", text: "Pause now. The owner-set token limit for this interaction has been reached." }],
1636
- stopReason: "end_turn",
1637
- usage: { inputTokens: 0, outputTokens: 0 }
1638
- }
1639
- };
1640
- }
1639
+ const { command, request, state } = input;
1641
1640
  const startedAt = Date.now();
1642
1641
  const response2 = await input.control.infer(command.sessionId, {
1643
1642
  requestId: request.requestId,
@@ -1657,7 +1656,6 @@ async function handleCodeRuntimeInference(input) {
1657
1656
  durationMs: Date.now() - startedAt,
1658
1657
  interactionId: command.commandId,
1659
1658
  interactionTokens: state.tokens,
1660
- interactionMaxTokens: metadata.maxTokensPerInteraction,
1661
1659
  ...costUsd === void 0 ? {} : { costUsd },
1662
1660
  ...state.costKnown ? { interactionCostUsd: state.costUsd } : {}
1663
1661
  }).catch(() => void 0);
@@ -2765,7 +2763,7 @@ var CodePiRuntimeEngine = class {
2765
2763
  recipeAuthorization: this.options.recipeAuthorization
2766
2764
  }, lease, metadata.role));
2767
2765
  const startedAt = Date.now();
2768
- const interaction = { tokens: 0, noticeEmitted: false, costUsd: 0, costKnown: true };
2766
+ const interaction = { tokens: 0, costUsd: 0, costKnown: true };
2769
2767
  const inference = createCodeRuntimeInference({
2770
2768
  command,
2771
2769
  metadata,
@@ -2780,31 +2778,30 @@ var CodePiRuntimeEngine = class {
2780
2778
  lease,
2781
2779
  workspaceDir: active.workspace.workspaceDir,
2782
2780
  prompt: metadata.prompt,
2783
- signal: active.abort.signal,
2784
- // The owner's per-interaction allowance, enforced by runAgent against
2785
- // INCREMENTAL usage. The control plane still reserves against the same
2786
- // ceiling, but this is what stops the loop cleanly at the boundary rather
2787
- // than letting it discover the limit through a synthesized pause reply.
2788
- budget: { maxTotalTokens: metadata.maxTokensPerInteraction }
2781
+ signal: active.abort.signal
2789
2782
  });
2790
- const body = result.finalText.trim() || (result.status === "completed" ? "The agent finished without a closing message." : result.error ?? "The agent failed.");
2783
+ const closing = result.finalText.trim();
2784
+ const completed = result.status === "completed" && Boolean(closing);
2785
+ const detail = result.error?.trim() || (closing ? "the Code agent failed" : "the Code agent did not produce a closing answer");
2786
+ const body = closing || detail;
2791
2787
  await this.#event(command, {
2792
2788
  type: "message",
2793
- actor: result.status === "completed" ? "agent" : "system",
2789
+ actor: completed ? "agent" : "system",
2794
2790
  body
2795
2791
  }, active.conversationRefs).catch(() => void 0);
2796
2792
  await this.#event(command, {
2797
2793
  type: "status",
2798
- status: result.status === "completed" ? "idle" : "failed",
2794
+ status: completed ? "idle" : "failed",
2799
2795
  durationMs: Date.now() - startedAt
2800
2796
  }, active.conversationRefs).catch(() => void 0);
2801
- if (result.status === "failed") {
2802
- const detail = (result.error ?? "").trim() || "the Code agent failed";
2797
+ if (!completed) {
2803
2798
  await this.#diagnostic(command, active, detail);
2804
2799
  await this.#failure(command, active, detail);
2805
2800
  }
2806
2801
  return {
2807
2802
  ...result,
2803
+ status: completed ? "completed" : "failed",
2804
+ ...!completed ? { error: detail } : {},
2808
2805
  tokens: interaction.tokens,
2809
2806
  ...interaction.costKnown ? { costUsd: interaction.costUsd } : {}
2810
2807
  };