@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.
@@ -6,7 +6,7 @@ import {
6
6
  assertCodeBuildRecipe,
7
7
  createCodeRuntimeControlClient,
8
8
  runCodeRuntimeHeartbeatLoop
9
- } from "./chunk-L2T3LPEF.js";
9
+ } from "./chunk-ZYNGL5SC.js";
10
10
  import {
11
11
  assertPinnedImage,
12
12
  selectContainerEngine
package/dist/node.cjs CHANGED
@@ -1966,6 +1966,9 @@ async function materializeCommandWorkspace(input) {
1966
1966
  }
1967
1967
  }
1968
1968
 
1969
+ // src/code-runtime-attempt.ts
1970
+ var import_ai2 = require("@odla-ai/ai");
1971
+
1969
1972
  // src/code-agent.ts
1970
1973
  var import_ai = require("@odla-ai/ai");
1971
1974
 
@@ -2017,7 +2020,12 @@ function codeSkill(opts) {
2017
2020
  { lease: opts.lease, workspaceDir: opts.workspaceDir, signal },
2018
2021
  { requestId: `bench-${tool}-${++seq}`, tool, input }
2019
2022
  );
2020
- opts.onToolCall?.({ tool, ok: response2.ok, durationMs: Date.now() - startedAt });
2023
+ opts.onToolCall?.({
2024
+ tool,
2025
+ ok: response2.ok,
2026
+ durationMs: Date.now() - startedAt,
2027
+ ...response2.ok ? {} : { error: String(response2.content).slice(0, 300) }
2028
+ });
2021
2029
  return { content: response2.content, isError: !response2.ok };
2022
2030
  };
