@inflexa-ai/harness 0.42.2 → 0.43.1

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 (199) hide show
  1. package/README.md +2 -2
  2. package/dist/agents/sandbox/shared.d.ts +1 -6
  3. package/dist/agents/sandbox/shared.js +0 -15
  4. package/dist/app/chat-turn.js +13 -1
  5. package/dist/config/environment-stores.d.ts +4 -2
  6. package/dist/contracts/chat-events.d.ts +9 -1
  7. package/dist/contracts/chat-frame.d.ts +3 -3
  8. package/dist/contracts/chat-frame.js +8 -3
  9. package/dist/contracts/chat-parts.d.ts +4 -1
  10. package/dist/contracts/data-profile.d.ts +4 -6
  11. package/dist/contracts/index.d.ts +1 -1
  12. package/dist/contracts/report-blocks.d.ts +1364 -75
  13. package/dist/contracts/report-blocks.js +221 -29
  14. package/dist/contracts/report-reference.js +1 -1
  15. package/dist/contracts/schemas/chat-events.d.ts +13 -0
  16. package/dist/contracts/schemas/chat-events.js +5 -0
  17. package/dist/contracts/schemas/chat-parts.d.ts +2 -2
  18. package/dist/contracts/schemas/index.d.ts +1 -1
  19. package/dist/contracts/schemas/index.js +1 -1
  20. package/dist/execution/input-signature.d.ts +7 -13
  21. package/dist/execution/input-signature.js +0 -0
  22. package/dist/execution/run-canceler.d.ts +3 -2
  23. package/dist/execution/run-canceler.js +3 -2
  24. package/dist/execution/run-event-stream.d.ts +16 -2
  25. package/dist/execution/run-event-stream.js +54 -3
  26. package/dist/index.d.ts +1 -8
  27. package/dist/index.js +5 -16
  28. package/dist/input-scan/enrich.d.ts +0 -2
  29. package/dist/input-scan/enrich.js +0 -1
  30. package/dist/lib/metrics.js +6 -7
  31. package/dist/lib/otel-spans.d.ts +4 -9
  32. package/dist/lib/otel-spans.js +3 -8
  33. package/dist/loop/run-agent.d.ts +4 -2
  34. package/dist/loop/run-agent.js +38 -23
  35. package/dist/memory/thread-history.d.ts +1 -1
  36. package/dist/prompts/report-session.d.ts +1 -1
  37. package/dist/prompts/report-session.js +17 -0
  38. package/dist/provenance/exec-frame.d.ts +1 -1
  39. package/dist/report-model/authoring-grammar.d.ts +416 -17
  40. package/dist/report-model/authoring-grammar.js +25 -4
  41. package/dist/report-model/block-walk.d.ts +20 -4
  42. package/dist/report-model/block-walk.js +64 -7
  43. package/dist/report-model/draft-finish.d.ts +6 -2
  44. package/dist/report-model/draft-finish.js +6 -1
  45. package/dist/report-model/production-resolver.d.ts +8 -0
  46. package/dist/report-model/production-resolver.js +1 -1
  47. package/dist/report-model/validate.d.ts +20 -10
  48. package/dist/report-model/validate.js +29 -13
  49. package/dist/report-render/chart-export.d.ts +52 -0
  50. package/dist/report-render/chart-export.js +192 -0
  51. package/dist/report-render/chart-presets.d.ts +46 -47
  52. package/dist/report-render/chart-presets.js +31 -101
  53. package/dist/report-render/chart-renderers.d.ts +163 -0
  54. package/dist/report-render/chart-renderers.js +1055 -0
  55. package/dist/report-render/chart-toolbox.d.ts +124 -0
  56. package/dist/report-render/chart-toolbox.js +595 -0
  57. package/dist/report-render/chart.d.ts +60 -27
  58. package/dist/report-render/chart.js +2323 -524
  59. package/dist/report-render/design.d.ts +476 -16
  60. package/dist/report-render/design.js +390 -56
  61. package/dist/report-render/figures/common.d.ts +321 -0
  62. package/dist/report-render/figures/common.js +759 -0
  63. package/dist/report-render/figures/dendrogram.d.ts +36 -0
  64. package/dist/report-render/figures/dendrogram.js +130 -0
  65. package/dist/report-render/figures/dense.d.ts +111 -0
  66. package/dist/report-render/figures/dense.js +204 -0
  67. package/dist/report-render/figures/dotplot.d.ts +28 -0
  68. package/dist/report-render/figures/dotplot.js +234 -0
  69. package/dist/report-render/figures/embedding.d.ts +43 -0
  70. package/dist/report-render/figures/embedding.js +360 -0
  71. package/dist/report-render/figures/equal-units.d.ts +101 -0
  72. package/dist/report-render/figures/equal-units.js +215 -0
  73. package/dist/report-render/figures/forest.d.ts +20 -0
  74. package/dist/report-render/figures/forest.js +398 -0
  75. package/dist/report-render/figures/gsea.d.ts +30 -0
  76. package/dist/report-render/figures/gsea.js +391 -0
  77. package/dist/report-render/figures/heatmap.d.ts +40 -0
  78. package/dist/report-render/figures/heatmap.js +395 -0
  79. package/dist/report-render/figures/index.d.ts +135 -0
  80. package/dist/report-render/figures/index.js +100 -0
  81. package/dist/report-render/figures/km.d.ts +16 -0
  82. package/dist/report-render/figures/km.js +406 -0
  83. package/dist/report-render/figures/label-room.d.ts +130 -0
  84. package/dist/report-render/figures/label-room.js +341 -0
  85. package/dist/report-render/figures/locuszoom.d.ts +50 -0
  86. package/dist/report-render/figures/locuszoom.js +675 -0
  87. package/dist/report-render/figures/lollipop.d.ts +16 -0
  88. package/dist/report-render/figures/lollipop.js +247 -0
  89. package/dist/report-render/figures/ma.d.ts +20 -0
  90. package/dist/report-render/figures/ma.js +114 -0
  91. package/dist/report-render/figures/manhattan.d.ts +60 -0
  92. package/dist/report-render/figures/manhattan.js +343 -0
  93. package/dist/report-render/figures/oncoprint.d.ts +41 -0
  94. package/dist/report-render/figures/oncoprint.js +420 -0
  95. package/dist/report-render/figures/pca.d.ts +37 -0
  96. package/dist/report-render/figures/pca.js +241 -0
  97. package/dist/report-render/figures/qq.d.ts +30 -0
  98. package/dist/report-render/figures/qq.js +182 -0
  99. package/dist/report-render/figures/roc.d.ts +17 -0
  100. package/dist/report-render/figures/roc.js +116 -0
  101. package/dist/report-render/figures/sankey.d.ts +48 -0
  102. package/dist/report-render/figures/sankey.js +353 -0
  103. package/dist/report-render/figures/upset.d.ts +60 -0
  104. package/dist/report-render/figures/upset.js +316 -0
  105. package/dist/report-render/figures/volcano.d.ts +25 -0
  106. package/dist/report-render/figures/volcano.js +166 -0
  107. package/dist/report-render/hybrid-svg.d.ts +75 -0
  108. package/dist/report-render/hybrid-svg.js +504 -0
  109. package/dist/report-render/number-format.d.ts +19 -0
  110. package/dist/report-render/number-format.js +25 -1
  111. package/dist/report-render/page.d.ts +41 -4
  112. package/dist/report-render/page.js +247 -12
  113. package/dist/report-render/render.d.ts +13 -4
  114. package/dist/report-render/render.js +37 -6
  115. package/dist/report-render/types.d.ts +23 -2
  116. package/dist/report-render/value-bridge.d.ts +38 -3
  117. package/dist/report-render/value-bridge.js +137 -6
  118. package/dist/report-render/views/chart-view.d.ts +42 -6
  119. package/dist/report-render/views/chart-view.js +70 -9
  120. package/dist/report-render/views/page-view.js +9 -10
  121. package/dist/runtime/assemble.js +2 -2
  122. package/dist/sandbox/client.d.ts +23 -32
  123. package/dist/sandbox/client.js +3 -11
  124. package/dist/sandbox/create-sandbox.d.ts +9 -24
  125. package/dist/sandbox/create-sandbox.js +15 -30
  126. package/dist/sandbox/docker-client.d.ts +12 -22
  127. package/dist/sandbox/docker-client.js +29 -43
  128. package/dist/sandbox/exec.d.ts +58 -0
  129. package/dist/sandbox/exec.js +197 -0
  130. package/dist/sandbox/identity.d.ts +5 -5
  131. package/dist/sandbox/identity.js +7 -10
  132. package/dist/sandbox/k8s-client.d.ts +4 -10
  133. package/dist/sandbox/k8s-client.js +5 -12
  134. package/dist/sandbox/liveness.d.ts +5 -12
  135. package/dist/sandbox/liveness.js +5 -12
  136. package/dist/sandbox/notification-sweep.d.ts +4 -7
  137. package/dist/sandbox/notification-sweep.js +4 -7
  138. package/dist/sandbox/reaper.d.ts +3 -3
  139. package/dist/sandbox/reaper.js +3 -3
  140. package/dist/sandbox/sandbox-error.d.ts +10 -11
  141. package/dist/sandbox/sandbox-error.js +10 -11
  142. package/dist/sandbox/sandbox-step-translate.d.ts +1 -1
  143. package/dist/sandbox/sandbox-step-translate.js +1 -1
  144. package/dist/sandbox/types.d.ts +31 -99
  145. package/dist/sandbox/types.js +17 -84
  146. package/dist/state/active-sandboxes.d.ts +7 -32
  147. package/dist/state/active-sandboxes.js +11 -46
  148. package/dist/state/index.d.ts +1 -2
  149. package/dist/state/index.js +1 -1
  150. package/dist/state/migrations/20261005120000_drop_the_active_exec_tracking.d.ts +7 -0
  151. package/dist/state/migrations/20261005120000_drop_the_active_exec_tracking.js +12 -0
  152. package/dist/state/migrations/index.js +2 -0
  153. package/dist/state/schema.d.ts +1 -5
  154. package/dist/state/schema.js +1 -6
  155. package/dist/state/step-executions.js +1 -2
  156. package/dist/tasks/data-profile.js +7 -20
  157. package/dist/tasks/derive-table-exec.d.ts +4 -14
  158. package/dist/tasks/derive-table-exec.js +9 -24
  159. package/dist/tasks/extract-values.d.ts +2 -2
  160. package/dist/tasks/extract-values.js +4 -7
  161. package/dist/tools/define-tool.d.ts +56 -13
  162. package/dist/tools/define-tool.js +28 -1
  163. package/dist/tools/execute-analysis.js +3 -3
  164. package/dist/tools/report-session/derive-table.d.ts +8 -9
  165. package/dist/tools/report-session/derive-table.js +3 -4
  166. package/dist/tools/report-session/preview-report.js +4 -49
  167. package/dist/tools/sandbox/list-available-packages.d.ts +1 -1
  168. package/dist/tools/sandbox/list-available-packages.js +5 -4
  169. package/dist/tools/workspace/edit-file.d.ts +5 -4
  170. package/dist/tools/workspace/edit-file.js +10 -13
  171. package/dist/tools/workspace/execute-command.d.ts +27 -42
  172. package/dist/tools/workspace/execute-command.js +42 -38
  173. package/dist/tools/workspace/index.d.ts +5 -6
  174. package/dist/tools/workspace/index.js +5 -6
  175. package/dist/tools/workspace/mutator.d.ts +43 -8
  176. package/dist/tools/workspace/mutator.js +45 -34
  177. package/dist/tools/workspace/run-exec.d.ts +3 -12
  178. package/dist/tools/workspace/run-exec.js +7 -24
  179. package/dist/tools/workspace/scan-inputs.d.ts +0 -3
  180. package/dist/tools/workspace/scan-inputs.js +0 -1
  181. package/dist/tools/workspace/write-file.d.ts +12 -3
  182. package/dist/tools/workspace/write-file.js +17 -13
  183. package/dist/workflows/sandbox-step.d.ts +7 -11
  184. package/dist/workflows/sandbox-step.js +24 -27
  185. package/package.json +5 -3
  186. package/dist/sandbox/await-exec.d.ts +0 -143
  187. package/dist/sandbox/await-exec.js +0 -417
  188. package/dist/sandbox/deliver-exec-event.d.ts +0 -25
  189. package/dist/sandbox/deliver-exec-event.js +0 -29
  190. package/dist/sandbox/digest.d.ts +0 -14
  191. package/dist/sandbox/digest.js +0 -17
  192. package/dist/sandbox/exec-id.d.ts +0 -12
  193. package/dist/sandbox/exec-id.js +0 -20
  194. package/dist/sandbox/hmac.d.ts +0 -62
  195. package/dist/sandbox/hmac.js +0 -72
  196. package/dist/sandbox/submit-exec.d.ts +0 -38
  197. package/dist/sandbox/submit-exec.js +0 -80
  198. package/dist/sandbox/watchdog.d.ts +0 -71
  199. package/dist/sandbox/watchdog.js +0 -161
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @inflexa-ai/harness
2
2
 
