@inflexa-ai/harness 0.12.0 → 0.14.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 (207) hide show
  1. package/dist/agents/conversation-agent.d.ts +9 -15
  2. package/dist/agents/conversation-agent.js +32 -31
  3. package/dist/agents/sandbox/cheminformatics-agent.js +1 -1
  4. package/dist/agents/sandbox/chromatin-agent.js +1 -1
  5. package/dist/agents/sandbox/dna-methylation-agent.js +1 -1
  6. package/dist/agents/sandbox/drug-repurposing-agent.js +5 -10
  7. package/dist/agents/sandbox/enrichment-agent.js +1 -1
  8. package/dist/agents/sandbox/genomic-variant-agent.js +1 -11
  9. package/dist/agents/sandbox/immune-profiling-agent.js +1 -1
  10. package/dist/agents/sandbox/index.js +0 -3
  11. package/dist/agents/sandbox/multi-omics-integration-agent.js +1 -1
  12. package/dist/agents/sandbox/network-agent.js +1 -1
  13. package/dist/agents/sandbox/pkpd-clinical-response-agent.js +3 -6
  14. package/dist/agents/sandbox/scientific-executor.js +1 -1
  15. package/dist/agents/sandbox/shared.d.ts +2 -2
  16. package/dist/agents/sandbox/shared.js +8 -14
  17. package/dist/agents/sandbox/translational-safety-agent.js +4 -7
  18. package/dist/agents/sandbox/types.d.ts +5 -5
  19. package/dist/agents/sandbox/types.js +4 -4
  20. package/dist/app/chat-turn.js +4 -1
  21. package/dist/app/message-assembly.d.ts +5 -2
  22. package/dist/app/message-assembly.js +7 -2
  23. package/dist/app/run-activity.d.ts +13 -0
  24. package/dist/app/run-activity.js +51 -0
  25. package/dist/config/resource-limits.d.ts +0 -7
  26. package/dist/config/resource-limits.js +0 -1
  27. package/dist/contracts/target-dossier.d.ts +10 -10
  28. package/dist/execution/dbos-run-launcher.js +1 -26
  29. package/dist/execution/report-runner.js +1 -1
  30. package/dist/execution/run-authorizer.d.ts +1 -1
  31. package/dist/execution/run-authorizer.js +1 -1
  32. package/dist/execution/run-event-parts.d.ts +44 -0
  33. package/dist/execution/run-event-parts.js +0 -0
  34. package/dist/execution/run-event-stream.d.ts +91 -0
  35. package/dist/execution/run-event-stream.js +212 -0
  36. package/dist/execution/run-launcher.d.ts +2 -18
  37. package/dist/execution/run-launcher.js +2 -4
  38. package/dist/execution/run-synthesis.js +1 -1
  39. package/dist/index.d.ts +7 -4
  40. package/dist/index.js +23 -6
  41. package/dist/input-sanitization.d.ts +14 -4
  42. package/dist/input-sanitization.js +27 -4
  43. package/dist/lib/storage.js +4 -1
  44. package/dist/loop/budget-exceeded.d.ts +18 -2
  45. package/dist/loop/budget-exceeded.js +49 -2
  46. package/dist/loop/run-agent.d.ts +22 -1
  47. package/dist/loop/run-agent.js +51 -5
  48. package/dist/loop/run-to-terminal.d.ts +0 -2
  49. package/dist/loop/run-to-terminal.js +8 -1
  50. package/dist/memory/ai-sdk-message-storage.d.ts +37 -4
  51. package/dist/memory/ai-sdk-message-storage.js +45 -4
  52. package/dist/memory/content-to-cortex.js +19 -3
  53. package/dist/memory/message-backfill.js +1 -1
  54. package/dist/memory/reconstruct-cards.d.ts +1 -1
  55. package/dist/memory/reconstruct-cards.js +7 -5
  56. package/dist/memory/thread-history.js +72 -8
  57. package/dist/prompts/conversation.d.ts +1 -1
  58. package/dist/prompts/conversation.js +41 -15
  59. package/dist/prompts/literature-reviewer.d.ts +1 -1
  60. package/dist/prompts/literature-reviewer.js +16 -14
  61. package/dist/prompts/planner.d.ts +3 -0
  62. package/dist/prompts/planner.js +16 -21
  63. package/dist/prompts/sandbox/drug-repurposing-agent.d.ts +1 -1
  64. package/dist/prompts/sandbox/drug-repurposing-agent.js +31 -22
  65. package/dist/prompts/sandbox/multi-omics-integration-agent.d.ts +1 -1
  66. package/dist/prompts/sandbox/multi-omics-integration-agent.js +9 -10
  67. package/dist/prompts/sandbox/pkpd-clinical-response-agent.d.ts +1 -1
  68. package/dist/prompts/sandbox/pkpd-clinical-response-agent.js +8 -7
  69. package/dist/prompts/sandbox/translational-safety-agent.d.ts +1 -1
  70. package/dist/prompts/sandbox/translational-safety-agent.js +20 -14
  71. package/dist/prompts/sandbox-standards.d.ts +4 -4
  72. package/dist/prompts/sandbox-standards.js +5 -5
  73. package/dist/prompts/synthesis-agent.d.ts +1 -1
  74. package/dist/prompts/synthesis-agent.js +7 -7
  75. package/dist/providers/errors.d.ts +7 -0
  76. package/dist/providers/errors.js +88 -3
  77. package/dist/runtime/assemble.d.ts +5 -10
  78. package/dist/runtime/assemble.js +0 -4
  79. package/dist/runtime/boot.d.ts +2 -2
  80. package/dist/runtime/boot.js +1 -1
  81. package/dist/runtime/dbos.d.ts +4 -5
  82. package/dist/runtime/dbos.js +6 -7
  83. package/dist/runtime/pools.d.ts +15 -1
  84. package/dist/runtime/pools.js +15 -1
  85. package/dist/sandbox/mount-plan.d.ts +1 -1
  86. package/dist/sandbox/sandbox-error.d.ts +1 -1
  87. package/dist/sandbox/sandbox-error.js +1 -1
  88. package/dist/sandbox/sandbox-step-translate.d.ts +15 -2
  89. package/dist/sandbox/sandbox-step-translate.js +17 -2
  90. package/dist/sandbox/types.d.ts +1 -1
  91. package/dist/schemas/validate-plan.d.ts +1 -1
  92. package/dist/schemas/workflow-state.d.ts +2 -2
  93. package/dist/schemas/workflow-state.js +2 -2
  94. package/dist/state/data-profile.d.ts +53 -1
  95. package/dist/state/data-profile.js +66 -6
  96. package/dist/state/index.d.ts +6 -6
  97. package/dist/state/index.js +4 -4
  98. package/dist/state/init.js +37 -2
  99. package/dist/state/plans.js +1 -1
  100. package/dist/state/runs.d.ts +49 -0
  101. package/dist/state/runs.js +150 -0
  102. package/dist/tasks/data-profile-activity.d.ts +87 -0
  103. package/dist/tasks/data-profile-activity.js +56 -0
  104. package/dist/tasks/data-profile.js +66 -4
  105. package/dist/tools/__fixtures__/tool-context.js +1 -0
  106. package/dist/tools/ad-hoc-router.d.ts +31 -0
  107. package/dist/tools/ad-hoc-router.js +132 -0
  108. package/dist/tools/analysis-invocation.d.ts +4 -0
  109. package/dist/tools/analysis-invocation.js +17 -0
  110. package/dist/tools/bio/chembl.d.ts +1 -1
  111. package/dist/tools/bio/chembl.js +51 -54
  112. package/dist/tools/bio/comptox.js +35 -33
  113. package/dist/tools/bio/drug-gene-interactions.d.ts +76 -0
  114. package/dist/tools/bio/drug-gene-interactions.js +175 -0
  115. package/dist/tools/bio/gene-disease-evidence.d.ts +61 -0
  116. package/dist/tools/bio/gene-disease-evidence.js +187 -0
  117. package/dist/tools/bio/gene-preclinical-profile.d.ts +58 -0
  118. package/dist/tools/bio/gene-preclinical-profile.js +125 -0
  119. package/dist/tools/bio/index.d.ts +23 -16
  120. package/dist/tools/bio/index.js +29 -22
  121. package/dist/tools/bio/keys.d.ts +16 -9
  122. package/dist/tools/bio/keys.js +22 -13
  123. package/dist/tools/bio/lookup-annotation.d.ts +48 -0
  124. package/dist/tools/bio/lookup-annotation.js +173 -0
  125. package/dist/tools/bio/opentargets.d.ts +7 -11
  126. package/dist/tools/bio/opentargets.js +24 -35
  127. package/dist/tools/bio/pubchem.js +6 -4
  128. package/dist/tools/bio/pubmed.d.ts +15 -7
  129. package/dist/tools/bio/pubmed.js +79 -20
  130. package/dist/tools/bio/search-clinical-trials.d.ts +20 -1
  131. package/dist/tools/bio/search-clinical-trials.js +26 -5
  132. package/dist/tools/bio/search-faers.js +9 -3
  133. package/dist/tools/bio/search-gene.d.ts +0 -1
  134. package/dist/tools/bio/search-gene.js +4 -5
  135. package/dist/tools/bio/search-geo-datasets.js +10 -4
  136. package/dist/tools/bio/search-interactions.d.ts +8 -4
  137. package/dist/tools/bio/search-interactions.js +28 -12
  138. package/dist/tools/bio/target-safety.d.ts +59 -0
  139. package/dist/tools/bio/target-safety.js +191 -0
  140. package/dist/tools/define-tool.d.ts +6 -2
  141. package/dist/tools/define-tool.js +1 -1
  142. package/dist/tools/execute-analysis.d.ts +44 -0
  143. package/dist/tools/execute-analysis.js +252 -0
  144. package/dist/tools/iterate-report.js +7 -6
  145. package/dist/tools/lib/dgidb-client.d.ts +49 -0
  146. package/dist/tools/lib/dgidb-client.js +168 -0
  147. package/dist/tools/lib/disgenet-client.d.ts +56 -0
  148. package/dist/tools/lib/disgenet-client.js +59 -0
  149. package/dist/tools/lib/drugbank-client.d.ts +83 -0
  150. package/dist/tools/lib/drugbank-client.js +95 -0
  151. package/dist/tools/lib/ensembl-client.d.ts +4 -1
  152. package/dist/tools/lib/ensembl-client.js +5 -3
  153. package/dist/tools/lib/gwas-catalog-client.d.ts +60 -0
  154. package/dist/tools/lib/gwas-catalog-client.js +136 -0
  155. package/dist/tools/lib/pharmgkb-client.d.ts +22 -0
  156. package/dist/tools/lib/pharmgkb-client.js +32 -0
  157. package/dist/tools/lib/pubmed-client.d.ts +57 -4
  158. package/dist/tools/lib/pubmed-client.js +57 -3
  159. package/dist/tools/lib/string-client.d.ts +25 -4
  160. package/dist/tools/lib/string-client.js +22 -5
  161. package/dist/tools/research/generate-plan.d.ts +16 -9
  162. package/dist/tools/research/generate-plan.js +116 -70
  163. package/dist/tools/research/inspect-data-profile.d.ts +31 -6
  164. package/dist/tools/research/inspect-data-profile.js +23 -7
  165. package/dist/tools/research/inspect-run.d.ts +33 -15
  166. package/dist/tools/research/inspect-run.js +155 -66
  167. package/dist/tools/research/literature-reviewer.js +7 -11
  168. package/dist/workflows/execute-analysis.d.ts +68 -5
  169. package/dist/workflows/execute-analysis.js +76 -7
  170. package/dist/workflows/sandbox-step.js +1 -11
  171. package/dist/workflows/target-assessment/decisions/index.d.ts +1 -1
  172. package/dist/workflows/target-assessment/phase4-assemble.d.ts +1 -1
  173. package/dist/workflows/target-assessment/steps/phase2-aggregate.d.ts +2 -2
  174. package/dist/workflows/target-assessment/steps/phase3-aggregate.d.ts +1 -1
  175. package/package.json +1 -1
  176. package/dist/agents/sandbox/ephemeral-executor.d.ts +0 -9
  177. package/dist/agents/sandbox/ephemeral-executor.js +0 -20
  178. package/dist/execution/ephemeral-runner.d.ts +0 -98
  179. package/dist/execution/ephemeral-runner.js +0 -189
  180. package/dist/prompts/sandbox/ephemeral-executor.d.ts +0 -1
  181. package/dist/prompts/sandbox/ephemeral-executor.js +0 -66
  182. package/dist/tools/bio/check-safety-panel.d.ts +0 -35
  183. package/dist/tools/bio/check-safety-panel.js +0 -76
  184. package/dist/tools/bio/get-impc-ko-profile.d.ts +0 -9
  185. package/dist/tools/bio/get-impc-ko-profile.js +0 -23
  186. package/dist/tools/bio/lookup-go-term.d.ts +0 -31
  187. package/dist/tools/bio/lookup-go-term.js +0 -116
  188. package/dist/tools/bio/search-bgee-expression.d.ts +0 -10
  189. package/dist/tools/bio/search-bgee-expression.js +0 -30
  190. package/dist/tools/bio/search-clinvar.d.ts +0 -13
  191. package/dist/tools/bio/search-clinvar.js +0 -28
  192. package/dist/tools/bio/search-dgidb.d.ts +0 -53
  193. package/dist/tools/bio/search-dgidb.js +0 -213
  194. package/dist/tools/bio/search-disgenet.d.ts +0 -30
  195. package/dist/tools/bio/search-disgenet.js +0 -84
  196. package/dist/tools/bio/search-drugbank.d.ts +0 -38
  197. package/dist/tools/bio/search-drugbank.js +0 -109
  198. package/dist/tools/bio/search-gwas-catalog.d.ts +0 -33
  199. package/dist/tools/bio/search-gwas-catalog.js +0 -172
  200. package/dist/tools/bio/search-pathway.d.ts +0 -12
  201. package/dist/tools/bio/search-pathway.js +0 -32
  202. package/dist/tools/bio/search-pharmgkb.d.ts +0 -17
  203. package/dist/tools/bio/search-pharmgkb.js +0 -52
  204. package/dist/tools/execute-plan.d.ts +0 -64
  205. package/dist/tools/execute-plan.js +0 -211
  206. package/dist/tools/run-ephemeral.d.ts +0 -33
  207. package/dist/tools/run-ephemeral.js +0 -65