2023
2031
  const read2 = {
@@ -2166,6 +2174,7 @@ async function runCodeAgent(options) {
2166
2174
  // src/code-runtime-attempt.ts
2167
2175
  async function runCodeAgentAttempt(options) {
2168
2176
  try {
2177
+ const surface = options.surface ?? "v2";
2169
2178
  const { run } = await runCodeAgent({
2170
2179
  inference: options.inference,
2171
2180
  broker: options.broker,
@@ -2175,17 +2184,31 @@ async function runCodeAgentAttempt(options) {
2175
2184
  // The brokered route resolves the real model from platform policy; this
2176
2185
  // id only labels the request the control plane is about to rewrite.
2177
2186
  model: "brokered",
2178
- surface: options.surface ?? "v2",
2187
+ surface,
2179
2188
  ...options.maxSteps === void 0 ? {} : { maxSteps: options.maxSteps },
2180
2189
  ...options.budget ? { budget: options.budget } : {},
2181
2190
  ...options.signal ? { signal: options.signal } : {},
2182
2191
  ...options.onToolCall ? { onToolCall: options.onToolCall } : {}
2183
2192
  });
2193
+ let finalText = run.finalText.trim();
2194
+ if (!finalText && run.stoppedReason !== "refusal") {
2195
+ const closing = await options.inference.chat({
2196
+ model: "brokered",
2197
+ system: `${SYSTEM_PROMPT_FOR[surface]}
2198
+
2199
+ Finish with a concise, non-empty answer to the owner. Do not call tools or promise future work.`,
2200
+ messages: [...run.messages, { role: "user", content: "Give the owner the closing answer now, grounded in the repository evidence and tool results above." }],
2201
+ maxTokens: 16384,
2202
+ ...options.signal ? { signal: options.signal } : {}
2203
+ });
2204
+ finalText = (0, import_ai2.extractText)(closing.content).trim();
2205
+ }
2206
+ const missingClosing = !finalText && run.stoppedReason !== "refusal";
2184
2207
  return {
2185
- status: run.stoppedReason === "refusal" ? "failed" : "completed",
2186
- finalText: run.finalText,
2208
+ status: run.stoppedReason === "refusal" || missingClosing ? "failed" : "completed",
2209
+ finalText,
2187
2210
  stoppedReason: run.stoppedReason,
2188
- ...run.stoppedReason === "refusal" ? { error: run.finalText || "the agent refused the task" } : {}
2211
+ ...run.stoppedReason === "refusal" ? { error: finalText || "the agent refused the task" } : missingClosing ? { error: "the Code agent did not produce a closing answer" } : {}
2189
2212
  };
2190
2213
  } catch (cause) {
2191
2214
  const error = (cause instanceof Error ? cause.message : String(cause)).slice(0, 2e3);
@@ -2195,31 +2218,7 @@ async function runCodeAgentAttempt(options) {
2195
2218
 
2196
2219
  // src/code-runtime-inference.ts
2197
2220
  async function handleCodeRuntimeInference(input) {
2198
- const { command, metadata, request, state } = input;
2199
- if (state.tokens >= metadata.maxTokensPerInteraction) {
2200
- if (!state.noticeEmitted) {
2201
- state.noticeEmitted = true;
2202
- await input.event({
2203
- type: "message",
2204
- actor: "system",
2205
- body: `The agent paused at the ${metadata.maxTokensPerInteraction.toLocaleString("en-US")}-token per-interaction limit. Send a new instruction to continue.`
2206
- }).catch(() => void 0);
2207
- }
2208
- return {
2209
- protocolVersion: HARNESS_PROTOCOL_VERSION,
2210
- type: "inference.response",
2211
- requestId: request.requestId,
2212
- response: {
2213
- id: `budget:${command.commandId}`,
2214
- provider: "openai",
2215
- model: "interaction-budget",
2216
- role: "assistant",
2217
- content: [{ type: "text", text: "Pause now. The owner-set token limit for this interaction has been reached." }],
2218
- stopReason: "end_turn",
2219
- usage: { inputTokens: 0, outputTokens: 0 }
2220
- }
2221
- };
2222
- }
2221
+ const { command, request, state } = input;
2223
2222
  const startedAt = Date.now();
2224
2223
  const response2 = await input.control.infer(command.sessionId, {
2225
2224
  requestId: request.requestId,
@@ -2239,7 +2238,6 @@ async function handleCodeRuntimeInference(input) {
2239
2238
  durationMs: Date.now() - startedAt,
2240
2239
  interactionId: command.commandId,
2241
2240
  interactionTokens: state.tokens,
2242
- interactionMaxTokens: metadata.maxTokensPerInteraction,
2243
2241
  ...costUsd === void 0 ? {} : { costUsd },
2244
2242
  ...state.costKnown ? { interactionCostUsd: state.costUsd } : {}
2245
2243
  }).catch(() => void 0);
@@ -3370,7 +3368,7 @@ var CodePiRuntimeEngine = class {
3370
3368
  recipeAuthorization: this.options.recipeAuthorization
3371
3369
  }, lease, metadata.role));
3372
3370
  const startedAt = Date.now();
3373
- const interaction = { tokens: 0, noticeEmitted: false, costUsd: 0, costKnown: true };
3371
+ const interaction = { tokens: 0, costUsd: 0, costKnown: true };
3374
3372
  const inference = createCodeRuntimeInference({
3375
3373
  command,
3376
3374
  metadata,
@@ -3385,31 +3383,30 @@ var CodePiRuntimeEngine = class {
3385
3383
  lease,
3386
3384
  workspaceDir: active.workspace.workspaceDir,
3387
3385
  prompt: metadata.prompt,
3388
- signal: active.abort.signal,
3389
- // The owner's per-interaction allowance, enforced by runAgent against
3390
- // INCREMENTAL usage. The control plane still reserves against the same
3391
- // ceiling, but this is what stops the loop cleanly at the boundary rather
3392
- // than letting it discover the limit through a synthesized pause reply.
3393
- budget: { maxTotalTokens: metadata.maxTokensPerInteraction }
3386
+ signal: active.abort.signal
3394
3387
  });
3395
- const body = result.finalText.trim() || (result.status === "completed" ? "The agent finished without a closing message." : result.error ?? "The agent failed.");
3388
+ const closing = result.finalText.trim();
3389
+ const completed = result.status === "completed" && Boolean(closing);
3390
+ const detail = result.error?.trim() || (closing ? "the Code agent failed" : "the Code agent did not produce a closing answer");
3391
+ const body = closing || detail;
3396
3392
  await this.#event(command, {
3397
3393
  type: "message",
3398
- actor: result.status === "completed" ? "agent" : "system",
3394
+ actor: completed ? "agent" : "system",
3399
3395
  body
3400
3396
  }, active.conversationRefs).catch(() => void 0);
3401
3397
  await this.#event(command, {
3402
3398
  type: "status",
3403
- status: result.status === "completed" ? "idle" : "failed",
3399
+ status: completed ? "idle" : "failed",
3404
3400
  durationMs: Date.now() - startedAt
3405
3401
  }, active.conversationRefs).catch(() => void 0);
3406
- if (result.status === "failed") {
3407
- const detail = (result.error ?? "").trim() || "the Code agent failed";
3402
+ if (!completed) {
3408
3403
  await this.#diagnostic(command, active, detail);
3409
3404
  await this.#failure(command, active, detail);
3410
3405
  }
3411
3406
  return {
3412
3407
  ...result,
3408
+ status: completed ? "completed" : "failed",
3409
+ ...!completed ? { error: detail } : {},
3413
3410
  tokens: interaction.tokens,
3414
3411
  ...interaction.costKnown ? { costUsd: interaction.costUsd } : {}
3415
3412
  };