3
- `@inflexa-ai/harness` is the host-agnostic agent harness — the `runAgent` loop, durable workflows, the sandbox submit/recv protocol, and the provider interfaces. It is a **library, not a server**: it ships everything that does not depend on a particular host, and an embedder supplies the composition root, transport, and any non-local seam realizations.
3
+ `@inflexa-ai/harness` is the host-agnostic agent harness — the `runAgent` loop, durable workflows, the sandbox submit and poll protocol, and the provider interfaces. It is a **library, not a server**: it ships everything that does not depend on a particular host, and an embedder supplies the composition root, transport, and any non-local seam realizations.
4
4
 
5
5
  ## Run locally
6
6
 
@@ -98,7 +98,7 @@ function pinoAsHarnessLogger(p: pino.Logger, names: readonly string[] = []): Log
98
98
 
99
99
  Chat is a plain in-process turn. A turn is `runChatTurn`, and the harness stores the opening, each round, and the outcome of the turn. The harness ships no HTTP layer, thus the host owns the route. Compute-heavy work runs as **durable workflows** — `executeAnalysis` starts a child workflow per plan step once its dependencies have completed, and each step drives a sandbox agent inside a container. The same `runAgent` primitive runs in both modes; durability and the event sink are injected, so the loop body is identical.
100
100
 
