@inflexa-ai/harness 0.46.2 → 0.48.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 (279) hide show
  1. package/README.md +2 -2
  2. package/dist/agents/conversation-agent.d.ts +7 -6
  3. package/dist/agents/conversation-agent.js +26 -4
  4. package/dist/agents/report-session-agent.d.ts +14 -14
  5. package/dist/agents/report-session-agent.js +40 -26
  6. package/dist/agents/sandbox/shared.d.ts +18 -13
  7. package/dist/agents/sandbox/shared.js +42 -27
  8. package/dist/agents/sandbox/types.d.ts +1 -1
  9. package/dist/agents/sandbox-catalog.d.ts +2 -0
  10. package/dist/agents/sandbox-catalog.js +30 -1
  11. package/dist/app/synthesize-run.d.ts +10 -6
  12. package/dist/app/synthesize-run.js +4 -2
  13. package/dist/contracts/analogy-report.d.ts +46 -2
  14. package/dist/contracts/analogy-report.js +31 -25
  15. package/dist/contracts/chat-parts.d.ts +3 -14
  16. package/dist/contracts/report-reference.d.ts +2 -1
  17. package/dist/contracts/report-reference.js +2 -1
  18. package/dist/contracts/schemas/chat-parts.d.ts +0 -27
  19. package/dist/contracts/schemas/chat-parts.js +1 -3
  20. package/dist/execution/run-canceler.d.ts +2 -0
  21. package/dist/execution/run-canceler.js +9 -0
  22. package/dist/execution/run-synthesis.d.ts +36 -8
  23. package/dist/execution/run-synthesis.js +114 -32
  24. package/dist/index.d.ts +5 -6
  25. package/dist/index.js +5 -7
  26. package/dist/input-scan/enrich.d.ts +5 -10
  27. package/dist/input-scan/enrich.js +12 -8
  28. package/dist/lib/hooks.d.ts +1 -1
  29. package/dist/lib/markdown-pdf.d.ts +27 -0
  30. package/dist/lib/markdown-pdf.js +236 -0
  31. package/dist/lib/metrics.d.ts +31 -0
  32. package/dist/lib/metrics.js +64 -0
  33. package/dist/lib/pdf-text.d.ts +23 -0
  34. package/dist/lib/pdf-text.js +34 -0
  35. package/dist/lib/regulatory-corpus/fetch-fda-guidance.js +3 -5
  36. package/dist/lib/regulatory-corpus/fetch-ich.js +3 -5
  37. package/dist/loop/chat-stream.js +2 -1
  38. package/dist/loop/run-loop.d.ts +5 -0
  39. package/dist/loop/run-loop.js +30 -2
  40. package/dist/loop/tool-name-repair.d.ts +11 -0
  41. package/dist/loop/tool-name-repair.js +23 -0
  42. package/dist/loop/types.d.ts +19 -0
  43. package/dist/memory/card-builders.d.ts +1 -1
  44. package/dist/prompts/SOUL.d.ts +6 -6
  45. package/dist/prompts/SOUL.js +22 -121
  46. package/dist/prompts/analogical-reasoner.d.ts +1 -1
  47. package/dist/prompts/analogical-reasoner.js +35 -101
  48. package/dist/prompts/briefing.d.ts +20 -11
  49. package/dist/prompts/briefing.js +36 -19
  50. package/dist/prompts/conversation.d.ts +1 -1
  51. package/dist/prompts/conversation.js +103 -383
  52. package/dist/prompts/planner.d.ts +1 -5
  53. package/dist/prompts/planner.js +45 -128
  54. package/dist/prompts/report-session.d.ts +1 -1
  55. package/dist/prompts/report-session.js +29 -58
  56. package/dist/prompts/sandbox/bulk-transcriptomics-agent.d.ts +1 -1
  57. package/dist/prompts/sandbox/bulk-transcriptomics-agent.js +3 -3
  58. package/dist/prompts/sandbox/cheminformatics-agent.d.ts +1 -1
  59. package/dist/prompts/sandbox/cheminformatics-agent.js +12 -47
  60. package/dist/prompts/sandbox/chromatin-agent.d.ts +1 -1
  61. package/dist/prompts/sandbox/chromatin-agent.js +4 -5
  62. package/dist/prompts/sandbox/data-profiler.js +11 -34
  63. package/dist/prompts/sandbox/dna-methylation-agent.d.ts +1 -1
  64. package/dist/prompts/sandbox/dna-methylation-agent.js +3 -1
  65. package/dist/prompts/sandbox/drug-repurposing-agent.d.ts +1 -1
  66. package/dist/prompts/sandbox/drug-repurposing-agent.js +23 -73
  67. package/dist/prompts/sandbox/enrichment-agent.d.ts +1 -1
  68. package/dist/prompts/sandbox/enrichment-agent.js +3 -1
  69. package/dist/prompts/sandbox/genomic-variant-agent.d.ts +1 -1
  70. package/dist/prompts/sandbox/genomic-variant-agent.js +3 -4
  71. package/dist/prompts/sandbox/immune-profiling-agent.d.ts +1 -1
  72. package/dist/prompts/sandbox/immune-profiling-agent.js +5 -4
  73. package/dist/prompts/sandbox/metabolomics-agent.d.ts +1 -1
  74. package/dist/prompts/sandbox/metabolomics-agent.js +3 -1
  75. package/dist/prompts/sandbox/microbiome-agent.d.ts +1 -1
  76. package/dist/prompts/sandbox/microbiome-agent.js +3 -1
  77. package/dist/prompts/sandbox/multi-omics-integration-agent.d.ts +1 -1
  78. package/dist/prompts/sandbox/multi-omics-integration-agent.js +3 -1
  79. package/dist/prompts/sandbox/multimodal-sc-agent.d.ts +1 -1
  80. package/dist/prompts/sandbox/multimodal-sc-agent.js +3 -1
  81. package/dist/prompts/sandbox/network-agent.d.ts +1 -1
  82. package/dist/prompts/sandbox/network-agent.js +3 -1
  83. package/dist/prompts/sandbox/pkpd-clinical-response-agent.d.ts +1 -1
  84. package/dist/prompts/sandbox/pkpd-clinical-response-agent.js +4 -7
  85. package/dist/prompts/sandbox/proteomics-agent.d.ts +1 -1
  86. package/dist/prompts/sandbox/proteomics-agent.js +3 -1
  87. package/dist/prompts/sandbox/scientific-executor.d.ts +1 -1
  88. package/dist/prompts/sandbox/scientific-executor.js +0 -12
  89. package/dist/prompts/sandbox/single-cell-agent.d.ts +1 -1
  90. package/dist/prompts/sandbox/single-cell-agent.js +3 -1
  91. package/dist/prompts/sandbox/spatial-omics-agent.d.ts +1 -1
  92. package/dist/prompts/sandbox/spatial-omics-agent.js +3 -1
  93. package/dist/prompts/sandbox/statistical-modeling-agent.d.ts +1 -1
  94. package/dist/prompts/sandbox/statistical-modeling-agent.js +4 -4
  95. package/dist/prompts/sandbox/translational-safety-agent.d.ts +1 -1
  96. package/dist/prompts/sandbox/translational-safety-agent.js +10 -29
  97. package/dist/prompts/sandbox-standards.d.ts +15 -18
  98. package/dist/prompts/sandbox-standards.js +96 -305
  99. package/dist/prompts/synthesis-agent.d.ts +1 -1
  100. package/dist/prompts/synthesis-agent.js +24 -90
  101. package/dist/provenance/collector.d.ts +2 -5
  102. package/dist/provenance/collector.js +2 -5
  103. package/dist/provenance/seam.d.ts +36 -1
  104. package/dist/provenance/workspace-reads.d.ts +36 -0
  105. package/dist/provenance/workspace-reads.js +33 -0
  106. package/dist/report-model/production-resolver.d.ts +22 -52
  107. package/dist/report-model/production-resolver.js +43 -112
  108. package/dist/report-render/chart-export.d.ts +9 -0
  109. package/dist/report-render/chart-export.js +1 -1
  110. package/dist/report-render/views/chart-view.d.ts +1 -0
  111. package/dist/report-render/views/chart-view.js +1 -0
  112. package/dist/report-render/views/lineage.d.ts +1 -0
  113. package/dist/report-render/views/page-view.d.ts +1 -0
  114. package/dist/report-render/views/page-view.js +1 -0
  115. package/dist/report-render/views/prose.d.ts +1 -0
  116. package/dist/report-render/views/prose.js +1 -0
  117. package/dist/report-render/views/references-view.d.ts +1 -0
  118. package/dist/report-render/views/values.d.ts +1 -0
  119. package/dist/report-render/views/values.js +1 -0
  120. package/dist/runtime/assemble.d.ts +32 -12
  121. package/dist/runtime/assemble.js +49 -38
  122. package/dist/sandbox/client.d.ts +5 -3
  123. package/dist/sandbox/create-sandbox.d.ts +7 -12
  124. package/dist/sandbox/create-sandbox.js +15 -37
  125. package/dist/sandbox/docker-client.d.ts +1 -3
  126. package/dist/sandbox/docker-client.js +3 -5
  127. package/dist/sandbox/exec-outcome.d.ts +11 -11
  128. package/dist/sandbox/exec-outcome.js +22 -22
  129. package/dist/sandbox/exec.d.ts +5 -0
  130. package/dist/sandbox/exec.js +9 -1
  131. package/dist/sandbox/identity.d.ts +4 -16
  132. package/dist/sandbox/identity.js +5 -21
  133. package/dist/sandbox/k8s-client.d.ts +0 -1
  134. package/dist/sandbox/k8s-client.js +8 -13
  135. package/dist/sandbox/lease-names.d.ts +6 -0
  136. package/dist/sandbox/lease-names.js +12 -0
  137. package/dist/sandbox/leases.d.ts +105 -0
  138. package/dist/sandbox/leases.js +519 -0
  139. package/dist/sandbox/liveness.d.ts +5 -2
  140. package/dist/sandbox/mount-plan.d.ts +10 -1
  141. package/dist/sandbox/mount-plan.js +7 -1
  142. package/dist/sandbox/reconciler.d.ts +58 -0
  143. package/dist/sandbox/reconciler.js +153 -0
  144. package/dist/sandbox/sandbox-step-translate.d.ts +1 -1
  145. package/dist/sandbox/types.d.ts +25 -18
  146. package/dist/sandbox/types.js +10 -4
  147. package/dist/schemas/plan-schemas.d.ts +0 -21
  148. package/dist/schemas/plan-schemas.js +2 -3
  149. package/dist/schemas/run-synthesis.d.ts +2 -2
  150. package/dist/schemas/run-synthesis.js +3 -3
  151. package/dist/schemas/validate-plan.d.ts +1 -14
  152. package/dist/schemas/validate-plan.js +5 -24
  153. package/dist/schemas/workflow-state.d.ts +3 -32
  154. package/dist/schemas/workflow-state.js +4 -13
  155. package/dist/state/index.d.ts +2 -3
  156. package/dist/state/index.js +1 -2
  157. package/dist/state/migrations/20261030120000_lease_the_sandboxes.d.ts +7 -0
  158. package/dist/state/migrations/20261030120000_lease_the_sandboxes.js +34 -0
  159. package/dist/state/migrations/20261030120100_drop_the_report_derivations.d.ts +5 -0
  160. package/dist/state/migrations/20261030120100_drop_the_report_derivations.js +9 -0
  161. package/dist/state/migrations/20261030120200_keep_the_report_derivations.d.ts +6 -0
  162. package/dist/state/migrations/20261030120200_keep_the_report_derivations.js +10 -0
  163. package/dist/state/migrations/index.js +6 -0
  164. package/dist/state/purge-analysis.d.ts +4 -2
  165. package/dist/state/purge-analysis.js +22 -11
  166. package/dist/state/sandbox-leases.d.ts +81 -0
  167. package/dist/state/sandbox-leases.js +247 -0
  168. package/dist/state/schema.d.ts +1 -13
  169. package/dist/state/schema.js +1 -6
  170. package/dist/state/step-executions.d.ts +13 -2
  171. package/dist/state/step-executions.js +23 -4
  172. package/dist/tasks/data-profile.d.ts +40 -2
  173. package/dist/tasks/data-profile.js +89 -87
  174. package/dist/tools/ad-hoc-router.d.ts +1 -6
  175. package/dist/tools/ad-hoc-router.js +5 -48
  176. package/dist/tools/bio/comptox.js +1 -1
  177. package/dist/tools/bio/drug-gene-interactions.js +1 -1
  178. package/dist/tools/bio/gene-disease-evidence.js +1 -1
  179. package/dist/tools/bio/keys.d.ts +1 -1
  180. package/dist/tools/bio/pubmed.js +31 -0
  181. package/dist/tools/bio/search-gene.js +17 -0
  182. package/dist/tools/bio/search-geo-datasets.js +13 -0
  183. package/dist/tools/bio/search-regulatory-approvals.js +1 -1
  184. package/dist/tools/define-tool.d.ts +25 -2
  185. package/dist/tools/define-tool.js +11 -1
  186. package/dist/tools/display/show-user.js +1 -1
  187. package/dist/tools/execute-analysis.d.ts +1 -3
  188. package/dist/tools/execute-analysis.js +5 -33
  189. package/dist/tools/report-authoring/authoring-tools.d.ts +2 -2
  190. package/dist/tools/report-authoring/authoring-tools.js +31 -6
  191. package/dist/tools/report-session/index.d.ts +0 -1
  192. package/dist/tools/report-session/index.js +0 -1
  193. package/dist/tools/report-session/script-tools.d.ts +33 -0
  194. package/dist/tools/report-session/script-tools.js +186 -0
  195. package/dist/tools/research/generate-analogy-report.d.ts +16 -9
  196. package/dist/tools/research/generate-analogy-report.js +111 -49
  197. package/dist/tools/research/generate-plan.d.ts +102 -7
  198. package/dist/tools/research/generate-plan.js +74 -43
  199. package/dist/tools/research/index.d.ts +4 -3
  200. package/dist/tools/research/index.js +4 -3
  201. package/dist/tools/research/inspect-run.d.ts +0 -1
  202. package/dist/tools/research/inspect-run.js +5 -10
  203. package/dist/tools/research/search-arxiv.js +15 -0
  204. package/dist/tools/research/search-github-repos.js +13 -0
  205. package/dist/tools/research/search-semantic-scholar.js +16 -0
  206. package/dist/tools/research/synthesis-lookups.d.ts +21 -0
  207. package/dist/tools/research/synthesis-lookups.js +29 -0
  208. package/dist/tools/research/web-fetch.d.ts +1 -1
  209. package/dist/tools/research/web-fetch.js +14 -12
  210. package/dist/tools/sandbox/lease-tools.d.ts +32 -0
  211. package/dist/tools/sandbox/lease-tools.js +60 -0
  212. package/dist/tools/script/archive.d.ts +34 -0
  213. package/dist/tools/script/archive.js +182 -0
  214. package/dist/tools/script/codemode-worker.d.ts +5 -0
  215. package/dist/tools/script/codemode-worker.js +5 -0
  216. package/dist/tools/script/file-tools.d.ts +106 -0
  217. package/dist/tools/script/file-tools.js +491 -0
  218. package/dist/tools/script/metrics.d.ts +30 -0
  219. package/dist/tools/script/metrics.js +53 -0
  220. package/dist/tools/script/quickjs.wasm +0 -0
  221. package/dist/tools/script/run-script.d.ts +76 -0
  222. package/dist/tools/script/run-script.js +413 -0
  223. package/dist/tools/script/scratch.d.ts +84 -0
  224. package/dist/tools/script/scratch.js +145 -0
  225. package/dist/tools/start-report-session.js +1 -1
  226. package/dist/tools/workspace/edit-file.js +2 -1
  227. package/dist/tools/workspace/execute-command.d.ts +9 -13
  228. package/dist/tools/workspace/execute-command.js +23 -19
  229. package/dist/tools/workspace/file-stat.js +1 -1
  230. package/dist/tools/workspace/grep.d.ts +5 -2
  231. package/dist/tools/workspace/grep.js +19 -10
  232. package/dist/tools/workspace/mutator.d.ts +51 -4
  233. package/dist/tools/workspace/mutator.js +54 -13
  234. package/dist/tools/workspace/read-file.d.ts +5 -2
  235. package/dist/tools/workspace/read-file.js +15 -11
  236. package/dist/tools/workspace/read-surface.d.ts +17 -0
  237. package/dist/tools/workspace/read-surface.js +17 -0
  238. package/dist/tools/workspace/result-bounds.d.ts +1 -0
  239. package/dist/tools/workspace/run-exec.d.ts +12 -13
  240. package/dist/tools/workspace/run-exec.js +13 -13
  241. package/dist/tools/workspace/scan-inputs.d.ts +2 -5
  242. package/dist/tools/workspace/scan-inputs.js +2 -3
  243. package/dist/tools/workspace/show-file.js +1 -1
  244. package/dist/tools/workspace/show-plan.js +4 -3
  245. package/dist/tools/workspace/write-file.js +2 -1
  246. package/dist/workflows/execute-analysis-scheduler.d.ts +0 -26
  247. package/dist/workflows/execute-analysis-scheduler.js +12 -32
  248. package/dist/workflows/execute-analysis.d.ts +17 -35
  249. package/dist/workflows/execute-analysis.js +13 -107
  250. package/dist/workflows/pause.js +29 -22
  251. package/dist/workflows/sandbox-step.d.ts +16 -31
  252. package/dist/workflows/sandbox-step.js +36 -71
  253. package/dist/workflows/test/sql-writes.d.ts +0 -1
  254. package/dist/workflows/test/sql-writes.js +0 -2
  255. package/dist/workspace/filesystem.d.ts +2 -2
  256. package/dist/workspace/filesystem.js +10 -5
  257. package/dist/workspace/paths.d.ts +19 -1
  258. package/dist/workspace/paths.js +22 -1
  259. package/dist/workspace/session-files.d.ts +35 -0
  260. package/dist/workspace/session-files.js +16 -0
  261. package/package.json +7 -3
  262. package/dist/prompts/literature-reviewer.d.ts +0 -1
  263. package/dist/prompts/literature-reviewer.js +0 -114
  264. package/dist/sandbox/reaper.d.ts +0 -81
  265. package/dist/sandbox/reaper.js +0 -161
  266. package/dist/sandbox/step-sandbox.d.ts +0 -47
  267. package/dist/sandbox/step-sandbox.js +0 -53
  268. package/dist/state/active-sandboxes.d.ts +0 -33
  269. package/dist/state/active-sandboxes.js +0 -65
  270. package/dist/tasks/extract-values-script.d.ts +0 -64
  271. package/dist/tasks/extract-values-script.js +0 -180
  272. package/dist/tasks/extract-values.d.ts +0 -77
  273. package/dist/tasks/extract-values.js +0 -146
  274. package/dist/tools/report-session/derive-table.d.ts +0 -164
  275. package/dist/tools/report-session/derive-table.js +0 -419
  276. package/dist/tools/research/literature-reviewer.d.ts +0 -42
  277. package/dist/tools/research/literature-reviewer.js +0 -107
  278. package/dist/workflows/metrics.d.ts +0 -23
  279. package/dist/workflows/metrics.js +0 -38
