@inflexa-ai/harness 0.22.1 → 0.24.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.
Files changed (73) hide show
  1. package/README.md +1 -2
  2. package/dist/agents/conversation-agent.d.ts +0 -9
  3. package/dist/app/chat-turn.js +1 -0
  4. package/dist/app/message-assembly.d.ts +3 -0
  5. package/dist/app/message-assembly.js +17 -0
  6. package/dist/contracts/chat-parts.d.ts +38 -26
  7. package/dist/contracts/content-url.d.ts +7 -41
  8. package/dist/contracts/content-url.js +7 -48
  9. package/dist/contracts/index.d.ts +2 -2
  10. package/dist/contracts/index.js +1 -1
  11. package/dist/contracts/message.d.ts +1 -1
  12. package/dist/contracts/message.js +1 -1
  13. package/dist/contracts/part-registry.js +2 -2
  14. package/dist/contracts/schemas/chat-parts.d.ts +16 -44
  15. package/dist/contracts/schemas/chat-parts.js +15 -18
  16. package/dist/contracts/schemas/index.d.ts +1 -1
  17. package/dist/contracts/schemas/index.js +1 -1
  18. package/dist/execution/run-authorizer.d.ts +1 -1
  19. package/dist/execution/run-authorizer.js +1 -1
  20. package/dist/index.d.ts +1 -3
  21. package/dist/index.js +0 -2
  22. package/dist/lib/zod-issues.d.ts +2 -3
  23. package/dist/lib/zod-issues.js +2 -3
  24. package/dist/loop/__fixtures__/scripted-provider.js +3 -1
  25. package/dist/loop/run-agent.d.ts +5 -0
  26. package/dist/loop/run-agent.js +50 -2
  27. package/dist/loop/run-to-terminal.d.ts +1 -1
  28. package/dist/loop/run-to-terminal.js +1 -1
  29. package/dist/memory/card-builders.d.ts +0 -27
  30. package/dist/memory/card-builders.js +0 -75
  31. package/dist/memory/conversation-display-backfill.d.ts +2 -4
  32. package/dist/memory/conversation-display-backfill.js +3 -9
  33. package/dist/memory/conversation-display-storage.d.ts +3 -3
  34. package/dist/memory/conversation-display-storage.js +3 -3
  35. package/dist/memory/reconstruct-cards.d.ts +5 -7
  36. package/dist/memory/reconstruct-cards.js +6 -20
  37. package/dist/memory/tool-call-integrity.d.ts +46 -0
  38. package/dist/memory/tool-call-integrity.js +92 -0
  39. package/dist/runtime/boot.js +2 -12
  40. package/dist/tools/report-session/preview-report.d.ts +2 -1
  41. package/dist/tools/report-session/preview-report.js +9 -1
  42. package/dist/tools/start-report-session.js +17 -7
  43. package/dist/workspace/paths.d.ts +0 -21
  44. package/dist/workspace/paths.js +0 -37
  45. package/package.json +1 -3
  46. package/dist/agents/report-builder.d.ts +0 -34
  47. package/dist/agents/report-builder.js +0 -34
  48. package/dist/execution/report-render.d.ts +0 -39
  49. package/dist/execution/report-render.js +0 -98
  50. package/dist/execution/report-runner.d.ts +0 -111
  51. package/dist/execution/report-runner.js +0 -230
  52. package/dist/prompts/report-builder.d.ts +0 -1
  53. package/dist/prompts/report-builder.js +0 -174
  54. package/dist/tools/iterate-report.d.ts +0 -227
  55. package/dist/tools/iterate-report.js +0 -883
  56. package/dist/tools/lib/preview-lock.d.ts +0 -20
  57. package/dist/tools/lib/preview-lock.js +0 -35
  58. package/dist/tools/lib/report-preflight.d.ts +0 -39
  59. package/dist/tools/lib/report-preflight.js +0 -283
  60. package/dist/tools/report/build-report.d.ts +0 -13
  61. package/dist/tools/report/build-report.js +0 -27
  62. package/dist/tools/report/index.d.ts +0 -15
  63. package/dist/tools/report/index.js +0 -15
  64. package/dist/tools/report/mint-preview-url.d.ts +0 -26
  65. package/dist/tools/report/mint-preview-url.js +0 -47
  66. package/dist/tools/report/preview-publisher.d.ts +0 -53
  67. package/dist/tools/report/preview-publisher.js +0 -45
  68. package/dist/tools/report/preview-snapshot.d.ts +0 -34
  69. package/dist/tools/report/preview-snapshot.js +0 -98
  70. package/dist/tools/report/submit-report.d.ts +0 -26
  71. package/dist/tools/report/submit-report.js +0 -148
  72. package/dist/tools/report/version-fs.d.ts +0 -15
  73. package/dist/tools/report/version-fs.js +0 -165