101
- The sandbox protocol is submit-then-retrieve, which is what lets a long run survive a host restart: the host `POST /exec`s a command and retrieves the result over one of two transports — **poll** (the default: the host asks, the sandbox initiates nothing and needs no network egress) or **callback** (opt-in: the sandbox POSTs signed callbacks to an ingress the embedder runs). Both exec endpoints are HMAC signature-authenticated. See the [`harness-sandbox-exec`](./openspec/specs/harness-sandbox-exec/) spec.
101
+ The sandbox protocol is submit-then-poll, which lets a long run survive a host restart. Each exec runs inside one durable step: the host submits the command with `POST /exec`, and then it polls `GET /exec/{execId}?since={cursor}` until the result. A recovered step submits the same exec id again, and the sandbox gives the existing record, thus the command does not run again. The sandbox initiates nothing and has no egress, and confinement keeps each other peer away from its exec port. Refer to the [`harness-sandbox-exec`](./openspec/specs/harness-sandbox-exec/) spec.
102
102
 
103
103
  ## Further reading
104
104
 
@@ -44,14 +44,9 @@ export interface SandboxStepCoords {
44
44
  /** Absolute host root of this analysis's workspace tree (resolved at the workflow body). */
45
45
  readonly workspaceRoot: string;
46
46
  readonly analysisId: string;
47
- readonly runId: string;
48
- readonly stepId: string;
49
- readonly workflowId: string;
50
47
  /** Absolute writable artifact directory for this step (e.g. stepWritePrefix(...)). */
51
48
  readonly allowedWritePrefix: string;
52
- /** Stable per-call function id minter (monotonic; replay-deterministic). */
53
- readonly nextFunctionId: () => string;
54
- /** Absolute unix-ms deadline for `awaitExec`. */
49
+ /** Absolute unix-ms deadline of each exec. */
55
50
  readonly deadlineMs: () => number;
56
51
  }
