@inflexa-ai/harness 0.1.1 → 0.3.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 +48 -0
- package/dist/agents/conversation-agent.d.ts +15 -11
- package/dist/agents/conversation-agent.js +31 -34
- package/dist/agents/report-builder.js +2 -1
- package/dist/agents/sandbox/bulk-transcriptomics-agent.js +1 -1
- package/dist/agents/sandbox/cheminformatics-agent.js +1 -19
- package/dist/agents/sandbox/chromatin-agent.js +1 -10
- package/dist/agents/sandbox/dna-methylation-agent.js +1 -10
- package/dist/agents/sandbox/drug-repurposing-agent.js +4 -14
- package/dist/agents/sandbox/enrichment-agent.js +1 -10
- package/dist/agents/sandbox/ephemeral-executor.js +1 -10
- package/dist/agents/sandbox/genomic-variant-agent.js +1 -3
- package/dist/agents/sandbox/immune-profiling-agent.js +1 -13
- package/dist/agents/sandbox/metabolomics-agent.js +1 -1
- package/dist/agents/sandbox/microbiome-agent.js +1 -1
- package/dist/agents/sandbox/multi-omics-integration-agent.js +1 -12
- package/dist/agents/sandbox/multimodal-sc-agent.js +1 -1
- package/dist/agents/sandbox/network-agent.js +1 -10
- package/dist/agents/sandbox/pkpd-clinical-response-agent.js +2 -8
- package/dist/agents/sandbox/proteomics-agent.js +1 -1
- package/dist/agents/sandbox/scientific-executor.js +1 -10
- package/dist/agents/sandbox/shared.d.ts +20 -6
- package/dist/agents/sandbox/shared.js +50 -39
- package/dist/agents/sandbox/single-cell-agent.js +1 -1
- package/dist/agents/sandbox/spatial-omics-agent.js +1 -1
- package/dist/agents/sandbox/statistical-modeling-agent.js +1 -1
- package/dist/agents/sandbox/translational-safety-agent.js +3 -9
- package/dist/agents/sandbox/types.d.ts +1 -1
- package/dist/agents/system-prompt.d.ts +37 -11
- package/dist/agents/system-prompt.js +35 -12
- package/dist/app/chat-turn.d.ts +3 -0
- package/dist/app/chat-turn.js +3 -1
- package/dist/app/data-profile-orientation.d.ts +34 -0
- package/dist/app/data-profile-orientation.js +117 -0
- package/dist/app/synthesize-run.d.ts +3 -0
- package/dist/app/synthesize-run.js +3 -1
- package/dist/contracts/schemas/chat-parts.d.ts +9 -9
- package/dist/execution/artifact-metadata.d.ts +3 -0
- package/dist/execution/artifact-metadata.js +10 -3
- package/dist/execution/artifact-registration.d.ts +2 -1
- package/dist/execution/artifact-registration.js +8 -2
- package/dist/execution/ephemeral-runner.d.ts +16 -0
- package/dist/execution/ephemeral-runner.js +31 -5
- package/dist/execution/post-step-pipeline.d.ts +3 -0
- package/dist/execution/post-step-pipeline.js +24 -4
- package/dist/execution/reconcile-manifest.d.ts +7 -0
- package/dist/execution/reconcile-manifest.js +19 -5
- package/dist/execution/report-runner.d.ts +3 -0
- package/dist/execution/report-runner.js +4 -4
- package/dist/execution/run-synthesis.js +20 -19
- package/dist/execution/step-summary.d.ts +3 -0
- package/dist/execution/step-summary.js +6 -3
- package/dist/index.d.ts +9 -2
- package/dist/index.js +24 -5
- package/dist/lib/chrome.d.ts +4 -1
- package/dist/lib/chrome.js +10 -7
- package/dist/lib/console-logger.d.ts +19 -0
- package/dist/lib/console-logger.js +62 -0
- package/dist/lib/logger.d.ts +88 -0
- package/dist/lib/logger.js +37 -0
- package/dist/lib/otel.d.ts +2 -1
- package/dist/lib/otel.js +8 -3
- package/dist/loop/__fixtures__/scripted-provider.d.ts +2 -2
- package/dist/loop/__fixtures__/scripted-provider.js +2 -1
- package/dist/loop/metrics.d.ts +33 -1
- package/dist/loop/metrics.js +56 -2
- package/dist/loop/run-agent.d.ts +13 -1
- package/dist/loop/run-agent.js +19 -4
- package/dist/memory/card-builders.d.ts +8 -1
- package/dist/memory/card-builders.js +20 -3
- package/dist/memory/reconstruct-cards.js +4 -3
- package/dist/memory/thread-history.d.ts +27 -2
- package/dist/memory/thread-history.js +45 -5
- package/dist/memory/working-memory.d.ts +93 -10
- package/dist/memory/working-memory.js +220 -84
- package/dist/prompts/SOUL.d.ts +22 -9
- package/dist/prompts/SOUL.js +56 -37
- package/dist/prompts/analogical-reasoner.d.ts +1 -1
- package/dist/prompts/analogical-reasoner.js +2 -2
- package/dist/prompts/briefing.d.ts +100 -0
- package/dist/prompts/briefing.js +166 -0
- package/dist/prompts/conversation.d.ts +1 -1
- package/dist/prompts/conversation.js +94 -440
- package/dist/prompts/literature-reviewer.d.ts +1 -1
- package/dist/prompts/literature-reviewer.js +10 -10
- package/dist/prompts/planner.js +28 -59
- package/dist/prompts/report-builder.d.ts +1 -1
- package/dist/prompts/report-builder.js +71 -24
- package/dist/prompts/sandbox/bulk-transcriptomics-agent.d.ts +1 -1
- package/dist/prompts/sandbox/bulk-transcriptomics-agent.js +2 -7
- package/dist/prompts/sandbox/cheminformatics-agent.d.ts +1 -1
- package/dist/prompts/sandbox/cheminformatics-agent.js +11 -15
- package/dist/prompts/sandbox/chromatin-agent.d.ts +1 -1
- package/dist/prompts/sandbox/chromatin-agent.js +3 -7
- package/dist/prompts/sandbox/data-profiler.d.ts +1 -1
- package/dist/prompts/sandbox/data-profiler.js +13 -8
- package/dist/prompts/sandbox/dna-methylation-agent.d.ts +1 -1
- package/dist/prompts/sandbox/dna-methylation-agent.js +2 -7
- package/dist/prompts/sandbox/drug-repurposing-agent.d.ts +1 -1
- package/dist/prompts/sandbox/drug-repurposing-agent.js +15 -16
- package/dist/prompts/sandbox/enrichment-agent.d.ts +1 -1
- package/dist/prompts/sandbox/enrichment-agent.js +2 -9
- package/dist/prompts/sandbox/genomic-variant-agent.d.ts +1 -1
- package/dist/prompts/sandbox/genomic-variant-agent.js +2 -6
- package/dist/prompts/sandbox/immune-profiling-agent.d.ts +1 -1
- package/dist/prompts/sandbox/immune-profiling-agent.js +3 -8
- package/dist/prompts/sandbox/metabolomics-agent.d.ts +1 -1
- package/dist/prompts/sandbox/metabolomics-agent.js +1 -7
- package/dist/prompts/sandbox/microbiome-agent.d.ts +1 -1
- package/dist/prompts/sandbox/microbiome-agent.js +2 -7
- package/dist/prompts/sandbox/multi-omics-integration-agent.d.ts +1 -1
- package/dist/prompts/sandbox/multi-omics-integration-agent.js +2 -8
- package/dist/prompts/sandbox/multimodal-sc-agent.d.ts +1 -1
- package/dist/prompts/sandbox/multimodal-sc-agent.js +2 -7
- package/dist/prompts/sandbox/network-agent.d.ts +1 -1
- package/dist/prompts/sandbox/network-agent.js +2 -7
- package/dist/prompts/sandbox/proteomics-agent.d.ts +1 -1
- package/dist/prompts/sandbox/proteomics-agent.js +2 -9
- package/dist/prompts/sandbox/single-cell-agent.d.ts +1 -1
- package/dist/prompts/sandbox/single-cell-agent.js +2 -9
- package/dist/prompts/sandbox/spatial-omics-agent.d.ts +1 -1
- package/dist/prompts/sandbox/spatial-omics-agent.js +3 -6
- package/dist/prompts/sandbox/statistical-modeling-agent.d.ts +1 -1
- package/dist/prompts/sandbox/statistical-modeling-agent.js +2 -7
- package/dist/prompts/sandbox/translational-safety-agent.d.ts +1 -1
- package/dist/prompts/sandbox/translational-safety-agent.js +13 -14
- package/dist/prompts/sandbox-standards.d.ts +22 -14
- package/dist/prompts/sandbox-standards.js +91 -71
- package/dist/prompts/synthesis-agent.d.ts +1 -1
- package/dist/prompts/synthesis-agent.js +33 -131
- package/dist/provenance/collector.js +1 -1
- package/dist/providers/ai-sdk.js +31 -4
- package/dist/providers/prompt-cache.d.ts +74 -0
- package/dist/providers/prompt-cache.js +77 -0
- package/dist/providers/types.d.ts +33 -0
- package/dist/reference-data/catalog.d.ts +131 -0
- package/dist/reference-data/catalog.js +348 -0
- package/dist/reference-data/receipt.d.ts +41 -0
- package/dist/reference-data/receipt.js +40 -0
- package/dist/runtime/boot.d.ts +2 -2
- package/dist/runtime/boot.js +1 -1
- package/dist/runtime/connection-budget.d.ts +2 -2
- package/dist/runtime/connection-budget.js +5 -3
- package/dist/runtime/dbos.d.ts +7 -7
- package/dist/runtime/dbos.js +14 -11
- package/dist/runtime/shutdown.d.ts +2 -2
- package/dist/runtime/shutdown.js +4 -3
- package/dist/sandbox/create-sandbox.d.ts +2 -2
- package/dist/sandbox/docker-client.d.ts +2 -2
- package/dist/sandbox/docker-client.js +4 -1
- package/dist/sandbox/k8s-client.d.ts +3 -0
- package/dist/sandbox/k8s-client.js +5 -4
- package/dist/sandbox/notification-sweep.d.ts +3 -3
- package/dist/sandbox/notification-sweep.js +4 -2
- package/dist/sandbox/reaper.d.ts +3 -3
- package/dist/sandbox/reaper.js +7 -4
- package/dist/sandbox/watchdog.d.ts +3 -3
- package/dist/sandbox/watchdog.js +8 -2
- package/dist/schemas/data-profile-schemas.js +5 -3
- package/dist/schemas/plan-schemas.d.ts +21 -21
- package/dist/schemas/plan-schemas.js +9 -3
- package/dist/schemas/run-synthesis.d.ts +8 -4
- package/dist/schemas/run-synthesis.js +92 -56
- package/dist/schemas/validate-plan.js +1 -1
- package/dist/schemas/workflow-state.d.ts +7 -1
- package/dist/schemas/workflow-state.js +33 -19
- package/dist/state/artifacts.d.ts +13 -0
- package/dist/state/artifacts.js +27 -0
- package/dist/state/data-profile.d.ts +64 -5
- package/dist/state/index.d.ts +3 -3
- package/dist/state/index.js +1 -1
- package/dist/state/init.d.ts +2 -1
- package/dist/state/init.js +5 -6
- package/dist/tasks/data-profile.d.ts +25 -2
- package/dist/tasks/data-profile.js +95 -39
- package/dist/tools/bio/chembl.d.ts +38 -0
- package/dist/tools/bio/chembl.js +138 -0
- package/dist/tools/bio/comptox.d.ts +50 -0
- package/dist/tools/bio/comptox.js +149 -0
- package/dist/tools/bio/get-impc-ko-profile.js +9 -6
- package/dist/tools/bio/index.d.ts +5 -17
- package/dist/tools/bio/index.js +5 -17
- package/dist/tools/bio/keys.d.ts +14 -9
- package/dist/tools/bio/keys.js +16 -16
- package/dist/tools/bio/opentargets.d.ts +38 -0
- package/dist/tools/bio/opentargets.js +89 -0
- package/dist/tools/bio/pubchem.d.ts +29 -0
- package/dist/tools/bio/pubchem.js +92 -0
- package/dist/tools/bio/pubmed.d.ts +51 -0
- package/dist/tools/bio/pubmed.js +100 -0
- package/dist/tools/bio/search-bgee-expression.js +12 -6
- package/dist/tools/bio/search-clinical-trials.js +16 -5
- package/dist/tools/bio/search-dgidb.d.ts +11 -1
- package/dist/tools/bio/search-dgidb.js +92 -78
- package/dist/tools/bio/search-faers.js +8 -4
- package/dist/tools/bio/search-geo-datasets.js +20 -6
- package/dist/tools/bio/search-gwas-catalog.d.ts +1 -1
- package/dist/tools/bio/search-pharmgkb.js +10 -4
- package/dist/tools/display/index.d.ts +1 -0
- package/dist/tools/display/index.js +1 -0
- package/dist/tools/display/normalize-echart-spec.d.ts +61 -0
- package/dist/tools/display/normalize-echart-spec.js +211 -0
- package/dist/tools/display/show-user.d.ts +6 -1
- package/dist/tools/display/show-user.js +25 -12
- package/dist/tools/execute-plan.js +5 -2
- package/dist/tools/iterate-report.d.ts +171 -118
- package/dist/tools/iterate-report.js +336 -96
- package/dist/tools/lib/chembl-client.d.ts +12 -0
- package/dist/tools/lib/chembl-client.js +127 -0
- package/dist/tools/lib/ctx-ops.d.ts +224 -0
- package/dist/tools/lib/ctx-ops.js +450 -0
- package/dist/tools/lib/iuphar-client.js +10 -1
- package/dist/tools/lib/openfda-client.js +11 -3
- package/dist/tools/lib/pathway-client.js +10 -4
- package/dist/tools/lib/pubchem-ops.d.ts +74 -0
- package/dist/tools/lib/pubchem-ops.js +224 -0
- package/dist/tools/memory/update-working-memory.d.ts +45 -7
- package/dist/tools/memory/update-working-memory.js +111 -41
- package/dist/tools/report/index.d.ts +3 -2
- package/dist/tools/report/index.js +3 -2
- package/dist/tools/research/generate-analogy-report.js +25 -12
- package/dist/tools/research/generate-plan.d.ts +12 -5
- package/dist/tools/research/generate-plan.js +168 -37
- package/dist/tools/research/index.d.ts +1 -0
- package/dist/tools/research/index.js +1 -0
- package/dist/tools/research/inspect-data-profile.d.ts +85 -0
- package/dist/tools/research/inspect-data-profile.js +161 -0
- package/dist/tools/research/literature-reviewer.d.ts +3 -0
- package/dist/tools/research/literature-reviewer.js +5 -6
- package/dist/tools/sandbox/list-available-packages.d.ts +79 -5
- package/dist/tools/sandbox/list-available-packages.js +152 -10
- package/dist/tools/sandbox/list-available-refs.d.ts +141 -5
- package/dist/tools/sandbox/list-available-refs.js +647 -134
- package/dist/tools/sandbox/report-blocker.d.ts +39 -9
- package/dist/tools/sandbox/report-blocker.js +43 -20
- package/dist/tools/workspace/execute-command.d.ts +3 -0
- package/dist/tools/workspace/execute-command.js +3 -1
- package/dist/tools/workspace/read-file.js +4 -5
- package/dist/tools/workspace/run-exec.d.ts +4 -4
- package/dist/tools/workspace/run-exec.js +4 -4
- package/dist/tools/workspace/show-file.js +10 -6
- package/dist/tools/workspace/show-plan.js +12 -6
- package/dist/tools/workspace/workspace-search.d.ts +1 -1
- package/dist/tools/workspace/workspace-search.js +11 -5
- package/dist/workflows/execute-analysis.d.ts +46 -4
- package/dist/workflows/execute-analysis.js +118 -13
- package/dist/workflows/execute-target-assessment.d.ts +3 -0
- package/dist/workflows/execute-target-assessment.js +19 -15
- package/dist/workflows/sandbox-step.d.ts +9 -0
- package/dist/workflows/sandbox-step.js +39 -17
- package/dist/workflows/target-assessment/lib/citation-validator.js +2 -2
- package/dist/workflows/target-assessment/lib/clinical-consequence-annotator.js +2 -1
- package/dist/workflows/target-assessment/lib/llm-step.d.ts +3 -0
- package/dist/workflows/target-assessment/lib/llm-step.js +3 -1
- package/dist/workflows/target-assessment/lib/structured-llm.d.ts +3 -0
- package/dist/workflows/target-assessment/lib/structured-llm.js +1 -0
- package/dist/workflows/target-assessment/phase5-persist.d.ts +3 -0
- package/dist/workflows/target-assessment/phase5-persist.js +8 -3
- package/dist/workflows/target-assessment/progress.d.ts +2 -1
- package/dist/workflows/target-assessment/progress.js +4 -3
- package/dist/workspace/filesystem.js +163 -74
- package/dist/workspace/paths.d.ts +2 -2
- package/dist/workspace/paths.js +2 -2
- package/package.json +95 -96
- package/dist/execution/filesystem-artifact-registry.d.ts +0 -57
- package/dist/execution/filesystem-artifact-registry.js +0 -92
- package/dist/lib/identifiers.d.ts +0 -8
- package/dist/lib/identifiers.js +0 -10
- package/dist/lib/mime-detect.d.ts +0 -17
- package/dist/lib/mime-detect.js +0 -29
- package/dist/lib/streamed-download.d.ts +0 -28
- package/dist/lib/streamed-download.js +0 -111
- package/dist/lib/trace-context.d.ts +0 -11
- package/dist/lib/trace-context.js +0 -49
- package/dist/providers/llm-capabilities.d.ts +0 -33
- package/dist/providers/llm-capabilities.js +0 -58
- package/dist/schemas/render-step-prompt.d.ts +0 -32
- package/dist/schemas/render-step-prompt.js +0 -76
- package/dist/tools/bio/find-approval-precedent.d.ts +0 -32
- package/dist/tools/bio/find-approval-precedent.js +0 -72
- package/dist/tools/bio/get-article-details.d.ts +0 -11
- package/dist/tools/bio/get-article-details.js +0 -20
- package/dist/tools/bio/get-article-full-text.d.ts +0 -19
- package/dist/tools/bio/get-article-full-text.js +0 -32
- package/dist/tools/bio/get-bioactivity.d.ts +0 -11
- package/dist/tools/bio/get-bioactivity.js +0 -23
- package/dist/tools/bio/get-drug-info.d.ts +0 -9
- package/dist/tools/bio/get-drug-info.js +0 -22
- package/dist/tools/bio/get-mechanism.d.ts +0 -8
- package/dist/tools/bio/get-mechanism.js +0 -18
- package/dist/tools/bio/get-pubchem-assays.d.ts +0 -22
- package/dist/tools/bio/get-pubchem-assays.js +0 -107
- package/dist/tools/bio/get-pubchem-cross-refs.d.ts +0 -15
- package/dist/tools/bio/get-pubchem-cross-refs.js +0 -68
- package/dist/tools/bio/get-target-safety.d.ts +0 -18
- package/dist/tools/bio/get-target-safety.js +0 -26
- package/dist/tools/bio/search-compounds.d.ts +0 -22
- package/dist/tools/bio/search-compounds.js +0 -160
- package/dist/tools/bio/search-ctx-chemical.d.ts +0 -50
- package/dist/tools/bio/search-ctx-chemical.js +0 -130
- package/dist/tools/bio/search-ctx-exposure.d.ts +0 -55
- package/dist/tools/bio/search-ctx-exposure.js +0 -176
- package/dist/tools/bio/search-ctx-hazard.d.ts +0 -111
- package/dist/tools/bio/search-ctx-hazard.js +0 -178
- package/dist/tools/bio/search-opentargets.d.ts +0 -11
- package/dist/tools/bio/search-opentargets.js +0 -25
- package/dist/tools/bio/search-pubchem-compound.d.ts +0 -26
- package/dist/tools/bio/search-pubchem-compound.js +0 -110
- package/dist/tools/bio/search-pubmed.d.ts +0 -17
- package/dist/tools/bio/search-pubmed.js +0 -31
- package/dist/tools/bio/search-targets.d.ts +0 -9
- package/dist/tools/bio/search-targets.js +0 -20
- package/dist/tools/bio/search-toxcast.d.ts +0 -36
- package/dist/tools/bio/search-toxcast.js +0 -141
- package/dist/workflows/register-workflows.d.ts +0 -51
- package/dist/workflows/register-workflows.js +0 -48
- package/dist/workflows/resume-execute-analysis.d.ts +0 -70
- package/dist/workflows/resume-execute-analysis.js +0 -80
- package/dist/workflows/target-assessment/correction-loop.d.ts +0 -45
- package/dist/workflows/target-assessment/correction-loop.js +0 -62
- package/dist/workflows/target-assessment/steps/phase0-resolve.d.ts +0 -71
- package/dist/workflows/target-assessment/steps/phase0-resolve.js +0 -21
- package/dist/workflows/target-assessment/steps/phase1-aggregate.d.ts +0 -1018
- package/dist/workflows/target-assessment/steps/phase1-aggregate.js +0 -25
- package/dist/workspace/mount-strategy.d.ts +0 -50
- package/dist/workspace/mount-strategy.js +0 -67
- package/dist/workspace/provenance-collector.d.ts +0 -34
- package/dist/workspace/provenance-collector.js +0 -16
- package/dist/workspace/workspace-paths.d.ts +0 -26
- package/dist/workspace/workspace-paths.js +0 -31
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt-cache policy → provider wire options.
|
|
3
|
+
*
|
|
4
|
+
* This is the **only** place in the harness that names a vendor for caching.
|
|
5
|
+
* Everything upstream — `PromptCachePolicy`, `ChatUsage`, `RunAgentOptions` —
|
|
6
|
+
* speaks the neutral harness concept; this module translates it once, at the
|
|
7
|
+
* provider seam, so the loop never learns which vendor it is talking to.
|
|
8
|
+
*
|
|
9
|
+
* ## Why the emitted options are safe on every provider
|
|
10
|
+
*
|
|
11
|
+
* The AI SDK's `providerOptions` is a namespaced bag: each provider reads only
|
|
12
|
+
* `providerOptions[<its own name>]` and ignores every other key
|
|
13
|
+
* (`parseProviderOptions` in `@ai-sdk/provider-utils` returns `undefined` when
|
|
14
|
+
* its namespace is absent). So the `anthropic` namespace is inert — not an
|
|
15
|
+
* error — on an OpenAI-compatible model, which is exactly what we want: that
|
|
16
|
+
* family does automatic server-side prefix caching and needs no directive.
|
|
17
|
+
*
|
|
18
|
+
* ## What the Anthropic namespace does
|
|
19
|
+
*
|
|
20
|
+
* A request-level `cacheControl` makes the provider emit a single top-level
|
|
21
|
+
* `cache_control` marker; the server then places the breakpoint on the last
|
|
22
|
+
* cacheable block, so the whole prefix (tools → system → history) is cached
|
|
23
|
+
* without the harness hand-placing per-block markers.
|
|
24
|
+
*
|
|
25
|
+
* ## Cache defeaters — what silently kills the hit rate
|
|
26
|
+
*
|
|
27
|
+
* The cache keys on an *exact prefix*. Anything that perturbs the head of the
|
|
28
|
+
* request invalidates everything after it. One known defeater remains in this
|
|
29
|
+
* codebase, flagged at its own site as a separate change:
|
|
30
|
+
*
|
|
31
|
+
* 1. `runAgent`'s forced wrap-up swaps the tool set to `{}` — tools sit at the
|
|
32
|
+
* very front of the prefix, so that one call reads nothing back and rewrites
|
|
33
|
+
* the cache from scratch (`loop/run-agent.ts`).
|
|
34
|
+
*
|
|
35
|
+
* `loadRecent`'s history eviction used to be a second defeater — it advanced the
|
|
36
|
+
* window one turn per turn, shifting the message prefix every request. It now
|
|
37
|
+
* evicts in whole blocks so the prefix holds still between block boundaries
|
|
38
|
+
* (`memory/thread-history.ts`).
|
|
39
|
+
*
|
|
40
|
+
* A sandbox agent's system prompt is NOT one of them: it is a pure function of
|
|
41
|
+
* its agent type, byte-identical across every step of every run, and the per-step
|
|
42
|
+
* paths ride in the step's briefing instead (`agents/sandbox/shared.ts`,
|
|
43
|
+
* `prompts/briefing.ts`). Keep it that way — one interpolated id or path there
|
|
44
|
+
* makes every step's ~20k-char prefix unique.
|
|
45
|
+
*
|
|
46
|
+
* ## Where caching is a no-op regardless
|
|
47
|
+
*
|
|
48
|
+
* The Claude Max OAuth path does not honour cache directives, and the OSS CLI
|
|
49
|
+
* defaults to routing through a local CLIProxyAPI on exactly that path. Caching
|
|
50
|
+
* only engages against a direct API key or a gateway. The cache-token metrics
|
|
51
|
+
* (`loop/metrics.ts`) are what tell the two apart at runtime — a flat-zero
|
|
52
|
+
* `cache_read_tokens` counter is the symptom.
|
|
53
|
+
*/
|
|
54
|
+
/**
|
|
55
|
+
* The default policy: cache with the 5-minute TTL.
|
|
56
|
+
*
|
|
57
|
+
* A cache write costs a premium over a plain input token and only pays for
|
|
58
|
+
* itself once something reads it back, so caching is worth it exactly when a
|
|
59
|
+
* shared prefix is re-sent within the TTL. An agent loop always re-sends: every
|
|
60
|
+
* iteration replays the same tools + system + the whole transcript so far, and
|
|
61
|
+
* even a two-iteration run breaks even. The 5m TTL covers a live loop; `1h` is
|
|
62
|
+
* for hosts that also want the *next* turn on a thread to land warm, and costs
|
|
63
|
+
* more per write. One-shot LLM calls should stay `"off"` — they pay the write
|
|
64
|
+
* premium for a cache nothing ever reads.
|
|
65
|
+
*/
|
|
66
|
+
export const DEFAULT_PROMPT_CACHE = { ttl: "5m" };
|
|
67
|
+
/**
|
|
68
|
+
* Translate a neutral cache policy into provider wire options.
|
|
69
|
+
*
|
|
70
|
+
* Returns `undefined` for `"off"` so the caller can leave `providerOptions`
|
|
71
|
+
* entirely unset rather than sending an empty bag.
|
|
72
|
+
*/
|
|
73
|
+
export function promptCacheProviderOptions(policy) {
|
|
74
|
+
if (policy === "off")
|
|
75
|
+
return undefined;
|
|
76
|
+
return { anthropic: { cacheControl: { type: "ephemeral", ttl: policy.ttl } } };
|
|
77
|
+
}
|
|
@@ -24,12 +24,45 @@ export interface ChatRequest {
|
|
|
24
24
|
};
|
|
25
25
|
readonly providerOptions?: ProviderOptions;
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Vendor-neutral prompt-cache policy — a harness concept, not a vendor one.
|
|
29
|
+
*
|
|
30
|
+
* `{ ttl }` asks the provider to cache the request prefix (system + tools +
|
|
31
|
+
* message history) for that lifetime; `"off"` sends no cache directive at all.
|
|
32
|
+
* Vendors that cache automatically (the OpenAI-compatible family does prefix
|
|
33
|
+
* caching server-side, unprompted) need no directive, so the policy is a no-op
|
|
34
|
+
* for them rather than an error — see `./prompt-cache.ts`, the single place the
|
|
35
|
+
* harness translates this into vendor wire options.
|
|
36
|
+
*/
|
|
37
|
+
export type PromptCachePolicy = {
|
|
38
|
+
readonly ttl: "5m" | "1h";
|
|
39
|
+
} | "off";
|
|
40
|
+
/**
|
|
41
|
+
* Token accounting for one chat call, in harness-neutral names.
|
|
42
|
+
*
|
|
43
|
+
* `inputTokens` is the *total* billed prefix — cached and uncached alike — so a
|
|
44
|
+
* cache hit rate is `cacheReadInputTokens / inputTokens`, not a ratio against
|
|
45
|
+
* some separate uncached figure. `cacheCreationInputTokens` is the write that
|
|
46
|
+
* seeds the cache (billed at a premium; it only pays for itself once a later
|
|
47
|
+
* call reads it back).
|
|
48
|
+
*
|
|
49
|
+
* Every field is optional: a provider that reports no usage at all, or reports
|
|
50
|
+
* totals without a cache breakdown, is legitimate. Absent means "not reported",
|
|
51
|
+
* never "zero".
|
|
52
|
+
*/
|
|
53
|
+
export interface ChatUsage {
|
|
54
|
+
readonly inputTokens?: number;
|
|
55
|
+
readonly outputTokens?: number;
|
|
56
|
+
readonly cacheCreationInputTokens?: number;
|
|
57
|
+
readonly cacheReadInputTokens?: number;
|
|
58
|
+
}
|
|
27
59
|
export interface ChatResponse {
|
|
28
60
|
readonly message: Extract<ModelMessage, {
|
|
29
61
|
role: "assistant";
|
|
30
62
|
}>;
|
|
31
63
|
readonly finishReason: FinishReason;
|
|
32
64
|
readonly rawFinishReason?: string;
|
|
65
|
+
readonly usage?: ChatUsage;
|
|
33
66
|
}
|
|
34
67
|
export type ChatStreamEvent = {
|
|
35
68
|
readonly type: "text-delta";
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { type Result } from "neverthrow";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
/** Schema version for the checked-in reference-data catalog. */
|
|
4
|
+
export declare const REFERENCE_DATA_CATALOG_VERSION: 1;
|
|
5
|
+
/** Dataset-relative destination of one artifact below its install path. */
|
|
6
|
+
export declare const ReferenceArtifactPathSchema: z.ZodString;
|
|
7
|
+
/** Lowercase SHA-256 digest of one artifact's bytes. */
|
|
8
|
+
export declare const ReferenceSha256Schema: z.ZodString;
|
|
9
|
+
/** One immutable final file distributed for a reference dataset. */
|
|
10
|
+
export declare const ReferenceArtifactSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
11
|
+
integrity: z.ZodLiteral<"pinned">;
|
|
12
|
+
path: z.ZodString;
|
|
13
|
+
url: z.ZodURL;
|
|
14
|
+
bytes: z.ZodNumber;
|
|
15
|
+
sha256: z.ZodString;
|
|
16
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
17
|
+
integrity: z.ZodLiteral<"unpinned">;
|
|
18
|
+
path: z.ZodString;
|
|
19
|
+
url: z.ZodURL;
|
|
20
|
+
}, z.core.$strict>], "integrity">;
|
|
21
|
+
/** Which integrity guarantee an artifact can actually offer. */
|
|
22
|
+
export type ReferenceIntegrity = z.infer<typeof ReferenceArtifactSchema>["integrity"];
|
|
23
|
+
/** Provenance and licensing information for one supported reference dataset. */
|
|
24
|
+
export declare const ReferenceDatasetSchema: z.ZodObject<{
|
|
25
|
+
id: z.ZodString;
|
|
26
|
+
version: z.ZodString;
|
|
27
|
+
title: z.ZodString;
|
|
28
|
+
description: z.ZodString;
|
|
29
|
+
sourceUrl: z.ZodURL;
|
|
30
|
+
license: z.ZodObject<{
|
|
31
|
+
identifier: z.ZodString;
|
|
32
|
+
url: z.ZodOptional<z.ZodURL>;
|
|
33
|
+
}, z.core.$strip>;
|
|
34
|
+
recommendation: z.ZodObject<{
|
|
35
|
+
group: z.ZodString;
|
|
36
|
+
recommended: z.ZodBoolean;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
artifacts: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
39
|
+
integrity: z.ZodLiteral<"pinned">;
|
|
40
|
+
path: z.ZodString;
|
|
41
|
+
url: z.ZodURL;
|
|
42
|
+
bytes: z.ZodNumber;
|
|
43
|
+
sha256: z.ZodString;
|
|
44
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
45
|
+
integrity: z.ZodLiteral<"unpinned">;
|
|
46
|
+
path: z.ZodString;
|
|
47
|
+
url: z.ZodURL;
|
|
48
|
+
}, z.core.$strict>], "integrity">>;
|
|
49
|
+
}, z.core.$strip>;
|
|
50
|
+
/** Versioned canonical catalog consumed identically by every harness embedder. */
|
|
51
|
+
export declare const ReferenceDataCatalogSchema: z.ZodObject<{
|
|
52
|
+
version: z.ZodLiteral<1>;
|
|
53
|
+
datasets: z.ZodArray<z.ZodObject<{
|
|
54
|
+
id: z.ZodString;
|
|
55
|
+
version: z.ZodString;
|
|
56
|
+
title: z.ZodString;
|
|
57
|
+
description: z.ZodString;
|
|
58
|
+
sourceUrl: z.ZodURL;
|
|
59
|
+
license: z.ZodObject<{
|
|
60
|
+
identifier: z.ZodString;
|
|
61
|
+
url: z.ZodOptional<z.ZodURL>;
|
|
62
|
+
}, z.core.$strip>;
|
|
63
|
+
recommendation: z.ZodObject<{
|
|
64
|
+
group: z.ZodString;
|
|
65
|
+
recommended: z.ZodBoolean;
|
|
66
|
+
}, z.core.$strip>;
|
|
67
|
+
artifacts: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
68
|
+
integrity: z.ZodLiteral<"pinned">;
|
|
69
|
+
path: z.ZodString;
|
|
70
|
+
url: z.ZodURL;
|
|
71
|
+
bytes: z.ZodNumber;
|
|
72
|
+
sha256: z.ZodString;
|
|
73
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
74
|
+
integrity: z.ZodLiteral<"unpinned">;
|
|
75
|
+
path: z.ZodString;
|
|
76
|
+
url: z.ZodURL;
|
|
77
|
+
}, z.core.$strict>], "integrity">>;
|
|
78
|
+
}, z.core.$strip>>;
|
|
79
|
+
}, z.core.$strip>;
|
|
80
|
+
type DeepReadonly<T> = T extends (...args: never[]) => unknown ? T : T extends readonly (infer Item)[] ? readonly DeepReadonly<Item>[] : T extends object ? {
|
|
81
|
+
readonly [Key in keyof T]: DeepReadonly<T[Key]>;
|
|
82
|
+
} : T;
|
|
83
|
+
export type ReferenceArtifact = DeepReadonly<z.infer<typeof ReferenceArtifactSchema>>;
|
|
84
|
+
export type ReferenceDataset = DeepReadonly<z.infer<typeof ReferenceDatasetSchema>>;
|
|
85
|
+
export type ReferenceDataCatalog = DeepReadonly<z.infer<typeof ReferenceDataCatalogSchema>>;
|
|
86
|
+
/**
|
|
87
|
+
* Stable identity of one artifact within the catalog, independent of its URL.
|
|
88
|
+
* Embedders key resumable partials off this, so a moved upstream URL does not
|
|
89
|
+
* orphan a half-finished transfer.
|
|
90
|
+
*/
|
|
91
|
+
export declare function referenceArtifactKey(dataset: {
|
|
92
|
+
readonly id: string;
|
|
93
|
+
readonly version: string;
|
|
94
|
+
}, artifact: {
|
|
95
|
+
readonly path: string;
|
|
96
|
+
}): string;
|
|
97
|
+
/**
|
|
98
|
+
* Canonical release catalog. Every artifact is fetched directly from the third
|
|
99
|
+
* party that publishes it; this project hosts, mirrors, and redistributes
|
|
100
|
+
* nothing. Entries are added only with real upstream URLs, provenance, and
|
|
101
|
+
* licensing data — plus a size and digest whenever the upstream publishes
|
|
102
|
+
* immutable bytes we can pin to.
|
|
103
|
+
*
|
|
104
|
+
* `version` is the dataset's upstream release identifier. Datasets built on an
|
|
105
|
+
* upstream that has no immutable release — NCBI regenerates `gene_info` daily,
|
|
106
|
+
* Reactome overwrites `current` and deletes prior releases — are versioned
|
|
107
|
+
* `current` and carry `unpinned` artifacts.
|
|
108
|
+
*/
|
|
109
|
+
export declare const REFERENCE_DATA_CATALOG: ReferenceDataCatalog;
|
|
110
|
+
/** One selected dataset and its host-neutral installation location. */
|
|
111
|
+
export type ReferenceInstallPlanDataset = ReferenceDataset & {
|
|
112
|
+
readonly installPath: string;
|
|
113
|
+
};
|
|
114
|
+
/** Deterministic plan; every artifact carries the upstream URL it is fetched from. */
|
|
115
|
+
export interface ReferenceInstallPlan {
|
|
116
|
+
readonly catalogVersion: typeof REFERENCE_DATA_CATALOG_VERSION;
|
|
117
|
+
readonly datasets: readonly ReferenceInstallPlanDataset[];
|
|
118
|
+
}
|
|
119
|
+
/** A requested dataset id was not present in the selected catalog. */
|
|
120
|
+
export declare class UnknownReferenceDatasetError extends Error {
|
|
121
|
+
readonly code: "unknown_reference_dataset";
|
|
122
|
+
readonly unknownId: string;
|
|
123
|
+
readonly availableIds: readonly string[];
|
|
124
|
+
constructor(unknownId: string, availableIds: readonly string[]);
|
|
125
|
+
}
|
|
126
|
+
/** Resolve dataset ids without I/O, preserving a stable dataset-id ordering. */
|
|
127
|
+
/** @internal Fixture seam for harness contract tests; not exported by the package barrel. */
|
|
128
|
+
export declare function resolveReferenceInstallPlanFromCatalogForTesting(datasetIds: readonly string[], catalog: ReferenceDataCatalog): Result<ReferenceInstallPlan, UnknownReferenceDatasetError>;
|
|
129
|
+
/** Resolve ids strictly against the immutable canonical catalog shipped by this package. */
|
|
130
|
+
export declare function resolveReferenceInstallPlan(datasetIds: readonly string[]): Result<ReferenceInstallPlan, UnknownReferenceDatasetError>;
|
|
131
|
+
export {};
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import { posix as posixPath } from "node:path";
|
|
2
|
+
import { err, ok } from "neverthrow";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
/** Schema version for the checked-in reference-data catalog. */
|
|
5
|
+
export const REFERENCE_DATA_CATALOG_VERSION = 1;
|
|
6
|
+
const SAFE_ID = /^[a-z0-9]+(?:[._-][a-z0-9]+)*$/;
|
|
7
|
+
const SAFE_VERSION = /^[A-Za-z0-9]+(?:[._-][A-Za-z0-9]+)*$/;
|
|
8
|
+
const SHA256 = /^[a-f0-9]{64}$/;
|
|
9
|
+
function isSafeRelativePath(value) {
|
|
10
|
+
if (value.length === 0 || value.includes("\\") || value.startsWith("/"))
|
|
11
|
+
return false;
|
|
12
|
+
const segments = value.split("/");
|
|
13
|
+
return segments.every((segment) => segment.length > 0 && segment !== "." && segment !== "..") && posixPath.normalize(value) === value;
|
|
14
|
+
}
|
|
15
|
+
/** Dataset-relative destination of one artifact below its install path. */
|
|
16
|
+
export const ReferenceArtifactPathSchema = z.string().refine(isSafeRelativePath, "Expected a safe dataset-relative path");
|
|
17
|
+
/** Lowercase SHA-256 digest of one artifact's bytes. */
|
|
18
|
+
export const ReferenceSha256Schema = z.string().regex(SHA256, "Expected a lowercase SHA-256 digest");
|
|
19
|
+
/**
|
|
20
|
+
* Artifacts are fetched from the upstream that publishes them — this project
|
|
21
|
+
* redistributes nothing — so the URL must be a real third-party https endpoint.
|
|
22
|
+
*/
|
|
23
|
+
const ReferenceArtifactUrlSchema = z.url().refine((value) => value.startsWith("https://"), "Reference artifacts must be fetched over https");
|
|
24
|
+
/**
|
|
25
|
+
* An artifact whose upstream publishes immutable, versioned bytes. The catalog
|
|
26
|
+
* carries the size and digest, so a download is verified against *this file*
|
|
27
|
+
* before it is ever activated: a mismatch means the bytes are not what we
|
|
28
|
+
* reviewed, and the install fails.
|
|
29
|
+
*/
|
|
30
|
+
const PinnedReferenceArtifactSchema = z.strictObject({
|
|
31
|
+
integrity: z.literal("pinned"),
|
|
32
|
+
path: ReferenceArtifactPathSchema,
|
|
33
|
+
url: ReferenceArtifactUrlSchema,
|
|
34
|
+
bytes: z.number().int().positive(),
|
|
35
|
+
sha256: ReferenceSha256Schema,
|
|
36
|
+
});
|
|
37
|
+
/**
|
|
38
|
+
* An artifact whose upstream regenerates the same URL in place — NCBI rebuilds
|
|
39
|
+
* `gene_info` continuously and Reactome's `current` release is overwritten and
|
|
40
|
+
* its predecessors deleted. No checked-in digest can survive that, and pinning
|
|
41
|
+
* one would only guarantee a broken download. Integrity is therefore
|
|
42
|
+
* trust-on-first-use: the installer records the bytes it actually received in
|
|
43
|
+
* the receipt, and `verify` proves the files have not changed *since install*.
|
|
44
|
+
* This is a weaker guarantee than `pinned` and is surfaced as such to the user.
|
|
45
|
+
*/
|
|
46
|
+
const UnpinnedReferenceArtifactSchema = z.strictObject({
|
|
47
|
+
integrity: z.literal("unpinned"),
|
|
48
|
+
path: ReferenceArtifactPathSchema,
|
|
49
|
+
url: ReferenceArtifactUrlSchema,
|
|
50
|
+
});
|
|
51
|
+
/** One immutable final file distributed for a reference dataset. */
|
|
52
|
+
export const ReferenceArtifactSchema = z.discriminatedUnion("integrity", [PinnedReferenceArtifactSchema, UnpinnedReferenceArtifactSchema]);
|
|
53
|
+
/** Provenance and licensing information for one supported reference dataset. */
|
|
54
|
+
export const ReferenceDatasetSchema = z.object({
|
|
55
|
+
id: z.string().regex(SAFE_ID, "Expected a stable lowercase dataset id"),
|
|
56
|
+
version: z.string().regex(SAFE_VERSION, "Expected a safe dataset version path segment"),
|
|
57
|
+
title: z.string().min(1),
|
|
58
|
+
description: z.string().min(1),
|
|
59
|
+
sourceUrl: z.url(),
|
|
60
|
+
license: z.object({
|
|
61
|
+
identifier: z.string().min(1),
|
|
62
|
+
url: z.url().optional(),
|
|
63
|
+
}),
|
|
64
|
+
recommendation: z.object({
|
|
65
|
+
group: z.string().min(1),
|
|
66
|
+
recommended: z.boolean(),
|
|
67
|
+
}),
|
|
68
|
+
artifacts: z.array(ReferenceArtifactSchema).min(1),
|
|
69
|
+
});
|
|
70
|
+
/** Versioned canonical catalog consumed identically by every harness embedder. */
|
|
71
|
+
export const ReferenceDataCatalogSchema = z
|
|
72
|
+
.object({
|
|
73
|
+
version: z.literal(REFERENCE_DATA_CATALOG_VERSION),
|
|
74
|
+
datasets: z.array(ReferenceDatasetSchema),
|
|
75
|
+
})
|
|
76
|
+
.superRefine((catalog, ctx) => {
|
|
77
|
+
const ids = new Set();
|
|
78
|
+
for (const [datasetIndex, dataset] of catalog.datasets.entries()) {
|
|
79
|
+
if (ids.has(dataset.id)) {
|
|
80
|
+
ctx.addIssue({ code: "custom", message: `Duplicate dataset id: ${dataset.id}`, path: ["datasets", datasetIndex, "id"] });
|
|
81
|
+
}
|
|
82
|
+
ids.add(dataset.id);
|
|
83
|
+
const paths = new Set();
|
|
84
|
+
for (const [artifactIndex, artifact] of dataset.artifacts.entries()) {
|
|
85
|
+
if (paths.has(artifact.path)) {
|
|
86
|
+
ctx.addIssue({
|
|
87
|
+
code: "custom",
|
|
88
|
+
message: `Duplicate artifact path in ${dataset.id}: ${artifact.path}`,
|
|
89
|
+
path: ["datasets", datasetIndex, "artifacts", artifactIndex, "path"],
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
paths.add(artifact.path);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
/**
|
|
97
|
+
* Stable identity of one artifact within the catalog, independent of its URL.
|
|
98
|
+
* Embedders key resumable partials off this, so a moved upstream URL does not
|
|
99
|
+
* orphan a half-finished transfer.
|
|
100
|
+
*/
|
|
101
|
+
export function referenceArtifactKey(dataset, artifact) {
|
|
102
|
+
return `${dataset.id}/${dataset.version}/${artifact.path}`;
|
|
103
|
+
}
|
|
104
|
+
function deepFreeze(value) {
|
|
105
|
+
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
106
|
+
for (const nested of Object.values(value))
|
|
107
|
+
deepFreeze(nested);
|
|
108
|
+
Object.freeze(value);
|
|
109
|
+
}
|
|
110
|
+
return value;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Canonical release catalog. Every artifact is fetched directly from the third
|
|
114
|
+
* party that publishes it; this project hosts, mirrors, and redistributes
|
|
115
|
+
* nothing. Entries are added only with real upstream URLs, provenance, and
|
|
116
|
+
* licensing data — plus a size and digest whenever the upstream publishes
|
|
117
|
+
* immutable bytes we can pin to.
|
|
118
|
+
*
|
|
119
|
+
* `version` is the dataset's upstream release identifier. Datasets built on an
|
|
120
|
+
* upstream that has no immutable release — NCBI regenerates `gene_info` daily,
|
|
121
|
+
* Reactome overwrites `current` and deletes prior releases — are versioned
|
|
122
|
+
* `current` and carry `unpinned` artifacts.
|
|
123
|
+
*/
|
|
124
|
+
export const REFERENCE_DATA_CATALOG = deepFreeze(ReferenceDataCatalogSchema.parse({
|
|
125
|
+
version: REFERENCE_DATA_CATALOG_VERSION,
|
|
126
|
+
datasets: [
|
|
127
|
+
{
|
|
128
|
+
id: "ncbi-gene-human",
|
|
129
|
+
version: "current",
|
|
130
|
+
title: "NCBI human gene identifiers",
|
|
131
|
+
description: "Entrez Gene records for Homo sapiens (NCBI taxonomy 9606): identifiers, approved symbols, synonyms, and cross-references (Ensembl, HGNC) in the dbXrefs column. Tab-separated, gzipped. NCBI rebuilds this file in place, so it is verified against what you downloaded rather than a checked-in digest.",
|
|
132
|
+
sourceUrl: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/GENE_INFO/Mammalia/",
|
|
133
|
+
license: {
|
|
134
|
+
identifier: "NCBI-Molecular-Data-Usage-Policy",
|
|
135
|
+
url: "https://www.ncbi.nlm.nih.gov/home/about/policies/",
|
|
136
|
+
},
|
|
137
|
+
recommendation: { group: "gene-identifiers", recommended: true },
|
|
138
|
+
artifacts: [
|
|
139
|
+
{
|
|
140
|
+
integrity: "unpinned",
|
|
141
|
+
path: "Homo_sapiens.gene_info.gz",
|
|
142
|
+
url: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/GENE_INFO/Mammalia/Homo_sapiens.gene_info.gz",
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
id: "ncbi-gene-mouse",
|
|
148
|
+
version: "current",
|
|
149
|
+
title: "NCBI mouse gene identifiers",
|
|
150
|
+
description: "Entrez Gene records for Mus musculus (NCBI taxonomy 10090): identifiers, approved symbols, synonyms, and cross-references (Ensembl, MGI) in the dbXrefs column. Tab-separated, gzipped. NCBI rebuilds this file in place, so it is verified against what you downloaded rather than a checked-in digest.",
|
|
151
|
+
sourceUrl: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/GENE_INFO/Mammalia/",
|
|
152
|
+
license: {
|
|
153
|
+
identifier: "NCBI-Molecular-Data-Usage-Policy",
|
|
154
|
+
url: "https://www.ncbi.nlm.nih.gov/home/about/policies/",
|
|
155
|
+
},
|
|
156
|
+
recommendation: { group: "gene-identifiers", recommended: true },
|
|
157
|
+
artifacts: [
|
|
158
|
+
{
|
|
159
|
+
integrity: "unpinned",
|
|
160
|
+
path: "Mus_musculus.gene_info.gz",
|
|
161
|
+
url: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/GENE_INFO/Mammalia/Mus_musculus.gene_info.gz",
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
id: "ncbi-gene-rat",
|
|
167
|
+
version: "current",
|
|
168
|
+
title: "NCBI rat gene identifiers",
|
|
169
|
+
description: "Entrez Gene records for Rattus norvegicus (NCBI taxonomy 10116): identifiers, approved symbols, synonyms, and cross-references (Ensembl, RGD) in the dbXrefs column. Tab-separated, gzipped. NCBI rebuilds this file in place, so it is verified against what you downloaded rather than a checked-in digest.",
|
|
170
|
+
sourceUrl: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/GENE_INFO/Mammalia/",
|
|
171
|
+
license: {
|
|
172
|
+
identifier: "NCBI-Molecular-Data-Usage-Policy",
|
|
173
|
+
url: "https://www.ncbi.nlm.nih.gov/home/about/policies/",
|
|
174
|
+
},
|
|
175
|
+
recommendation: { group: "gene-identifiers", recommended: true },
|
|
176
|
+
artifacts: [
|
|
177
|
+
{
|
|
178
|
+
integrity: "unpinned",
|
|
179
|
+
path: "Rattus_norvegicus.gene_info.gz",
|
|
180
|
+
url: "https://ftp.ncbi.nlm.nih.gov/gene/DATA/GENE_INFO/Mammalia/Rattus_norvegicus.gene_info.gz",
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
id: "reactome-pathways",
|
|
186
|
+
version: "current",
|
|
187
|
+
title: "Reactome pathways",
|
|
188
|
+
description: "Reactome pathway gene sets (GMT) and the pathway index — the enrichment workhorse, ~2 MB. Reactome overwrites its `current` release each quarter and removes the prior one, so this is verified against what you downloaded rather than a checked-in digest. For identifier-to-pathway mapping tables, add `reactome-mappings`.",
|
|
189
|
+
sourceUrl: "https://reactome.org/download-data",
|
|
190
|
+
license: { identifier: "CC0-1.0", url: "https://reactome.org/license" },
|
|
191
|
+
recommendation: { group: "pathways", recommended: true },
|
|
192
|
+
artifacts: [
|
|
193
|
+
{ integrity: "unpinned", path: "ReactomePathways.gmt", url: "https://reactome.org/download/current/ReactomePathways.gmt" },
|
|
194
|
+
{ integrity: "unpinned", path: "ReactomePathways.txt", url: "https://reactome.org/download/current/ReactomePathways.txt" },
|
|
195
|
+
],
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
// Split out of `reactome-pathways` and NOT recommended by default: upstream serves these
|
|
199
|
+
// as uncompressed TSV and they total roughly 700 MB, two orders of magnitude more than the
|
|
200
|
+
// GMT most workflows actually want. Anyone who needs Entrez/Ensembl/UniProt -> pathway
|
|
201
|
+
// joins opts in deliberately, rather than every `setup` paying for them by accident.
|
|
202
|
+
id: "reactome-mappings",
|
|
203
|
+
version: "current",
|
|
204
|
+
title: "Reactome identifier mappings (large)",
|
|
205
|
+
description: "Entrez/Ensembl/UniProt-to-Reactome mapping tables at all pathway levels. Large: roughly 700 MB of uncompressed TSV, because Reactome publishes no compressed form. Only needed to join external identifiers onto Reactome pathways; the gene sets themselves live in `reactome-pathways`.",
|
|
206
|
+
sourceUrl: "https://reactome.org/download-data",
|
|
207
|
+
license: { identifier: "CC0-1.0", url: "https://reactome.org/license" },
|
|
208
|
+
recommendation: { group: "pathways", recommended: false },
|
|
209
|
+
artifacts: [
|
|
210
|
+
{
|
|
211
|
+
integrity: "unpinned",
|
|
212
|
+
path: "NCBI2Reactome_All_Levels.txt",
|
|
213
|
+
url: "https://reactome.org/download/current/NCBI2Reactome_All_Levels.txt",
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
integrity: "unpinned",
|
|
217
|
+
path: "Ensembl2Reactome_All_Levels.txt",
|
|
218
|
+
url: "https://reactome.org/download/current/Ensembl2Reactome_All_Levels.txt",
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
integrity: "unpinned",
|
|
222
|
+
path: "UniProt2Reactome_All_Levels.txt",
|
|
223
|
+
url: "https://reactome.org/download/current/UniProt2Reactome_All_Levels.txt",
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
id: "wikipathways-human",
|
|
229
|
+
version: "2026.07.10",
|
|
230
|
+
title: "WikiPathways human pathways",
|
|
231
|
+
description: "Community-curated Homo sapiens pathway gene sets (GMT) from the immutable 2026-07-10 WikiPathways snapshot.",
|
|
232
|
+
sourceUrl: "https://data.wikipathways.org/20260710/gmt/",
|
|
233
|
+
license: { identifier: "CC0-1.0", url: "https://www.wikipathways.org/about/terms.html" },
|
|
234
|
+
recommendation: { group: "pathways", recommended: true },
|
|
235
|
+
artifacts: [
|
|
236
|
+
{
|
|
237
|
+
integrity: "pinned",
|
|
238
|
+
path: "wikipathways_Homo_sapiens.gmt",
|
|
239
|
+
url: "https://data.wikipathways.org/20260710/gmt/wikipathways-20260710-gmt-Homo_sapiens.gmt",
|
|
240
|
+
bytes: 341_474,
|
|
241
|
+
sha256: "79615a079246bb0b07cc3505265b1f75ea6cffec88001ce27f644dd86a39c97d",
|
|
242
|
+
},
|
|
243
|
+
],
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
id: "collectri-human",
|
|
247
|
+
version: "2.0",
|
|
248
|
+
title: "CollecTRI human regulatory network",
|
|
249
|
+
description: "A literature-curated human transcription-factor target interaction network (CSV) from the immutable Zenodo record 8192729.",
|
|
250
|
+
sourceUrl: "https://zenodo.org/records/8192729",
|
|
251
|
+
license: { identifier: "CC-BY-4.0", url: "https://zenodo.org/records/8192729" },
|
|
252
|
+
recommendation: { group: "regulatory-networks", recommended: true },
|
|
253
|
+
artifacts: [
|
|
254
|
+
{
|
|
255
|
+
integrity: "pinned",
|
|
256
|
+
path: "CollecTRI_regulons.csv",
|
|
257
|
+
url: "https://zenodo.org/records/8192729/files/CollecTRI_regulons.csv",
|
|
258
|
+
bytes: 4_345_649,
|
|
259
|
+
sha256: "4473c9189dd53dacc80297709ad1452dda1086a1cc2185f9a56146c261668701",
|
|
260
|
+
},
|
|
261
|
+
],
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
id: "gtex-v8",
|
|
265
|
+
version: "8",
|
|
266
|
+
title: "GTEx v8 normal tissue expression",
|
|
267
|
+
description: "GTEx v8 median gene TPM by tissue (GCT) with the sample attributes table, for normal-reference workflows. Immutable v8 release files.",
|
|
268
|
+
sourceUrl: "https://gtexportal.org/home/downloads/adult-gtex/bulk_tissue_expression",
|
|
269
|
+
license: { identifier: "GTEx-Portal-Data-License", url: "https://gtexportal.org/home/license" },
|
|
270
|
+
recommendation: { group: "normal-expression", recommended: true },
|
|
271
|
+
artifacts: [
|
|
272
|
+
{
|
|
273
|
+
integrity: "pinned",
|
|
274
|
+
path: "GTEx_Analysis_2017-06-05_v8_RNASeQCv1.1.9_gene_median_tpm.gct.gz",
|
|
275
|
+
url: "https://storage.googleapis.com/adult-gtex/bulk-gex/v8/rna-seq/GTEx_Analysis_2017-06-05_v8_RNASeQCv1.1.9_gene_median_tpm.gct.gz",
|
|
276
|
+
bytes: 6_952_331,
|
|
277
|
+
sha256: "ee7201ff2f280b0de5657d4b08e9a240362d9757efed7f7bd5dba35a5f8617b8",
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
integrity: "pinned",
|
|
281
|
+
path: "GTEx_Analysis_v8_Annotations_SampleAttributesDS.txt",
|
|
282
|
+
url: "https://storage.googleapis.com/adult-gtex/annotations/v8/metadata-files/GTEx_Analysis_v8_Annotations_SampleAttributesDS.txt",
|
|
283
|
+
bytes: 11_512_258,
|
|
284
|
+
sha256: "74f6ab4c34ed2648d708a0ae6e6dff324f6c86ea723ae7d1c37d76f5221148f0",
|
|
285
|
+
},
|
|
286
|
+
],
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
id: "celltypist-immune",
|
|
290
|
+
version: "2",
|
|
291
|
+
title: "CellTypist immune cell models",
|
|
292
|
+
description: "CellTypist Immune All low- and high-resolution models for immune cell-type annotation. Load by absolute path — CellTypist's by-name lookup expects its own cache layout, which the reference store deliberately does not impersonate.",
|
|
293
|
+
sourceUrl: "https://www.celltypist.org/models",
|
|
294
|
+
license: { identifier: "NOASSERTION" },
|
|
295
|
+
recommendation: { group: "cell-typing", recommended: true },
|
|
296
|
+
artifacts: [
|
|
297
|
+
{
|
|
298
|
+
integrity: "pinned",
|
|
299
|
+
path: "Immune_All_Low.pkl",
|
|
300
|
+
url: "https://celltypist.cog.sanger.ac.uk/models/Pan_Immune_CellTypist/v2/Immune_All_Low.pkl",
|
|
301
|
+
bytes: 2_824_990,
|
|
302
|
+
sha256: "290874d35dac039d4c9218c343fde4aac1077709b72a331ce7266f6828c36502",
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
integrity: "pinned",
|
|
306
|
+
path: "Immune_All_High.pkl",
|
|
307
|
+
url: "https://celltypist.cog.sanger.ac.uk/models/Pan_Immune_CellTypist/v2/Immune_All_High.pkl",
|
|
308
|
+
bytes: 1_070_426,
|
|
309
|
+
sha256: "a715fec36c2c421f7c4e31cf4cb4bea883eedab7fd7b20a4b76f091c22660448",
|
|
310
|
+
},
|
|
311
|
+
],
|
|
312
|
+
},
|
|
313
|
+
],
|
|
314
|
+
}));
|
|
315
|
+
/** A requested dataset id was not present in the selected catalog. */
|
|
316
|
+
export class UnknownReferenceDatasetError extends Error {
|
|
317
|
+
code = "unknown_reference_dataset";
|
|
318
|
+
unknownId;
|
|
319
|
+
availableIds;
|
|
320
|
+
constructor(unknownId, availableIds) {
|
|
321
|
+
super(`Unknown reference dataset "${unknownId}". Available ids: ${availableIds.join(", ") || "(none)"}`);
|
|
322
|
+
this.name = "UnknownReferenceDatasetError";
|
|
323
|
+
this.unknownId = unknownId;
|
|
324
|
+
this.availableIds = availableIds;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/** Resolve dataset ids without I/O, preserving a stable dataset-id ordering. */
|
|
328
|
+
/** @internal Fixture seam for harness contract tests; not exported by the package barrel. */
|
|
329
|
+
export function resolveReferenceInstallPlanFromCatalogForTesting(datasetIds, catalog) {
|
|
330
|
+
const byId = new Map(catalog.datasets.map((dataset) => [dataset.id, dataset]));
|
|
331
|
+
const availableIds = [...byId.keys()].sort();
|
|
332
|
+
const selectedIds = [...new Set(datasetIds)].sort();
|
|
333
|
+
for (const id of selectedIds) {
|
|
334
|
+
if (!byId.has(id))
|
|
335
|
+
return err(new UnknownReferenceDatasetError(id, availableIds));
|
|
336
|
+
}
|
|
337
|
+
return ok({
|
|
338
|
+
catalogVersion: catalog.version,
|
|
339
|
+
datasets: selectedIds.map((id) => {
|
|
340
|
+
const dataset = byId.get(id);
|
|
341
|
+
return { ...dataset, installPath: `${dataset.id}/${dataset.version}` };
|
|
342
|
+
}),
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
/** Resolve ids strictly against the immutable canonical catalog shipped by this package. */
|
|
346
|
+
export function resolveReferenceInstallPlan(datasetIds) {
|
|
347
|
+
return resolveReferenceInstallPlanFromCatalogForTesting(datasetIds, REFERENCE_DATA_CATALOG);
|
|
348
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Schema version for installation receipts shared by all embedders. */
|
|
3
|
+
export declare const REFERENCE_INSTALL_RECEIPT_VERSION: 1;
|
|
4
|
+
/**
|
|
5
|
+
* What was actually written to disk for one artifact. The size and digest are
|
|
6
|
+
* *observed at install*, never copied from the catalog — for a `pinned`
|
|
7
|
+
* artifact they equal the catalog's (the install would have failed otherwise),
|
|
8
|
+
* and for an `unpinned` one they are the only record of what the mutable
|
|
9
|
+
* upstream served, which is what `verify` later checks the files against.
|
|
10
|
+
*/
|
|
11
|
+
declare const ReferenceReceiptArtifactSchema: z.ZodObject<{
|
|
12
|
+
path: z.ZodString;
|
|
13
|
+
bytes: z.ZodNumber;
|
|
14
|
+
sha256: z.ZodString;
|
|
15
|
+
integrity: z.ZodEnum<{
|
|
16
|
+
pinned: "pinned";
|
|
17
|
+
unpinned: "unpinned";
|
|
18
|
+
}>;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
/** Optional metadata describing one activated reference dataset version. */
|
|
21
|
+
export declare const ReferenceInstallReceiptSchema: z.ZodObject<{
|
|
22
|
+
version: z.ZodLiteral<1>;
|
|
23
|
+
datasetId: z.ZodString;
|
|
24
|
+
datasetVersion: z.ZodString;
|
|
25
|
+
activatedAt: z.ZodISODateTime;
|
|
26
|
+
artifacts: z.ZodArray<z.ZodObject<{
|
|
27
|
+
path: z.ZodString;
|
|
28
|
+
bytes: z.ZodNumber;
|
|
29
|
+
sha256: z.ZodString;
|
|
30
|
+
integrity: z.ZodEnum<{
|
|
31
|
+
pinned: "pinned";
|
|
32
|
+
unpinned: "unpinned";
|
|
33
|
+
}>;
|
|
34
|
+
}, z.core.$strip>>;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
export type ReferenceInstallReceipt = z.infer<typeof ReferenceInstallReceiptSchema>;
|
|
37
|
+
/** One artifact as recorded by a completed installation. */
|
|
38
|
+
export type ReferenceReceiptArtifact = z.infer<typeof ReferenceReceiptArtifactSchema>;
|
|
39
|
+
/** Parse optional/untrusted receipt metadata; invalid receipts are ignored. */
|
|
40
|
+
export declare function parseReferenceInstallReceipt(input: unknown): ReferenceInstallReceipt | undefined;
|
|
41
|
+
export {};
|