@@ -1,27 +1,11 @@
1
1
  /**
2
- * Sandbox identity minting — the durable half of the two-step create (ADR
3
- * 0016). Backend-agnostic: the `sandboxId` is minted here, checkpointed by the
4
- * `sandbox.mint` DBOS step, then handed to the backend's spawn step. Because the
5
- * identity is durable before any machine exists, a crash between spawn and the
6
- * spawn-step checkpoint is recoverable — the re-run adopts the existing machine
7
- * under the same name.
2
+ * The name of a sandbox machine. It comes from a key: the id of the lease workflow and the machine generation. Thus
3
+ * a rerun of the spawn step adopts the machine of the earlier attempt, and no step checkpoints a name before a spawn.
8
4
  */
9
- import { createHash, randomUUID } from "node:crypto";
10
- /** `sbx-{run8}-{rand8}` — run prefix aids `kubectl` triage; the 8-hex random
11
- * suffix makes within-run collisions across a run's concurrent steps
12
- * negligible. Names are NOT the idempotency mechanism (the checkpoint is), and
13
- * adoption is owner-label-guarded, but a unique name keeps a collision from
14
- * ever reaching that guard. */
15
- export function mintSandboxIdentity(runId) {
16
- const run8 = runId.replaceAll("-", "").slice(0, 8);
17
- const suffix = randomUUID().replaceAll("-", "").slice(0, 8);
18
- return { sandboxId: `sbx-${run8}-${suffix}` };
19
- }
5
+ import { createHash } from "node:crypto";
20
6
  /**
21
- * `sbx-{run8}-{hash12}` — the name of a sandbox whose identity comes from a
22
- * key, not from a checkpoint. The same key gives the same name, thus a rerun
23
- * of a step adopts the machine of the earlier attempt. The key is hashed,
24
- * because a workflow id can hold characters that a container name refuses.
7
+ * `sbx-{run8}-{hash12}`. The run prefix aids `kubectl` triage. The same key gives the same name, and the key is
8
+ * hashed, because a workflow id can hold characters that a container name refuses.
25
9
  */