57
52
  /** The shared dependency graph every sandbox agent draws from. */
@@ -40,7 +40,6 @@ import { createReadToolOutputTool } from "../../tools/read-tool-output.js";
40
40
  import { createReportBlockerTool } from "../../tools/sandbox/report-blocker.js";
41
41
  import { createSubmitFileMetadataTool } from "../../tools/sandbox/submit-file-metadata.js";
42
42
  import { toSandboxPath } from "../../workspace/paths.js";
43
- import { setActiveExecId } from "../../state/index.js";
44
43
  import { SANDBOX_AGENT_DEFAULT_MAX_ITERATIONS } from "./types.js";
45
44
  import { createResolveCitationTool } from "../../tools/research/resolve-citation.js";
46
45
  /**
@@ -76,9 +75,6 @@ function resolveSandboxTools(deps, tools) {
76
75
  analysisId: deps.step.analysisId,
77
76
  sandboxClient: deps.sandboxClient,
78
77
  sandbox: deps.step.sandbox,
79
- workflowId: deps.step.workflowId,
80
- stepId: deps.step.stepId,
81
- nextFunctionId: deps.step.nextFunctionId,
82
78
  deadlineMs: deps.step.deadlineMs,
83
79
  }),
84
80
  resolveLibraryId: resolveLibraryIdTool,
@@ -116,18 +112,11 @@ function resolveSandboxTools(deps, tools) {
116
112
  }
117
113
  return resolved;
118
114
  }
119
- function createMarkExecActive(deps) {
120
- return (execId) => setActiveExecId(deps.pool, deps.step.runId, deps.step.stepId, execId).match(() => { }, () => { });
121
- }
122
115
  /** Build the workspace mutate + read tools every sandbox agent receives. In
123
116
  * `readOnly` mode the write_file/edit_file pair is omitted; execute_command
124
117
  * and the read tools stay. */