@@ -1,211 +0,0 @@
1
- /**
2
- * executePlan — launch the DBOS `executeAnalysis` parent workflow for an
3
- * approved plan.
4
- *
5
- * Results are pull-only: the tool does NOT register a `.then(saveRunResult)`
6
- * or any completion callback that writes to the conversation thread. The
7
- * conversation agent retrieves run results via `inspectRun` on a later turn.
8
- *
9
- * Authorization contract: the tool runs in the chat HTTP route, so its session
10
- * carries the live auth. It authorizes through the injected `RunAuthorizer`
11
- * seam and never reads a credential. The flow is dedup → reserve → authorize
12
- * → startWorkflow:
13
- *
14
- * 1. Dedup pre-check via `queryActiveRun`. On hit, return the existing
15
- * `runId` with no authorization and no `startWorkflow`.
16
- * 2. Reserve the slot: `insertRun` the `cortex_runs` row (`runId =
17
- * randomUUID()`, the bare UUID that IS the DBOS workflowID) BEFORE
18
- * authorizing. The partial-unique index is the race backstop; the loser
19
- * returns the winner's `runId` without authorizing — nothing to revoke.
20
- * 3. `runAuthorizer.authorize({ ..., frame: { runId } })` — authorizes the
21
- * run; the authorizer's persisted handle now lands because the row
22
- * exists. On failure, mark the reserved row `failed` (releasing the dedup
23
- * slot for a retry) and rethrow.
24
- * 4. `runLauncher.launch(executeAnalysis, { workflowId: runId }, ...)`,
25
- * passing the `RunSession` in the workflow input. On failure, revoke + mark
26
- * failed.
27
- */
28
- import { randomUUID } from "node:crypto";
29
- import { ok } from "neverthrow";
30
- import { z } from "zod";
31
- import { buildRunCardData } from "../memory/card-builders.js";
32
- import { unwrapOrThrow } from "../lib/result.js";
33
- import { validatePlan } from "../schemas/validate-plan.js";
34
- import { AnalysisPlanSchema } from "../schemas/workflow-state.js";
35
- import { RunDedupCollisionError, insertRun, loadPlan, queryActiveRun, updateRunStatus } from "../state/index.js";
36
- import { defineTool } from "./define-tool.js";
37
- const planIdSchema = z.string().regex(/^pln-[a-f0-9]{8}$/, "planId must be a pln-<8hex> value");
38
- const inputSchema = z.object({
39
- planId: planIdSchema,
40
- });
41
- export class PlanNotFoundError extends Error {
42
- constructor(planId) {
43
- super(`Plan ${planId} not found for this analysis`);
44
- this.name = "PlanNotFoundError";
45
- }
46
- }
47
- export class PlanMalformedError extends Error {
48
- constructor(planId) {
49
- super(`Plan ${planId} is malformed`);
50
- this.name = "PlanMalformedError";
51
- }
52
- }
53
- export class PlanValidationError extends Error {
54
- errors;
55
- constructor(planId, errors) {
56
- super(`Plan ${planId} failed validation: ${errors.length} error(s)`);
57
- this.errors = errors;
58
- this.name = "PlanValidationError";
59
- }
60
- }
61
- function isDedupCollision(err) {
62
- return err instanceof RunDedupCollisionError || (err instanceof Error && err.name === "RunDedupCollisionError");
63
- }
64
- export function createExecutePlanTool(deps) {
65
- const { pool, executeAnalysisWorkflow, runAuthorizer, runLauncher, resourcePolicy } = deps;
66
- return defineTool({
67
- id: "execute_plan",
68
- description: "Execute an approved analysis plan by its planId. " +
69
- "Pass the planId returned from generatePlan — the tool resolves the plan " +
70
- "server-side, validates the DAG, and starts the executeAnalysis workflow " +
71
- "asynchronously. Returns the runId on success. " +
72
- "The user sees a run card in chat (also tracked in the Runs panel); " +
73
- "run results become available for inspection on a later turn. " +
74
- "Do not instruct the user to invoke any tool.",
75
- inputSchema,
76
- execute: async (input, ctx) => {
77
- const { planId } = input;
78
- // Mirror show_plan: emit a live display card so chat renders a run card
79
- // rather than a generic "used 1 tool" chip. Null (plan/run unresolvable)
80
- // simply skips the card — the run still starts.
81
- const emitRunCard = async (analysisId, runId) => {
82
- const card = await buildRunCardData(pool, {
83
- planId,
84
- analysisId,
85
- runId,
86
- }).unwrapOr(null);
87
- if (card) {
88
- await ctx.emit({
89
- type: "data-run-card",
90
- source: ctx.session.provenance,
91
- data: card,
92
- });
93
- }
94
- };
95
- const { session } = ctx;
96
- if (session.scope.kind !== "analysis") {
97
- throw new Error("executePlan can only be invoked on an analysis-scoped session");
98
- }
99
- if (!session.auth) {
100
- throw new Error("executePlan: session is missing its auth capability");
101
- }
102
- const analysisId = session.scope.analysisId;
103
- const threadId = session.scope.threadId ?? null;
104
- const raw = unwrapOrThrow(await loadPlan(pool, planId, { analysisId }));
105
- if (!raw)
106
- throw new PlanNotFoundError(planId);
107
- const parsed = AnalysisPlanSchema.safeParse(raw);
108
- if (!parsed.success)
109
- throw new PlanMalformedError(planId);
110
- const plan = parsed.data;
111
- const result = validatePlan(plan);
112
- if (!result.valid) {
113
- throw new PlanValidationError(planId, result.errors);
114
- }
115
- // (1) Dedup pre-check — common case is the user re-clicked Execute on
116
- // an in-flight plan. A hit avoids both the authorization and the DBOS
117
- // startWorkflow.
118
- const existingPre = unwrapOrThrow(await queryActiveRun(pool, analysisId, planId));
119
- if (existingPre) {
120
- await emitRunCard(analysisId, existingPre.runId);
121
- return ok({ runId: existingPre.runId });
122
- }
123
- // (2) Reserve the dedup slot by inserting the run row BEFORE authorizing.
124
- // The partial-unique index is the race backstop for two callers that both
125
- // passed the pre-check; the loser returns the winner's runId without
126
- // having authorized — there is nothing to revoke. The authorization handle is left
127
- // null here and populated by the authorizer, whose UPDATE lands
128
- // because the row now exists.
129
- const runId = randomUUID();
130
- try {
131
- // On the dedup collision `insertRun` throws `RunDedupCollisionError`
132
- // (a control-flow signal that rides out of the ResultAsync as a
133
- // rejection) — `unwrapOrThrow` never sees it; the catch below does.
134
- unwrapOrThrow(await insertRun(pool, {
135
- runId,
136
- analysisId,
137
- threadId,
138
- workflowName: "executeAnalysis",
139
- planId,
140
- }));
141
- }
142
- catch (err) {
143
- if (isDedupCollision(err)) {
144
- const existing = unwrapOrThrow(await queryActiveRun(pool, analysisId, planId));
145
- if (existing) {
146
- await emitRunCard(analysisId, existing.runId);
147
- return ok({ runId: existing.runId });
148
- }
149
- }
150
- throw err;
151
- }
152
- // (3) Authorize the run. The row exists, so the authorizer's persisted handle
153
- // persists. On failure, mark the reserved row failed — releasing the
154
- // partial-unique slot so a retry can re-run — and rethrow.
155
- let authorization;
156
- try {
157
- authorization = await runAuthorizer.authorize({
158
- auth: session.auth,
159
- scope: session.scope,
160
- provenance: session.provenance,
161
- frame: { runId },
162
- });
163
- }
164
- catch (err) {
165
- await updateRunStatus(pool, runId, "failed", "run authorization failed").match(() => { }, () => { });
166
- throw err;
167
- }
168
- const { runSession } = authorization;
169
- const planSummary = plan.title?.trim() || plan.analytical_narrative.trim().slice(0, 280);
170
- const workflowInput = {
171
- analysisId,
172
- planId,
173
- planSummary,
174
- threadId,
175
- steps: plan.steps.map((s) => ({
176
- id: s.id,
177
- depends_on: s.depends_on ?? [],
178
- })),
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])),
184
- agentByStepId: Object.fromEntries(plan.steps.map((s) => [s.id, s.agent ?? "unknown"])),
185
- resourcesByStepId: Object.fromEntries(plan.steps.map((s) => {
186
- if (!s.resources) {
187
- throw new Error(`Step "${s.id}" has no resources — validatePlan should have rejected this plan`);
188
- }
189
- return [s.id, s.resources];
190
- })),
191
- timeoutByStepId: Object.fromEntries(plan.steps.filter((s) => s.timeout !== undefined).map((s) => [s.id, s.timeout])),
192
- budget: resourcePolicy?.budget,
193
- runSession,
194
- ownsMandate: authorization.ownsMandate, // oss-core-managed-ok
195
- };
196
- // (4) Dispatch the workflow. `workflowId = runId` — both are the same
197
- // bare UUID. On failure after insert + authorize, revoke the authorization and
198
- // mark the row failed.
199
- try {
200
- await runLauncher.launch(executeAnalysisWorkflow, { workflowId: runId }, workflowInput);
201
- }
202
- catch (err) {
203
- await runAuthorizer.revoke(authorization, "workflow-start-failed").catch(() => { });
204
- await updateRunStatus(pool, runId, "failed", "workflow start failed").match(() => { }, () => { });
205
- throw err;
206
- }
207
- await emitRunCard(analysisId, runId);
208
- return ok({ runId });
209
- },
210
- });
211
- }
@@ -1,33 +0,0 @@
1
- /**
2
- * run_ephemeral — ad-hoc data exploration in a read-only sandbox.
3
- *
4
- * Authorizes the run at the async edge via the RunAuthorizer seam, then starts
5
- * the ephemeral workflow through the RunLauncher seam and awaits its result
6
- * inline within the chat turn. Chat disconnect cancels the run; the
7
- * authorization is revoked on every terminal path. The workflow is never
8
- * recovered — a turn-scoped exploration outliving its turn has no value.
9
- *
10
- * Available to: conversation-agent.
11
- */
12
- import type { RunAuthorizer } from "../execution/run-authorizer.js";
13
- import type { RunLauncher } from "../execution/run-launcher.js";
14
- import { type EphemeralResult, type EphemeralWorkflowInput } from "../execution/ephemeral-runner.js";
15
- export interface RunEphemeralToolDeps {
16
- /** Registered ephemeral workflow callable. */
17
- readonly workflow: (input: EphemeralWorkflowInput) => Promise<EphemeralResult>;
18
- /** Authorizes the run at the async edge and revokes on the terminal path. */
19
- readonly runAuthorizer: RunAuthorizer;
20
- /** Starts the durable run — the durability engine stays behind this seam. */
21
- readonly runLauncher: RunLauncher;
22
- }
23
- export interface RunEphemeralToolOutput {
24
- readonly text: string;
25
- readonly durationMs: number;
26
- }
27
- /** Build the `run_ephemeral` tool bound to the registered workflow + mint deps. */
28
- export declare function createRunEphemeralTool(deps: RunEphemeralToolDeps): import("./define-tool.js").Tool<{
29
- prompt: string;
30
- }, {
31
- text: string;
32
- durationMs: number;
33
- }>;
@@ -1,65 +0,0 @@
1
- /**
2
- * run_ephemeral — ad-hoc data exploration in a read-only sandbox.
3
- *
4
- * Authorizes the run at the async edge via the RunAuthorizer seam, then starts
5
- * the ephemeral workflow through the RunLauncher seam and awaits its result
6
- * inline within the chat turn. Chat disconnect cancels the run; the
7
- * authorization is revoked on every terminal path. The workflow is never
8
- * recovered — a turn-scoped exploration outliving its turn has no value.
9
- *
10
- * Available to: conversation-agent.
11
- */
12
- import { ok } from "neverthrow";
13
- import { z } from "zod";
14
- import { EPHEMERAL_WORKFLOW_PREFIX } from "../execution/ephemeral-runner.js";
15
- import { generateExecutionId } from "../sandbox/execution-id.js";
16
- import { defineTool } from "./define-tool.js";
17
- const inputSchema = z.object({
18
- prompt: z
19
- .string()
20
- .min(1)
21
- .describe("What to compute. Be specific: which files to read, what analysis to " + "run, what output format to return (table, statistics, base64 plot)."),
22
- });
23
- /** Build the `run_ephemeral` tool bound to the registered workflow + mint deps. */
24
- export function createRunEphemeralTool(deps) {
25
- return defineTool({
26
- id: "run_ephemeral",
27
- description: "Run a quick computation on the analysis data in a read-only sandbox. " +
28
- "Use for ad-hoc data exploration: inspect a CSV, compute statistics, " +
29
- "generate plot data, preview transformations. The sandbox cannot " +
30
- "create or save files — results are returned inline. For persistent " +
31
- "analyses that produce artifacts, use generate_plan + executePlan instead.",
32
- inputSchema,
33
- execute: async (input, ctx) => {
34
- const { session } = ctx;
35
- if (session.scope.kind !== "analysis") {
36
- throw new Error("run_ephemeral requires an analysis-scoped session — got " + session.scope.kind);
37
- }
38
- if (!session.auth) {
39
- throw new Error("run_ephemeral: session is missing its auth capability");
40
- }
41
- const authorization = await deps.runAuthorizer.authorize({
42
- auth: session.auth,
43
- scope: session.scope,
44
- provenance: session.provenance,
45
- frame: { runId: "ephemeral", stepId: "ephemeral" },
46
- });
47
- const { runSession } = authorization;
48
- const execId = generateExecutionId("ephemeral-executor");
49
- const workflowId = `${EPHEMERAL_WORKFLOW_PREFIX}${execId}`;
50
- try {
51
- const outcome = await deps.runLauncher.launchAndAwait(deps.workflow, { workflowId }, { runSession, prompt: input.prompt }, { signal: ctx.signal });
52
- if (outcome.status === "cancelled") {
53
- return ok({ text: "(ephemeral exploration cancelled)", durationMs: 0 });
54
- }
55
- return ok({
56
- text: outcome.result.text,
57
- durationMs: outcome.result.durationMs,
58
- });
59
- }
60
- finally {
61
- await deps.runAuthorizer.revoke(authorization, "ephemeral-completed").catch(() => { });
62
- }
63
- },
64
- });
65
- }