@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
package/README.md CHANGED
@@ -36,7 +36,6 @@ import {
36
36
  createNoopRunCharge, // RunCharge seam
37
37
  createNoopUsageRecorder, // UsageRecorder seam
38
38
  createNoopArtifactRegistry, // ArtifactRegistry seam
39
- UnavailablePreviewPublisher, // PreviewPublisher seam
40
39
  createDbosRunLauncher, // shared RunLauncher
41
40
  createConsoleLogger, // Logger — writes to console
42
41
  createNoopLogger, // Logger — discards (the fallback when none is wired)
@@ -47,7 +46,7 @@ import {
47
46
  } from "@inflexa-ai/harness";
48
47
  ```
49
48
 
50
- `assembleCoreRuntime` is the single composition point: it registers the durable workflows and builds the conversation agent over them. The harness declares **six capability seams** an embedder wires — `RunAuthorizer`, `ResolveBilling`, `ArtifactRegistry`, `RunCharge`, `UsageRecorder`, `PreviewPublisher` — plus the **shared `RunLauncher`** (one host-neutral realization, `createDbosRunLauncher`). Local, dependency-free realizations of all six ship from the barrel; an embedder constructs them (or its own) and passes them in. The harness only ever sees the interface.
49
+ `assembleCoreRuntime` is the single composition point: it registers the durable workflows and builds the conversation agent over them. The harness declares **five capability seams** an embedder wires — `RunAuthorizer`, `ResolveBilling`, `ArtifactRegistry`, `RunCharge`, `UsageRecorder` — plus the **shared `RunLauncher`** (one host-neutral realization, `createDbosRunLauncher`). Local, dependency-free realizations of all five ship from the barrel; an embedder constructs them (or its own) and passes them in. The harness only ever sees the interface.
51
50
 
52
51
  ## Logging
53
52
 
@@ -35,7 +35,6 @@ import { type BioToolKeys } from "../tools/bio/keys.js";
35
35
  import type { EnvironmentStorePaths } from "../config/environment-stores.js";
36
36
  import type { RunAuthorizer } from "../execution/run-authorizer.js";
37
37
  import type { RunLauncher } from "../execution/run-launcher.js";
38
- import type { SubmitReportDeps } from "../tools/iterate-report.js";
39
38
  import type { Logger } from "../lib/logger.js";
40
39
  import type { UsageRecorder } from "../billing/usage-recorder.js";
41
40
  import type { CitationResolver } from "../citations/types.js";
@@ -98,16 +97,8 @@ export interface ConversationAgentDeps extends EnvironmentStorePaths {
98
97
  * workflows through it so the durability engine stays out of the tools.
99
98
  */
100
99
  readonly runLauncher: RunLauncher;
101
- /**
102
- * Preview-publishing seam factory. No tool of the roster reads it. The field
103
- * stays, because a change to the deps breaks an embedder at its composition
104
- * root.
105
- */
106
- readonly createPreviewPublisher: SubmitReportDeps["createPreviewPublisher"];
107
100
  /** API keys for the external bio/chem data sources. */
108
101
  readonly bioKeys: BioToolKeys;
109
- /** Root templates dir. No tool of the roster reads it. */
110
- readonly templatesDir: string;
111
102
  /** Skills root. No tool of the roster reads it. */
112
103
  readonly skillsDir: string;
113
104
  /** Headless-Chrome config for report snapshot/preview rendering. */
@@ -75,6 +75,7 @@ export async function prepareChatTurn(deps, params) {
75
75
  runActivityContext,
76
76
  history,
77
77
  workingMemory: createWorkingMemory(pool),
78
+ ...(deps.logger ? { logger: deps.logger } : {}),
78
79
  });
79
80
  return { kind: "ok", threadType, messages, userMessage };
80
81
  }
@@ -35,6 +35,7 @@
35
35
  * thread store.
36
36
  */
37
37
  import type { ModelMessage } from "ai";
38
+ import type { Logger } from "../lib/logger.js";
38
39
  import type { LoopMessage } from "../loop/types.js";
39
40
  import type { ThreadHistory } from "../memory/thread-history.js";
40
41
  import type { ThreadType } from "../memory/thread-store.js";
@@ -64,6 +65,8 @@ export interface AssembleMessagesArgs {
64
65
  readonly workingMemory: WorkingMemoryStore;
65
66
  /** History-window token budget. Defaults to {@link DEFAULT_HISTORY_TOKEN_BUDGET}. */
66
67
  readonly tokenBudget?: number;
68
+ /** Diagnostic seam for the history repair record; omitted falls back to no-op. */
69
+ readonly logger?: Logger;
67
70
  }
68
71
  export interface AssembledMessages {
69
72
  /** The full message array for `runAgent`. */
@@ -34,7 +34,9 @@
34
34
  * tail injections (ephemeral, re-derived each turn) are never written to the
35
35
  * thread store.
36
36
  */
37
+ import { createNoopLogger } from "../lib/console-logger.js";
37
38
  import { unwrapOrThrow } from "../lib/result.js";
39
+ import { stripUnansweredToolCalls } from "../memory/tool-call-integrity.js";
38
40
  import { normalizeUnicode, redactSecrets } from "../input-sanitization.js";
39
41
  /**
40
42
  * Token budget for the `loadRecent` history window. Sized to leave headroom
@@ -49,6 +51,21 @@ export const DEFAULT_HISTORY_TOKEN_BUDGET = 120_000;
49
51
  export async function assembleMessages(args) {
50
52
  const budget = args.tokenBudget ?? DEFAULT_HISTORY_TOKEN_BUDGET;
51
53
  const history = unwrapOrThrow(await args.history.loadRecent(args.threadId, budget, { keepFirstTurn: args.threadType === "report" }));
54
+ // Read-side safety net for the wire contract: every tool call carries a
55
+ // result. The loop upholds it at every exit, but the store outlives any one
56
+ // writer — a row an older build wrote, or a hand-edited database, can carry
57
+ // an unanswered call, and the provider boundary then refuses the WHOLE
58
+ // transcript on every turn: the thread is wedged forever. Stripping the
59
+ // orphan here degrades one message instead. The warning is the only account
60
+ // a reader gets that the stored thread and the assembled one differ.
61
+ const repaired = stripUnansweredToolCalls(history);
62
+ if (repaired.length > 0) {
63
+ (args.logger ?? createNoopLogger()).named("assembly").warn("unanswered tool calls stripped from thread history", {
64
+ threadId: args.threadId,
65
+ toolCallIds: repaired.map((d) => d.toolCallId),
66
+ tools: repaired.map((d) => d.toolName),
67
+ });
68
+ }
52
69
  // Sanitization — applied once, here, to the new user input only.
53
70
  const userMessage = {
54
71
  role: "user",
@@ -331,32 +331,44 @@ export interface RunFailedPart {
331
331
  /** Machine-readable failure reason (e.g., "budget_exceeded"). */
332
332
  reason?: string;
333
333
  }
334
- export interface PreviewPart {
335
- type: "data-report-preview";
336
- /** Unique per emission (UUID). */
337
- id: string;
338
- /** Groups all versions of the same preview. */
339
- previewId: string;
340
- /** Version number (1, 2, 3, ...). */
341
- version: number;
342
- /** Report title. */
343
- title: string;
344
- /** Version-relative path (e.g., "v1/index.html"). */
345
- previewPath: string;
346
- /** Report format. */
347
- format: "html" | "pdf";
334
+ /**
335
+ * The record that a turn started a child session. It rides the chat stream
336
+ * live, and it persists into the turn at the position of the spawn.
337
+ *
338
+ * The part is a placement record and a freshness signal only. The thread
339
+ * store is the authority for the session: its existence, its title, and its
340
+ * archived state. When the thread of the part is archived or absent, a
341
+ * consumer renders nothing for it.
342
+ */
343
+ export interface ChildSessionStartedPart {
344
+ type: "data-child-session-started";
345
+ /** The id of the child thread that the spawn made. */
346
+ threadId: string;
347
+ /** The id of the conversation thread that spawned it. */
348
+ parentThreadId: string;
349
+ /**
350
+ * The type of the child thread, in the thread store's vocabulary.
351
+ * Known values today: `"report"`.
352
+ */
353
+ threadType: string;
348
354
  }
349
- export interface DataPreviewFailedPart {
350
- type: "data-report-preview-failed";
351
- /** Unique per emission (UUID). */
355
+ /**
356
+ * The record that a report-session preview rendered the page. It rides the
357
+ * chat stream live, and it persists into the turn at the position of the
358
+ * render.
359
+ *
360
+ * The part is a placement record and a freshness signal only. The version
361
+ * store and the session-page mint stay the authority for what is viewable:
362
+ * the part carries no path, no format, and no URL. A consumer that wants the
363
+ * page reads those surfaces.
364
+ */
365
+ export interface ReportRenderedPart {
366
+ type: "data-report-rendered";
367
+ /** Unique per emission. */
352
368
  id: string;
353
- /** Groups all versions of the same preview. */
354
- previewId: string;
355
- /** Attempted version number that failed. */
356
- version: number;
357
- /** Human-readable failure reason. */
358
- reason: string;
359
- /** Optional taxonomy of failure kinds. */
360
- errorKind?: "render" | "submit" | "build" | "timeout" | "internal";
369
+ /** The ISO timestamp of the successful render. */
370
+ renderedAt: string;
371
+ /** The title of the rendered document. */
372
+ title?: string;
361
373
  }
362
- export type CortexChatPart = PresentationPart | PlanPart | RunCardPart | FileReferencePart | AskPart | RunStartedPart | DagStatePart | StepActivityPart | StepFileTreePart | StepOutputPart | StepSummaryPart | StepUsagePart | StepBlockedPart | RunSynthesisPart | SynthesisProgressPart | RunCompletedPart | RunFailedPart | PreviewPart | DataPreviewFailedPart;
374
+ export type CortexChatPart = PresentationPart | PlanPart | RunCardPart | FileReferencePart | AskPart | RunStartedPart | DagStatePart | StepActivityPart | StepFileTreePart | StepOutputPart | StepSummaryPart | StepUsagePart | StepBlockedPart | RunSynthesisPart | SynthesisProgressPart | RunCompletedPart | RunFailedPart | ChildSessionStartedPart | ReportRenderedPart;
@@ -1,60 +1,26 @@
1
1
  /**
2
2
  * Content URL construction — shared between the frontend and Cortex.
3
3
  *
4
- * The `res` claim formulas and URL shapes are the canonical TypeScript contract
5
- * for the content-token flow. The storage backend mirrors each formula in Go; both
6
- * sides are locked by the shared test vectors at
7
- * `src/__tests__/fixtures/preview-res.json` (previews) and
8
- * `src/__tests__/fixtures/report-session-res.json` (report-session pages), each a
4
+ * The `res` claim formula and URL shape are the canonical TypeScript contract
5
+ * for the content-token flow. The storage backend mirrors the formula in Go; both
6
+ * sides are locked by the shared test vector at
7
+ * `src/__tests__/fixtures/report-session-res.json` (report-session pages), a
9
8
  * byte-identical copy of the storage backend's `kernel/contenttoken/testdata` file.
10
9
  *
11
- * End-to-end contract (previews):
12
- * token res claim : "previews/{analysisId}/{previewId}"
13
- * URL : {contentBaseUrl}/previews/{analysisId}/{previewId}/{previewPath}?t={token}
14
- * Caddy predicate : request.path.startsWith("/" + res + "/")
15
- *
16
10
  * End-to-end contract (report-session pages):
17
11
  * token res claim : "report-sessions/{analysisId}/{threadId}" (token kind "rs")
18
12
  * URL : {contentBaseUrl}/report-sessions/{analysisId}/{threadId}/{pagePath}?t={token}
19
13
  * Caddy predicate : request.path.startsWith("/" + res + "/")
20
14
  *
21
- * This is URL space only. On disk a preview lives inside its analysis's workspace tree, at
22
- * `{resolveWorkspaceRoot(analysisId)}/previews/{previewId}/{previewPath}` (the workspace-layout
23
- * spec), and a session page at `{resolveWorkspaceRoot(analysisId)}/report-sessions/{threadId}/{pagePath}`
15
+ * This is URL space only. On disk a session page lives inside its analysis's workspace tree, at
16
+ * `{resolveWorkspaceRoot(analysisId)}/report-sessions/{threadId}/{pagePath}`
24
17
  * (the report-session-agent spec) — the `res` claim carries the analysis id because the URL needs an
25
18
  * authorization boundary, whereas the resolved root already identifies the analysis and so does not
26
- * repeat it. A host that serves either space owns the map between the two.
19
+ * repeat it. A host that serves the space owns the map between the two.
27
20
  *
28
21
  * The harness's contracts module owns this TS implementation so both the harness and
29
22
  * react-client consume one canonical formula.
30
23
  */
31
- /**
32
- * Canonical `res` claim formula for a preview. Returns the literal string
33
- * `previews/{analysisId}/{previewId}` with no leading or trailing slash.
34
- *
35
- * This is the URL sub-path served by the content-server (Caddy) and the token's
36
- * authorization boundary — NOT a filesystem sub-path; see the module doc.
37
- *
38
- * MUST match `fmt.Sprintf("previews/%s/%s", analysisID, previewID)` in
39
- * the storage backend's Go preview-access implementation. Drift is caught by the shared test
40
- * vector at `src/__tests__/fixtures/preview-res.json`.
41
- */
42
- export declare function previewResourceId(analysisId: string, previewId: string): string;
43
- /**
44
- * Build a content-token preview URL for an iframe src.
45
- *
46
- * Produces `{contentBaseUrl}/{res}/{previewPath}?t={token}` where `res` is
47
- * the output of `previewResourceId(analysisId, previewId)`. The query parameter
48
- * name is `t` (matching Caddy's `from_query t` directive). The token is
49
- * URL-encoded.
50
- *
51
- * @param contentBaseUrl - Content server base URL (trailing slash tolerated)
52
- * @param analysisId - The analysis ID (authorization boundary)
53
- * @param previewId - The preview ID (groups all versions)
54
- * @param previewPath - Version-relative path (e.g., "v1/index.html"). Leading slash tolerated.
55
- * @param token - Short-lived content token minted by the storage backend (required)
56
- */
57
- export declare function buildPreviewUrl(contentBaseUrl: string, analysisId: string, previewId: string, previewPath: string, token: string): string;
58
24
  /**
59
25
  * Canonical `res` claim formula for a report-session page. Returns the literal string
60
26
  * `report-sessions/{analysisId}/{threadId}` with no leading or trailing slash.
@@ -1,67 +1,26 @@
1
1
  /**
2
2
  * Content URL construction — shared between the frontend and Cortex.
3
3
  *
4
- * The `res` claim formulas and URL shapes are the canonical TypeScript contract
5
- * for the content-token flow. The storage backend mirrors each formula in Go; both
6
- * sides are locked by the shared test vectors at
7
- * `src/__tests__/fixtures/preview-res.json` (previews) and
8
- * `src/__tests__/fixtures/report-session-res.json` (report-session pages), each a
4
+ * The `res` claim formula and URL shape are the canonical TypeScript contract
5
+ * for the content-token flow. The storage backend mirrors the formula in Go; both
6
+ * sides are locked by the shared test vector at
7
+ * `src/__tests__/fixtures/report-session-res.json` (report-session pages), a
9
8
  * byte-identical copy of the storage backend's `kernel/contenttoken/testdata` file.
10
9
  *
11
- * End-to-end contract (previews):
12
- * token res claim : "previews/{analysisId}/{previewId}"
13
- * URL : {contentBaseUrl}/previews/{analysisId}/{previewId}/{previewPath}?t={token}
14
- * Caddy predicate : request.path.startsWith("/" + res + "/")
15
- *
16
10
  * End-to-end contract (report-session pages):
17
11
  * token res claim : "report-sessions/{analysisId}/{threadId}" (token kind "rs")
18
12
  * URL : {contentBaseUrl}/report-sessions/{analysisId}/{threadId}/{pagePath}?t={token}
19
13
  * Caddy predicate : request.path.startsWith("/" + res + "/")
20
14
  *
21
- * This is URL space only. On disk a preview lives inside its analysis's workspace tree, at
22
- * `{resolveWorkspaceRoot(analysisId)}/previews/{previewId}/{previewPath}` (the workspace-layout
23
- * spec), and a session page at `{resolveWorkspaceRoot(analysisId)}/report-sessions/{threadId}/{pagePath}`
15
+ * This is URL space only. On disk a session page lives inside its analysis's workspace tree, at
16
+ * `{resolveWorkspaceRoot(analysisId)}/report-sessions/{threadId}/{pagePath}`
24
17
  * (the report-session-agent spec) — the `res` claim carries the analysis id because the URL needs an
25
18
  * authorization boundary, whereas the resolved root already identifies the analysis and so does not
26
- * repeat it. A host that serves either space owns the map between the two.
19
+ * repeat it. A host that serves the space owns the map between the two.
27
20
  *
28
21
  * The harness's contracts module owns this TS implementation so both the harness and
29
22
  * react-client consume one canonical formula.
30
23
  */
31
- /**
32
- * Canonical `res` claim formula for a preview. Returns the literal string
33
- * `previews/{analysisId}/{previewId}` with no leading or trailing slash.
34
- *
35
- * This is the URL sub-path served by the content-server (Caddy) and the token's
36
- * authorization boundary — NOT a filesystem sub-path; see the module doc.
37
- *
38
- * MUST match `fmt.Sprintf("previews/%s/%s", analysisID, previewID)` in
39
- * the storage backend's Go preview-access implementation. Drift is caught by the shared test
40
- * vector at `src/__tests__/fixtures/preview-res.json`.
41
- */
42
- export function previewResourceId(analysisId, previewId) {
43
- return `previews/${analysisId}/${previewId}`;
44
- }
45
- /**
46
- * Build a content-token preview URL for an iframe src.
47
- *
48
- * Produces `{contentBaseUrl}/{res}/{previewPath}?t={token}` where `res` is
49
- * the output of `previewResourceId(analysisId, previewId)`. The query parameter
50
- * name is `t` (matching Caddy's `from_query t` directive). The token is
51
- * URL-encoded.
52
- *
53
- * @param contentBaseUrl - Content server base URL (trailing slash tolerated)
54
- * @param analysisId - The analysis ID (authorization boundary)
55
- * @param previewId - The preview ID (groups all versions)
56
- * @param previewPath - Version-relative path (e.g., "v1/index.html"). Leading slash tolerated.
57
- * @param token - Short-lived content token minted by the storage backend (required)
58
- */
59
- export function buildPreviewUrl(contentBaseUrl, analysisId, previewId, previewPath, token) {
60
- const base = contentBaseUrl.replace(/\/+$/, "");
61
- const path = previewPath.replace(/^\/+/, "");
62
- const res = previewResourceId(analysisId, previewId);
63
- return `${base}/${res}/${path}?t=${encodeURIComponent(token)}`;
64
- }
65
24
  /**
66
25
  * Canonical `res` claim formula for a report-session page. Returns the literal string
67
26
  * `report-sessions/{analysisId}/{threadId}` with no leading or trailing slash.
@@ -2,7 +2,7 @@ export { ORGAN_SYSTEMS, OrganSystemSchema, ORGAN_SYSTEM_LABELS, organSystemLabel
2
2
  export type { OrganSystem } from "./organ-system.js";
3
3
  export { SEVERITIES, SeveritySchema } from "./severity.js";
4
4
  export type { Severity } from "./severity.js";
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, PreviewPart, DataPreviewFailedPart, CortexChatPart, } from "./chat-parts.js";
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, CortexChatPart, } from "./chat-parts.js";
6
6
  export type { EventSource, TextDeltaEvent, ToolStartedEvent, ToolFinishedEvent, FinishEvent, ChatErrorEvent, CortexChatEvent } from "./chat-events.js";
7
7
  export type { TokenUsageRollup } from "./usage.js";
8
8
  export { DATA_PROFILE_RUN_LITERAL } from "./data-profile.js";
@@ -15,4 +15,4 @@ export { CoverageSchema, RowCoverageSchema, EntitySchema, ClaimSupportSchema, Cl
15
15
  export type { Coverage, RowCoverage, Entity, EvidenceItem, ClaimSupport, ClaimEvidence, LiabilityBullet, LiabilitySummary, TractabilitySection, ClinicalTrialAttribution, ClinicalTrialRow, ClinicalDevelopment, FailedTrialRow, TrialOutcomeRow, OrganRiskRow, OffTargetRow, RegulatoryActionRow, SafetyFlag, SafetyProfile, OffTissueRow, QualityGateStatus, QualityGates, Derived, Dossier, DossierBody, SectionBlurbKey, TargetAssessmentPhase, TargetAssessmentProgressEvent, } from "./target-dossier.js";
16
16
  export { TargetAssessmentStatusSchema, TargetAssessmentErrorSchema, TargetAssessmentListRowSchema, TargetAssessmentRowSchema, } from "./target-assessment-row.js";
17
17
  export type { TargetAssessmentStatus, TargetAssessmentError, TargetAssessmentListRow, TargetAssessmentRow } from "./target-assessment-row.js";
18
- export { buildPreviewUrl, buildReportSessionUrl, previewResourceId, reportSessionResourceId } from "./content-url.js";
18
+ export { buildReportSessionUrl, reportSessionResourceId } from "./content-url.js";
@@ -5,4 +5,4 @@ export { PART_REGISTRY, isTransient, isReconciling, isSidebarPart } from "./part
5
5
  export { AnalogyCoverageSchema, AnalogyReportSchema, AnalogyReportErrorSchema, AnalogicalReasonerOutputSchema } from "./analogy-report.js";
6
6
  export { CoverageSchema, RowCoverageSchema, EntitySchema, ClaimSupportSchema, ClaimEvidenceSchema, LiabilityBulletSchema, LiabilitySummarySchema, TractabilitySchema, IndicationsSchema, DrugInteractionsSchema, ClinicalTrialAttributionSchema, ClinicalDevelopmentSchema, OrganRiskRowSchema, OffTargetRowSchema, OffTargetPanelSchema, RegulatoryActionRowSchema, SafetyFlagSchema, SafetyProfileSchema, OffTissueRowSchema, OffTissueRiskSchema, ReferenceBiologyShape, EvidenceConflictsSchema, EvidenceTimelineSchema, TranslationalChainSchema, AdditionalEvidenceSchema, DiscoveryTrialsSchema, QualityGateStatusSchema, QualityGatesSchema, DerivedSchema, DossierSchema, DossierBodySchema, isDossier, dossierJsonSchema, SECTION_BLURBS, TargetAssessmentPhaseSchema, TargetAssessmentProgressEventSchema, } from "./target-dossier.js";
7
7
  export { TargetAssessmentStatusSchema, TargetAssessmentErrorSchema, TargetAssessmentListRowSchema, TargetAssessmentRowSchema, } from "./target-assessment-row.js";
8
- export { buildPreviewUrl, buildReportSessionUrl, previewResourceId, reportSessionResourceId } from "./content-url.js";
8
+ export { buildReportSessionUrl, reportSessionResourceId } from "./content-url.js";
@@ -3,7 +3,7 @@
3
3
  * and the public API for everything the chat path exchanges.
4
4
  *
5
5
  * No AI SDK types appear here or anywhere else in the package. The
6
- * discriminant is `type`, so `switch (part.type) { case "data-report-preview": ... }`
6
+ * discriminant is `type`, so `switch (part.type) { case "data-child-session-started": ... }`
7
7
  * narrows the union member without any `as` cast.
8
8
  */
9
9
  import type { ToolCallDetail, ToolCallOutcome } from "./chat-events.js";
@@ -3,7 +3,7 @@
3
3
  * and the public API for everything the chat path exchanges.
4
4
  *
5
5
  * No AI SDK types appear here or anywhere else in the package. The
6
- * discriminant is `type`, so `switch (part.type) { case "data-report-preview": ... }`
6
+ * discriminant is `type`, so `switch (part.type) { case "data-child-session-started": ... }`
7
7
  * narrows the union member without any `as` cast.
8
8
  */
9
9
  export {};
@@ -16,8 +16,8 @@ export const PART_REGISTRY = {
16
16
  "data-synthesis-progress": { emitter: "workflow", consumer: "sidebar", transient: false, reconciling: true },
17
17
  "data-run-completed": { emitter: "workflow", consumer: "sidebar", transient: false, reconciling: false },
18
18
  "data-run-failed": { emitter: "workflow", consumer: "sidebar", transient: false, reconciling: false },
19
- "data-report-preview": { emitter: "conversation", consumer: "conversation", transient: false, reconciling: false },
20
- "data-report-preview-failed": { emitter: "conversation", consumer: "conversation", transient: false, reconciling: false },
19
+ "data-child-session-started": { emitter: "conversation", consumer: "conversation", transient: false, reconciling: false },
20
+ "data-report-rendered": { emitter: "conversation", consumer: "conversation", transient: false, reconciling: false },
21
21
  };
22
22
  export function isTransient(type) {
23
23
  return PART_REGISTRY[type].transient;
@@ -441,31 +441,17 @@ export declare const RunFailedPartSchema: z.ZodObject<{
441
441
  error: z.ZodString;
442
442
  reason: z.ZodOptional<z.ZodString>;
443
443
  }, z.core.$strip>;
444
- export declare const PreviewPartSchema: z.ZodObject<{
445
- type: z.ZodLiteral<"data-report-preview">;
446
- id: z.ZodString;
447
- previewId: z.ZodString;
448
- version: z.ZodNumber;
449
- title: z.ZodString;
450
- previewPath: z.ZodString;
451
- format: z.ZodEnum<{
452
- html: "html";
453
- pdf: "pdf";
454
- }>;
444
+ export declare const ChildSessionStartedPartSchema: z.ZodObject<{
445
+ type: z.ZodLiteral<"data-child-session-started">;
446
+ threadId: z.ZodString;
447
+ parentThreadId: z.ZodString;
448
+ threadType: z.ZodString;
455
449
  }, z.core.$strip>;
456
- export declare const DataPreviewFailedPartSchema: z.ZodObject<{
457
- type: z.ZodLiteral<"data-report-preview-failed">;
450
+ export declare const ReportRenderedPartSchema: z.ZodObject<{
451
+ type: z.ZodLiteral<"data-report-rendered">;
458
452
  id: z.ZodString;
459
- previewId: z.ZodString;
460
- version: z.ZodNumber;
461
- reason: z.ZodString;
462
- errorKind: z.ZodOptional<z.ZodEnum<{
463
- timeout: "timeout";
464
- render: "render";
465
- submit: "submit";
466
- build: "build";
467
- internal: "internal";
468
- }>>;
453
+ renderedAt: z.ZodString;
454
+ title: z.ZodOptional<z.ZodString>;
469
455
  }, z.core.$strip>;
470
456
  export declare const CortexChatPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
471
457
  type: z.ZodLiteral<"data-presentation">;
@@ -740,27 +726,13 @@ export declare const CortexChatPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
740
726
  error: z.ZodString;
741
727
  reason: z.ZodOptional<z.ZodString>;
742
728
  }, z.core.$strip>, z.ZodObject<{
743
- type: z.ZodLiteral<"data-report-preview">;
744
- id: z.ZodString;
745
- previewId: z.ZodString;
746
- version: z.ZodNumber;
747
- title: z.ZodString;
748
- previewPath: z.ZodString;
749
- format: z.ZodEnum<{
750
- html: "html";
751
- pdf: "pdf";
752
- }>;
729
+ type: z.ZodLiteral<"data-child-session-started">;
730
+ threadId: z.ZodString;
731
+ parentThreadId: z.ZodString;
732
+ threadType: z.ZodString;
753
733
  }, z.core.$strip>, z.ZodObject<{
754
- type: z.ZodLiteral<"data-report-preview-failed">;
734
+ type: z.ZodLiteral<"data-report-rendered">;
755
735
  id: z.ZodString;
756
- previewId: z.ZodString;
757
- version: z.ZodNumber;
758
- reason: z.ZodString;
759
- errorKind: z.ZodOptional<z.ZodEnum<{
760
- timeout: "timeout";
761
- render: "render";
762
- submit: "submit";
763
- build: "build";
764
- internal: "internal";
765
- }>>;
736
+ renderedAt: z.ZodString;
737
+ title: z.ZodOptional<z.ZodString>;
766
738
  }, z.core.$strip>], "type">;
@@ -275,24 +275,21 @@ export const RunFailedPartSchema = z.object({
275
275
  error: z.string(),
276
276
  reason: z.string().optional(),
277
277
  });
278
- // ── Preview ────────────────────────────────────────────────────────
279
- export const PreviewPartSchema = z.object({
280
- type: z.literal("data-report-preview"),
281
- id: z.string(),
282
- previewId: z.string(),
283
- version: z.number(),
284
- title: z.string(),
285
- previewPath: z.string(),
286
- format: z.enum(["html", "pdf"]),
278
+ // ── Child Session Started ──────────────────────────────────────────
279
+ export const ChildSessionStartedPartSchema = z.object({
280
+ type: z.literal("data-child-session-started"),
281
+ threadId: z.string(),
282
+ parentThreadId: z.string(),
283
+ // A plain string, deliberately not an enum: a future session type must
284
+ // not fail validation in an older consumer.
285
+ threadType: z.string(),
287
286
  });
288
- // ── Preview Failed ─────────────────────────────────────────────────
289
- export const DataPreviewFailedPartSchema = z.object({
290
- type: z.literal("data-report-preview-failed"),
287
+ // ── Report Rendered ────────────────────────────────────────────────
288
+ export const ReportRenderedPartSchema = z.object({
289
+ type: z.literal("data-report-rendered"),
291
290
  id: z.string(),
292
- previewId: z.string(),
293
- version: z.number(),
294
- reason: z.string(),
295
- errorKind: z.enum(["render", "submit", "build", "timeout", "internal"]).optional(),
291
+ renderedAt: z.string(),
292
+ title: z.string().optional(),
296
293
  });
297
294
  // ── Union ───────────────────────────────────────────────────────────
298
295
  export const CortexChatPartSchema = z.discriminatedUnion("type", [
@@ -313,6 +310,6 @@ export const CortexChatPartSchema = z.discriminatedUnion("type", [
313
310
  SynthesisProgressPartSchema,
314
311
  RunCompletedPartSchema,
315
312
  RunFailedPartSchema,
316
- PreviewPartSchema,
317
- DataPreviewFailedPartSchema,
313
+ ChildSessionStartedPartSchema,
314
+ ReportRenderedPartSchema,
318
315
  ]);
@@ -1,3 +1,3 @@
1
- export { PlanStepSchema, PresentationContentSchema, PresentationPartSchema, PlanPartSchema, RunCardPartSchema, FileReferenceEntrySchema, FileReferencePartSchema, RunStartedPartSchema, StepStatusSchema, DagStepStateSchema, DagStatePartSchema, StepPhaseSchema, StepActivityPartSchema, FileTreeEntrySchema, StepFileTreePartSchema, StepOutputFileSchema, StepOutputPartSchema, StepSummaryPartSchema, StepUsagePartSchema, StepBlockedPartSchema, SynthesizedFindingSchema, BiologicalThemeSchema, RunSynthesisPartSchema, SynthesisPhaseSchema, SynthesisProgressPartSchema, RunCompletedFindingSchema, RunCompletedPartSchema, RunFailedPartSchema, PreviewPartSchema, DataPreviewFailedPartSchema, CortexChatPartSchema, } from "./chat-parts.js";
1
+ export { PlanStepSchema, PresentationContentSchema, PresentationPartSchema, PlanPartSchema, RunCardPartSchema, FileReferenceEntrySchema, FileReferencePartSchema, RunStartedPartSchema, StepStatusSchema, DagStepStateSchema, DagStatePartSchema, StepPhaseSchema, StepActivityPartSchema, FileTreeEntrySchema, StepFileTreePartSchema, StepOutputFileSchema, StepOutputPartSchema, StepSummaryPartSchema, StepUsagePartSchema, StepBlockedPartSchema, SynthesizedFindingSchema, BiologicalThemeSchema, RunSynthesisPartSchema, SynthesisPhaseSchema, SynthesisProgressPartSchema, RunCompletedFindingSchema, RunCompletedPartSchema, RunFailedPartSchema, CortexChatPartSchema, } from "./chat-parts.js";
2
2
  export { EventSourceSchema, TextDeltaEventSchema, ToolStartedEventSchema, ToolFinishedEventSchema, FinishEventSchema, ChatErrorEventSchema, CortexChatEventSchema, } from "./chat-events.js";
3
3
  export { TokenUsageRollupSchema } from "./usage.js";
@@ -1,3 +1,3 @@
1
- export { PlanStepSchema, PresentationContentSchema, PresentationPartSchema, PlanPartSchema, RunCardPartSchema, FileReferenceEntrySchema, FileReferencePartSchema, RunStartedPartSchema, StepStatusSchema, DagStepStateSchema, DagStatePartSchema, StepPhaseSchema, StepActivityPartSchema, FileTreeEntrySchema, StepFileTreePartSchema, StepOutputFileSchema, StepOutputPartSchema, StepSummaryPartSchema, StepUsagePartSchema, StepBlockedPartSchema, SynthesizedFindingSchema, BiologicalThemeSchema, RunSynthesisPartSchema, SynthesisPhaseSchema, SynthesisProgressPartSchema, RunCompletedFindingSchema, RunCompletedPartSchema, RunFailedPartSchema, PreviewPartSchema, DataPreviewFailedPartSchema, CortexChatPartSchema, } from "./chat-parts.js";
1
+ export { PlanStepSchema, PresentationContentSchema, PresentationPartSchema, PlanPartSchema, RunCardPartSchema, FileReferenceEntrySchema, FileReferencePartSchema, RunStartedPartSchema, StepStatusSchema, DagStepStateSchema, DagStatePartSchema, StepPhaseSchema, StepActivityPartSchema, FileTreeEntrySchema, StepFileTreePartSchema, StepOutputFileSchema, StepOutputPartSchema, StepSummaryPartSchema, StepUsagePartSchema, StepBlockedPartSchema, SynthesizedFindingSchema, BiologicalThemeSchema, RunSynthesisPartSchema, SynthesisPhaseSchema, SynthesisProgressPartSchema, RunCompletedFindingSchema, RunCompletedPartSchema, RunFailedPartSchema, CortexChatPartSchema, } from "./chat-parts.js";
2
2
  export { EventSourceSchema, TextDeltaEventSchema, ToolStartedEventSchema, ToolFinishedEventSchema, FinishEventSchema, ChatErrorEventSchema, CortexChatEventSchema, } from "./chat-events.js";
3
3
  export { TokenUsageRollupSchema } from "./usage.js";
@@ -11,7 +11,7 @@
11
11
  * `RunSession` with no host call, no jti, no revoke. The harness's tools depend only on
12
12
  * this interface and never read a credential.
13
13
  *
14
- * Mirrors the `PreviewPublisher` seam: a narrow interface in the harness, the managed
14
+ * Mirrors the `SessionPagePublisher` seam: a narrow interface in the harness, the managed
15
15
  * realization injected at the composition root.
16
16
  */
17
17
  import type { AuthContext, Provenance, RunFrame, RunSession, Scope } from "../auth/types.js";
@@ -11,7 +11,7 @@
11
11
  * `RunSession` with no host call, no jti, no revoke. The harness's tools depend only on
12
12
  * this interface and never read a credential.
13
13
  *
14
- * Mirrors the `PreviewPublisher` seam: a narrow interface in the harness, the managed
14
+ * Mirrors the `SessionPagePublisher` seam: a narrow interface in the harness, the managed
15
15
  * realization injected at the composition root.
16
16
  */
17
17
  export {};
package/dist/index.d.ts CHANGED
@@ -33,8 +33,6 @@ export { createNoopArtifactRegistry } from "./execution/noop-artifact-registry.j
33
33
  export type { ArtifactRegistry, ArtifactRegistrationInput, ArtifactSyncInput, ExternalRegistrationResult } from "./execution/artifact-registry.js";
34
34
  export type { ArtifactManifestEntry } from "./schemas/artifact-manifest.js";
35
35
  export type { ProvenanceCollector } from "./provenance/collector.js";
36
- export { UnavailablePreviewPublisher } from "./tools/report/preview-publisher.js";
37
- export type { PreviewPublisher, PreviewMintResult } from "./tools/report/preview-publisher.js";
38
36
  export { UnavailableSessionPagePublisher } from "./tools/report-session/session-page-publisher.js";
39
37
  export type { MakeSessionPagePublisher, SessionPagePublisher, SessionPageMintResult } from "./tools/report-session/session-page-publisher.js";
40
38
  export type { ResolvePageUrl, SessionPageAccess } from "./tools/report-session/index.js";
@@ -88,7 +86,7 @@ export type { ConversationDisplayMetadata, ConversationUIData, ConversationUIMes
88
86
  export { storedMessagesToCortex } from "./memory/conversation-display-replay.js";
89
87
  export type { CortexChatEvent, TextDeltaEvent, ToolStartedEvent, ToolFinishedEvent, ToolOutcome, ToolCallOutcome, ToolCallDetail, FinishEvent, ChatErrorEvent, } from "./contracts/chat-events.js";
90
88
  export type { TokenUsageRollup } from "./contracts/usage.js";
91
- export type { CortexChatPart, PresentationPart, PresentationContent, PlanPart, RunCardPart, FileReferencePart, FileReferenceEntry, RunStartedPart, DagStatePart, DagStepState, StepStatus, StepActivityPart, StepPhase, StepFileTreePart, FileTreeEntry, StepOutputPart, StepOutputFile, StepSummaryPart, StepUsagePart, StepBlockedPart, RunSynthesisPart, SynthesizedFinding, BiologicalTheme, SynthesisProgressPart, SynthesisPhase, RunCompletedPart, RunCompletedFinding, RunFailedPart, PreviewPart, DataPreviewFailedPart, } from "./contracts/chat-parts.js";
89
+ export type { CortexChatPart, PresentationPart, PresentationContent, PlanPart, RunCardPart, FileReferencePart, FileReferenceEntry, RunStartedPart, DagStatePart, DagStepState, StepStatus, StepActivityPart, StepPhase, StepFileTreePart, FileTreeEntry, StepOutputPart, StepOutputFile, StepSummaryPart, StepUsagePart, StepBlockedPart, RunSynthesisPart, SynthesizedFinding, BiologicalTheme, SynthesisProgressPart, SynthesisPhase, RunCompletedPart, RunCompletedFinding, RunFailedPart, } from "./contracts/chat-parts.js";
92
90
  export { PART_REGISTRY, isTransient, isReconciling, isSidebarPart } from "./contracts/part-registry.js";
93
91
  export type { CortexChatPartType, PartDescriptor, PartEmitter, PartConsumer } from "./contracts/part-registry.js";
94
92
  export { launchDbos, shutdownDbos, sweepEphemeralWorkflows } from "./runtime/dbos.js";
package/dist/index.js CHANGED
@@ -40,8 +40,6 @@ export { createNoopRunCharge } from "./billing/noop-run-charge.js";
40
40
  export { createNoopUsageRecorder } from "./billing/noop-usage-recorder.js";
41
41
  // Seam: artifact registration.
42
42
  export { createNoopArtifactRegistry } from "./execution/noop-artifact-registry.js";
43
- // Seam: report preview publishing.
44
- export { UnavailablePreviewPublisher } from "./tools/report/preview-publisher.js";
45
43
  // Seam: the hosted view of a report-session page. A managed host serves the URL space
46
44
  // `report-sessions/{analysisId}/{threadId}` and mints access through its own publisher,
47
45
  // thus the seam belongs on the front door. Both seams bind per call over the auth of the
@@ -13,10 +13,9 @@
13
13
  * ` ```json {…}``` `). The payload is complete; only the wrapper makes it a
14
14
  * string.
15
15
  *
16
- * This module owns both halves of the response for the four model-facing
16
+ * This module owns both halves of the response for the three model-facing
17
17
  * validation sites (`loop/run-agent.ts`'s tool-input boundary,
18
- * `execution/run-synthesis.ts`, `tools/research/generate-plan.ts`,
19
- * `tools/iterate-report.ts`):
18
+ * `execution/run-synthesis.ts`, `tools/research/generate-plan.ts`):
20
19
  *
21
20
  * - `hintForZodIssue` — a **diagnostic only**. It parses nothing into the
22
21
  * caller's data; it distinguishes the two modes so the message the model
@@ -13,10 +13,9 @@
13
13
  * ` ```json {…}``` `). The payload is complete; only the wrapper makes it a
14
14
  * string.
15
15
  *
16
- * This module owns both halves of the response for the four model-facing
16
+ * This module owns both halves of the response for the three model-facing
17
17
  * validation sites (`loop/run-agent.ts`'s tool-input boundary,
18
- * `execution/run-synthesis.ts`, `tools/research/generate-plan.ts`,
19
- * `tools/iterate-report.ts`):
18
+ * `execution/run-synthesis.ts`, `tools/research/generate-plan.ts`):
20
19
  *
21
20
  * - `hintForZodIssue` — a **diagnostic only**. It parses nothing into the
22
21
  * caller's data; it distinguishes the two modes so the message the model
@@ -14,9 +14,11 @@ function mapFinishReason(finishReason) {
14
14
  }
15
15
  }
16
16
  export function makeMessage(content, finishReason, usage) {
17
+ const mapped = mapFinishReason(finishReason);
17
18
  return {
18
19
  message: { role: "assistant", content },
19
- finishReason: mapFinishReason(finishReason),
20
+ finishReason: mapped,
21
+ ...(mapped === finishReason ? {} : { rawFinishReason: finishReason }),
20
22
  usage,
21
23
  };
22
24
  }