@inflexa-ai/harness 0.1.1 → 0.2.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 (268) hide show
  1. package/dist/agents/conversation-agent.d.ts +12 -11
  2. package/dist/agents/conversation-agent.js +30 -33
  3. package/dist/agents/report-builder.js +2 -1
  4. package/dist/agents/sandbox/bulk-transcriptomics-agent.js +1 -1
  5. package/dist/agents/sandbox/cheminformatics-agent.js +1 -19
  6. package/dist/agents/sandbox/chromatin-agent.js +1 -10
  7. package/dist/agents/sandbox/dna-methylation-agent.js +1 -10
  8. package/dist/agents/sandbox/drug-repurposing-agent.js +4 -14
  9. package/dist/agents/sandbox/enrichment-agent.js +1 -10
  10. package/dist/agents/sandbox/ephemeral-executor.js +1 -10
  11. package/dist/agents/sandbox/genomic-variant-agent.js +1 -3
  12. package/dist/agents/sandbox/immune-profiling-agent.js +1 -13
  13. package/dist/agents/sandbox/metabolomics-agent.js +1 -1
  14. package/dist/agents/sandbox/microbiome-agent.js +1 -1
  15. package/dist/agents/sandbox/multi-omics-integration-agent.js +1 -12
  16. package/dist/agents/sandbox/multimodal-sc-agent.js +1 -1
  17. package/dist/agents/sandbox/network-agent.js +1 -10
  18. package/dist/agents/sandbox/pkpd-clinical-response-agent.js +2 -8
  19. package/dist/agents/sandbox/proteomics-agent.js +1 -1
  20. package/dist/agents/sandbox/scientific-executor.js +1 -10
  21. package/dist/agents/sandbox/shared.d.ts +17 -6
  22. package/dist/agents/sandbox/shared.js +49 -38
  23. package/dist/agents/sandbox/single-cell-agent.js +1 -1
  24. package/dist/agents/sandbox/spatial-omics-agent.js +1 -1
  25. package/dist/agents/sandbox/statistical-modeling-agent.js +1 -1
  26. package/dist/agents/sandbox/translational-safety-agent.js +3 -9
  27. package/dist/agents/sandbox/types.d.ts +1 -1
  28. package/dist/agents/system-prompt.d.ts +37 -11
  29. package/dist/agents/system-prompt.js +35 -12
  30. package/dist/app/data-profile-orientation.d.ts +34 -0
  31. package/dist/app/data-profile-orientation.js +117 -0
  32. package/dist/contracts/schemas/chat-parts.d.ts +9 -9
  33. package/dist/execution/artifact-metadata.js +2 -1
  34. package/dist/execution/ephemeral-runner.d.ts +13 -0
  35. package/dist/execution/ephemeral-runner.js +23 -1
  36. package/dist/execution/run-synthesis.js +20 -19
  37. package/dist/execution/step-summary.js +2 -1
  38. package/dist/index.d.ts +6 -2
  39. package/dist/index.js +19 -5
  40. package/dist/loop/__fixtures__/scripted-provider.d.ts +2 -2
  41. package/dist/loop/__fixtures__/scripted-provider.js +2 -1
  42. package/dist/loop/metrics.d.ts +33 -1
  43. package/dist/loop/metrics.js +56 -2
  44. package/dist/loop/run-agent.d.ts +13 -1
  45. package/dist/loop/run-agent.js +19 -4
  46. package/dist/memory/card-builders.d.ts +8 -1
  47. package/dist/memory/card-builders.js +20 -3
  48. package/dist/memory/reconstruct-cards.js +4 -3
  49. package/dist/memory/thread-history.d.ts +27 -2
  50. package/dist/memory/thread-history.js +45 -5
  51. package/dist/memory/working-memory.d.ts +93 -10
  52. package/dist/memory/working-memory.js +220 -84
  53. package/dist/prompts/SOUL.d.ts +22 -9
  54. package/dist/prompts/SOUL.js +56 -37
  55. package/dist/prompts/analogical-reasoner.d.ts +1 -1
  56. package/dist/prompts/analogical-reasoner.js +2 -2
  57. package/dist/prompts/briefing.d.ts +100 -0
  58. package/dist/prompts/briefing.js +166 -0
  59. package/dist/prompts/conversation.d.ts +1 -1
  60. package/dist/prompts/conversation.js +94 -440
  61. package/dist/prompts/literature-reviewer.d.ts +1 -1
  62. package/dist/prompts/literature-reviewer.js +10 -10
  63. package/dist/prompts/planner.js +28 -59
  64. package/dist/prompts/report-builder.d.ts +1 -1
  65. package/dist/prompts/report-builder.js +71 -24
  66. package/dist/prompts/sandbox/bulk-transcriptomics-agent.d.ts +1 -1
  67. package/dist/prompts/sandbox/bulk-transcriptomics-agent.js +2 -7
  68. package/dist/prompts/sandbox/cheminformatics-agent.d.ts +1 -1
  69. package/dist/prompts/sandbox/cheminformatics-agent.js +11 -15
  70. package/dist/prompts/sandbox/chromatin-agent.d.ts +1 -1
  71. package/dist/prompts/sandbox/chromatin-agent.js +3 -7
  72. package/dist/prompts/sandbox/data-profiler.d.ts +1 -1
  73. package/dist/prompts/sandbox/data-profiler.js +13 -8
  74. package/dist/prompts/sandbox/dna-methylation-agent.d.ts +1 -1
  75. package/dist/prompts/sandbox/dna-methylation-agent.js +2 -7
  76. package/dist/prompts/sandbox/drug-repurposing-agent.d.ts +1 -1
  77. package/dist/prompts/sandbox/drug-repurposing-agent.js +15 -16
  78. package/dist/prompts/sandbox/enrichment-agent.d.ts +1 -1
  79. package/dist/prompts/sandbox/enrichment-agent.js +2 -9
  80. package/dist/prompts/sandbox/genomic-variant-agent.d.ts +1 -1
  81. package/dist/prompts/sandbox/genomic-variant-agent.js +2 -6
  82. package/dist/prompts/sandbox/immune-profiling-agent.d.ts +1 -1
  83. package/dist/prompts/sandbox/immune-profiling-agent.js +3 -8
  84. package/dist/prompts/sandbox/metabolomics-agent.d.ts +1 -1
  85. package/dist/prompts/sandbox/metabolomics-agent.js +1 -7
  86. package/dist/prompts/sandbox/microbiome-agent.d.ts +1 -1
  87. package/dist/prompts/sandbox/microbiome-agent.js +2 -7
  88. package/dist/prompts/sandbox/multi-omics-integration-agent.d.ts +1 -1
  89. package/dist/prompts/sandbox/multi-omics-integration-agent.js +2 -8
  90. package/dist/prompts/sandbox/multimodal-sc-agent.d.ts +1 -1
  91. package/dist/prompts/sandbox/multimodal-sc-agent.js +2 -7
  92. package/dist/prompts/sandbox/network-agent.d.ts +1 -1
  93. package/dist/prompts/sandbox/network-agent.js +2 -7
  94. package/dist/prompts/sandbox/proteomics-agent.d.ts +1 -1
  95. package/dist/prompts/sandbox/proteomics-agent.js +2 -9
  96. package/dist/prompts/sandbox/single-cell-agent.d.ts +1 -1
  97. package/dist/prompts/sandbox/single-cell-agent.js +2 -9
  98. package/dist/prompts/sandbox/spatial-omics-agent.d.ts +1 -1
  99. package/dist/prompts/sandbox/spatial-omics-agent.js +3 -6
  100. package/dist/prompts/sandbox/statistical-modeling-agent.d.ts +1 -1
  101. package/dist/prompts/sandbox/statistical-modeling-agent.js +2 -7
  102. package/dist/prompts/sandbox/translational-safety-agent.d.ts +1 -1
  103. package/dist/prompts/sandbox/translational-safety-agent.js +13 -14
  104. package/dist/prompts/sandbox-standards.d.ts +22 -14
  105. package/dist/prompts/sandbox-standards.js +91 -71
  106. package/dist/prompts/synthesis-agent.d.ts +1 -1
  107. package/dist/prompts/synthesis-agent.js +33 -131
  108. package/dist/provenance/collector.js +1 -1
  109. package/dist/providers/ai-sdk.js +31 -4
  110. package/dist/providers/prompt-cache.d.ts +74 -0
  111. package/dist/providers/prompt-cache.js +77 -0
  112. package/dist/providers/types.d.ts +33 -0
  113. package/dist/reference-data/catalog.d.ts +131 -0
  114. package/dist/reference-data/catalog.js +348 -0
  115. package/dist/reference-data/receipt.d.ts +41 -0
  116. package/dist/reference-data/receipt.js +40 -0
  117. package/dist/schemas/data-profile-schemas.js +5 -3
  118. package/dist/schemas/plan-schemas.d.ts +21 -21
  119. package/dist/schemas/plan-schemas.js +9 -3
  120. package/dist/schemas/run-synthesis.d.ts +8 -4
  121. package/dist/schemas/run-synthesis.js +92 -56
  122. package/dist/schemas/validate-plan.js +1 -1
  123. package/dist/schemas/workflow-state.d.ts +7 -1
  124. package/dist/schemas/workflow-state.js +33 -19
  125. package/dist/state/artifacts.d.ts +13 -0
  126. package/dist/state/artifacts.js +27 -0
  127. package/dist/state/data-profile.d.ts +64 -5
  128. package/dist/state/index.d.ts +3 -3
  129. package/dist/state/index.js +1 -1
  130. package/dist/tasks/data-profile.d.ts +20 -2
  131. package/dist/tasks/data-profile.js +71 -22
  132. package/dist/tools/bio/chembl.d.ts +38 -0
  133. package/dist/tools/bio/chembl.js +138 -0
  134. package/dist/tools/bio/comptox.d.ts +50 -0
  135. package/dist/tools/bio/comptox.js +149 -0
  136. package/dist/tools/bio/get-impc-ko-profile.js +9 -6
  137. package/dist/tools/bio/index.d.ts +5 -17
  138. package/dist/tools/bio/index.js +5 -17
  139. package/dist/tools/bio/keys.d.ts +14 -9
  140. package/dist/tools/bio/keys.js +16 -16
  141. package/dist/tools/bio/opentargets.d.ts +38 -0
  142. package/dist/tools/bio/opentargets.js +89 -0
  143. package/dist/tools/bio/pubchem.d.ts +29 -0
  144. package/dist/tools/bio/pubchem.js +92 -0
  145. package/dist/tools/bio/pubmed.d.ts +51 -0
  146. package/dist/tools/bio/pubmed.js +100 -0
  147. package/dist/tools/bio/search-bgee-expression.js +12 -6
  148. package/dist/tools/bio/search-clinical-trials.js +16 -5
  149. package/dist/tools/bio/search-faers.js +8 -4
  150. package/dist/tools/bio/search-geo-datasets.js +20 -6
  151. package/dist/tools/bio/search-gwas-catalog.d.ts +1 -1
  152. package/dist/tools/bio/search-pharmgkb.js +10 -4
  153. package/dist/tools/display/index.d.ts +1 -0
  154. package/dist/tools/display/index.js +1 -0
  155. package/dist/tools/display/normalize-echart-spec.d.ts +61 -0
  156. package/dist/tools/display/normalize-echart-spec.js +211 -0
  157. package/dist/tools/display/show-user.d.ts +6 -1
  158. package/dist/tools/display/show-user.js +25 -12
  159. package/dist/tools/execute-plan.js +5 -2
  160. package/dist/tools/iterate-report.d.ts +168 -118
  161. package/dist/tools/iterate-report.js +334 -96
  162. package/dist/tools/lib/chembl-client.d.ts +12 -0
  163. package/dist/tools/lib/chembl-client.js +127 -0
  164. package/dist/tools/lib/ctx-ops.d.ts +224 -0
  165. package/dist/tools/lib/ctx-ops.js +450 -0
  166. package/dist/tools/lib/iuphar-client.js +10 -1
  167. package/dist/tools/lib/openfda-client.js +11 -3
  168. package/dist/tools/lib/pathway-client.js +10 -4
  169. package/dist/tools/lib/pubchem-ops.d.ts +74 -0
  170. package/dist/tools/lib/pubchem-ops.js +224 -0
  171. package/dist/tools/memory/update-working-memory.d.ts +45 -7
  172. package/dist/tools/memory/update-working-memory.js +111 -41
  173. package/dist/tools/report/index.d.ts +3 -2
  174. package/dist/tools/report/index.js +3 -2
  175. package/dist/tools/research/generate-analogy-report.js +25 -12
  176. package/dist/tools/research/generate-plan.d.ts +12 -5
  177. package/dist/tools/research/generate-plan.js +168 -37
  178. package/dist/tools/research/index.d.ts +1 -0
  179. package/dist/tools/research/index.js +1 -0
  180. package/dist/tools/research/inspect-data-profile.d.ts +85 -0
  181. package/dist/tools/research/inspect-data-profile.js +161 -0
  182. package/dist/tools/research/literature-reviewer.js +3 -4
  183. package/dist/tools/sandbox/list-available-packages.d.ts +79 -5
  184. package/dist/tools/sandbox/list-available-packages.js +152 -10
  185. package/dist/tools/sandbox/list-available-refs.d.ts +141 -5
  186. package/dist/tools/sandbox/list-available-refs.js +647 -134
  187. package/dist/tools/sandbox/report-blocker.d.ts +39 -9
  188. package/dist/tools/sandbox/report-blocker.js +43 -20
  189. package/dist/tools/workspace/read-file.js +4 -5
  190. package/dist/tools/workspace/run-exec.d.ts +4 -4
  191. package/dist/tools/workspace/run-exec.js +4 -4
  192. package/dist/tools/workspace/show-file.js +10 -6
  193. package/dist/tools/workspace/show-plan.js +12 -6
  194. package/dist/tools/workspace/workspace-search.d.ts +1 -1
  195. package/dist/tools/workspace/workspace-search.js +11 -5
  196. package/dist/workflows/execute-analysis.d.ts +43 -4
  197. package/dist/workflows/execute-analysis.js +107 -6
  198. package/dist/workflows/target-assessment/lib/citation-validator.js +2 -2
  199. package/dist/workflows/target-assessment/lib/clinical-consequence-annotator.js +2 -1
  200. package/dist/workspace/paths.d.ts +2 -2
  201. package/dist/workspace/paths.js +2 -2
  202. package/package.json +33 -33
  203. package/dist/execution/filesystem-artifact-registry.d.ts +0 -57
  204. package/dist/execution/filesystem-artifact-registry.js +0 -92
  205. package/dist/lib/identifiers.d.ts +0 -8
  206. package/dist/lib/identifiers.js +0 -10
  207. package/dist/lib/mime-detect.d.ts +0 -17
  208. package/dist/lib/mime-detect.js +0 -29
  209. package/dist/lib/streamed-download.d.ts +0 -28
  210. package/dist/lib/streamed-download.js +0 -111
  211. package/dist/lib/trace-context.d.ts +0 -11
  212. package/dist/lib/trace-context.js +0 -49
  213. package/dist/providers/llm-capabilities.d.ts +0 -33
  214. package/dist/providers/llm-capabilities.js +0 -58
  215. package/dist/schemas/render-step-prompt.d.ts +0 -32
  216. package/dist/schemas/render-step-prompt.js +0 -76
  217. package/dist/tools/bio/find-approval-precedent.d.ts +0 -32
  218. package/dist/tools/bio/find-approval-precedent.js +0 -72
  219. package/dist/tools/bio/get-article-details.d.ts +0 -11
  220. package/dist/tools/bio/get-article-details.js +0 -20
  221. package/dist/tools/bio/get-article-full-text.d.ts +0 -19
  222. package/dist/tools/bio/get-article-full-text.js +0 -32
  223. package/dist/tools/bio/get-bioactivity.d.ts +0 -11
  224. package/dist/tools/bio/get-bioactivity.js +0 -23
  225. package/dist/tools/bio/get-drug-info.d.ts +0 -9
  226. package/dist/tools/bio/get-drug-info.js +0 -22
  227. package/dist/tools/bio/get-mechanism.d.ts +0 -8
  228. package/dist/tools/bio/get-mechanism.js +0 -18
  229. package/dist/tools/bio/get-pubchem-assays.d.ts +0 -22
  230. package/dist/tools/bio/get-pubchem-assays.js +0 -107
  231. package/dist/tools/bio/get-pubchem-cross-refs.d.ts +0 -15
  232. package/dist/tools/bio/get-pubchem-cross-refs.js +0 -68
  233. package/dist/tools/bio/get-target-safety.d.ts +0 -18
  234. package/dist/tools/bio/get-target-safety.js +0 -26
  235. package/dist/tools/bio/search-compounds.d.ts +0 -22
  236. package/dist/tools/bio/search-compounds.js +0 -160
  237. package/dist/tools/bio/search-ctx-chemical.d.ts +0 -50
  238. package/dist/tools/bio/search-ctx-chemical.js +0 -130
  239. package/dist/tools/bio/search-ctx-exposure.d.ts +0 -55
  240. package/dist/tools/bio/search-ctx-exposure.js +0 -176
  241. package/dist/tools/bio/search-ctx-hazard.d.ts +0 -111
  242. package/dist/tools/bio/search-ctx-hazard.js +0 -178
  243. package/dist/tools/bio/search-opentargets.d.ts +0 -11
  244. package/dist/tools/bio/search-opentargets.js +0 -25
  245. package/dist/tools/bio/search-pubchem-compound.d.ts +0 -26
  246. package/dist/tools/bio/search-pubchem-compound.js +0 -110
  247. package/dist/tools/bio/search-pubmed.d.ts +0 -17
  248. package/dist/tools/bio/search-pubmed.js +0 -31
  249. package/dist/tools/bio/search-targets.d.ts +0 -9
  250. package/dist/tools/bio/search-targets.js +0 -20
  251. package/dist/tools/bio/search-toxcast.d.ts +0 -36
  252. package/dist/tools/bio/search-toxcast.js +0 -141
  253. package/dist/workflows/register-workflows.d.ts +0 -51
  254. package/dist/workflows/register-workflows.js +0 -48
  255. package/dist/workflows/resume-execute-analysis.d.ts +0 -70
  256. package/dist/workflows/resume-execute-analysis.js +0 -80
  257. package/dist/workflows/target-assessment/correction-loop.d.ts +0 -45
  258. package/dist/workflows/target-assessment/correction-loop.js +0 -62
  259. package/dist/workflows/target-assessment/steps/phase0-resolve.d.ts +0 -71
  260. package/dist/workflows/target-assessment/steps/phase0-resolve.js +0 -21
  261. package/dist/workflows/target-assessment/steps/phase1-aggregate.d.ts +0 -1018
  262. package/dist/workflows/target-assessment/steps/phase1-aggregate.js +0 -25
  263. package/dist/workspace/mount-strategy.d.ts +0 -50
  264. package/dist/workspace/mount-strategy.js +0 -67
  265. package/dist/workspace/provenance-collector.d.ts +0 -34
  266. package/dist/workspace/provenance-collector.js +0 -16
  267. package/dist/workspace/workspace-paths.d.ts +0 -26
  268. package/dist/workspace/workspace-paths.js +0 -31
