@odla-ai/harness 0.11.17 → 0.11.19

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.
Files changed (39) hide show
  1. package/dist/{chunk-T2IW7MYQ.js → chunk-4TG55ATB.js} +2 -2
  2. package/dist/{chunk-RDCU4PIP.js → chunk-7NP3YOMY.js} +37 -9
  3. package/dist/chunk-7NP3YOMY.js.map +1 -0
  4. package/dist/{chunk-3ON6UAOV.js → chunk-A5B3CEK2.js} +3 -3
  5. package/dist/{chunk-EXSEQEZ6.js → chunk-M6BNH25Z.js} +4 -4
  6. package/dist/{chunk-ONYW2VSB.js → chunk-O4QLHUGO.js} +1 -1
  7. package/dist/chunk-O4QLHUGO.js.map +1 -0
  8. package/dist/{chunk-6T26HEWI.js → chunk-SMN2FWQE.js} +17 -3
  9. package/dist/{chunk-6T26HEWI.js.map → chunk-SMN2FWQE.js.map} +1 -1
  10. package/dist/cli.cjs.map +1 -1
  11. package/dist/cli.js +4 -4
  12. package/dist/code-runtime-cli.cjs +46 -7
  13. package/dist/code-runtime-cli.cjs.map +1 -1
  14. package/dist/code-runtime-cli.js +5 -5
  15. package/dist/code-session-event-data-C6mQB76s.d.cts +134 -0
  16. package/dist/code-session-event-data-wCQc2py3.d.ts +134 -0
  17. package/dist/index.cjs +19 -2
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +15 -4
  20. package/dist/index.d.ts +15 -4
  21. package/dist/index.js +9 -3
  22. package/dist/index.js.map +1 -1
  23. package/dist/node.cjs +46 -7
  24. package/dist/node.cjs.map +1 -1
  25. package/dist/node.d.cts +23 -7
  26. package/dist/node.d.ts +23 -7
  27. package/dist/node.js +6 -6
  28. package/dist/testing.cjs.map +1 -1
  29. package/dist/testing.d.cts +1 -1
  30. package/dist/testing.d.ts +1 -1
  31. package/dist/testing.js +1 -1
  32. package/dist/{types-D-Kv1svf.d.ts → types-DM-UgoBN.d.cts} +2 -118
  33. package/dist/{types-D-Kv1svf.d.cts → types-DM-UgoBN.d.ts} +2 -118
  34. package/package.json +1 -1
  35. package/dist/chunk-ONYW2VSB.js.map +0 -1
  36. package/dist/chunk-RDCU4PIP.js.map +0 -1
  37. /package/dist/{chunk-T2IW7MYQ.js.map → chunk-4TG55ATB.js.map} +0 -0
  38. /package/dist/{chunk-3ON6UAOV.js.map → chunk-A5B3CEK2.js.map} +0 -0
  39. /package/dist/{chunk-EXSEQEZ6.js.map → chunk-M6BNH25Z.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
- import { f as HarnessToolBroker, C as CodeSessionEventData, g as HarnessToolResponse, h as HarnessAgentInput, b as HarnessEventInput, i as HarnessAgentOutput, H as HarnessControlPlane, j as HarnessAiConnection } from './types-D-Kv1svf.js';
2
- export { k as CodeSessionEvent, l as CodeToolLocationPreview, m as CodeToolPresentation, D as DEFAULT_AI_ROUTE, n as HARNESS_PROTOCOL_VERSION, o as HarnessActor, p as HarnessAttemptStatus, q as HarnessAttemptSummary, c as HarnessCompletion, r as HarnessEvent, d as HarnessInferenceRequest, e as HarnessInferenceResponse, a as HarnessLease, s as HarnessPolicy, t as HarnessRunnerView, u as HarnessTaskDetail, v as HarnessTaskSpec, w as HarnessTaskStatus, x as HarnessTaskSummary, y as HarnessToolName, z as HarnessToolRequest } from './types-D-Kv1svf.js';
1
+ import { g as HarnessToolBroker, h as HarnessToolResponse, i as HarnessAgentInput, b as HarnessEventInput, j as HarnessAgentOutput, H as HarnessControlPlane, k as HarnessAiConnection } from './types-DM-UgoBN.js';
2
+ export { D as DEFAULT_AI_ROUTE, l as HARNESS_PROTOCOL_VERSION, m as HarnessActor, n as HarnessAttemptStatus, o as HarnessAttemptSummary, c as HarnessCompletion, p as HarnessEvent, d as HarnessInferenceRequest, e as HarnessInferenceResponse, a as HarnessLease, q as HarnessPolicy, r as HarnessRunnerView, s as HarnessTaskDetail, t as HarnessTaskSpec, u as HarnessTaskStatus, v as HarnessTaskSummary, f as HarnessToolName, w as HarnessToolRequest } from './types-DM-UgoBN.js';
3
+ import { C as CodeSessionEventData } from './code-session-event-data-wCQc2py3.js';
4
+ export { a as CodeSessionEvent, b as CodeToolLocationPreview, c as CodeToolPresentation } from './code-session-event-data-wCQc2py3.js';
3
5
  import { Ai } from '@odla-ai/ai';
4
6
 
5
7
  /** Longest failure reason forwarded onto a session event. A reason is a short
@@ -11,16 +13,25 @@ declare const MAX_FAILURE_REASON = 240;
11
13
  * failed and could never see why — which is what made an 84% apply_patch
12
14
  * failure rate undiagnosable (PM bugs 515655ec and 38d92f1d). */
13
15
  declare function toolFailureReason(response: HarnessToolResponse): string | undefined;
16
+ /** Longest serialized tool input, and longest tool output, a verbose stream carries. */
17
+ declare const MAX_VERBOSE_TOOL_BYTES = 4096;
18
+ /** A tool input as a verbose watcher sees it: the object when it fits, else a
19
+ * marker saying how large it was. A stream must never carry a whole file. */
20
+ declare function boundedToolInput(value: Record<string, unknown>): Record<string, unknown>;
21
+ /** A tool output as a verbose watcher sees it, bounded. */
22
+ declare function boundedToolOutput(content: string): string;
14
23
  /** Wrap `broker` so every effect reports its start and its finish.
15
24
  *
16
25
  * `emit` is the engine's own event sink; it already swallows its own errors, so
17
- * reporting can never fail the effect it is reporting on.
26
+ * reporting can never fail the effect it is reporting on. With `detail:
27
+ * "verbose"` each event also carries the bounded input and output.
18
28
  */
19
29
  declare function observedBroker(input: {
20
30
  broker: HarnessToolBroker;
21
31
  operationIdFor: (requestId: string) => string;
22
32
  emit: (event: CodeSessionEventData) => Promise<void>;
23
33
  now?: () => number;
34
+ detail?: "standard" | "verbose";
24
35
  }): HarnessToolBroker;
25
36
 
26
37
  /** Error raised when an agent emits malformed, oversized, or unsupported protocol data. */
@@ -62,4 +73,4 @@ declare function createOdlaAiConnection(ai: Pick<Ai, "chat">, options?: {
62
73
  policyVersion?: number;
63
74
  }): HarnessAiConnection;
64
75
 
65
- export { CodeSessionEventData, HarnessAgentInput, HarnessAgentOutput, HarnessAiConnection, type HarnessControlClientOptions, HarnessControlError, HarnessControlPlane, HarnessEventInput, HarnessProtocolError, HarnessToolBroker, HarnessToolResponse, MAX_FAILURE_REASON, createHarnessControlClient, createOdlaAiConnection, encodeAgentInput, makeHarnessEvent, observedBroker, parseAgentOutput, toolFailureReason };
76
+ export { CodeSessionEventData, HarnessAgentInput, HarnessAgentOutput, HarnessAiConnection, type HarnessControlClientOptions, HarnessControlError, HarnessControlPlane, HarnessEventInput, HarnessProtocolError, HarnessToolBroker, HarnessToolResponse, MAX_FAILURE_REASON, MAX_VERBOSE_TOOL_BYTES, boundedToolInput, boundedToolOutput, createHarnessControlClient, createOdlaAiConnection, encodeAgentInput, makeHarnessEvent, observedBroker, parseAgentOutput, toolFailureReason };
package/dist/index.js CHANGED
@@ -4,19 +4,22 @@ import {
4
4
  } from "./chunk-PTXZVYD4.js";
5
5
  import {
6
6
  MAX_FAILURE_REASON,
7
+ MAX_VERBOSE_TOOL_BYTES,
8
+ boundedToolInput,
9
+ boundedToolOutput,
7
10
  observedBroker,
8
11
  toolFailureReason
9
- } from "./chunk-6T26HEWI.js";
12
+ } from "./chunk-SMN2FWQE.js";
10
13
  import {
11
14
  HarnessProtocolError,
12
15
  encodeAgentInput,
13
16
  makeHarnessEvent,
14
17
  parseAgentOutput
15
- } from "./chunk-T2IW7MYQ.js";
18
+ } from "./chunk-4TG55ATB.js";
16
19
  import {
17
20
  DEFAULT_AI_ROUTE,
18
21
  HARNESS_PROTOCOL_VERSION
19
- } from "./chunk-ONYW2VSB.js";
22
+ } from "./chunk-O4QLHUGO.js";
20
23
 