@@ -167,13 +167,23 @@ export function createStartReportSessionTool(deps) {
167
167
  }
168
168
  }
169
169
  const spawned = await spawn.spawnReportSession(parentThreadId, brief);
170
- return ok(spawned.match((child) => ({ outcome: "started", threadId: child.threadId, title: child.title }), (fault) => {
171
- const outcome = toOutcome(fault);
172
- if (outcome.outcome === "failed") {
173
- logger.warn("the report session did not start", { parentThreadId, reason: fault.type, ...logger.errorFields(causeOf(fault)) });
174
- }
175
- return outcome;
176
- }));
170
+ if (spawned.isOk()) {
171
+ const child = spawned.value;
172
+ // The part rides the started arm only. The existing-session arm
173
+ // names a session that an earlier turn announced, thus a second
174
+ // part would put a second entry into the transcript.
175
+ await ctx.emit({
176
+ type: "data-child-session-started",
177
+ data: { threadId: child.threadId, parentThreadId, threadType: "report" },
178
+ });
179
+ return ok({ outcome: "started", threadId: child.threadId, title: child.title });
180
+ }
181
+ const fault = spawned.error;
182
+ const outcome = toOutcome(fault);
183
+ if (outcome.outcome === "failed") {
184
+ logger.warn("the report session did not start", { parentThreadId, reason: fault.type, ...logger.errorFields(causeOf(fault)) });
185
+ }
186
+ return ok(outcome);
177
187
  },
178
188
  });
179
189
  }
