@inflexa-ai/harness 0.46.2 → 0.47.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.
- package/README.md +1 -1
- package/dist/agents/conversation-agent.d.ts +3 -8
- package/dist/agents/conversation-agent.js +24 -4
- package/dist/agents/report-session-agent.d.ts +11 -14
- package/dist/agents/report-session-agent.js +30 -17
- package/dist/agents/sandbox/shared.d.ts +18 -13
- package/dist/agents/sandbox/shared.js +42 -27
- package/dist/agents/sandbox/types.d.ts +1 -1
- package/dist/agents/sandbox-catalog.d.ts +2 -0
- package/dist/agents/sandbox-catalog.js +30 -1
- package/dist/app/synthesize-run.d.ts +10 -6
- package/dist/app/synthesize-run.js +4 -2
- package/dist/contracts/analogy-report.d.ts +46 -2
- package/dist/contracts/analogy-report.js +31 -25
- package/dist/contracts/chat-parts.d.ts +3 -14
- package/dist/contracts/report-reference.d.ts +2 -1
- package/dist/contracts/report-reference.js +2 -1
- package/dist/contracts/schemas/chat-parts.d.ts +0 -27
- package/dist/contracts/schemas/chat-parts.js +1 -3
- package/dist/execution/run-canceler.d.ts +2 -0
- package/dist/execution/run-canceler.js +9 -0
- package/dist/execution/run-synthesis.d.ts +36 -8
- package/dist/execution/run-synthesis.js +114 -32
- package/dist/index.d.ts +2 -5
- package/dist/index.js +3 -6
- package/dist/input-scan/enrich.d.ts +5 -10
- package/dist/input-scan/enrich.js +12 -8
- package/dist/lib/markdown-pdf.d.ts +27 -0
- package/dist/lib/markdown-pdf.js +236 -0
- package/dist/lib/metrics.d.ts +31 -0
- package/dist/lib/metrics.js +64 -0
- package/dist/lib/pdf-text.d.ts +23 -0
- package/dist/lib/pdf-text.js +34 -0
- package/dist/lib/regulatory-corpus/fetch-fda-guidance.js +3 -5
- package/dist/lib/regulatory-corpus/fetch-ich.js +3 -5
- package/dist/loop/run-loop.d.ts +5 -0
- package/dist/loop/run-loop.js +30 -2
- package/dist/loop/tool-name-repair.d.ts +11 -0
- package/dist/loop/tool-name-repair.js +23 -0
- package/dist/loop/types.d.ts +14 -0
- package/dist/memory/card-builders.d.ts +1 -1
- package/dist/prompts/SOUL.d.ts +6 -6
- package/dist/prompts/SOUL.js +22 -121
- package/dist/prompts/analogical-reasoner.d.ts +1 -1
- package/dist/prompts/analogical-reasoner.js +35 -101
- package/dist/prompts/briefing.d.ts +20 -11
- package/dist/prompts/briefing.js +36 -19
- package/dist/prompts/conversation.d.ts +1 -1
- package/dist/prompts/conversation.js +103 -383
- package/dist/prompts/planner.d.ts +1 -5
- package/dist/prompts/planner.js +45 -128
- package/dist/prompts/report-session.d.ts +1 -1
- package/dist/prompts/report-session.js +26 -57
- package/dist/prompts/sandbox/bulk-transcriptomics-agent.d.ts +1 -1
- package/dist/prompts/sandbox/bulk-transcriptomics-agent.js +3 -3
- package/dist/prompts/sandbox/cheminformatics-agent.d.ts +1 -1
- package/dist/prompts/sandbox/cheminformatics-agent.js +12 -47
- package/dist/prompts/sandbox/chromatin-agent.d.ts +1 -1
- package/dist/prompts/sandbox/chromatin-agent.js +4 -5
- package/dist/prompts/sandbox/data-profiler.js +11 -34
- package/dist/prompts/sandbox/dna-methylation-agent.d.ts +1 -1
- package/dist/prompts/sandbox/dna-methylation-agent.js +3 -1
- package/dist/prompts/sandbox/drug-repurposing-agent.d.ts +1 -1
- package/dist/prompts/sandbox/drug-repurposing-agent.js +23 -73
- package/dist/prompts/sandbox/enrichment-agent.d.ts +1 -1
- package/dist/prompts/sandbox/enrichment-agent.js +3 -1
- package/dist/prompts/sandbox/genomic-variant-agent.d.ts +1 -1
- package/dist/prompts/sandbox/genomic-variant-agent.js +3 -4
- package/dist/prompts/sandbox/immune-profiling-agent.d.ts +1 -1
- package/dist/prompts/sandbox/immune-profiling-agent.js +5 -4
- package/dist/prompts/sandbox/metabolomics-agent.d.ts +1 -1
- package/dist/prompts/sandbox/metabolomics-agent.js +3 -1
- package/dist/prompts/sandbox/microbiome-agent.d.ts +1 -1
- package/dist/prompts/sandbox/microbiome-agent.js +3 -1
- package/dist/prompts/sandbox/multi-omics-integration-agent.d.ts +1 -1
- package/dist/prompts/sandbox/multi-omics-integration-agent.js +3 -1
- package/dist/prompts/sandbox/multimodal-sc-agent.d.ts +1 -1
- package/dist/prompts/sandbox/multimodal-sc-agent.js +3 -1
- package/dist/prompts/sandbox/network-agent.d.ts +1 -1
- package/dist/prompts/sandbox/network-agent.js +3 -1
- package/dist/prompts/sandbox/pkpd-clinical-response-agent.d.ts +1 -1
- package/dist/prompts/sandbox/pkpd-clinical-response-agent.js +4 -7
- package/dist/prompts/sandbox/proteomics-agent.d.ts +1 -1
- package/dist/prompts/sandbox/proteomics-agent.js +3 -1
- package/dist/prompts/sandbox/scientific-executor.d.ts +1 -1
- package/dist/prompts/sandbox/scientific-executor.js +0 -12
- package/dist/prompts/sandbox/single-cell-agent.d.ts +1 -1
- package/dist/prompts/sandbox/single-cell-agent.js +3 -1
- package/dist/prompts/sandbox/spatial-omics-agent.d.ts +1 -1
- package/dist/prompts/sandbox/spatial-omics-agent.js +3 -1
- package/dist/prompts/sandbox/statistical-modeling-agent.d.ts +1 -1
- package/dist/prompts/sandbox/statistical-modeling-agent.js +4 -4
- package/dist/prompts/sandbox/translational-safety-agent.d.ts +1 -1
- package/dist/prompts/sandbox/translational-safety-agent.js +10 -29
- package/dist/prompts/sandbox-standards.d.ts +15 -18
- package/dist/prompts/sandbox-standards.js +96 -305
- package/dist/prompts/synthesis-agent.d.ts +1 -1
- package/dist/prompts/synthesis-agent.js +24 -90
- package/dist/provenance/collector.d.ts +2 -5
- package/dist/provenance/collector.js +2 -5
- package/dist/provenance/seam.d.ts +36 -1
- package/dist/provenance/workspace-reads.d.ts +36 -0
- package/dist/provenance/workspace-reads.js +33 -0
- package/dist/report-model/production-resolver.d.ts +22 -52
- package/dist/report-model/production-resolver.js +43 -112
- package/dist/report-render/chart-export.d.ts +9 -0
- package/dist/report-render/chart-export.js +1 -1
- package/dist/report-render/views/chart-view.d.ts +1 -0
- package/dist/report-render/views/chart-view.js +1 -0
- package/dist/report-render/views/lineage.d.ts +1 -0
- package/dist/report-render/views/page-view.d.ts +1 -0
- package/dist/report-render/views/page-view.js +1 -0
- package/dist/report-render/views/prose.d.ts +1 -0
- package/dist/report-render/views/prose.js +1 -0
- package/dist/report-render/views/references-view.d.ts +1 -0
- package/dist/report-render/views/values.d.ts +1 -0
- package/dist/report-render/views/values.js +1 -0
- package/dist/runtime/assemble.d.ts +20 -9
- package/dist/runtime/assemble.js +47 -38
- package/dist/sandbox/client.d.ts +5 -3
- package/dist/sandbox/create-sandbox.d.ts +7 -12
- package/dist/sandbox/create-sandbox.js +15 -37
- package/dist/sandbox/docker-client.d.ts +1 -3
- package/dist/sandbox/docker-client.js +3 -5
- package/dist/sandbox/exec-outcome.d.ts +11 -11
- package/dist/sandbox/exec-outcome.js +22 -22
- package/dist/sandbox/exec.d.ts +5 -0
- package/dist/sandbox/exec.js +9 -1
- package/dist/sandbox/identity.d.ts +4 -16
- package/dist/sandbox/identity.js +5 -21
- package/dist/sandbox/k8s-client.d.ts +0 -1
- package/dist/sandbox/k8s-client.js +8 -13
- package/dist/sandbox/lease-names.d.ts +6 -0
- package/dist/sandbox/lease-names.js +12 -0
- package/dist/sandbox/leases.d.ts +105 -0
- package/dist/sandbox/leases.js +519 -0
- package/dist/sandbox/liveness.d.ts +5 -2
- package/dist/sandbox/mount-plan.d.ts +10 -1
- package/dist/sandbox/mount-plan.js +7 -1
- package/dist/sandbox/reconciler.d.ts +58 -0
- package/dist/sandbox/reconciler.js +153 -0
- package/dist/sandbox/sandbox-step-translate.d.ts +1 -1
- package/dist/sandbox/types.d.ts +25 -18
- package/dist/sandbox/types.js +10 -4
- package/dist/schemas/plan-schemas.d.ts +0 -21
- package/dist/schemas/plan-schemas.js +2 -3
- package/dist/schemas/run-synthesis.d.ts +2 -2
- package/dist/schemas/run-synthesis.js +3 -3
- package/dist/schemas/validate-plan.d.ts +1 -14
- package/dist/schemas/validate-plan.js +5 -24
- package/dist/schemas/workflow-state.d.ts +3 -32
- package/dist/schemas/workflow-state.js +4 -13
- package/dist/state/index.d.ts +0 -1
- package/dist/state/index.js +0 -1
- package/dist/state/migrations/20261030120000_lease_the_sandboxes.d.ts +7 -0
- package/dist/state/migrations/20261030120000_lease_the_sandboxes.js +34 -0
- package/dist/state/migrations/20261030120100_drop_the_report_derivations.d.ts +5 -0
- package/dist/state/migrations/20261030120100_drop_the_report_derivations.js +9 -0
- package/dist/state/migrations/20261030120200_keep_the_report_derivations.d.ts +6 -0
- package/dist/state/migrations/20261030120200_keep_the_report_derivations.js +10 -0
- package/dist/state/migrations/index.js +6 -0
- package/dist/state/purge-analysis.d.ts +4 -2
- package/dist/state/purge-analysis.js +22 -11
- package/dist/state/sandbox-leases.d.ts +81 -0
- package/dist/state/sandbox-leases.js +247 -0
- package/dist/state/schema.d.ts +1 -13
- package/dist/state/schema.js +1 -6
- package/dist/state/step-executions.d.ts +0 -2
- package/dist/state/step-executions.js +1 -4
- package/dist/tasks/data-profile.d.ts +40 -2
- package/dist/tasks/data-profile.js +89 -87
- package/dist/tools/ad-hoc-router.d.ts +1 -6
- package/dist/tools/ad-hoc-router.js +5 -48
- package/dist/tools/bio/comptox.js +1 -1
- package/dist/tools/bio/drug-gene-interactions.js +1 -1
- package/dist/tools/bio/gene-disease-evidence.js +1 -1
- package/dist/tools/bio/keys.d.ts +1 -1
- package/dist/tools/bio/pubmed.js +31 -0
- package/dist/tools/bio/search-gene.js +17 -0
- package/dist/tools/bio/search-geo-datasets.js +13 -0
- package/dist/tools/bio/search-regulatory-approvals.js +1 -1
- package/dist/tools/define-tool.d.ts +25 -2
- package/dist/tools/define-tool.js +11 -1
- package/dist/tools/display/show-user.js +1 -1
- package/dist/tools/execute-analysis.d.ts +1 -3
- package/dist/tools/execute-analysis.js +5 -33
- package/dist/tools/report-session/index.d.ts +0 -1
- package/dist/tools/report-session/index.js +0 -1
- package/dist/tools/report-session/script-tools.d.ts +30 -0
- package/dist/tools/report-session/script-tools.js +177 -0
- package/dist/tools/research/generate-analogy-report.d.ts +16 -9
- package/dist/tools/research/generate-analogy-report.js +111 -49
- package/dist/tools/research/generate-plan.d.ts +102 -7
- package/dist/tools/research/generate-plan.js +74 -43
- package/dist/tools/research/index.d.ts +4 -3
- package/dist/tools/research/index.js +4 -3
- package/dist/tools/research/inspect-run.d.ts +0 -1
- package/dist/tools/research/inspect-run.js +5 -10
- package/dist/tools/research/search-arxiv.js +15 -0
- package/dist/tools/research/search-github-repos.js +13 -0
- package/dist/tools/research/search-semantic-scholar.js +16 -0
- package/dist/tools/research/synthesis-lookups.d.ts +21 -0
- package/dist/tools/research/synthesis-lookups.js +29 -0
- package/dist/tools/research/web-fetch.d.ts +1 -1
- package/dist/tools/research/web-fetch.js +14 -12
- package/dist/tools/sandbox/lease-tools.d.ts +32 -0
- package/dist/tools/sandbox/lease-tools.js +60 -0
- package/dist/tools/script/codemode-worker.d.ts +5 -0
- package/dist/tools/script/codemode-worker.js +5 -0
- package/dist/tools/script/file-tools.d.ts +100 -0
- package/dist/tools/script/file-tools.js +377 -0
- package/dist/tools/script/metrics.d.ts +21 -0
- package/dist/tools/script/metrics.js +38 -0
- package/dist/tools/script/quickjs.wasm +0 -0
- package/dist/tools/script/run-script.d.ts +76 -0
- package/dist/tools/script/run-script.js +326 -0
- package/dist/tools/script/scratch.d.ts +81 -0
- package/dist/tools/script/scratch.js +142 -0
- package/dist/tools/start-report-session.js +1 -1
- package/dist/tools/workspace/edit-file.js +2 -1
- package/dist/tools/workspace/execute-command.d.ts +9 -13
- package/dist/tools/workspace/execute-command.js +23 -19
- package/dist/tools/workspace/file-stat.js +1 -1
- package/dist/tools/workspace/grep.d.ts +5 -2
- package/dist/tools/workspace/grep.js +19 -10
- package/dist/tools/workspace/mutator.d.ts +48 -4
- package/dist/tools/workspace/mutator.js +43 -12
- package/dist/tools/workspace/read-file.d.ts +5 -2
- package/dist/tools/workspace/read-file.js +15 -11
- package/dist/tools/workspace/read-surface.d.ts +17 -0
- package/dist/tools/workspace/read-surface.js +17 -0
- package/dist/tools/workspace/result-bounds.d.ts +1 -0
- package/dist/tools/workspace/run-exec.d.ts +12 -13
- package/dist/tools/workspace/run-exec.js +13 -13
- package/dist/tools/workspace/scan-inputs.d.ts +2 -5
- package/dist/tools/workspace/scan-inputs.js +2 -3
- package/dist/tools/workspace/show-file.js +1 -1
- package/dist/tools/workspace/show-plan.js +4 -3
- package/dist/tools/workspace/write-file.js +2 -1
- package/dist/workflows/execute-analysis-scheduler.d.ts +0 -26
- package/dist/workflows/execute-analysis-scheduler.js +12 -32
- package/dist/workflows/execute-analysis.d.ts +17 -35
- package/dist/workflows/execute-analysis.js +13 -107
- package/dist/workflows/pause.js +29 -22
- package/dist/workflows/sandbox-step.d.ts +16 -31
- package/dist/workflows/sandbox-step.js +36 -71
- package/dist/workflows/test/sql-writes.d.ts +0 -1
- package/dist/workflows/test/sql-writes.js +0 -2
- package/dist/workspace/filesystem.d.ts +2 -2
- package/dist/workspace/filesystem.js +10 -5
- package/dist/workspace/paths.d.ts +19 -1
- package/dist/workspace/paths.js +22 -1
- package/package.json +6 -3
- package/dist/prompts/literature-reviewer.d.ts +0 -1
- package/dist/prompts/literature-reviewer.js +0 -114
- package/dist/sandbox/reaper.d.ts +0 -81
- package/dist/sandbox/reaper.js +0 -161
- package/dist/sandbox/step-sandbox.d.ts +0 -47
- package/dist/sandbox/step-sandbox.js +0 -53
- package/dist/state/active-sandboxes.d.ts +0 -33
- package/dist/state/active-sandboxes.js +0 -65
- package/dist/tasks/extract-values-script.d.ts +0 -64
- package/dist/tasks/extract-values-script.js +0 -180
- package/dist/tasks/extract-values.d.ts +0 -77
- package/dist/tasks/extract-values.js +0 -146
- package/dist/tools/report-session/derive-table.d.ts +0 -164
- package/dist/tools/report-session/derive-table.js +0 -419
- package/dist/tools/research/literature-reviewer.d.ts +0 -42
- package/dist/tools/research/literature-reviewer.js +0 -107
- package/dist/workflows/metrics.d.ts +0 -23
- package/dist/workflows/metrics.js +0 -38
package/README.md
CHANGED
|
@@ -101,7 +101,7 @@ function pinoAsHarnessLogger(p: pino.Logger, names: readonly string[] = []): Log
|
|
|
101
101
|
|
|
102
102
|
A chat turn is a **durable workflow**. The harness stores the opening, each round, and the outcome of the turn, and a recovery continues a turn from its checkpoints. The harness ships no HTTP layer, thus the host owns the route. Compute-heavy work runs as durable workflows too — `executeAnalysis` starts a child workflow per plan step once its dependencies have completed, and each step drives a sandbox agent inside a container. The same `runLoop` primitive runs in each workflow, and each model call and each tool call is a durable step.
|
|
103
103
|
|
|
104
|
-
The sandbox protocol is submit-then-poll, which lets a long run survive a host restart. Each exec runs inside one durable step: the host submits the command with `POST /exec`, and then it polls `GET /exec/{execId}?since={cursor}` until the result. A recovered step submits the same exec id again, and the sandbox gives the existing record, thus the command does not run again. The sandbox initiates nothing and has no egress, and confinement keeps each other peer away from its exec port. Refer to the [`harness-sandbox-exec`](./openspec/specs/harness-sandbox-exec/) spec.
|
|
104
|
+
The sandbox protocol is submit-then-poll, which lets a long run survive a host restart. Each exec runs inside one durable step: the host submits the command with `POST /exec`, and then it polls `GET /exec/{execId}?since={cursor}` until the result. A recovered step submits the same exec id again, and the sandbox gives the existing record, thus the command does not run again. The sandbox initiates nothing and has no egress, and confinement keeps each other peer away from its exec port. Refer to the [`harness-sandbox-exec`](./openspec/specs/harness-sandbox-exec/) spec. A consumer holds a sandbox through a lease: the step agent acquires a size with `acquire_sandbox`, and a detached lease workflow owns the machine, its admission against one budget, its idle removal, and its teardown. Refer to the [`sandbox-leases`](./openspec/specs/sandbox-leases/) spec.
|
|
105
105
|
|
|
106
106
|
## Further reading
|
|
107
107
|
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
import type { Pool } from "pg";
|
|
27
27
|
import type { ExecuteAnalysisInput, ExecuteAnalysisResult } from "../workflows/execute-analysis.js";
|
|
28
28
|
import type { EnsureSessionStateResult } from "../app/report-session-runtime.js";
|
|
29
|
-
import type { ResourcePolicy } from "../config/resource-limits.js";
|
|
30
29
|
import type { ChromeConfig } from "../lib/chrome.js";
|
|
31
30
|
import type { AcquireEyes } from "../lib/eyes.js";
|
|
32
31
|
import type { ToolOutputStore } from "../loop/tool-output.js";
|
|
@@ -47,6 +46,7 @@ import type { Logger } from "../lib/logger.js";
|
|
|
47
46
|
import type { UsageRecorder } from "../billing/usage-recorder.js";
|
|
48
47
|
import type { CitationResolver } from "../citations/types.js";
|
|
49
48
|
import { type WebSearchEngine } from "../tools/research/web-search.js";
|
|
49
|
+
import type { ScriptRuntime } from "../tools/script/run-script.js";
|
|
50
50
|
/** Canonical agent id — the single source of truth. */
|
|
51
51
|
export declare const CONVERSATION_AGENT_ID: "conversation-agent";
|
|
52
52
|
/**
|
|
@@ -142,13 +142,6 @@ export type ConversationAgentDeps = EnvironmentStorePaths & {
|
|
|
142
142
|
* `write-file` session event for each successful write.
|
|
143
143
|
*/
|
|
144
144
|
readonly provenance?: ProvenanceSeam;
|
|
145
|
-
/**
|
|
146
|
-
* Host resource policy — per-step ceilings + machine budget. `generate_plan`
|
|
147
|
-
* states the ceilings to the planner and validates against them;
|
|
148
|
-
* `execute_analysis` snapshots the budget into the workflow input. Absent,
|
|
149
|
-
* planning guidance and scheduling keep their legacy behavior.
|
|
150
|
-
*/
|
|
151
|
-
readonly resourcePolicy?: ResourcePolicy;
|
|
152
145
|
/**
|
|
153
146
|
* Embedder-contributed conversation-tool seam — additional tools the host
|
|
154
147
|
* supplies, appended after the built-in roster. The harness stays agnostic to
|
|
@@ -156,6 +149,8 @@ export type ConversationAgentDeps = EnvironmentStorePaths & {
|
|
|
156
149
|
* built-in tool.
|
|
157
150
|
*/
|
|
158
151
|
readonly hostTools?: readonly Tool[];
|
|
152
|
+
/** Where the VM of `run_script` comes from. A bundled host gives the embedded paths; see `ScriptRuntime`. */
|
|
153
|
+
readonly scriptRuntime?: ScriptRuntime;
|
|
159
154
|
/**
|
|
160
155
|
* The farm-extension seam of the embedder. When it is bound,
|
|
161
156
|
* `execute_analysis` links the packages of the plan into the farm of the
|
|
@@ -44,6 +44,9 @@ import { createStartReportSessionTool } from "../tools/start-report-session.js";
|
|
|
44
44
|
import { createResolveCitationTool } from "../tools/research/resolve-citation.js";
|
|
45
45
|
import { createWebFetchTool } from "../tools/research/web-fetch.js";
|
|
46
46
|
import { createWebSearchTool } from "../tools/research/web-search.js";
|
|
47
|
+
import { createScriptFileTools } from "../tools/script/file-tools.js";
|
|
48
|
+
import { createScriptScratch } from "../tools/script/scratch.js";
|
|
49
|
+
import { conversationSessionDir } from "../workspace/paths.js";
|
|
47
50
|
/** Canonical agent id — the single source of truth. */
|
|
48
51
|
export const CONVERSATION_AGENT_ID = "conversation-agent";
|
|
49
52
|
/** Runaway guard — heavy tool-driving turns need generous headroom. */
|
|
@@ -52,7 +55,7 @@ const CONVERSATION_MAX_ITERATIONS = 200;
|
|
|
52
55
|
const CONVERSATION_COMPACTION = { turnStartBudget: 150_000, budget: 200_000 };
|
|
53
56
|
/** Build the conversation `AgentDefinition` with every tool fully dep-bound. */
|
|
54
57
|
export function createConversationAgent(deps) {
|
|
55
|
-
const { provider, pool, embedding, workspaceFs, model, utilityProvider, utilityModel, executeAnalysisWorkflow, runAuthorizer, runLauncher, bioKeys, chrome,
|
|
58
|
+
const { provider, pool, embedding, workspaceFs, model, utilityProvider, utilityModel, executeAnalysisWorkflow, runAuthorizer, runLauncher, bioKeys, chrome, hostTools, refStorePath, farmLockFile, imagePackagesFile, readPoolInventory, usageRecorder, toolOutputStore, citationResolver, webSearch, } = deps;
|
|
56
59
|
const workingMemory = createWorkingMemory(pool);
|
|
57
60
|
const ncbi = createNcbiTools(bioKeys);
|
|
58
61
|
const chemDb = createChemDbTools(bioKeys, { logger: deps.logger });
|
|
@@ -65,7 +68,18 @@ export function createConversationAgent(deps) {
|
|
|
65
68
|
provenance: deps.provenance,
|
|
66
69
|
logger: deps.logger,
|
|
67
70
|
});
|
|
68
|
-
|
|
71
|
+
// The scratch directory of each conversation: the scripts of `run_script`, and the files that they derive.
|
|
72
|
+
const scriptScratch = createScriptScratch({
|
|
73
|
+
resolveWorkspaceRoot: deps.resolveWorkspaceRoot,
|
|
74
|
+
sessionDir: conversationSessionDir,
|
|
75
|
+
provenance: deps.provenance,
|
|
76
|
+
logger: deps.logger,
|
|
77
|
+
});
|
|
78
|
+
// The lookups and the light work on tables run in a script (`run_script`). Each tool asks no approval, and a
|
|
79
|
+
// script writes only into the scratch directory of its conversation.
|
|
80
|
+
const scriptTools = [
|
|
81
|
+
// Tables of the workspace in, derived files and chart files out.
|
|
82
|
+
...createScriptFileTools({ workspaceFs, resolveWorkspaceRoot: deps.resolveWorkspaceRoot, scratch: scriptScratch }),
|
|
69
83
|
// Identifier resolution — the ENSG most other bio tools key off, and the
|
|
70
84
|
// UniProt accession that the structure tools take.
|
|
71
85
|
searchGeneTool,
|
|
@@ -112,6 +126,8 @@ export function createConversationAgent(deps) {
|
|
|
112
126
|
targetSafetyTool,
|
|
113
127
|
// EPA CompTox (toxcast / hazard / chemical / exposure behind one dataset).
|
|
114
128
|
chemDb.comptox,
|
|
129
|
+
];
|
|
130
|
+
const tools = [
|
|
115
131
|
// What reference data this install actually holds. The conversation agent is
|
|
116
132
|
// where provisioning is decided — an embedder may give it a way to install more,
|
|
117
133
|
// and a host that does asks the user to approve the download. Deciding that
|
|
@@ -140,10 +156,11 @@ export function createConversationAgent(deps) {
|
|
|
140
156
|
createGeneratePlanTool({
|
|
141
157
|
conversation: { provider, model },
|
|
142
158
|
pool,
|
|
143
|
-
resourcePolicy,
|
|
144
159
|
usageRecorder,
|
|
145
160
|
toolOutputStore,
|
|
146
161
|
bioKeys,
|
|
162
|
+
workspace: { workspaceFs, pool, embedding, resolveWorkspaceRoot: deps.resolveWorkspaceRoot },
|
|
163
|
+
scriptRuntime: deps.scriptRuntime,
|
|
147
164
|
knowledge: deps.knowledge,
|
|
148
165
|
refStorePath,
|
|
149
166
|
farmLockFile,
|
|
@@ -156,7 +173,6 @@ export function createConversationAgent(deps) {
|
|
|
156
173
|
executeAnalysisWorkflow,
|
|
157
174
|
runAuthorizer,
|
|
158
175
|
runLauncher,
|
|
159
|
-
resourcePolicy,
|
|
160
176
|
utilityProvider,
|
|
161
177
|
utilityModel,
|
|
162
178
|
farmLockFile,
|
|
@@ -193,6 +209,7 @@ export function createConversationAgent(deps) {
|
|
|
193
209
|
usageRecorder,
|
|
194
210
|
toolOutputStore,
|
|
195
211
|
logger: deps.logger,
|
|
212
|
+
scriptRuntime: deps.scriptRuntime,
|
|
196
213
|
}, deps.registerSubAgent),
|
|
197
214
|
// Workspace semantic search + raw read/grep over the read seam.
|
|
198
215
|
createWorkspaceSearchTool(pool, embedding),
|
|
@@ -219,6 +236,9 @@ export function createConversationAgent(deps) {
|
|
|
219
236
|
systemPrompt: composeSystemPrompt(conversationPrompt, { identity: true, conversational: true }),
|
|
220
237
|
model,
|
|
221
238
|
tools,
|
|
239
|
+
scriptTools,
|
|
240
|
+
scriptRuntime: deps.scriptRuntime,
|
|
241
|
+
scriptScratch,
|
|
222
242
|
maxIterations: CONVERSATION_MAX_ITERATIONS,
|
|
223
243
|
compaction: CONVERSATION_COMPACTION,
|
|
224
244
|
};
|
|
@@ -11,11 +11,12 @@
|
|
|
11
11
|
* the workspace search, the run inspection, and the data-profile inspection. It
|
|
12
12
|
* holds no planner, no run launcher, no working-memory write, and no sandbox
|
|
13
13
|
* mutate surface. Thus no tool starts a run, and no tool changes an analysis. The
|
|
14
|
-
* roster omits those tools, and no runtime guard blocks them.
|
|
14
|
+
* roster omits those tools, and no runtime guard blocks them. No tool runs a
|
|
15
|
+
* container.
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
* analysis
|
|
18
|
-
*
|
|
17
|
+
* A derivation of a table runs in a script (`run_script`), and it changes no
|
|
18
|
+
* analysis: it mints no run id, it registers no artifact, and it writes under the
|
|
19
|
+
* directory of the session alone.
|
|
19
20
|
*
|
|
20
21
|
* The definition carries no per-session value. The system prompt composes through
|
|
21
22
|
* `composeSystemPrompt` with the identity part and the conversational part, the
|
|
@@ -26,11 +27,10 @@ import type { Pool } from "pg";
|
|
|
26
27
|
import type { AuthContext, Identity } from "../auth/types.js";
|
|
27
28
|
import type { ToolOutputStore } from "../loop/tool-output.js";
|
|
28
29
|
import type { AgentDefinition } from "../loop/types.js";
|
|
29
|
-
import type { SandboxClient } from "../sandbox/client.js";
|
|
30
30
|
import type { ReportSessionStateStore } from "../state/report-session-state.js";
|
|
31
31
|
import type { EmbeddingProvider, ProviderOptions } from "../providers/types.js";
|
|
32
32
|
import type { WorkspaceFilesystem } from "../workspace/filesystem.js";
|
|
33
|
-
import type
|
|
33
|
+
import { type ResolveWorkspaceRoot } from "../workspace/paths.js";
|
|
34
34
|
import type { ChromeConfig } from "../lib/chrome.js";
|
|
35
35
|
import type { AcquireEyes } from "../lib/eyes.js";
|
|
36
36
|
import type { Logger } from "../lib/logger.js";
|
|
@@ -40,6 +40,7 @@ import type { ReportVersionStore } from "../state/report-versions.js";
|
|
|
40
40
|
import type { ReportSessionStateGateway } from "../tools/report-authoring/authoring-tools.js";
|
|
41
41
|
import type { ProvenanceSeam } from "../provenance/seam.js";
|
|
42
42
|
import { type MakeSessionPagePublisher, type ResolvePageAsset, type ResolvePageUrl } from "../tools/report-session/index.js";
|
|
43
|
+
import type { ScriptRuntime } from "../tools/script/run-script.js";
|
|
43
44
|
/** Canonical agent id -- distinct from the id of the old templating agent. */
|
|
44
45
|
export declare const REPORT_SESSION_AGENT_ID: "report-session";
|
|
45
46
|
/**
|
|
@@ -68,14 +69,8 @@ export type ReportSessionAgentDeps = {
|
|
|
68
69
|
readonly resolveWorkspaceRoot: ResolveWorkspaceRoot;
|
|
69
70
|
/** Append-only version store -- the record tool gates the whole document first, then records one version. */
|
|
70
71
|
readonly store: ReportVersionStore;
|
|
71
|
-
/** Derivation ledger --
|
|
72
|
+
/** Derivation ledger -- `write_derived` appends one record for each derived table. */
|
|
72
73
|
readonly derivations: Pick<ReportSessionStateStore, "appendDerivation">;
|
|
73
|
-
/**
|
|
74
|
-
* Sandbox client -- the derivation tool runs one ephemeral container for each derived table, inside the
|
|
75
|
-
* step of its call. Omitted, the tool reports that the composition gives no sandbox, and it derives
|
|
76
|
-
* nothing.
|
|
77
|
-
*/
|
|
78
|
-
readonly sandboxClient?: SandboxClient;
|
|
79
74
|
/** Thread store -- the record tool reads the anchor of the report thread, and the preview tool names it. */
|
|
80
75
|
readonly threads: Pick<ThreadStore, "getThread" | "setAutoTitle">;
|
|
81
76
|
/** Headless-Chrome config -- the eyes tool opens the rendered page. */
|
|
@@ -118,7 +113,7 @@ export type ReportSessionAgentDeps = {
|
|
|
118
113
|
readonly resolvePageUrl?: ResolvePageUrl;
|
|
119
114
|
/**
|
|
120
115
|
* The provenance seam -- the acts of the session as typed events, and the frozen document of the
|
|
121
|
-
* analysis as opaque bytes. The tools that change the draft,
|
|
116
|
+
* analysis as opaque bytes. The tools that change the draft, preview the page, and
|
|
122
117
|
* record a version each emit through the session member, thus one bound member carries the whole
|
|
123
118
|
* session. The preview asks the read member before each render, and the page then carries the
|
|
124
119
|
* document. An unbound member emits nothing, or gives absence, and every tool acts the same.
|
|
@@ -128,6 +123,8 @@ export type ReportSessionAgentDeps = {
|
|
|
128
123
|
readonly logger?: Logger;
|
|
129
124
|
/** Adds `read_tool_output`. The loop of a report turn must keep its texts in the same store. */
|
|
130
125
|
readonly toolOutputStore?: ToolOutputStore;
|
|
126
|
+
/** Where the VM of `run_script` comes from. A bundled host gives the embedded paths; see `ScriptRuntime`. */
|
|
127
|
+
readonly scriptRuntime?: ScriptRuntime;
|
|
131
128
|
};
|
|
132
129
|
/** Build the report `AgentDefinition` with every tool bound to its deps. */
|
|
133
130
|
export declare function createReportSessionAgent(deps: ReportSessionAgentDeps): AgentDefinition;
|
|
@@ -11,11 +11,12 @@
|
|
|
11
11
|
* the workspace search, the run inspection, and the data-profile inspection. It
|
|
12
12
|
* holds no planner, no run launcher, no working-memory write, and no sandbox
|
|
13
13
|
* mutate surface. Thus no tool starts a run, and no tool changes an analysis. The
|
|
14
|
-
* roster omits those tools, and no runtime guard blocks them.
|
|
14
|
+
* roster omits those tools, and no runtime guard blocks them. No tool runs a
|
|
15
|
+
* container.
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
* analysis
|
|
18
|
-
*
|
|
17
|
+
* A derivation of a table runs in a script (`run_script`), and it changes no
|
|
18
|
+
* analysis: it mints no run id, it registers no artifact, and it writes under the
|
|
19
|
+
* directory of the session alone.
|
|
19
20
|
*
|
|
20
21
|
* The definition carries no per-session value. The system prompt composes through
|
|
21
22
|
* `composeSystemPrompt` with the identity part and the conversational part, the
|
|
@@ -23,16 +24,20 @@
|
|
|
23
24
|
* across threads, and the provider cache reuses it.
|
|
24
25
|
*/
|
|
25
26
|
import { createReadToolOutputTool } from "../tools/read-tool-output.js";
|
|
27
|
+
import { reportSessionDir } from "../workspace/paths.js";
|
|
28
|
+
import { createDocumentTools, createReadPdfTool } from "../tools/script/file-tools.js";
|
|
26
29
|
import { createReportAuthoringTools } from "../tools/report-authoring/authoring-tools.js";
|
|
27
|
-
import {
|
|
30
|
+
import { createExaminePageTool, createListPinnedArtifactsTool, createPreviewReportTool, createRecordVersionTool, } from "../tools/report-session/index.js";
|
|
28
31
|
import { createFileStatTool, createGrepTool, createListFilesTool, createReadFileTool, createWorkspaceSearchTool } from "../tools/workspace/index.js";
|
|
29
32
|
import { createInspectDataProfileTool, createInspectRunTool } from "../tools/research/index.js";
|
|
30
33
|
import { reportSessionPrompt } from "../prompts/report-session.js";
|
|
31
34
|
import { composeSystemPrompt } from "./system-prompt.js";
|
|
35
|
+
import { createReportScriptTools } from "../tools/report-session/script-tools.js";
|
|
36
|
+
import { createScriptScratch } from "../tools/script/scratch.js";
|
|
32
37
|
/** Canonical agent id -- distinct from the id of the old templating agent. */
|
|
33
38
|
export const REPORT_SESSION_AGENT_ID = "report-session";
|
|
34
39
|
/**
|
|
35
|
-
* Runaway guard. A full session — orient,
|
|
40
|
+
* Runaway guard. A full session — orient, compose each section, preview,
|
|
36
41
|
* look, record — drives more small tool calls than a conversation turn, thus it
|
|
37
42
|
* gets the headroom of the report runner (REPORT_AGENT_MAX_STEPS).
|
|
38
43
|
*/
|
|
@@ -50,7 +55,7 @@ export const REPORT_SESSION_PROVIDER_OPTIONS = {
|
|
|
50
55
|
/** Build the report `AgentDefinition` with every tool bound to its deps. */
|
|
51
56
|
export function createReportSessionAgent(deps) {
|
|
52
57
|
const { model, pool, embedding, workspaceFs, gateway, resolveWorkspaceRoot, store, threads, chrome, eyes, makeResolver, resolvePageAsset, logger } = deps;
|
|
53
|
-
const { derivations,
|
|
58
|
+
const { derivations, makeSessionPages, resolvePageUrl, provenance } = deps;
|
|
54
59
|
// The seam rides into each tool that lands an act of the session, thus the composition binds it one
|
|
55
60
|
// time and no tool reads a second source.
|
|
56
61
|
const observation = provenance ? { provenance } : {};
|
|
@@ -82,16 +87,6 @@ export function createReportSessionAgent(deps) {
|
|
|
82
87
|
resolveWorkspaceRoot,
|
|
83
88
|
logger,
|
|
84
89
|
}),
|
|
85
|
-
// The derivation tool. It reshapes the pinned evidence into one table under the
|
|
86
|
-
// session directory, on the sandbox rails of the value tier.
|
|
87
|
-
createDeriveTableTool({
|
|
88
|
-
gateway,
|
|
89
|
-
resolveWorkspaceRoot,
|
|
90
|
-
derivations,
|
|
91
|
-
sandboxClient,
|
|
92
|
-
...observation,
|
|
93
|
-
logger,
|
|
94
|
-
}),
|
|
95
90
|
// The render-and-preview tool. It resolves the page root per call.
|
|
96
91
|
createPreviewReportTool({
|
|
97
92
|
gateway,
|
|
@@ -126,11 +121,29 @@ export function createReportSessionAgent(deps) {
|
|
|
126
121
|
logger,
|
|
127
122
|
}),
|
|
128
123
|
];
|
|
124
|
+
// A derivation of a table of up to the read cap runs in a script, thus it starts no container. The scripts
|
|
125
|
+
// of a session stay beside its page.
|
|
126
|
+
const scriptScratch = createScriptScratch({ resolveWorkspaceRoot, sessionDir: reportSessionDir, provenance, logger });
|
|
127
|
+
// A PDF of the report is a document that a script builds from the content of the session, not a print of the
|
|
128
|
+
// page. Its images come from the directory of the session alone, thus no unpinned file reaches it.
|
|
129
|
+
const scriptTools = [
|
|
130
|
+
...createReportScriptTools({ gateway, workspaceFs, resolveWorkspaceRoot, derivations, provenance, logger }),
|
|
131
|
+
createReadPdfTool({ workspaceFs, resolveWorkspaceRoot }),
|
|
132
|
+
...createDocumentTools({
|
|
133
|
+
workspaceFs,
|
|
134
|
+
resolveWorkspaceRoot,
|
|
135
|
+
scratch: scriptScratch,
|
|
136
|
+
imageScope: (session) => (session.scope.threadId === undefined ? undefined : reportSessionDir(session.scope.threadId)),
|
|
137
|
+
}),
|
|
138
|
+
];
|
|
129
139
|
return {
|
|
130
140
|
id: REPORT_SESSION_AGENT_ID,
|
|
131
141
|
systemPrompt: composeSystemPrompt(reportSessionPrompt, { identity: true, conversational: true }),
|
|
132
142
|
model,
|
|
133
143
|
tools,
|
|
144
|
+
scriptTools,
|
|
145
|
+
scriptRuntime: deps.scriptRuntime,
|
|
146
|
+
scriptScratch,
|
|
134
147
|
maxIterations: REPORT_SESSION_MAX_ITERATIONS,
|
|
135
148
|
compaction: REPORT_SESSION_COMPACTION,
|
|
136
149
|
providerOptions: REPORT_SESSION_PROVIDER_OPTIONS,
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* `allowedWritePrefix` through the host-side `WorkspaceMutator` —,
|
|
11
11
|
* the workspace read tools (`read_file`, `grep`) over the shared
|
|
12
12
|
* `WorkspaceFilesystem`, `inspect_data_profile` over the shared `Pool`, and the
|
|
13
|
-
* bio/literature/context7
|
|
13
|
+
* bio/literature/context7 tools its `meta.tools` allowlist names.
|
|
14
14
|
*
|
|
15
15
|
* Tool resolution is a single registry lookup — every name in `meta.tools`
|
|
16
16
|
* must map to a concrete `Tool`; unknown names throw at composition time
|
|
@@ -20,8 +20,8 @@ import type { Querier } from "../../state/db.js";
|
|
|
20
20
|
import type { ToolOutputStore } from "../../loop/tool-output.js";
|
|
21
21
|
import type { AgentDefinition } from "../../loop/types.js";
|
|
22
22
|
import type { ChatProvider, EmbeddingProvider } from "../../providers/types.js";
|
|
23
|
-
import type {
|
|
24
|
-
import type { ExtendAnalysisFarm,
|
|
23
|
+
import type { BoundLease } from "../../sandbox/leases.js";
|
|
24
|
+
import type { ExtendAnalysisFarm, ToolchainSource } from "../../sandbox/types.js";
|
|
25
25
|
import type { WorkspaceFilesystem } from "../../workspace/filesystem.js";
|
|
26
26
|
import type { ProvenanceCollector as LineageCollector } from "../../provenance/collector.js";
|
|
27
27
|
import { type BioToolKeys } from "../../tools/bio/keys.js";
|
|
@@ -31,9 +31,10 @@ import type { EnvironmentStorePaths } from "../../config/environment-stores.js";
|
|
|
31
31
|
import type { Logger } from "../../lib/logger.js";
|
|
32
32
|
import type { CitationResolver } from "../../citations/types.js";
|
|
33
33
|
import { type KnowledgeClient, type TemplateBinding } from "../../tools/knowledge/index.js";
|
|
34
|
+
import type { ScriptRuntime } from "../../tools/script/run-script.js";
|
|
34
35
|
/**
|
|
35
36
|
* Tools every sandbox agent receives — sandbox-environment introspection,
|
|
36
|
-
* library docs,
|
|
37
|
+
* library docs, and the knowledge template. Spread into each
|
|
37
38
|
* agent's `meta.tools` so planner-facing metadata and the resolved tool record
|
|
38
39
|
* stay in sync. Keep minimal — only tools every agent genuinely needs.
|
|
39
40
|
*
|
|
@@ -47,14 +48,13 @@ import { type KnowledgeClient, type TemplateBinding } from "../../tools/knowledg
|
|
|
47
48
|
export declare const BASE_SANDBOX_TOOLS: readonly SandboxToolName[];
|
|
48
49
|
/** Per-step coordinates the composition root threads through every mutate tool. */
|
|
49
50
|
export type SandboxStepCoords = {
|
|
50
|
-
|
|
51
|
+
/** The lease of the step. `acquire_sandbox` and `release_sandbox` drive it, and each command runs on it. */
|
|
52
|
+
readonly lease: BoundLease;
|
|
51
53
|
/** Absolute host root of this analysis's workspace tree (resolved at the workflow body). */
|
|
52
54
|
readonly workspaceRoot: string;
|
|
53
55
|
readonly analysisId: string;
|
|
54
56
|
/** Absolute writable artifact directory for this step (e.g. stepWritePrefix(...)). */
|
|
55
57
|
readonly allowedWritePrefix: string;
|
|
56
|
-
/** Absolute unix-ms deadline of each exec. */
|
|
57
|
-
readonly deadlineMs: () => number;
|
|
58
58
|
/**
|
|
59
59
|
* The plan settings bound to the template of this step, from the durable
|
|
60
60
|
* step input. Reaches `knowledge_template` alone. Absent when the step
|
|
@@ -68,14 +68,16 @@ export type SandboxAgentDeps = EnvironmentStorePaths & {
|
|
|
68
68
|
readonly logger?: Logger;
|
|
69
69
|
readonly provider: ChatProvider;
|
|
70
70
|
readonly pool: Querier;
|
|
71
|
-
|
|
71
|
+
/** The toolchain of the sandboxes, as the sandbox client declares it. The orient-core prompt keys on it. */
|
|
72
|
+
readonly toolchainSource: ToolchainSource;
|
|
72
73
|
readonly workspaceFs: WorkspaceFilesystem;
|
|
73
74
|
/** Embedding provider for in-sandbox semantic `workspace_search`. Omit to skip that tool. */
|
|
74
75
|
readonly embedding?: EmbeddingProvider;
|
|
75
76
|
/**
|
|
76
77
|
* Step-scoped lineage collector fed by each `execute_command`'s
|
|
77
|
-
* `ExecResult.provenance` frame
|
|
78
|
-
*
|
|
78
|
+
* `ExecResult.provenance` frame, and by the reads of `read_file`, `grep`, and
|
|
79
|
+
* `read_pdf`. Records the input/script edges post-step registration
|
|
80
|
+
* translates into provenance parents.
|
|
79
81
|
*/
|
|
80
82
|
readonly lineageCollector?: LineageCollector;
|
|
81
83
|
/** Model id provenance label — the provider owns the wire model. */
|
|
@@ -103,8 +105,9 @@ export type SandboxAgentDeps = EnvironmentStorePaths & {
|
|
|
103
105
|
readonly toolOutputStore?: ToolOutputStore;
|
|
104
106
|
/**
|
|
105
107
|
* The farm-extension seam of the embedder. When it is bound, every
|
|
106
|
-
* sandbox agent gets the `link_packages` tool in its always-on substrate
|
|
107
|
-
*
|
|
108
|
+
* sandbox agent gets the `link_packages` tool in its always-on substrate.
|
|
109
|
+
* The system prompt is the same with and without it: the descriptions of
|
|
110
|
+
* `link_packages` and `list_available_packages` carry the link rules.
|
|
108
111
|
*/
|
|
109
112
|
readonly extendAnalysisFarm?: ExtendAnalysisFarm;
|
|
110
113
|
/**
|
|
@@ -114,6 +117,8 @@ export type SandboxAgentDeps = EnvironmentStorePaths & {
|
|
|
114
117
|
* of the open-source host and never an error.
|
|
115
118
|
*/
|
|
116
119
|
readonly knowledge?: KnowledgeClient;
|
|
120
|
+
/** Where the VM of `run_script` comes from, for the lookups of the agent. */
|
|
121
|
+
readonly scriptRuntime?: ScriptRuntime;
|
|
117
122
|
};
|
|
118
123
|
/** Per-agent override for the prompt composition and tool surface. */
|
|
119
124
|
export type SandboxAgentPromptOptions = {
|
|
@@ -138,7 +143,7 @@ export type SandboxAgentPromptOptions = {
|
|
|
138
143
|
*
|
|
139
144
|
* The composed `systemPrompt` is a **pure function of the agent type** — nothing
|
|
140
145
|
* from `deps.step` reaches it, so two steps of one run, and two runs of one
|
|
141
|
-
* analysis, send a byte-identical
|
|
146
|
+
* analysis, send a byte-identical prefix that the provider's prompt
|
|
142
147
|
* cache can actually reuse. Keep it that way: a single interpolated id or path
|
|
143
148
|
* makes every step's prefix unique again, and each step pays a full cache write
|
|
144
149
|
* and reads nothing back. Per-step values belong in the step's briefing (its
|
|
@@ -10,21 +10,20 @@
|
|
|
10
10
|
* `allowedWritePrefix` through the host-side `WorkspaceMutator` —,
|
|
11
11
|
* the workspace read tools (`read_file`, `grep`) over the shared
|
|
12
12
|
* `WorkspaceFilesystem`, `inspect_data_profile` over the shared `Pool`, and the
|
|
13
|
-
* bio/literature/context7
|
|
13
|
+
* bio/literature/context7 tools its `meta.tools` allowlist names.
|
|
14
14
|
*
|
|
15
15
|
* Tool resolution is a single registry lookup — every name in `meta.tools`
|
|
16
16
|
* must map to a concrete `Tool`; unknown names throw at composition time
|
|
17
17
|
* so misconfigured agents fail at startup, not at the first LLM call.
|
|
18
18
|
*/
|
|
19
19
|
import { createEditIntentStore } from "../../state/edit-intents.js";
|
|
20
|
-
import {
|
|
20
|
+
import { createWorkspaceReadLineage } from "../../provenance/workspace-reads.js";
|
|
21
|
+
import { sandboxOrientCorePromptFor, sandboxAnalysisStepStandardsPrompt } from "../../prompts/sandbox-standards.js";
|
|
21
22
|
import { composeSystemPrompt } from "../system-prompt.js";
|
|
22
23
|
// Sandbox-environment introspection, plus the farm-extension seam face.
|
|
23
24
|
import { createLinkPackagesTool, createListAvailablePackagesTool, createListAvailableRefsTool } from "../../tools/sandbox/index.js";
|
|
24
25
|
// Context7 docs (pure leaves).
|
|
25
26
|
import { queryDocsTool, resolveLibraryIdTool } from "../../tools/research/context7-docs.js";
|
|
26
|
-
// Run-inspection (dependency-bearing).
|
|
27
|
-
import { createInspectRunTool } from "../../tools/research/inspect-run.js";
|
|
28
27
|
// Data-profile retrieval (dependency-bearing) — always-on, see `createSandboxAgent`.
|
|
29
28
|
import { createInspectDataProfileTool } from "../../tools/research/inspect-data-profile.js";
|
|
30
29
|
// Bio leaf tools.
|
|
@@ -38,15 +37,17 @@ import { createEditFileTool, createExecuteCommandTool, createWorkspaceMutator, c
|
|
|
38
37
|
// Skills (declared per agent via meta.skills).
|
|
39
38
|
import { createSkillTools } from "../../tools/sandbox/skills.js";
|
|
40
39
|
import { createReadToolOutputTool } from "../../tools/read-tool-output.js";
|
|
40
|
+
import { createAcquireSandboxTool, createReleaseSandboxTool } from "../../tools/sandbox/lease-tools.js";
|
|
41
41
|
import { createReportBlockerTool } from "../../tools/sandbox/report-blocker.js";
|
|
42
42
|
import { createSubmitFileMetadataTool } from "../../tools/sandbox/submit-file-metadata.js";
|
|
43
43
|
import { toSandboxPath } from "../../workspace/paths.js";
|
|
44
44
|
import { SANDBOX_AGENT_DEFAULT_MAX_ITERATIONS } from "./types.js";
|
|
45
45
|
import { createResolveCitationTool } from "../../tools/research/resolve-citation.js";
|
|
46
46
|
import { createKnowledgeTemplateTool } from "../../tools/knowledge/index.js";
|
|
47
|
+
import { createReadPdfTool } from "../../tools/script/file-tools.js";
|
|
47
48
|
/**
|
|
48
49
|
* Tools every sandbox agent receives — sandbox-environment introspection,
|
|
49
|
-
* library docs,
|
|
50
|
+
* library docs, and the knowledge template. Spread into each
|
|
50
51
|
* agent's `meta.tools` so planner-facing metadata and the resolved tool record
|
|
51
52
|
* stay in sync. Keep minimal — only tools every agent genuinely needs.
|
|
52
53
|
*
|
|
@@ -62,9 +63,13 @@ export const BASE_SANDBOX_TOOLS = [
|
|
|
62
63
|
"listAvailableRefs",
|
|
63
64
|
"resolveLibraryId",
|
|
64
65
|
"queryDocs",
|
|
65
|
-
"inspectRun",
|
|
66
66
|
"knowledgeTemplate",
|
|
67
67
|
];
|
|
68
|
+
/**
|
|
69
|
+
* The tools of the allowlist that stay direct: the environment of the step. Each other tool of the allowlist is a
|
|
70
|
+
* lookup of an outside source, and it runs in `run_script`.
|
|
71
|
+
*/
|
|
72
|
+
const DIRECT_ALLOWLIST_TOOLS = new Set(["list_available_packages", "list_available_refs", "scan_inputs", "knowledge_template"]);
|
|
68
73
|
/**
|
|
69
74
|
* Resolve `meta.tools` into the bio/research tools record. The workspace
|
|
70
75
|
* read/mutate tools and `inspect_data_profile` are added by `createSandboxAgent`
|
|
@@ -89,13 +94,10 @@ function resolveSandboxTools(deps, tools, mutator) {
|
|
|
89
94
|
scanInputs: createScanInputsTool({
|
|
90
95
|
workspaceFs: deps.workspaceFs,
|
|
91
96
|
analysisId: deps.step.analysisId,
|
|
92
|
-
|
|
93
|
-
sandbox: deps.step.sandbox,
|
|
94
|
-
deadlineMs: deps.step.deadlineMs,
|
|
97
|
+
lease: deps.step.lease,
|
|
95
98
|
}),
|
|
96
99
|
resolveLibraryId: resolveLibraryIdTool,
|
|
97
100
|
queryDocs: queryDocsTool,
|
|
98
|
-
inspectRun: createInspectRunTool(deps.pool),
|
|
99
101
|
pubmed: ncbi.pubmed,
|
|
100
102
|
resolve_citation: deps.citationResolver === undefined ? undefined : createResolveCitationTool(deps.citationResolver),
|
|
101
103
|
searchGene: searchGeneTool,
|
|
@@ -146,8 +148,8 @@ function resolveSandboxTools(deps, tools, mutator) {
|
|
|
146
148
|
/** Build the workspace mutate + read tools every sandbox agent receives. In
|
|
147
149
|
* `readOnly` mode the write_file/edit_file pair is omitted; execute_command
|
|
148
150
|
* and the read tools stay. */
|
|
149
|
-
function buildWorkspaceTools(deps, readOnly) {
|
|
150
|
-
const { step,
|
|
151
|
+
function buildWorkspaceTools(deps, readOnly, readLineage) {
|
|
152
|
+
const { step, workspaceFs, pool, embedding, lineageCollector } = deps;
|
|
151
153
|
// The agent's writable working directory: relative paths resolve here, and
|
|
152
154
|
// writes are confined here. `allowedWritePrefix` is its host path; the
|
|
153
155
|
// in-sandbox path (the `execute_command` default cwd, see the harness-workspace-tools spec) is the same
|
|
@@ -170,10 +172,10 @@ function buildWorkspaceTools(deps, readOnly) {
|
|
|
170
172
|
]
|
|
171
173
|
: [];
|
|
172
174
|
const tools = [
|
|
175
|
+
createAcquireSandboxTool(step.lease),
|
|
176
|
+
createReleaseSandboxTool(step.lease),
|
|
173
177
|
createExecuteCommandTool({
|
|
174
|
-
|
|
175
|
-
sandbox: step.sandbox,
|
|
176
|
-
deadlineMs: step.deadlineMs,
|
|
178
|
+
lease: step.lease,
|
|
177
179
|
defaultCwd: sandboxWorkingDir,
|
|
178
180
|
lineageCollector,
|
|
179
181
|
mountRoot: `/${step.analysisId}`,
|
|
@@ -181,10 +183,10 @@ function buildWorkspaceTools(deps, readOnly) {
|
|
|
181
183
|
mutator,
|
|
182
184
|
}),
|
|
183
185
|
...mutateTools,
|
|
184
|
-
createReadFileTool(workspaceFs, hostWorkingDir),
|
|
186
|
+
createReadFileTool(workspaceFs, hostWorkingDir, readLineage),
|
|
185
187
|
createListFilesTool(workspaceFs, hostWorkingDir),
|
|
186
188
|
createFileStatTool(workspaceFs, hostWorkingDir),
|
|
187
|
-
createGrepTool(workspaceFs, hostWorkingDir),
|
|
189
|
+
createGrepTool(workspaceFs, hostWorkingDir, readLineage),
|
|
188
190
|
...(embedding ? [createWorkspaceSearchTool(pool, embedding)] : []),
|
|
189
191
|
];
|
|
190
192
|
return { tools, mutator };
|
|
@@ -200,7 +202,7 @@ function buildWorkspaceTools(deps, readOnly) {
|
|
|
200
202
|
*
|
|
201
203
|
* The composed `systemPrompt` is a **pure function of the agent type** — nothing
|
|
202
204
|
* from `deps.step` reaches it, so two steps of one run, and two runs of one
|
|
203
|
-
* analysis, send a byte-identical
|
|
205
|
+
* analysis, send a byte-identical prefix that the provider's prompt
|
|
204
206
|
* cache can actually reuse. Keep it that way: a single interpolated id or path
|
|
205
207
|
* makes every step's prefix unique again, and each step pays a full cache write
|
|
206
208
|
* and reads nothing back. Per-step values belong in the step's briefing (its
|
|
@@ -210,20 +212,27 @@ function buildWorkspaceTools(deps, readOnly) {
|
|
|
210
212
|
export function createSandboxAgent(deps, meta, body, opts = {}) {
|
|
211
213
|
const appendStandards = opts.appendAnalysisStepStandards ?? true;
|
|
212
214
|
// The layer order is fixed by the harness-sandbox-agents spec: the agent
|
|
213
|
-
// body, the orient core keyed on the toolchain of the sandbox client,
|
|
214
|
-
//
|
|
215
|
+
// body, the orient core keyed on the toolchain of the sandbox client, then
|
|
216
|
+
// the step standards.
|
|
215
217
|
// The client is the one declaration: the environment it provisions and the
|
|
216
218
|
// text that describes it come from the same value, thus a bag cannot
|
|
217
219
|
// describe a toolchain the sandbox does not have.
|
|
218
|
-
const sandboxLayer = [
|
|
219
|
-
sandboxOrientCorePromptFor(deps.sandboxClient.toolchainSource),
|
|
220
|
-
...(deps.extendAnalysisFarm ? [sandboxPackageLinkPrompt] : []),
|
|
221
|
-
...(appendStandards ? [sandboxAnalysisStepStandardsPrompt] : []),
|
|
222
|
-
];
|
|
220
|
+
const sandboxLayer = [sandboxOrientCorePromptFor(deps.toolchainSource), ...(appendStandards ? [sandboxAnalysisStepStandardsPrompt] : [])];
|
|
223
221
|
const agentBody = [body, ...sandboxLayer].map((s) => s.trim()).join("\n\n");
|
|
224
222
|
const systemPrompt = composeSystemPrompt(agentBody);
|
|
225
223
|
const skillTools = deps.skillsDir ? Object.values(createSkillTools({ skillsDir: deps.skillsDir, skills: meta.skills })) : [];
|
|
226
|
-
|
|
224
|
+
// The working directory is the one of the read tools, thus a relative path resolves to the same file.
|
|
225
|
+
const readLineage = deps.lineageCollector
|
|
226
|
+
? createWorkspaceReadLineage({
|
|
227
|
+
collector: deps.lineageCollector,
|
|
228
|
+
workspaceRoot: deps.step.workspaceRoot,
|
|
229
|
+
analysisId: deps.step.analysisId,
|
|
230
|
+
workingDir: deps.step.allowedWritePrefix,
|
|
231
|
+
logger: deps.logger,
|
|
232
|
+
})
|
|
233
|
+
: undefined;
|
|
234
|
+
const workspace = buildWorkspaceTools(deps, opts.readOnly ?? false, readLineage);
|
|
235
|
+
const allowlisted = resolveSandboxTools(deps, meta.tools, workspace.mutator);
|
|
227
236
|
const tools = [
|
|
228
237
|
...workspace.tools,
|
|
229
238
|
...(deps.toolOutputStore ? [createReadToolOutputTool(deps.toolOutputStore)] : []),
|
|
@@ -238,7 +247,7 @@ export function createSandboxAgent(deps, meta, body, opts = {}) {
|
|
|
238
247
|
// seam (the harness-sandbox-agents spec).
|
|
239
248
|
...(deps.extendAnalysisFarm ? [createLinkPackagesTool({ extendAnalysisFarm: deps.extendAnalysisFarm, analysisId: deps.step.analysisId })] : []),
|
|
240
249
|
...skillTools,
|
|
241
|
-
...
|
|
250
|
+
...allowlisted.filter((tool) => DIRECT_ALLOWLIST_TOOLS.has(tool.id)),
|
|
242
251
|
...(deps.reportsBlocker === true ? [createReportBlockerTool()] : []),
|
|
243
252
|
...(deps.fileMetadata ? [createSubmitFileMetadataTool(deps.fileMetadata)] : []),
|
|
244
253
|
];
|
|
@@ -247,6 +256,12 @@ export function createSandboxAgent(deps, meta, body, opts = {}) {
|
|
|
247
256
|
systemPrompt,
|
|
248
257
|
model: deps.model,
|
|
249
258
|
tools,
|
|
259
|
+
// A paper of the analysis is a PDF, and each step can need it, thus each agent reads PDFs in a script.
|
|
260
|
+
scriptTools: [
|
|
261
|
+
...allowlisted.filter((tool) => !DIRECT_ALLOWLIST_TOOLS.has(tool.id)),
|
|
262
|
+
createReadPdfTool({ workspaceFs: deps.workspaceFs, resolveWorkspaceRoot: () => Promise.resolve(deps.step.workspaceRoot), lineage: readLineage }),
|
|
263
|
+
],
|
|
264
|
+
scriptRuntime: deps.scriptRuntime,
|
|
250
265
|
maxIterations: meta.defaultMaxSteps ?? SANDBOX_AGENT_DEFAULT_MAX_ITERATIONS,
|
|
251
266
|
};
|
|
252
267
|
}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* in the tool's `perSource` report; the rest of the call still answers.
|
|
13
13
|
*/
|
|
14
14
|
/** Closed allowlist of tools any sandbox agent may declare. */
|
|
15
|
-
export type SandboxToolName = "listAvailablePackages" | "listAvailableRefs" | "scanInputs" | "resolveLibraryId" | "queryDocs" | "
|
|
15
|
+
export type SandboxToolName = "listAvailablePackages" | "listAvailableRefs" | "scanInputs" | "resolveLibraryId" | "queryDocs" | "pubmed" | "resolve_citation" | "searchGene" | "lookupAnnotation" | "searchInteractions" | "chembl" | "pubchem" | "opentargets" | "geneDiseaseEvidence" | "drugGeneInteractions" | "genePreclinicalProfile" | "searchFaers" | "searchClinicalTrials" | "searchGeoDatasets" | "searchRegulatoryApprovals" | "targetSafety" | "comptox" | "knowledgeTemplate";
|
|
16
16
|
/**
|
|
17
17
|
* The reference datasets that one capability of one agent cannot run without.
|
|
18
18
|
*
|
|
@@ -12,6 +12,8 @@ export type PlannerAgentMeta = {
|
|
|
12
12
|
readonly id: string;
|
|
13
13
|
readonly capabilities: readonly string[];
|
|
14
14
|
readonly suitableFor: readonly string[];
|
|
15
|
+
/** The public databases that the agent queries at run time, thus a step of the agent needs no staged copy of them. */
|
|
16
|
+
readonly liveSources: readonly string[];
|
|
15
17
|
};
|
|
16
18
|
/** The sandbox agents the planner may assign to analysis-plan steps. */
|
|
17
19
|
export declare const PLANNABLE_AGENT_CATALOG: readonly PlannerAgentMeta[];
|