26
10
  export function keyedSandboxIdentity(runId, key) {
27
11
  const run8 = runId.replaceAll("-", "").slice(0, 8);
@@ -105,7 +105,6 @@ export type K8sClientConfig = {
105
105
  /** Injected for tests. */
106
106
  batchApi?: BatchJobApi;
107
107
  coreApi?: CorePodApi;
108
- registerSandbox: (session: SpawnSession, spec: SandboxSpec, ref: SandboxRef) => Promise<void>;
109
108
  };
110
109
  /** Clock and sleep seams, so a test can drive the slow-pod warning without waiting a minute. */
111
110
  export type WaitForPodReadyDeps = {
@@ -171,6 +171,12 @@ async function buildJobSpec(session, sandboxSpec, hostLabels, config, identity,
171
171
  readOnly: false,
172
172
  });
173
173
  }
174
+ volumeMounts.push({
175
+ name: SESSION_VOLUME_NAME,
176
+ mountPath: plan.recordsPath,
177
+ subPath: subPaths.records,
178
+ readOnly: false,
179
+ });
174
180
  }
175
181
  if (config.libStorePvc && plan.libsPath) {
176
182
  const cacheSubPath = farm?.cachePath !== undefined && plan.cachePath ? pvcSubPath(farm.cachePath, "the farm cache") : undefined;
@@ -263,7 +269,7 @@ async function buildJobSpec(session, sandboxSpec, hostLabels, config, identity,
263
269
  name: sandboxId,
264
270
  namespace: config.namespace,
265
271
  annotations: {
266
- [OWNER_WORKFLOW_ANNOTATION]: sandboxSpec.childWorkflowId,
272
+ [OWNER_WORKFLOW_ANNOTATION]: sandboxSpec.ownerWorkflowId,
267
273
  },
268
274
  labels,
269
275
  },
@@ -493,7 +499,7 @@ export function createK8sSandboxOps(config) {
493
499
  }
494
500
  }