@@ -159,27 +159,6 @@ export declare function tailWritePrefix(args: {
159
159
  * a step briefing names (see the harness-workspace-tools spec).
160
160
  */
161
161
  export declare function toSandboxPath(workspaceRoot: string, resourceId: string, hostAbsPath: string): string;
162
- /**
163
- * Parent of every preview, workspace-root-relative. Callers that enumerate
164
- * previews join this; callers that address one join {@link previewDir}. Both
165
- * spell the segment through this constant so the tree has one owner.
166
- */
167
- export declare const PREVIEWS_ROOT = "previews";
168
- /**
169
- * Versioned preview directory, workspace-root-relative. Previews live inside
170
- * the analysis tree (`previews/{previewId}/v{N}`); the content-token `res`
171
- * claim keeps the separate `previews/{analysisId}/{previewId}` formula in
172
- * `contracts/content-url.ts` — that is URL space, not a filesystem sub-path,
173
- * and hosts that serve previews map one onto the other themselves.
174
- */
175
- export declare function previewVersionDir(previewId: string, version: number): string;
176
- /** Preview root for a specific preview (all versions), workspace-root-relative. */
177
- export declare function previewDir(previewId: string): string;
178
- /**
179
- * Find the highest version number from a list of version directory names.
180
- * Expects names like "v1", "v2", etc. Returns 0 if no versions found.
181
- */
182
- export declare function latestPreviewVersion(dirNames: string[]): number;
183
162
  /**
184
163
  * Parent of every report session, workspace-root-relative. Callers that
185
164
  * enumerate the sessions join this. Callers that address one join
@@ -151,43 +151,6 @@ export function toSandboxPath(workspaceRoot, resourceId, hostAbsPath) {
151
151
  }
152
152
  return tail === "" ? `/${resourceId}` : `/${resourceId}/${tail}`;
153
153
  }
154
- /**
155
- * Parent of every preview, workspace-root-relative. Callers that enumerate
156
- * previews join this; callers that address one join {@link previewDir}. Both
157
- * spell the segment through this constant so the tree has one owner.
158
- */
159
- export const PREVIEWS_ROOT = "previews";
160
- /**
161
- * Versioned preview directory, workspace-root-relative. Previews live inside
162
- * the analysis tree (`previews/{previewId}/v{N}`); the content-token `res`
163
- * claim keeps the separate `previews/{analysisId}/{previewId}` formula in
164
- * `contracts/content-url.ts` — that is URL space, not a filesystem sub-path,
165
- * and hosts that serve previews map one onto the other themselves.
166
- */
167
- export function previewVersionDir(previewId, version) {
168
- return `${previewDir(previewId)}/v${version}`;
169
- }
170
- /** Preview root for a specific preview (all versions), workspace-root-relative. */
171
- export function previewDir(previewId) {
172
- assertSafeId(previewId, "previewId");
173
- return `${PREVIEWS_ROOT}/${previewId}`;
174
- }
175
- /**
176
- * Find the highest version number from a list of version directory names.
177
- * Expects names like "v1", "v2", etc. Returns 0 if no versions found.
178
- */
179
- export function latestPreviewVersion(dirNames) {
180
- let max = 0;
181
- for (const name of dirNames) {
182
- const match = name.match(/^v(\d+)$/);
183
- if (match) {
184
- const n = parseInt(match[1], 10);
185
- if (n > max)
186
- max = n;
187
- }
188
- }
189
- return max;
190
- }
191
154
  /**
192
155
  * Parent of every report session, workspace-root-relative. Callers that
193
156
  * enumerate the sessions join this. Callers that address one join
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inflexa-ai/harness",
3
- "version": "0.22.1",
3
+ "version": "0.24.0",
4
4
  "description": "Host-agnostic bioinformatics agent harness — hand-rolled agent loop, DBOS-durable workflows, sandboxed compute.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -76,7 +76,6 @@
76
76
  "mime": "^4.1.0",
77
77
  "nanoid": "^5.1.16",
78
78
  "neverthrow": "^8.2.0",
79
- "nunjucks": "^3.2.4",
80
79
  "openai": "^7.4.0",
81
80
  "p-queue": "^9.3.3",
82
81
  "pdf-parse": "^2.4.5",
@@ -89,7 +88,6 @@
89
88
  "@types/bun": "latest",
90
89
  "@types/dockerode": "^3.3.47",
91
90
  "@types/node": "^24.13.3",
92
- "@types/nunjucks": "^3.2.6",
93
91
  "@types/pdf-parse": "^1.1.5",
94
92
  "@types/pg": "^8.20.0",
95
93
  "csstree-validator": "^4.0.1",
@@ -1,34 +0,0 @@
1
- /**
2
- * Report Builder Agent — in-process templating agent (no sandbox).
3
- *
4
- * Authors HTML reports via Jinja2 templating. Runs in the Cortex Node
5
- * process — file IO is in-process via the `versionFs` tool roster, rendering
6
- * is Node-side via Nunjucks (`build_report` tool), and visual validation
7
- * uses headless Chrome via the `preview_snapshot` tool.
8
- *
9
- * The agent receives a complete brief from iterate-report's pre-flight
10
- * (assets staged, columns parsed, sections fully composed) and has no
11
- * discovery surface — its workspace is rooted at the version directory.
12
- *
13
- * NOT a sandbox-agent catalog member (per design Decision #2 — not
14
- * plannable). The full tool roster is constructed inside the runner so
15
- * each tool shares the runner's closure-captured outcome state and
16
- * preview-dir paths; this factory just packages the result into a plain
17
- * `AgentDefinition`.
18
- */
19
- import type { AgentDefinition } from "../loop/types.js";
20
- import type { Tool } from "../tools/define-tool.js";
21
- export declare const REPORT_BUILDER_AGENT_ID = "report-builder";
22
- /** Skill pack the report-builder prompt directs the model to read (design-system reference). */
23
- export declare const REPORT_BUILDER_SKILLS: readonly ["report-html"];
24
- export interface CreateReportBuilderAgentDeps {
25
- /** Model id — provenance / metric label; the provider owns the wire model. */
26
- readonly model: string;
27
- /**
28
- * Full tool roster — the 4 custom report tools plus the in-process
29
- * versionFs surface, all constructed inside the runner so they close
30
- * over the iteration's outcome state and preview-dir paths.
31
- */
32
- readonly tools: readonly Tool[];
33
- }
34
- export declare function createReportBuilderAgent(deps: CreateReportBuilderAgentDeps): AgentDefinition;
@@ -1,34 +0,0 @@
1
- /**
2
- * Report Builder Agent — in-process templating agent (no sandbox).
3
- *
4
- * Authors HTML reports via Jinja2 templating. Runs in the Cortex Node
5
- * process — file IO is in-process via the `versionFs` tool roster, rendering
6
- * is Node-side via Nunjucks (`build_report` tool), and visual validation
7
- * uses headless Chrome via the `preview_snapshot` tool.
8
- *
9
- * The agent receives a complete brief from iterate-report's pre-flight
10
- * (assets staged, columns parsed, sections fully composed) and has no
11
- * discovery surface — its workspace is rooted at the version directory.
12
- *
13
- * NOT a sandbox-agent catalog member (per design Decision #2 — not
14
- * plannable). The full tool roster is constructed inside the runner so
15
- * each tool shares the runner's closure-captured outcome state and
16
- * preview-dir paths; this factory just packages the result into a plain
17
- * `AgentDefinition`.
18
- */
19
- import { reportBuilderPrompt } from "../prompts/report-builder.js";
20
- import { composeSystemPrompt } from "./system-prompt.js";
21
- export const REPORT_BUILDER_AGENT_ID = "report-builder";
22
- /** Skill pack the report-builder prompt directs the model to read (design-system reference). */
23
- export const REPORT_BUILDER_SKILLS = ["report-html"];
24
- /** Runaway guard — Jinja recovery may take several build/edit cycles. */
25
- const REPORT_BUILDER_MAX_ITERATIONS = 75;
26
- export function createReportBuilderAgent(deps) {
27
- return {
28
- id: REPORT_BUILDER_AGENT_ID,
29
- systemPrompt: composeSystemPrompt(reportBuilderPrompt),
30
- model: deps.model,
31
- tools: deps.tools,
32
- maxIterations: REPORT_BUILDER_MAX_ITERATIONS,
33
- };
34
- }
@@ -1,39 +0,0 @@
1
- /**
2
- * Report renderer — Node-side Nunjucks render of v{N}/report.html.j2 to v{N}/index.html.
3
- *
4
- * Stateless pure module: no harness imports, no env reads at import time,
5
- * safe to run standalone in tests.
6
- */
7
- export interface RenderReportOptions {
8
- versionDir: string;
9
- templatesDir: string;
10
- }
11
- export interface RenderReportResult {
12
- ok: boolean;
13
- indexBytes: number;
14
- error?: {
15
- kind: "missing-template" | "syntax" | "runtime";
16
- message: string;
17
- line?: number;
18
- snippet?: string;
19
- };
20
- }
21
- /**
22
- * Render `${versionDir}/report.html.j2` to `${versionDir}/index.html`.
23
- *
24
- * Loader resolution order: [versionDir, templatesDir]. `report.html.j2`
25
- * lives in versionDir; `extends "base.html.j2"` and `include "components/..."`
26
- * resolve from templatesDir. Autoescape is OFF — templates own escaping.
27
- *
28
- * `${templatesDir}/echarts-theme.json` is read, parsed, re-stringified, and
29
- * passed as `echarts_theme` (a JSON string) for safe inlining inside a
30
- * `<script>` block.
31
- *
32
- * Returns `{ ok: true, indexBytes }` on success. On failure, returns
33
- * `{ ok: false, indexBytes: 0, error }` with `error.kind`:
34
- * - "missing-template" — `report.html.j2` (or any `extends`/`include` target)
35
- * not found by either loader. Message identifies the missing path.
36
- * - "syntax" — Nunjucks parse error in any loaded template.
37
- * - "runtime" — anything else thrown during render or write.
38
- */
39
- export declare function renderReport(opts: RenderReportOptions): Promise<RenderReportResult>;
@@ -1,98 +0,0 @@
1
- /**
2
- * Report renderer — Node-side Nunjucks render of v{N}/report.html.j2 to v{N}/index.html.
3
- *
4
- * Stateless pure module: no harness imports, no env reads at import time,
5
- * safe to run standalone in tests.
6
- */
7
- import { readFile, writeFile } from "node:fs/promises";
8
- import { join } from "node:path";
9
- import nunjucks from "nunjucks";
10
- /**
11
- * Render `${versionDir}/report.html.j2` to `${versionDir}/index.html`.
12
- *
13
- * Loader resolution order: [versionDir, templatesDir]. `report.html.j2`
14
- * lives in versionDir; `extends "base.html.j2"` and `include "components/..."`
15
- * resolve from templatesDir. Autoescape is OFF — templates own escaping.
16
- *
17
- * `${templatesDir}/echarts-theme.json` is read, parsed, re-stringified, and
18
- * passed as `echarts_theme` (a JSON string) for safe inlining inside a
19
- * `<script>` block.
20
- *
21
- * Returns `{ ok: true, indexBytes }` on success. On failure, returns
22
- * `{ ok: false, indexBytes: 0, error }` with `error.kind`:
23
- * - "missing-template" — `report.html.j2` (or any `extends`/`include` target)
24
- * not found by either loader. Message identifies the missing path.
25
- * - "syntax" — Nunjucks parse error in any loaded template.
26
- * - "runtime" — anything else thrown during render or write.
27
- */
28
- export async function renderReport(opts) {
29
- const { versionDir, templatesDir } = opts;
30
- let echartsThemeJson;
31
- try {
32
- const raw = await readFile(join(templatesDir, "echarts-theme.json"), "utf8");
33
- echartsThemeJson = JSON.stringify(JSON.parse(raw));
34
- }
35
- catch (err) {
36
- const msg = err instanceof Error ? err.message : String(err);
37
- const kind = isNotFound(err) ? "missing-template" : "runtime";
38
- return {
39
- ok: false,
40
- indexBytes: 0,
41
- error: { kind, message: `failed to load echarts-theme.json: ${msg}` },
42
- };
43
- }
44
- const env = new nunjucks.Environment(new nunjucks.FileSystemLoader([versionDir, templatesDir], {
45
- noCache: true,
46
- }), { autoescape: false, throwOnUndefined: false });
47
- let html;
48
- try {
49
- html = env.render("report.html.j2", { echarts_theme: echartsThemeJson });
50
- }
51
- catch (err) {
52
- return { ok: false, indexBytes: 0, error: classifyNunjucksError(err) };
53
- }
54
- try {
55
- const indexPath = join(versionDir, "index.html");
56
- await writeFile(indexPath, html, "utf8");
57
- return { ok: true, indexBytes: Buffer.byteLength(html, "utf8") };
58
- }
59
- catch (err) {
60
- const msg = err instanceof Error ? err.message : String(err);
61
- return {
62
- ok: false,
63
- indexBytes: 0,
64
- error: { kind: "runtime", message: `failed to write index.html: ${msg}` },
65
- };
66
- }
67
- }
68
- function isNotFound(err) {
69
- if (!err || typeof err !== "object")
70
- return false;
71
- const code = err.code;
72
- return code === "ENOENT";
73
- }
74
- function classifyNunjucksError(err) {
75
- const message = err instanceof Error ? err.message : String(err);
76
- if (/template not found/i.test(message)) {
77
- return { kind: "missing-template", message };
78
- }
79
- // Nunjucks tags parse errors with "Template render error" + "expected" /
80
- // "unexpected" / "parseError" markers; the Template error carries lineno.
81
- const lineno = err?.lineno;
82
- const colno = err?.colno;
83
- const line = typeof lineno === "number" ? lineno : undefined;
84
- const isSyntax = /parseError|expected|unexpected token|unexpected end of/i.test(message) || /Template render error.*line \d+/i.test(message);
85
- if (isSyntax) {
86
- const snippet = extractSnippet(message, line, typeof colno === "number" ? colno : undefined);
87
- return snippet ? { kind: "syntax", message, line, snippet } : line !== undefined ? { kind: "syntax", message, line } : { kind: "syntax", message };
88
- }
89
- return line !== undefined ? { kind: "runtime", message, line } : { kind: "runtime", message };
90
- }
91
- function extractSnippet(message, line, col) {
92
- if (!line)
93
- return undefined;
94
- const m = message.split("\n").find((l) => l.trim().length > 0 && !/^\s*at\s/.test(l));
95
- if (!m)
96
- return undefined;
97
- return col !== undefined ? `${m} (col ${col})` : m;
98
- }
@@ -1,111 +0,0 @@
1
- /**
2
- * Report runner — orchestrates an iterative report build entirely in the
3
- * Cortex Node process. No sandbox, no Python.
4
- *
5
- * Lifecycle:
6
- * 1. Resolve version (latest + 1, or baseVersion + 1)
7
- * 2. Prepare version dir (mkdir, copy v{base}/report.html.j2, symlink ../assets)
8
- * 3. Construct the 4 custom report tools + the in-process versionFs surface;
9
- * all of them close over the iteration's preview-dir state and a single
10
- * `outcome: ReportOutcome | undefined` variable (the closure-state
11
- * closure-state capture — see design.md Decision #9, mirrors
12
- * `harness/tools/research/generate-plan.ts`'s
13
- * `PlannerOutcome` capture).
14
- * 4. Build the `report-builder` AgentDefinition with that tool roster and
15
- * drive it via `runAgent` + `passthroughStep`.
16
- * 5. Verify the closure-captured `outcome` is `{ ok: true, ... }` (else
17
- * classify the failure, roll back the version dir, return a structured
18
- * failure).
19
- * 6. Return success or a structured failure.
20
- *
21
- * Concurrency: per-previewId serialization via `withPreviewLock` so two
22
- * iterations on the same preview don't race on shared assets/.
23
- *
24
- * Billing: the report-builder's LLM calls flow through the `ChatProvider`
25
- * seam with `forSubAgent(session, REPORT_BUILDER_AGENT_ID)` — the provider's
26
- * lazy `resolveBilling` fires at the call site. No ALS, no fetch-patch
27
- * (Decision #6).
28
- *
29
- * Preview surface: the `preview_snapshot` and `mint_preview_url` tools mint
30
- * a content-server URL through the injected `PreviewPublisher` seam. The
31
- * managed publisher owns the short-lived host credential; the local default
32
- * returns "unavailable" so the report still builds without a hosted preview.
33
- */
34
- import type { Pool } from "pg";
35
- import { type RequestSession } from "../auth/types.js";
36
- import type { EmitFn } from "../loop/types.js";
37
- import type { ChatProvider } from "../providers/types.js";
38
- import type { PreviewPublisher } from "../tools/report/preview-publisher.js";
39
- import type { ChromeConfig } from "../lib/chrome.js";
40
- import type { Logger } from "../lib/logger.js";
41
- import type { UsageRecorder } from "../billing/usage-recorder.js";
42
- import type { AgentRunUsage } from "../loop/metrics.js";
43
- export interface ReportRunnerDeps {
44
- /** Operational logging seam; omitted falls back to no-op. */
45
- readonly logger?: Logger;
46
- readonly provider: ChatProvider;
47
- readonly pool: Pool;
48
- /** Model id — provenance / metric label; provider owns the wire model. */
49
- readonly model: string;
50
- /** Root templates dir; `report-html` is joined onto it. */
51
- readonly templatesDir: string;
52
- /** Skills root; the report-builder gets read-only `report-html` skill tools. */
53
- readonly skillsDir: string;
54
- readonly chrome: ChromeConfig;
55
- /** LLM usage-accounting seam for the report-builder loop; omitted falls back to the no-op recorder. */
56
- readonly usageRecorder?: UsageRecorder;
57
- }
58
- export interface ReportRunnerOptions {
59
- readonly resourceId: string;
60
- /** Absolute host root of the analysis's workspace tree (previews live inside it). */
61
- readonly workspaceRoot: string;
62
- readonly previews: PreviewPublisher;
63
- /** Preview group ID. Auto-generated by the tool layer if not provided. */
64
- readonly previewId: string;
65
- /** Base version to iterate from. Defaults to latest. */
66
- readonly baseVersion?: number;
67
- /**
68
- * Format the preview was built as. The tool boundary admits only `"html"`,
69
- * so no other value can reach a live iteration; the union stays wide because
70
- * previews persisted with a broader vocabulary must still parse. Read this
71
- * field as a record of what a preview is, not as a request for a renderer.
72
- */
73
- readonly format: "html" | "pdf";
74
- /** Prompt for the report-builder agent. */
75
- readonly prompt: string;
76
- /** Live chat session — derives the child agent's session via forSubAgent. */
77
- readonly session: RequestSession;
78
- /** Cancellation signal — propagates to the agent stream. */
79
- readonly signal: AbortSignal;
80
- /** Event sink — forwarded to the agent loop. */
81
- readonly emit: EmitFn;
82
- /**
83
- * The calling turn's usage accumulator (`ctx.turnUsage`), so the
84
- * report-builder loop's tokens land in the turn total its root reports.
85
- */
86
- readonly turnUsage?: AgentRunUsage;
87
- /**
88
- * The dispatching tool call's id (`ctx.invocationId`), which discriminates
89
- * the builder loop's usage record keys from those of a sibling iteration
90
- * dispatched in the same round — same frame, same call path, same
91
- * loop-local step names.
92
- */
93
- readonly invocationId?: string;
94
- }
95
- export type ReportRunnerResult = {
96
- ok: true;
97
- previewId: string;
98
- version: number;
99
- previewPath: string;
100
- durationMs: number;
101
- /** Caveats surfaced by the agent via submit_report. */
102
- notes: readonly string[];
103
- } | {
104
- ok: false;
105
- previewId: string;
106
- version: number;
107
- reason: string;
108
- errorKind: "render" | "submit" | "build" | "timeout" | "internal";
109
- durationMs: number;
110
- };
111
- export declare function runReportIteration(deps: ReportRunnerDeps, opts: ReportRunnerOptions): Promise<ReportRunnerResult>;