21
24
  // src/ai.ts
22
25
  function createOdlaAiConnection(ai, options = {}) {
@@ -43,6 +46,9 @@ export {
43
46
  HarnessControlError,
44
47
  HarnessProtocolError,
45
48
  MAX_FAILURE_REASON,
49
+ MAX_VERBOSE_TOOL_BYTES,
50
+ boundedToolInput,
51
+ boundedToolOutput,
46
52
  createHarnessControlClient,
47
53
  createOdlaAiConnection,
48
54
  encodeAgentInput,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ai.ts"],"sourcesContent":["import type { Ai } from \"@odla-ai/ai\";\nimport type { HarnessAiConnection, HarnessInferenceRequest, HarnessInferenceResponse } from \"./types\";\n\n/**\n * Adapt the normalized odla AI chat surface to a harness connection.\n * Provider credentials remain in the process that owns `ai`; only normalized\n * requests and responses cross the container protocol.\n */\nexport function createOdlaAiConnection(\n ai: Pick<Ai, \"chat\">,\n options: { model?: string; policyVersion?: number } = {},\n): HarnessAiConnection {\n return {\n async infer(request: HarnessInferenceRequest): Promise<HarnessInferenceResponse> {\n const response = await ai.chat({ ...request.call, ...(options.model ? { model: options.model } : {}) });\n return {\n requestId: request.requestId,\n response,\n receipt: {\n provider: response.provider,\n model: response.model,\n policyVersion: options.policyVersion ?? 1,\n inputTokens: response.usage.inputTokens ?? 0,\n outputTokens: response.usage.outputTokens ?? 0,\n },\n };\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAQO,SAAS,uBACd,IACA,UAAsD,CAAC,GAClC;AACrB,SAAO;AAAA,IACL,MAAM,MAAM,SAAqE;AAC/E,YAAM,WAAW,MAAM,GAAG,KAAK,EAAE,GAAG,QAAQ,MAAM,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC,EAAG,CAAC;AACtG,aAAO;AAAA,QACL,WAAW,QAAQ;AAAA,QACnB;AAAA,QACA,SAAS;AAAA,UACP,UAAU,SAAS;AAAA,UACnB,OAAO,SAAS;AAAA,UAChB,eAAe,QAAQ,iBAAiB;AAAA,UACxC,aAAa,SAAS,MAAM,eAAe;AAAA,UAC3C,cAAc,SAAS,MAAM,gBAAgB;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/ai.ts"],"sourcesContent":["import type { Ai } from \"@odla-ai/ai\";\nimport type { HarnessAiConnection, HarnessInferenceRequest, HarnessInferenceResponse } from \"./types\";\n\n/**\n * Adapt the normalized odla AI chat surface to a harness connection.\n * Provider credentials remain in the process that owns `ai`; only normalized\n * requests and responses cross the container protocol.\n */\nexport function createOdlaAiConnection(\n ai: Pick<Ai, \"chat\">,\n options: { model?: string; policyVersion?: number } = {},\n): HarnessAiConnection {\n return {\n async infer(request: HarnessInferenceRequest): Promise<HarnessInferenceResponse> {\n const response = await ai.chat({ ...request.call, ...(options.model ? { model: options.model } : {}) });\n return {\n requestId: request.requestId,\n response,\n receipt: {\n provider: response.provider,\n model: response.model,\n policyVersion: options.policyVersion ?? 1,\n inputTokens: response.usage.inputTokens ?? 0,\n outputTokens: response.usage.outputTokens ?? 0,\n },\n };\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAQO,SAAS,uBACd,IACA,UAAsD,CAAC,GAClC;AACrB,SAAO;AAAA,IACL,MAAM,MAAM,SAAqE;AAC/E,YAAM,WAAW,MAAM,GAAG,KAAK,EAAE,GAAG,QAAQ,MAAM,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC,EAAG,CAAC;AACtG,aAAO;AAAA,QACL,WAAW,QAAQ;AAAA,QACnB;AAAA,QACA,SAAS;AAAA,UACP,UAAU,SAAS;AAAA,UACnB,OAAO,SAAS;AAAA,UAChB,eAAe,QAAQ,iBAAiB;AAAA,UACxC,aAAa,SAAS,MAAM,eAAe;AAAA,UAC3C,cAAc,SAAS,MAAM,gBAAgB;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
package/dist/node.cjs CHANGED
@@ -1446,7 +1446,7 @@ var CodeRuntimeReconciler = class {
1446
1446
  };
1447
1447
 
1448
1448
  // src/code-runtime.ts
1449
- var CODE_RUNTIME_PROTOCOL_VERSION = 3;
1449
+ var CODE_RUNTIME_PROTOCOL_VERSION = 4;
1450
1450
  async function runCodeRuntimeHeartbeatLoop(options) {
1451
1451
  const heartbeatMs = options.heartbeatMs ?? 15e3;
1452
1452
  if (!Number.isSafeInteger(heartbeatMs) || heartbeatMs < 1e3 || heartbeatMs > 3e5) {
@@ -2334,13 +2334,13 @@ function codeCommandMetadata(payload, resume) {
2334
2334
  const title = payload.title;
2335
2335
  const prompt = payload.prompt;
2336
2336
  const maxTokensPerInteraction = payload.maxTokensPerInteraction ?? 32e3;
2337
- if (role !== "coding" && role !== "review" || typeof title !== "string" || typeof prompt !== "string") {
2337
+ if (role !== "coding" && role !== "review" && role !== "planning" || typeof title !== "string" || typeof prompt !== "string") {
2338
2338
  throw new TypeError(`invalid Code ${resume ? "resume" : "start"} metadata`);
2339
2339
  }
2340
2340
  if (payload.readOnly !== void 0 && typeof payload.readOnly !== "boolean") {
2341
2341
  throw new TypeError(`invalid Code ${resume ? "resume" : "start"} read-only capability`);
2342
2342
  }
2343
- const readOnly = role === "review" || payload.readOnly === true;
2343
+ const readOnly = role !== "coding" || payload.readOnly === true;
2344
2344
  const planning = trusted?.planningInputDigest;
2345
2345
  const attestation = trusted?.attestationDigest;
2346
2346
  const repository = trusted?.repository;
@@ -2353,11 +2353,16 @@ function codeCommandMetadata(payload, resume) {
2353
2353
  if (!Number.isSafeInteger(maxTokensPerInteraction) || Number(maxTokensPerInteraction) < 4e3 || Number(maxTokensPerInteraction) > 2e5) {
2354
2354
  throw new TypeError(`invalid Code ${resume ? "resume" : "start"} interaction token limit`);
2355
2355
  }
2356
+ const eventDetail = payload.eventDetail ?? "standard";
2357
+ if (eventDetail !== "standard" && eventDetail !== "verbose") {
2358
+ throw new TypeError(`invalid Code ${resume ? "resume" : "start"} event detail`);
2359
+ }
2356
2360
  return {
2357
2361
  role,
2358
2362
  readOnly,
2359
2363
  title,
2360
2364
  prompt,
2365
+ eventDetail,
2361
2366
  proof: codeCommandProof(payload.proof, resume),
2362
2367
  maxTokensPerInteraction: Number(maxTokensPerInteraction),
2363
2368
  planningInputDigest: typeof planning === "string" && /^sha256:[0-9a-f]{64}$/.test(planning) ? planning : null,
@@ -3306,6 +3311,20 @@ async function sessionSkillsFor(options, command) {
3306
3311
 
3307
3312
  // src/code-runtime-inference.ts
3308
3313
  var inferWithBackoff = (infer, wait2, onRetry) => withOverloadRetry(infer, wait2, (cause, delayMs) => onRetry(cause, delayMs), transientControlFailure);
3314
+ var MAX_VERBOSE_TEXT = 4e3;
3315
+ var clip = (text2) => text2.length <= MAX_VERBOSE_TEXT ? text2 : `${text2.slice(0, MAX_VERBOSE_TEXT - 1)}\u2026`;
3316
+ function verboseTurnEvents(response2, durationMs) {
3317
+ const events = [];
3318
+ const interim = response2.response.stopReason === "tool_use";
3319
+ for (const block of response2.response.content) {
3320
+ if (block.type === "thinking" && block.thinking.trim()) {
3321
+ events.push({ type: "thinking", available: true, durationMs, text: clip(block.thinking.trim()) });
3322
+ } else if (block.type === "text" && interim && block.text.trim()) {
3323
+ events.push({ type: "text", text: clip(block.text.trim()) });
3324
+ }
3325
+ }
3326
+ return events;
3327
+ }
3309
3328
  async function handleCodeRuntimeInference(input) {
3310
3329
  const { command, request, state } = input;
3311
3330
  const startedAt = Date.now();
@@ -3323,6 +3342,11 @@ async function handleCodeRuntimeInference(input) {
3323
3342
  message: `Code control plane overloaded (${cause.code}); retrying the model call in ${delayMs / 1e3}s`
3324
3343
  }).catch(() => void 0)
3325
3344
  );
3345
+ if (input.metadata.eventDetail === "verbose") {
3346
+ for (const event of verboseTurnEvents(response2, Date.now() - startedAt)) {
3347
+ await input.event(event).catch(() => void 0);
3348
+ }
3349
+ }
3326
3350
  state.tokens += response2.receipt.inputTokens + response2.receipt.outputTokens;
3327
3351
  const { costUsd } = response2.receipt;
3328
3352
  if (costUsd === void 0) state.costKnown = false;
@@ -3517,8 +3541,17 @@ var DEFAULT_FAILURE_REASON = {
3517
3541
  "tool denied by CaMeL policy": "tool denied by CaMeL policy",
3518
3542
  "review sessions are read-only": "review session is read-only; workspace changes are not permitted"
3519
3543
  };
3544
+ var MAX_VERBOSE_TOOL_BYTES = 4096;
3545
+ function boundedToolInput(value) {
3546
+ const serialized = JSON.stringify(value);
3547
+ return serialized.length <= MAX_VERBOSE_TOOL_BYTES ? value : { truncated: true, bytes: serialized.length, keys: Object.keys(value).slice(0, 20) };
3548
+ }
3549
+ function boundedToolOutput(content) {
3550
+ return content.length <= MAX_VERBOSE_TOOL_BYTES ? content : `${content.slice(0, MAX_VERBOSE_TOOL_BYTES - 1)}\u2026`;
3551
+ }
3520
3552
  function observedBroker(input) {
3521
3553
  const now = input.now ?? Date.now;
3554
+ const verbose = input.detail === "verbose";
3522
3555
  return {
3523
3556
  execute: async (context, request) => {
3524
3557
  const startedAt = now();
@@ -3529,7 +3562,8 @@ function observedBroker(input) {
3529
3562
  phase: "started",
3530
3563
  tool: request.tool,
3531
3564
  operationId,
3532
- ...startedPresentation ? { presentation: startedPresentation } : {}
3565
+ ...startedPresentation ? { presentation: startedPresentation } : {},
3566
+ ...verbose ? { input: boundedToolInput(request.input) } : {}
3533
3567
  });
3534
3568
  const response2 = await input.broker.execute(context, request);
3535
3569
  const completedPresentation = codeToolResultPresentation(request, response2);
@@ -3542,7 +3576,8 @@ function observedBroker(input) {
3542
3576
  durationMs: now() - startedAt,
3543
3577
  operationId,
3544
3578
  ...failureReason ? { failureReason } : {},
3545
- ...completedPresentation ? { presentation: completedPresentation } : {}
3579
+ ...completedPresentation ? { presentation: completedPresentation } : {},
3580
+ ...verbose ? { output: boundedToolOutput(response2.content) } : {}
3546
3581
  });
3547
3582
  return response2;
3548
3583
  }
@@ -4435,7 +4470,7 @@ function createCodeRuntimeToolBroker(input, lease, role) {
4435
4470
  "sandbox.who_touches",
4436
4471
  "sandbox.run_recipe"
4437
4472
  ]);
4438
- 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" }) };
4473
+ return role !== "review" ? 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" }) };
4439
4474
  }
4440
4475
 
4441
4476
  // src/code-runtime-events.ts
@@ -5022,6 +5057,7 @@ var TheseusRuntimeEngine = class {
5022
5057
  buildPolicyDigest: resolvedRecipes.buildPolicyDigest,
5023
5058
  role: metadata.role,
5024
5059
  readOnly: metadata.readOnly,
5060
+ eventDetail: metadata.eventDetail,
5025
5061
  title: metadata.title,
5026
5062
  proof: metadata.proof,
5027
5063
  maxTokensPerInteraction: metadata.maxTokensPerInteraction,
@@ -5089,6 +5125,7 @@ var TheseusRuntimeEngine = class {
5089
5125
  prompt,
5090
5126
  proof: active.proof,
5091
5127
  maxTokensPerInteraction: active.maxTokensPerInteraction,
5128
+ eventDetail: active.eventDetail,
5092
5129
  planningInputDigest: active.planningInputDigest,
5093
5130
  attestationDigest: "pursue",
5094
5131
  repository: active.repository,
@@ -5133,6 +5170,7 @@ var TheseusRuntimeEngine = class {
5133
5170
  prompt,
5134
5171
  proof: active.proof,
5135
5172
  maxTokensPerInteraction: active.maxTokensPerInteraction,
5173
+ eventDetail: active.eventDetail,
5136
5174
  planningInputDigest: active.planningInputDigest,
5137
5175
  attestationDigest: "follow-up",
5138
5176
  repository: active.repository,
@@ -5216,7 +5254,8 @@ var TheseusRuntimeEngine = class {
5216
5254
  return observedBroker({
5217
5255
  broker,
5218
5256
  operationIdFor: (requestId) => digestRuntimeValue(`${command.commandId}:${requestId}`),
5219
- emit: (event) => this.#event(command, event, active.conversationRefs).catch(() => void 0)
5257
+ emit: (event) => this.#event(command, event, active.conversationRefs).catch(() => void 0),
5258
+ detail: active.eventDetail
5220
5259
  });
5221
5260
  }
5222
5261
  async #checkpoint(command) {