125
118
  function buildWorkspaceTools(deps, readOnly) {
126
119
  const { step, sandboxClient, workspaceFs, pool, embedding, lineageCollector } = deps;
127
- // Registry tagging is a best-effort watchdog backstop (`run-exec.ts` already
128
- // swallows a throw here); fold a `DbError` into a no-op so a registry write
129
- // failure neither fails the exec nor surfaces as an unhandled rejection.
130
- const markExecActive = createMarkExecActive(deps);
131
120
  // The agent's writable working directory: relative paths resolve here, and
132
121
  // writes are confined here. `allowedWritePrefix` is its host path; the
133
122
  // in-sandbox path (the `execute_command` default cwd, see the harness-workspace-tools spec) is the same
@@ -150,12 +139,8 @@ function buildWorkspaceTools(deps, readOnly) {
150
139
  createExecuteCommandTool({
151
140
  sandboxClient,
152
141
  sandbox: step.sandbox,
153
- workflowId: step.workflowId,
154
- stepId: step.stepId,
155
- nextFunctionId: step.nextFunctionId,
156
142
  deadlineMs: step.deadlineMs,
157
143
  defaultCwd: sandboxWorkingDir,
158
- markExecActive,
159
144
  ...(lineageCollector ? { lineageCollector, mountRoot: `/${step.analysisId}` } : {}),
160
145
  }),
161
146
  ...mutateTools,
@@ -6,7 +6,7 @@
6
6
  import { unwrapOrThrow } from "../lib/result.js";
7
7
  import { finalText, runAgent } from "../loop/run-agent.js";
8
8
  import { passthroughStep } from "../loop/run-step.js";
9
- import { compactionExchangeOf } from "../memory/ai-sdk-message-storage.js";
9
+ import { compactionExchangeOf, syntheticUserMessage } from "../memory/ai-sdk-message-storage.js";
10
10
  import { createConversationDisplayRecorder } from "../memory/conversation-display-recorder.js";
11
11
  import { deriveThreadTitle } from "../memory/derive-thread-title.js";
12
12
  import { conversationRecordTurn, createThreadHistory } from "../memory/thread-history.js";
@@ -217,6 +217,7 @@ async function runOpenTurn(deps, turn, prepared, agent, params) {
217
217
  await flush({
218
218
  status: outcome.status,
219
219
  ...(outcome.status === "failed" ? { reason: outcome.reason, note: conversationRecordTurn(failureNote(outcome.reason)) } : {}),
220
+ ...(outcome.status === "aborted" ? { note: interruptionNote() } : {}),
220
221
  ...(turnUsage === undefined ? {} : { turnUsage }),
221
222
  turnDurationMs: durationMs,
222
223
  });
@@ -265,6 +266,17 @@ function failureReasonOf(err) {
265
266
  return "The model request failed.";
266
267
  return "The turn stopped on an internal error.";
267
268
  }
269
+ /**
270
+ * The note of an aborted turn. Without it, the next turn reads the request of the aborted turn as open, and
271
+ * its reply also answers that request. The transcript shows the interruption from the turn record, thus the
272
+ * note has no display.
273
+ */
274
+ function interruptionNote() {
275
+ return {
276
+ modelMessages: [syntheticUserMessage("[The user interrupted the request above. Do not continue it unless the user asks you to.]")],
277
+ displayMessages: [],
278
+ };
279
+ }
268
280
  function failureNote(reason) {
269
281
  return ["[Turn Failed]", `The turn stopped before it finished. Reason: ${reason}`, "The rounds above this note ran, and their results are stored."].join("\n");
270
282
  }
@@ -42,9 +42,11 @@ export interface EnvironmentStorePaths {
42
42
  * importable inside a sandbox. Omit when the host mounts the farm at the
43
43
  * sandbox's own path, which makes the container path correct as-is; a host
44
44
  * that reads the farm somewhere else must inject the path, or the
45
- * inventory reads as unknown.
45
+ * inventory reads as unknown. A host that keeps one farm for each analysis
46
+ * gives a function, and each read resolves the path with the analysis id
47
+ * of its session.
46
48
  */
47
- readonly farmLockFile?: string;
49
+ readonly farmLockFile?: string | ((analysisId: string) => string);
48
50
  /**
49
51
  * Host path of the image inventory record, `image-packages.json` at the
50
52
  * root of the package store — the image-owned tools and Node packages
@@ -65,6 +65,14 @@ export type ToolCallOutcome = ToolOutcome | "incomplete";
65
65
  * when the detail could not be produced.
66
66
  */
67
67
  export type ToolCallDetail = string;
68
+ /**
69
+ * A sub-agent loop started a request to its model. Only a sub-agent gives this frame, thus a consumer that
70
+ * keeps the root frames only (`isRootFrame`) never sees it. A host reads it as "the sub-agent thinks".
71
+ */
72
+ export interface IterationEvent {
73
+ type: "iteration";
74
+ source: EventSource;
75
+ }
68
76
  /** A tool call has been dispatched. */
69
77
  export interface ToolStartedEvent {
70
78
  type: "tool-started";
@@ -133,7 +141,7 @@ export interface ChatErrorEvent {
133
141
  source: EventSource;
134
142
  }
135
143
  /** The discriminated union of all chat-stream events. */
136
- export type ChatEvent = TextDeltaEvent | ToolStartedEvent | ToolFinishedEvent | FinishEvent | ChatErrorEvent;
144
+ export type ChatEvent = TextDeltaEvent | IterationEvent | ToolStartedEvent | ToolFinishedEvent | FinishEvent | ChatErrorEvent;
137
145
  /** A `data-*` part as a frame, with the source of its emitter when the emitter stamped one. */
138
146
  export type ChatPartFrame = ChatPart & {
139
147
  source?: EventSource;
@@ -17,9 +17,9 @@ export type ChatPartCheck = {
17
17
  readonly error: string;
18
18
  };
19
19
  /**
20
- * The frame of one emitted event, or `null` for `iteration` and `done`. A frame of a sub-agent keeps its source, thus a
21
- * consumer can filter it. A `text-delta` has no source, thus its frame gets `fallbackSource`, the source of the root agent.
22
- * A part frame is not checked here: {@link checkChatPart} checks it where it arrives.
20
+ * The frame of one emitted event, or `null` for `done` and for an `iteration` of the root agent. A frame of a sub-agent
21
+ * keeps its source, thus a consumer can filter it. A `text-delta` has no source, thus its frame gets `fallbackSource`,
22
+ * the source of the root agent. A part frame is not checked here: {@link checkChatPart} checks it where it arrives.
23
23
  */
24
24
  export declare function toChatFrame(event: EmitEvent | ChatStreamEvent | ChatDataPart, fallbackSource: EmitEvent["source"]): ChatFrame | null;
25
25
  /**
@@ -6,13 +6,16 @@ function toSource(source) {
6
6
  return { agentId: source.agentId, callPath: [...source.callPath] };
7
7
  }
8
8
  /**
9
- * The frame of one emitted event, or `null` for `iteration` and `done`. A frame of a sub-agent keeps its source, thus a
10
- * consumer can filter it. A `text-delta` has no source, thus its frame gets `fallbackSource`, the source of the root agent.
11
- * A part frame is not checked here: {@link checkChatPart} checks it where it arrives.
9
+ * The frame of one emitted event, or `null` for `done` and for an `iteration` of the root agent. A frame of a sub-agent
10
+ * keeps its source, thus a consumer can filter it. A `text-delta` has no source, thus its frame gets `fallbackSource`,
11
+ * the source of the root agent. A part frame is not checked here: {@link checkChatPart} checks it where it arrives.
12
12
  */
13
13
  export function toChatFrame(event, fallbackSource) {
14
14
  switch (event.type) {
15
15
  case "iteration":
16
+ // The root loop gives none: a consumer of the root frames, for example the first-frame time of a
17
+ // browser, must not read the start of a model request as output.
18
+ return event.source.callPath.length > 1 ? { type: "iteration", source: toSource(event.source) } : null;
16
19
  case "done":
17
20
  return null;
18
21
  case "tool-started":
@@ -100,6 +103,8 @@ export function applyChatFrame(messages, frame, assistantId) {
100
103
  if (frame.type === "error") {
101
104
  return { messages, terminal: { error: frame } };
102
105
  }
106
+ if (frame.type === "iteration")
107
+ return { messages, terminal: null };
103
108
  const partFrame = frame;
104
109
  const next = updateAssistant(messages, assistantId, (parts) => applyPartFrame(parts, partFrame));
105
110
  return { messages: next, terminal: null };
@@ -348,7 +348,10 @@ export interface RunFailedPart {
348
348
  runId: string;
349
349
  /** Scrubbed error message (no internal details). */
350
350
  error: string;
351
- /** The suspend reason of the host, carried unread; present only when the run suspended. */
351
+ /**
352
+ * The suspend reason of the host, carried unread, when the run suspended.
353
+ * `canceled` when an external cancel ended the run. Absent for a failure.
354
+ */
352
355
  reason?: string;
353
356
  }
354
357
  /**
@@ -345,14 +345,12 @@ export interface DataProfileRecipeStep {
345
345
  groupIds: string[];
346
346
  }
347
347
  /**
348
- * The comparand identifying WHICH files a profile covered and whether the SAME BYTES
349
- * were profiled.
348
+ * The record of WHICH files a profile covered and of the bytes behind them.
350
349
  *
351
350
  * `digest` is a stable hash over the staged inputs' identities, sizes, and mtimes in a
352
351
  * canonical order, so it depends on the set and not on enumeration order. It excludes
353
- * content hashes deliberately: enumerating those would mean reading every input in full
354
- * on every parity check. An edit preserving both byte length and mtime is therefore not
355
- * detected — bounded, and documented.
352
+ * content hashes deliberately: a content hash means a full read of every input. Two
353
+ * inputs with the same byte length and mtime therefore give the same digest.
356
354
  */
357
355
  export interface DataProfileInputSignature {
358
356
  count: number;
@@ -413,7 +411,7 @@ export interface DataProfileResult {
413
411
  kinds?: DataProfileKind[];
414
412
  /** What varies across those sets, on a snapshot of the same era. */
415
413
  axes?: DataProfileAxis[];
416
- /** The drift comparand. */
414
+ /** The record of the profiled kept input set. */
417
415
  inputSignature?: DataProfileInputSignature;
418
416
  /** How much of the scanned tree the kinds describe, on a snapshot of the kinds era. Superseded by `partition`. */
419
417
  coverage?: DataProfileCoverage;
@@ -3,7 +3,7 @@ export type { OrganSystem } from "./organ-system.js";
3
3
  export { SEVERITIES, SeveritySchema } from "./severity.js";
4
4
  export type { Severity } from "./severity.js";
5
5
  export type { PlanStep, PresentationContent, PresentationPart, PlanPart, RunCardPart, FileReferenceEntry, FileReferencePart, AskPart, RunStartedPart, StepStatus, DagStepState, DagStatePart, StepPhase, StepActivityPart, FileTreeEntry, StepFileTreePart, StepOutputFile, StepOutputPart, StepSummaryPart, StepUsagePart, StepBlockedPart, SynthesizedFinding, BiologicalTheme, RunSynthesisPart, SynthesisPhase, SynthesisProgressPart, RunCompletedFinding, RunCompletedPart, RunFailedPart, ChildSessionStartedPart, ReportRenderedPart, CompactionPart, ChatPart, } from "./chat-parts.js";
6
- export type { EventSource, TextDeltaEvent, ToolStartedEvent, ToolFinishedEvent, FinishEvent, ChatErrorEvent, ChatEvent, ChatFrame, ChatPartFrame, } from "./chat-events.js";
6
+ export type { EventSource, TextDeltaEvent, IterationEvent, ToolStartedEvent, ToolFinishedEvent, FinishEvent, ChatErrorEvent, ChatEvent, ChatFrame, ChatPartFrame, } from "./chat-events.js";
7
7
  export type { TokenUsageRollup } from "./usage.js";
8
8
  export { DATA_PROFILE_RUN_LITERAL } from "./data-profile.js";
9
9
  export type { DataProfileAxis, DataProfileChecked, DataProfileCompanionCompleteness, DataProfileCoverage, DataProfileDimension, DataProfileFile, DataProfileGroup, DataProfileGroupSlot, DataProfileInputSignature, DataProfileKind, DataProfileLifecycleStatus, DataProfileMemberAnnotation, DataProfileObservation, DataProfileOrganism, DataProfilePartition, DataProfileProbeReport, DataProfileQualityAssessment, DataProfileQuarantine, DataProfileRecipeStep, DataProfileResult, DataProfileSubjectSource, } from "./data-profile.js";