495
501
  const job = await buildJobSpec(session, spec, hostLabels, config, identity, farm, libsMounted);
496
- const adopted = await createOrAdoptJob(batchApi, coreApi, config.namespace, sandboxId, spec.childWorkflowId, job);
502
+ const adopted = await createOrAdoptJob(batchApi, coreApi, config.namespace, sandboxId, spec.ownerWorkflowId, job);
497
503
  if (adopted.isErr())
498
504
  return err(adopted.error);
499
505
  // A Job whose pod never schedules (quota rejection, no nodes, spot
@@ -510,17 +516,6 @@ export function createK8sSandboxOps(config) {
510
516
  port: SANDBOX_SERVER_PORT,
511
517
  backend: "k8s",
512
518
  };
513
- const registered = await trySandbox(() => config.registerSandbox(session, spec, ref), (status, cause) => ({
514
- type: "container_create_failed",
515
- op: "k8s.registerSandbox",
516
- sandboxId,
517
- status,
518
- cause,
519
- }));
520
- if (registered.isErr()) {
521
- await cleanupFailedJob(batchApi, config.namespace, sandboxId, config.logger ?? createNoopLogger());
522
- return err(registered.error);
523
- }
524
519
  return ok(ref);
525
520
  }
526
521
  await cleanupFailedJob(batchApi, config.namespace, sandboxId, config.logger ?? createNoopLogger());