@@ -9,6 +9,11 @@
9
9
  * downstream reconciliation concern of the emit pipeline (change 3), not a
10
10
  * per-request `Set` smuggled through an ambient context bag.
11
11
  *
12
+ * An `echart` spec's layout is normalized (`normalize-echart-spec.ts`) inside
13
+ * `buildPresentationCardData`, the one construction site both this tool and the
14
+ * reconstruct-on-read path share — the model authors the data, the renderer owns
15
+ * the layout.
16
+ *
12
17
  * For stored plans, use `show_plan`. For existing files, use `show_file`.
13
18
  */
14
19
  import { ok } from "neverthrow";
@@ -22,12 +27,18 @@ import { validatePath } from "../lib/path-validation.js";
22
27
  // LLM picks the right ones based on `kind`.
23
28
  const ShowUserInputSchema = z.object({
24
29
  kind: z.enum(["echart", "markdown", "code", "svg", "table"]).describe("The type of agent-synthesized content to display"),
25
- title: z.string().optional().describe("Title shown above the content"),
26
- spec: z.record(z.string(), z.unknown()).optional().describe("Full ECharts option spec as JSON (kind=echart)"),
30
+ title: z
31
+ .string()
32
+ .optional()
33
+ .describe("Card heading rendered above the content. For an echart it is the chart's only title, and it seeds the PNG download filename."),
34
+ spec: z
35
+ .record(z.string(), z.unknown())
36
+ .optional()
37
+ .describe("Full ECharts option JSON (kind=echart). Author the data, series, `encode`, and tooltip — and OMIT `title`: the card heading is the `title` param, so an in-spec title is stripped (put stats in `tooltip.formatter`, never in `title.subtext`). Layout is normalized for you at render time (legend placement, grid margins, `axisLabel.interval`/rotation, and a PNG `saveAsImage` toolbox), so do not hand-tune it."),
27
38
  dataPath: z
28
39
  .string()
29
40
  .optional()
30
- .describe("echart only: analysis-rooted CSV artifact path (e.g. 'runs/run-abc/step-2/output/de-summary.csv') the host loads as the ECharts `dataset.source` at render time. Author `encode`/dimensions against the CSV's column names and omit `dataset.source` from the spec — the data is never pulled through the context window."),
41
+ .describe("echart only: analysis-rooted CSV artifact path (e.g. 'runs/run-abc/step-2/output/de-summary.csv') the host loads as the ECharts `dataset.source` at render time. Author `encode`/dimensions against the CSV's column names (read only its header) and omit `dataset.source` from the spec — the rows are never pulled through the context window. If the data is not chart-ready (needs aggregation, filtering, reshaping), do that in a sandbox step that writes a chart-ready CSV. Inline `dataset.source` is only for a handful of numbers you just computed in conversation that exist nowhere as an artifact."),
31
42
  body: z.string().optional().describe("Markdown content to render (kind=markdown)"),
32
43
  code: z.string().optional().describe("Code content (kind=code)"),
33
44
  language: z.string().optional().describe("Language identifier, e.g. r, python, bash (kind=code)"),
@@ -38,15 +49,17 @@ const ShowUserInputSchema = z.object({
38
49
  });
39
50
  export const showUserTool = defineTool({
40
51
  id: "show_user",
41
- description: "Display agent-synthesized content to the user: ECharts visualizations, " +
42
- "markdown, code blocks, SVG diagrams, or tables. " +
43
- "Use for content you are INVENTING (a chart you just built, a code snippet you are proposing, " +
44
- "a markdown synthesis, a table you constructed). " +
45
- "For an echart backed by a chart-ready CSV artifact a step already wrote, pass `dataPath` (analysis-rooted) " +
46
- "and author `encode`/dimensions by column name with no `dataset.source` — the host loads the CSV as the " +
47
- "dataset at render time, so you never inline the rows. " +
48
- "For stored plans, use `show_plan`. For existing analysis files (images, CSVs, etc.), use `show_file`. " +
49
- "Call once per distinct content item; an identical repeat call resolves to the same card.",
52
+ description: "Display content you are INVENTING — a chart you composed, a code snippet you are proposing, a markdown " +
53
+ "synthesis, an SVG diagram, a table you built. The content is inlined on the wire. " +
54
+ "Pick this tool by what you are referencing, not by how the output looks: " +
55
+ "NOT for an existing analysis file — never read an artifact and paste its bytes here, reference it with `show_file` " +
56
+ "(images, CSVs, PDFs, notebooks). NOT for a stored plan — use `show_plan`. " +
57
+ "NEVER put markdown image syntax pointing at a workspace file in a `markdown` body: `![](runs/.../volcano.png)` " +
58
+ "renders as a broken image, because the chat UI cannot resolve workspace-relative paths. To interleave figures " +
59
+ "with prose (a write-up, a narrative summary), emit a SEQUENCE of cards in display order — `show_user(markdown)` " +
60
+ "for a prose section, then `show_file` for the figures that follow it, and so on — instead of one monolithic card. " +
61
+ "One card per call, rendered in call order; an identical repeat call resolves to the same card, so compose the " +
62
+ "finished content before calling rather than re-rendering a draft.",
50
63
  inputSchema: ShowUserInputSchema,
51
64
  execute: async (input, ctx) => {
52
65
  // `dataPath` is a reference the host resolves at render time; validate its
@@ -32,7 +32,6 @@ import { buildRunCardData } from "../memory/card-builders.js";
32
32
  import { unwrapOrThrow } from "../lib/result.js";
33
33
  import { validatePlan } from "../schemas/validate-plan.js";
34
34
  import { AnalysisPlanSchema } from "../schemas/workflow-state.js";
35
- import { renderStepPrompt } from "../schemas/render-step-prompt.js";
36
35
  import { RunDedupCollisionError, insertRun, loadPlan, queryActiveRun, updateRunStatus } from "../state/index.js";
37
36
  import { defineTool } from "./define-tool.js";
38
37
  const planIdSchema = z.string().regex(/^pln-[a-f0-9]{8}$/, "planId must be a pln-<8hex> value");
@@ -177,7 +176,11 @@ export function createExecutePlanTool(deps) {
177
176
  id: s.id,
178
177
  depends_on: s.depends_on ?? [],
179
178
  })),
180
- promptByStepId: Object.fromEntries(plan.steps.map((s) => [s.id, renderStepPrompt(s)])),
179
+ // The step DATA, not a rendered prompt: each step's seed is composed
180
+ // by the scheduler at dispatch, when its dependencies' results exist.
181
+ // A prompt frozen here — before the first step has run — could never
182
+ // mention them.
183
+ planStepById: Object.fromEntries(plan.steps.map((s) => [s.id, s])),
181
184
  agentByStepId: Object.fromEntries(plan.steps.map((s) => [s.id, s.agent ?? "unknown"])),
182
185
  resourcesByStepId: Object.fromEntries(plan.steps.map((s) => {
183
186
  if (!s.resources) {
@@ -1,23 +1,43 @@
1
1
  /**
2
- * iterate_report — creates or iterates on a report.
2
+ * Report authoring tools for the conversation agent: `plan_report` + `submit_report`.
3
3
  *
4
- * Two modes:
5
- * - Creation (v1): pass `report` with title/audience/sources/sections.
6
- * Pre-flight stages every source into the preview's assets/ dir,
7
- * enriches the brief with kind/size/columns/headRows/rowCount, and
8
- * hands the report-builder agent a complete brief — no discovery, no
9
- * staging in the LLM loop.
10
- * - Iteration (v2+): pass `modifications` (natural language) with the
11
- * existing `previewId`. Optional top-level `sources` adds new assets
12
- * on top of the existing assets/ dir.
4
+ * WHY TWO TOOLS. The report brief (title/audience/sources plus the section
5
+ * union — narrative/metrics/figure/table/chart, each with its own
6
+ * encoding/transform/asset sub-fields) is a ~12k-char JSON schema. Every
7
+ * registered tool's schema ships on EVERY conversation turn, so parking that
8
+ * brief on an always-on tool would tax every turn for a tool used only when a
9
+ * report is actually built. We split the single former tool in two and deliver
10
+ * the heavy schema just-in-time:
13
11
  *
14
- * Emits a `data-report-preview` chat data part on success or `data-report-preview-failed`
15
- * on pre-flight or builder failure. The hosted preview surface is reached
16
- * through an injected `PreviewPublisher` seam (managed default mints a
17
- * short-lived run-authorization grant; local default returns "unavailable").
12
+ * - `plan_report` — a tiny, always-on trigger (no-arg). Its `execute` RETURNS
13
+ * the brief schema (`z.toJSONSchema(ReportBriefSchema)`) plus the authoring
14
+ * rules as its tool RESULT, so the full contract enters context only on a
15
+ * report-building turn — and thereafter rides in the cached history prefix,
16
+ * not at full price on every request.
17
+ * - `submit_report` — takes the composed brief and does the real work
18
+ * (pre-flight staging, previewId/versioning, `runReportIteration`, preview
19
+ * publishing). It accepts the brief as `unknown` so the 12k schema stays off
20
+ * the always-on surface, then validates it against `ReportBriefSchema` INSIDE
21
+ * `execute`, returning `{ ok: false, issues }` as DATA the model can fix (not
22
+ * a thrown error). That is the same trade `validate_plan` makes: a runtime
23
+ * contract in exchange for keeping the schema out of every request. The small
24
+ * iterate-mode + common fields (modifications / previewId / baseVersion /
25
+ * sources / format) stay fully typed — they cost little and guide iteration.
18
26
  *
19
- * The 4 custom report tools the builder drives are constructed inside
20
- * `runReportIteration` — see design.md Decision #9.
27
+ * On a valid brief, `submit_report`'s behaviour is identical to the former
28
+ * `iterate_report`: two modes (Create v1 via `report`; Iterate v2+ via
29
+ * `modifications` + `previewId`), pre-flight stages every source into the
30
+ * preview's assets/ dir, and it emits a `data-report-preview` chat data part on
31
+ * success or `data-report-preview-failed` on pre-flight/builder failure. The
32
+ * hosted preview surface is reached through an injected `PreviewPublisher` seam
33
+ * (managed default mints a short-lived run-authorization grant; local default
34
+ * returns "unavailable"). The 4 custom report tools the builder drives are
35
+ * constructed inside `runReportIteration` — see design.md Decision #9.
36
+ *
37
+ * Naming note: the report-builder SUB-agent has its OWN same-id `submit_report`
38
+ * terminal tool (`tools/report/submit-report.ts`). The two never share a tool
39
+ * roster — this one is the conversation agent's brief-submission entry point;
40
+ * that one is the builder's finalize gate.
21
41
  */
22
42
  import type { Pool } from "pg";
23
43
  import { z } from "zod";
@@ -27,119 +47,142 @@ import { type ResolveWorkspaceRoot } from "../workspace/paths.js";
27
47
  import { type StagedAsset } from "./lib/report-preflight.js";
28
48
  import type { PreviewPublisher } from "./report/preview-publisher.js";
29
49
  import type { ChromeConfig } from "../lib/chrome.js";
30
- /** Exported for schema-validation tests — the underlying Zod schema. */
31
- export declare const iterateReportInputSchema: z.ZodObject<{
50
+ /**
51
+ * The report brief the conversation agent composes: title/audience + sources +
52
+ * the section union. This is the ~12k-char schema that `plan_report` hands back
53
+ * just-in-time and that `submit_report` validates its `report` field against
54
+ * inside `execute`. Exported for `plan_report`, `submit_report`, and the
55
+ * brief-shape tests.
56
+ */
57
+ export declare const ReportBriefSchema: z.ZodObject<{
58
+ title: z.ZodString;
59
+ audience: z.ZodString;
60
+ styleGuidance: z.ZodOptional<z.ZodString>;
61
+ sources: z.ZodDefault<z.ZodArray<z.ZodObject<{
62
+ path: z.ZodString;
63
+ as: z.ZodOptional<z.ZodString>;
64
+ }, z.core.$strip>>>;
65
+ sections: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
66
+ type: z.ZodLiteral<"narrative">;
67
+ title: z.ZodString;
68
+ intent: z.ZodString;
69
+ content: z.ZodObject<{
70
+ prose: z.ZodString;
71
+ }, z.core.$strip>;
72
+ }, z.core.$strip>, z.ZodObject<{
73
+ type: z.ZodLiteral<"metrics">;
74
+ title: z.ZodString;
75
+ intent: z.ZodString;
76
+ content: z.ZodObject<{
77
+ stats: z.ZodArray<z.ZodObject<{
78
+ label: z.ZodString;
79
+ value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
80
+ unit: z.ZodOptional<z.ZodString>;
81
+ }, z.core.$strip>>;
82
+ }, z.core.$strip>;
83
+ }, z.core.$strip>, z.ZodObject<{
84
+ type: z.ZodLiteral<"figure">;
85
+ title: z.ZodString;
86
+ intent: z.ZodString;
87
+ content: z.ZodObject<{
88
+ imageAsset: z.ZodString;
89
+ caption: z.ZodOptional<z.ZodString>;
90
+ }, z.core.$strip>;
91
+ }, z.core.$strip>, z.ZodObject<{
92
+ type: z.ZodLiteral<"table">;
93
+ title: z.ZodString;
94
+ intent: z.ZodString;
95
+ content: z.ZodObject<{
96
+ dataAsset: z.ZodString;
97
+ columns: z.ZodOptional<z.ZodArray<z.ZodString>>;
98
+ topN: z.ZodOptional<z.ZodNumber>;
99
+ sortBy: z.ZodOptional<z.ZodObject<{
100
+ column: z.ZodString;
101
+ order: z.ZodEnum<{
102
+ desc: "desc";
103
+ asc: "asc";
104
+ }>;
105
+ }, z.core.$strip>>;
106
+ transform: z.ZodOptional<z.ZodString>;
107
+ caption: z.ZodOptional<z.ZodString>;
108
+ }, z.core.$strip>;
109
+ }, z.core.$strip>, z.ZodObject<{
110
+ type: z.ZodLiteral<"chart">;
111
+ title: z.ZodString;
112
+ intent: z.ZodString;
113
+ content: z.ZodObject<{
114
+ dataAsset: z.ZodOptional<z.ZodString>;
115
+ data: z.ZodOptional<z.ZodObject<{
116
+ columns: z.ZodArray<z.ZodString>;
117
+ rows: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>>>;
118
+ source: z.ZodString;
119
+ }, z.core.$strip>>;
120
+ chartType: z.ZodEnum<{
121
+ line: "line";
122
+ bar: "bar";
123
+ scatter: "scatter";
124
+ histogram: "histogram";
125
+ box: "box";
126
+ heatmap: "heatmap";
127
+ pie: "pie";
128
+ }>;
129
+ encoding: z.ZodObject<{
130
+ x: z.ZodOptional<z.ZodString>;
131
+ y: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
132
+ group: z.ZodOptional<z.ZodString>;
133
+ value: z.ZodOptional<z.ZodString>;
134
+ }, z.core.$strip>;
135
+ topN: z.ZodOptional<z.ZodNumber>;
136
+ sortBy: z.ZodOptional<z.ZodObject<{
137
+ column: z.ZodString;
138
+ order: z.ZodEnum<{
139
+ desc: "desc";
140
+ asc: "asc";
141
+ }>;
142
+ }, z.core.$strip>>;
143
+ transform: z.ZodOptional<z.ZodString>;
144
+ caption: z.ZodOptional<z.ZodString>;
145
+ }, z.core.$strip>;
146
+ }, z.core.$strip>, z.ZodObject<{
147
+ type: z.ZodLiteral<"methods">;
148
+ title: z.ZodString;
149
+ intent: z.ZodString;
150
+ content: z.ZodObject<{
151
+ prose: z.ZodString;
152
+ }, z.core.$strip>;
153
+ }, z.core.$strip>], "type">>;
154
+ }, z.core.$strip>;
155
+ /**
156
+ * `submit_report`'s always-on input surface. The heavy brief rides in `report`
157
+ * as `unknown` — typed that way ON PURPOSE so the ~12k `ReportBriefSchema` does
158
+ * NOT ship on every conversation turn; `execute` validates it against
159
+ * `ReportBriefSchema` and returns issues as data. The iterate-mode + common
160
+ * fields stay fully typed (they are small and guide iteration). Exported for
161
+ * the envelope-validation tests.
162
+ */
163
+ export declare const submitReportInputSchema: z.ZodObject<{
32
164
  previewId: z.ZodOptional<z.ZodString>;
33
165
  baseVersion: z.ZodOptional<z.ZodNumber>;
34
166
  format: z.ZodDefault<z.ZodEnum<{
35
167
  html: "html";
36
168
  pdf: "pdf";
37
169
  }>>;
38
- report: z.ZodOptional<z.ZodObject<{
39
- title: z.ZodString;
40
- audience: z.ZodString;
41
- styleGuidance: z.ZodOptional<z.ZodString>;
42
- sources: z.ZodDefault<z.ZodArray<z.ZodObject<{
43
- path: z.ZodString;
44
- as: z.ZodOptional<z.ZodString>;
45
- }, z.core.$strip>>>;
46
- sections: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
47
- type: z.ZodLiteral<"narrative">;
48
- title: z.ZodString;
49
- intent: z.ZodString;
50
- content: z.ZodObject<{
51
- prose: z.ZodString;
52
- }, z.core.$strip>;
53
- }, z.core.$strip>, z.ZodObject<{
54
- type: z.ZodLiteral<"metrics">;
55
- title: z.ZodString;
56
- intent: z.ZodString;
57
- content: z.ZodObject<{
58
- stats: z.ZodArray<z.ZodObject<{
59
- label: z.ZodString;
60
- value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
61
- unit: z.ZodOptional<z.ZodString>;
62
- }, z.core.$strip>>;
63
- }, z.core.$strip>;
64
- }, z.core.$strip>, z.ZodObject<{
65
- type: z.ZodLiteral<"figure">;
66
- title: z.ZodString;
67
- intent: z.ZodString;
68
- content: z.ZodObject<{
69
- imageAsset: z.ZodString;
70
- caption: z.ZodOptional<z.ZodString>;
71
- }, z.core.$strip>;
72
- }, z.core.$strip>, z.ZodObject<{
73
- type: z.ZodLiteral<"table">;
74
- title: z.ZodString;
75
- intent: z.ZodString;
76
- content: z.ZodObject<{
77
- dataAsset: z.ZodString;
78
- columns: z.ZodOptional<z.ZodArray<z.ZodString>>;
79
- topN: z.ZodOptional<z.ZodNumber>;
80
- sortBy: z.ZodOptional<z.ZodObject<{
81
- column: z.ZodString;
82
- order: z.ZodEnum<{
83
- desc: "desc";
84
- asc: "asc";
85
- }>;
86
- }, z.core.$strip>>;
87
- transform: z.ZodOptional<z.ZodString>;
88
- caption: z.ZodOptional<z.ZodString>;
89
- }, z.core.$strip>;
90
- }, z.core.$strip>, z.ZodObject<{
91
- type: z.ZodLiteral<"chart">;
92
- title: z.ZodString;
93
- intent: z.ZodString;
94
- content: z.ZodObject<{
95
- dataAsset: z.ZodOptional<z.ZodString>;
96
- data: z.ZodOptional<z.ZodObject<{
97
- columns: z.ZodArray<z.ZodString>;
98
- rows: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>>>;
99
- source: z.ZodString;
100
- }, z.core.$strip>>;
101
- chartType: z.ZodEnum<{
102
- line: "line";
103
- bar: "bar";
104
- scatter: "scatter";
105
- histogram: "histogram";
106
- box: "box";
107
- heatmap: "heatmap";
108
- pie: "pie";
109
- }>;
110
- encoding: z.ZodObject<{
111
- x: z.ZodOptional<z.ZodString>;
112
- y: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
113
- group: z.ZodOptional<z.ZodString>;
114
- value: z.ZodOptional<z.ZodString>;
115
- }, z.core.$strip>;
116
- topN: z.ZodOptional<z.ZodNumber>;
117
- sortBy: z.ZodOptional<z.ZodObject<{
118
- column: z.ZodString;
119
- order: z.ZodEnum<{
120
- desc: "desc";
121
- asc: "asc";
122
- }>;
123
- }, z.core.$strip>>;
124
- transform: z.ZodOptional<z.ZodString>;
125
- caption: z.ZodOptional<z.ZodString>;
126
- }, z.core.$strip>;
127
- }, z.core.$strip>, z.ZodObject<{
128
- type: z.ZodLiteral<"methods">;
129
- title: z.ZodString;
130
- intent: z.ZodString;
131
- content: z.ZodObject<{
132
- prose: z.ZodString;
133
- }, z.core.$strip>;
134
- }, z.core.$strip>], "type">>;
135
- }, z.core.$strip>>;
170
+ report: z.ZodOptional<z.ZodUnknown>;
136
171
  modifications: z.ZodOptional<z.ZodString>;
137
172
  sources: z.ZodOptional<z.ZodArray<z.ZodObject<{
138
173
  path: z.ZodString;
139
174
  as: z.ZodOptional<z.ZodString>;
140
175
  }, z.core.$strip>>>;
141
176
  }, z.core.$strip>;
142
- export interface IterateReportDeps {
177
+ /**
178
+ * `plan_report` — the tiny, always-on trigger (no args). Its result delivers
179
+ * the brief schema + authoring rules just-in-time, so the ~12k contract enters
180
+ * context only on a report-building turn (and thereafter rides in the cached
181
+ * history prefix). Compose the brief from what it returns, then call
182
+ * `submit_report`. Pure logic, no deps — hence a module-scope leaf tool.
183
+ */
184
+ export declare const planReportTool: Tool;
185
+ export interface SubmitReportDeps {
143
186
  readonly provider: ChatProvider;
144
187
  readonly pool: Pool;
145
188
  /** Embedder-supplied workspace-root resolution seam (see workspace/paths.ts). */
@@ -165,7 +208,14 @@ export interface IterateReportDeps {
165
208
  ttlSeconds: number;
166
209
  }) => Promise<PreviewPublisher>;
167
210
  }
168
- export declare function createIterateReportTool(deps: IterateReportDeps): Tool;
211
+ /**
212
+ * `submit_report` — takes the composed brief and drives the report iteration.
213
+ * On a valid brief its behaviour is byte-for-byte the former `iterate_report`:
214
+ * pre-flight staging, previewId/versioning, `runReportIteration`, preview
215
+ * publishing. The brief rides as `unknown` on the wire (keeping its ~12k schema
216
+ * off the always-on surface) and is validated against `ReportBriefSchema` here.
217
+ */
218
+ export declare function createReportSubmitTool(deps: SubmitReportDeps): Tool;
169
219
  /** Exported for unit tests — pipe-escape correctness. */
170
220
  export declare function stagedAssetsBlock(staged: StagedAsset[], opts?: {
171
221
  newOnly?: boolean;