@@ -0,0 +1,6 @@
1
+ /** The names that the lease module, the reconciler, and the purge share. */
2
+ /** The prefix of each lease workflow id. A purge finds the lease workflows of an analysis by it. */
3
+ export declare const LEASE_WORKFLOW_PREFIX = "sandboxlease";
4
+ export declare function leaseWorkflowIdOf(analysisId: string, leaseKey: string, generation: number): string;
5
+ /** The workspace-relative records directory of a lease key. Each generation of the key uses it. */
6
+ export declare function leaseRecordTail(leaseKey: string): string;
@@ -0,0 +1,12 @@
1
+ /** The names that the lease module, the reconciler, and the purge share. */
2
+ import { createHash } from "node:crypto";
3
+ import { HARNESS_PRIVATE_DIR } from "../workspace/paths.js";
4
+ /** The prefix of each lease workflow id. A purge finds the lease workflows of an analysis by it. */
5
+ export const LEASE_WORKFLOW_PREFIX = "sandboxlease";
6
+ export function leaseWorkflowIdOf(analysisId, leaseKey, generation) {
7
+ return `${LEASE_WORKFLOW_PREFIX}:${analysisId}:${leaseKey}:${generation}`;
8
+ }
9
+ /** The workspace-relative records directory of a lease key. Each generation of the key uses it. */
10
+ export function leaseRecordTail(leaseKey) {
11
+ return `${HARNESS_PRIVATE_DIR}/exec-records/${createHash("sha256").update(leaseKey, "utf8").digest("hex").slice(0, 16)}`;
12
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * The sandbox module (sandbox-leases spec). A consumer holds a sandbox through a lease, and the module owns each
3
+ * machine: the admission, the spawn, the replacement, the idle removal, and the teardown.
4
+ *
5
+ * Each generation of a lease has one lease workflow. A consumer enqueues it through a `DBOSClient`, thus the lease
6
+ * workflow is not a child of the consumer: a cancel, a pause, or a crash of the consumer does not stop it, and its
7
+ * teardown step can always run. The consumer waits for the events of the lease workflow with the same client,
8
+ * because DBOS refuses `recv` and `getEvent` inside a step, and each tool call is a step.
9
+ *
10
+ * A machine of a lease is replaceable. The state of a lease is its files, the exec records in its records
11
+ * directory, and the checkpoints of its consumer. Thus the module removes the machine of an idle lease, and the
12
+ * next exec gets a new one.
13
+ */
14
+ import { type DBOSClient } from "@dbos-inc/dbos-sdk";
15
+ import { type Result } from "neverthrow";
16
+ import type { SpawnSession } from "../auth/types.js";
17
+ import { type ResourcePolicy, type ResourceSpec } from "../config/resource-limits.js";
18
+ import type { PausePart, WorkKind } from "../contracts/chat-parts.js";
19
+ import type { RunAuthorizer } from "../execution/run-authorizer.js";
20
+ import type { Connectable } from "../lib/db-result.js";
21
+ import type { Logger } from "../lib/logger.js";
22
+ import type { Querier } from "../state/db.js";
23
+ import { type ResolveWorkspaceRoot } from "../workspace/paths.js";
24
+ import type { SandboxClient } from "./client.js";
25
+ import type { ExecEmit, ExecRequest, ExecResult, ToolchainSource } from "./types.js";
26
+ export declare const LEASE_WORKFLOW = "sandbox-lease";
27
+ export declare const LEASE_QUEUE = "sandbox-leases";
28
+ export declare const DEFAULT_IDLE_PERIOD_MS: number;
29
+ /** The timeout of a command that gives none. A step has no deadline of its own, thus each command has one. */
30
+ export declare const DEFAULT_COMMAND_TIMEOUT_SECONDS = 3600;
31
+ /** The spawn settings of a consumer, beside the size. */
32
+ export type LeaseSpawnSpec = {
33
+ readonly image?: string;
34
+ readonly extraEnv?: Readonly<Record<string, string>>;
35
+ readonly readOnly?: boolean;
36
+ readonly writableTail?: string;
37
+ };
38
+ /** Who holds a lease, and where its pause and its parts go. */
39
+ export type LeaseBinding = {
40
+ /** The key of the lease. A tool gives the id of its workflow. */
41
+ readonly leaseKey: string;
42
+ /** The spawn session of a run step or of a data profile. It goes into the input of the lease workflow. */
43
+ readonly session: SpawnSession;
44
+ /** The work of the consumer. A pause of the lease workflow belongs to it. */
45
+ readonly work: {
46
+ readonly kind: WorkKind;
47
+ readonly id: string;
48
+ };
49
+ readonly spawn?: LeaseSpawnSpec;
50
+ /** Writes a part to the stream of the consumer. A wait mirrors the pause of the lease workflow through it. */
51
+ readonly emit?: (part: PausePart) => Promise<void>;
52
+ };
53
+ export type AcquireOutcome = {
54
+ readonly kind: "granted";
55
+ readonly size: ResourceSpec;
56
+ } | {
57
+ readonly kind: "refused";
58
+ readonly reason: string;
59
+ } | {
60
+ readonly kind: "failed";
61
+ readonly detail: string;
62
+ };
63
+ /** An exec found no lease that can run it. `detail` says why, for a lease that ended. */
64
+ export type NoLease = {
65
+ readonly kind: "no_lease";
66
+ readonly detail?: string;
67
+ };
68
+ /** A lease bound to its consumer. A tool holds one, and gives the size and the command only. */
69
+ export type BoundLease = {
70
+ acquire(size: ResourceSpec): Promise<AcquireOutcome>;
71
+ release(): Promise<void>;
72
+ exec(request: ExecRequest, emit: ExecEmit): Promise<Result<ExecResult, NoLease>>;
73
+ };
74
+ export type SandboxLeases = {
75
+ readonly toolchainSource: ToolchainSource;
76
+ acquire(binding: LeaseBinding, size: ResourceSpec): Promise<AcquireOutcome>;
77
+ release(leaseKey: string): Promise<void>;
78
+ /**
79
+ * End each lease of the given owner workflows, and do not wait for the lease workflows. A host that cancels
80
+ * work calls it, thus the machines go now and not at the next tick of each lease workflow.
81
+ */
82
+ releaseOwnedBy(ownerWorkflowIds: readonly string[]): Promise<void>;
83
+ exec(leaseKey: string, request: ExecRequest, emit: ExecEmit, mirror?: LeaseBinding["emit"]): Promise<Result<ExecResult, NoLease>>;
84
+ bind(binding: LeaseBinding): BoundLease;
85
+ };
86
+ export type SandboxLeasesConfig = {
87
+ /** The application pool, which holds the lease table and the pause rows. */
88
+ readonly pool: Querier & Connectable;
89
+ readonly client: SandboxClient;
90
+ /** The budget of the grant. Absent: each lease gets its grant at once. */
91
+ readonly resourcePolicy?: ResourcePolicy;
92
+ readonly resolveWorkspaceRoot: ResolveWorkspaceRoot;
93
+ readonly runAuthorizer: RunAuthorizer;
94
+ /** Default {@link DEFAULT_IDLE_PERIOD_MS}. */
95
+ readonly idlePeriodMs?: number;
96
+ readonly pauseRetryDelaysMs?: readonly number[];
97
+ readonly logger?: Logger;
98
+ /** The DBOS client of the enqueue, the sends, and the waits of a consumer. */
99
+ readonly dbosClient: () => Promise<DBOSClient>;
100
+ /** The fetch of the health probe. Defaults to `globalThis.fetch`. */
101
+ readonly fetch?: (url: string, init?: RequestInit) => Promise<Response>;
102
+ /** The tick of a lease workflow, in seconds. Default 60. */
103
+ readonly tickSeconds?: number;
104
+ };
105
+ export declare function createSandboxLeases(config: SandboxLeasesConfig): SandboxLeases;