@inflexa-ai/harness 0.1.1 → 0.2.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/dist/agents/conversation-agent.d.ts +12 -11
- package/dist/agents/conversation-agent.js +30 -33
- 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 +17 -6
- package/dist/agents/sandbox/shared.js +49 -38
- 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/data-profile-orientation.d.ts +34 -0
- package/dist/app/data-profile-orientation.js +117 -0
- package/dist/contracts/schemas/chat-parts.d.ts +9 -9
- package/dist/execution/artifact-metadata.js +2 -1
- package/dist/execution/ephemeral-runner.d.ts +13 -0
- package/dist/execution/ephemeral-runner.js +23 -1
- package/dist/execution/run-synthesis.js +20 -19
- package/dist/execution/step-summary.js +2 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +19 -5
- 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/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/tasks/data-profile.d.ts +20 -2
- package/dist/tasks/data-profile.js +71 -22
- 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-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 +168 -118
- package/dist/tools/iterate-report.js +334 -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.js +3 -4
- 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/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 +43 -4
- package/dist/workflows/execute-analysis.js +107 -6
- 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/workspace/paths.d.ts +2 -2
- package/dist/workspace/paths.js +2 -2
- package/package.json +33 -33
- 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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inflexa-ai/harness",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Host-agnostic bioinformatics agent harness — hand-rolled agent loop, DBOS-durable workflows, sandboxed compute.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -43,53 +43,53 @@
|
|
|
43
43
|
"typecheck": "tsc --noEmit"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@ai-sdk/anthropic": "^4.0.
|
|
47
|
-
"@ai-sdk/openai-compatible": "^3.0.
|
|
48
|
-
"@ai-sdk/provider": "^4.0.
|
|
46
|
+
"@ai-sdk/anthropic": "^4.0.15",
|
|
47
|
+
"@ai-sdk/openai-compatible": "^3.0.10",
|
|
48
|
+
"@ai-sdk/provider": "^4.0.3",
|
|
49
49
|
"@anthropic-ai/sdk": "^0.107.0",
|
|
50
|
-
"@dbos-inc/dbos-sdk": "^4.23.
|
|
51
|
-
"@kubernetes/client-node": "^1.
|
|
50
|
+
"@dbos-inc/dbos-sdk": "^4.23.6",
|
|
51
|
+
"@kubernetes/client-node": "^1.4.0",
|
|
52
52
|
"@opentelemetry/api": "^1.9.1",
|
|
53
|
-
"@opentelemetry/core": "^2.
|
|
53
|
+
"@opentelemetry/core": "^2.9.0",
|
|
54
54
|
"@opentelemetry/exporter-metrics-otlp-http": "^0.219.0",
|
|
55
55
|
"@opentelemetry/exporter-trace-otlp-proto": "^0.219.0",
|
|
56
|
-
"@opentelemetry/resources": "^2.
|
|
57
|
-
"@opentelemetry/sdk-metrics": "^2.
|
|
58
|
-
"@opentelemetry/sdk-trace-base": "^2.
|
|
59
|
-
"@opentelemetry/sdk-trace-node": "^2.
|
|
60
|
-
"@opentelemetry/semantic-conventions": "^1.
|
|
61
|
-
"ai": "^7.0.
|
|
62
|
-
"cheerio": "^1.
|
|
63
|
-
"dockerode": "^4.0.
|
|
64
|
-
"fast-xml-parser": "^5.
|
|
65
|
-
"hono": "^4.
|
|
66
|
-
"js-tiktoken": "^1.0.
|
|
67
|
-
"mime": "^4.
|
|
68
|
-
"nanoid": "^5.
|
|
56
|
+
"@opentelemetry/resources": "^2.9.0",
|
|
57
|
+
"@opentelemetry/sdk-metrics": "^2.9.0",
|
|
58
|
+
"@opentelemetry/sdk-trace-base": "^2.9.0",
|
|
59
|
+
"@opentelemetry/sdk-trace-node": "^2.9.0",
|
|
60
|
+
"@opentelemetry/semantic-conventions": "^1.43.0",
|
|
61
|
+
"ai": "^7.0.28",
|
|
62
|
+
"cheerio": "^1.2.0",
|
|
63
|
+
"dockerode": "^4.0.12",
|
|
64
|
+
"fast-xml-parser": "^5.10.0",
|
|
65
|
+
"hono": "^4.12.30",
|
|
66
|
+
"js-tiktoken": "^1.0.21",
|
|
67
|
+
"mime": "^4.1.0",
|
|
68
|
+
"nanoid": "^5.1.16",
|
|
69
69
|
"neverthrow": "^8.2.0",
|
|
70
70
|
"nunjucks": "^3.2.4",
|
|
71
|
-
"openai": "^4.
|
|
72
|
-
"pdf-parse": "^2.4.
|
|
73
|
-
"pg": "^8.
|
|
71
|
+
"openai": "^4.104.0",
|
|
72
|
+
"pdf-parse": "^2.4.5",
|
|
73
|
+
"pg": "^8.22.0",
|
|
74
74
|
"pino": "^10.3.1",
|
|
75
|
-
"puppeteer-core": "^23.
|
|
75
|
+
"puppeteer-core": "^23.11.1",
|
|
76
76
|
"zod": "^4.4.3"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
79
|
"@eslint/js": "^10.0.1",
|
|
80
80
|
"@types/bun": "latest",
|
|
81
|
-
"@types/dockerode": "^3.3.
|
|
82
|
-
"@types/node": "^24.
|
|
81
|
+
"@types/dockerode": "^3.3.47",
|
|
82
|
+
"@types/node": "^24.13.3",
|
|
83
83
|
"@types/nunjucks": "^3.2.6",
|
|
84
|
-
"@types/pdf-parse": "^1.1.
|
|
85
|
-
"@types/pg": "^8.
|
|
86
|
-
"eslint": "^10.
|
|
84
|
+
"@types/pdf-parse": "^1.1.5",
|
|
85
|
+
"@types/pg": "^8.20.0",
|
|
86
|
+
"eslint": "^10.7.0",
|
|
87
87
|
"eslint-plugin-neverthrow": "^1.1.4",
|
|
88
|
-
"globals": "^17.
|
|
89
|
-
"prettier": "^3.
|
|
90
|
-
"testcontainers": "^10.
|
|
88
|
+
"globals": "^17.7.0",
|
|
89
|
+
"prettier": "^3.9.5",
|
|
90
|
+
"testcontainers": "^10.28.0",
|
|
91
91
|
"typescript": "^6.0.3",
|
|
92
|
-
"typescript-eslint": "^8.
|
|
92
|
+
"typescript-eslint": "^8.64.0"
|
|
93
93
|
},
|
|
94
94
|
"publishConfig": {
|
|
95
95
|
"access": "public",
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `FilesystemArtifactRegistry` — the harness's (cloud-free) `ArtifactRegistry`
|
|
3
|
-
* adapter.
|
|
4
|
-
*
|
|
5
|
-
* Instead of registering provenance with an external ledger, it writes a local
|
|
6
|
-
* provenance index file under the step directory:
|
|
7
|
-
*
|
|
8
|
-
* {sessionPath}/{resourceId}/runs/{runId}/{stepId}/provenance-index.json
|
|
9
|
-
*
|
|
10
|
-
* The index records the step's registered artifacts (analysis-scoped paths +
|
|
11
|
-
* hashes) and the tracked inputs/outputs captured by the `ProvenanceCollector`,
|
|
12
|
-
* so a local embedder (the CLI) retains a queryable lineage record with no
|
|
13
|
-
* cloud dependency. Re-registration merges by output path (latest wins).
|
|
14
|
-
*
|
|
15
|
-
* It returns no external ids — the local `cortex_artifacts` ledger is the only
|
|
16
|
-
* identity store in the cloud-free configuration.
|
|
17
|
-
*/
|
|
18
|
-
import type { ArtifactRegistry } from "./artifact-registry.js";
|
|
19
|
-
export interface FilesystemArtifactRegistryDeps {
|
|
20
|
-
/** Base path holding per-analysis session directories. */
|
|
21
|
-
sessionPath: string;
|
|
22
|
-
}
|
|
23
|
-
/** One registered artifact in the local index. */
|
|
24
|
-
export interface FilesystemArtifactEntry {
|
|
25
|
-
/** Analysis-scoped path (`runs/{runId}/{stepId}/...`). */
|
|
26
|
-
path: string;
|
|
27
|
-
hash: string;
|
|
28
|
-
size: number;
|
|
29
|
-
type: string;
|
|
30
|
-
}
|
|
31
|
-
/** One tracked output's lineage in the local index. */
|
|
32
|
-
export interface FilesystemLineageRecord {
|
|
33
|
-
outputPath: string;
|
|
34
|
-
outputHash: string;
|
|
35
|
-
producer: string;
|
|
36
|
-
scriptPath: string | null;
|
|
37
|
-
inputs: Array<{
|
|
38
|
-
path: string;
|
|
39
|
-
hash: string;
|
|
40
|
-
source: string;
|
|
41
|
-
}>;
|
|
42
|
-
}
|
|
43
|
-
/** Shape of the persisted provenance index file. */
|
|
44
|
-
export interface FilesystemProvenanceIndex {
|
|
45
|
-
resourceId: string;
|
|
46
|
-
runId: string;
|
|
47
|
-
stepId: string;
|
|
48
|
-
updatedAt: string;
|
|
49
|
-
artifacts: FilesystemArtifactEntry[];
|
|
50
|
-
inputs: Array<{
|
|
51
|
-
path: string;
|
|
52
|
-
hash: string;
|
|
53
|
-
source: string;
|
|
54
|
-
}>;
|
|
55
|
-
lineage: FilesystemLineageRecord[];
|
|
56
|
-
}
|
|
57
|
-
export declare function createFilesystemArtifactRegistry(deps: FilesystemArtifactRegistryDeps): ArtifactRegistry;
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `FilesystemArtifactRegistry` — the harness's (cloud-free) `ArtifactRegistry`
|
|
3
|
-
* adapter.
|
|
4
|
-
*
|
|
5
|
-
* Instead of registering provenance with an external ledger, it writes a local
|
|
6
|
-
* provenance index file under the step directory:
|
|
7
|
-
*
|
|
8
|
-
* {sessionPath}/{resourceId}/runs/{runId}/{stepId}/provenance-index.json
|
|
9
|
-
*
|
|
10
|
-
* The index records the step's registered artifacts (analysis-scoped paths +
|
|
11
|
-
* hashes) and the tracked inputs/outputs captured by the `ProvenanceCollector`,
|
|
12
|
-
* so a local embedder (the CLI) retains a queryable lineage record with no
|
|
13
|
-
* cloud dependency. Re-registration merges by output path (latest wins).
|
|
14
|
-
*
|
|
15
|
-
* It returns no external ids — the local `cortex_artifacts` ledger is the only
|
|
16
|
-
* identity store in the cloud-free configuration.
|
|
17
|
-
*/
|
|
18
|
-
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
19
|
-
import { dirname, join } from "node:path";
|
|
20
|
-
import { runStepDir } from "../workspace/paths.js";
|
|
21
|
-
function indexPath(sessionPath, input) {
|
|
22
|
-
return join(sessionPath, runStepDir(input.resourceId, input.runId, input.stepId), "provenance-index.json");
|
|
23
|
-
}
|
|
24
|
-
async function readIndex(path) {
|
|
25
|
-
try {
|
|
26
|
-
return JSON.parse(await readFile(path, "utf8"));
|
|
27
|
-
}
|
|
28
|
-
catch (err) {
|
|
29
|
-
if (err.code === "ENOENT")
|
|
30
|
-
return null;
|
|
31
|
-
// Corrupt/partial index (e.g. crash mid-write) → treat as absent and rebuild.
|
|
32
|
-
if (err instanceof SyntaxError)
|
|
33
|
-
return null;
|
|
34
|
-
throw err;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
/** Merge two keyed lists, latest (incoming) winning per key. */
|
|
38
|
-
function mergeBy(prior, incoming, key) {
|
|
39
|
-
const byKey = new Map();
|
|
40
|
-
for (const item of prior)
|
|
41
|
-
byKey.set(key(item), item);
|
|
42
|
-
for (const item of incoming)
|
|
43
|
-
byKey.set(key(item), item);
|
|
44
|
-
return [...byKey.values()];
|
|
45
|
-
}
|
|
46
|
-
export function createFilesystemArtifactRegistry(deps) {
|
|
47
|
-
const { sessionPath } = deps;
|
|
48
|
-
return {
|
|
49
|
-
async register(input, _session) {
|
|
50
|
-
const { runId, stepId, artifacts, collector } = input;
|
|
51
|
-
if (artifacts.length === 0) {
|
|
52
|
-
return { registered: [], failed: [], failedCount: 0 };
|
|
53
|
-
}
|
|
54
|
-
const dbPathPrefix = `runs/${runId}/${stepId}/`;
|
|
55
|
-
const entries = artifacts.map((a) => ({
|
|
56
|
-
path: `${dbPathPrefix}${a.path}`,
|
|
57
|
-
hash: a.hash ?? "",
|
|
58
|
-
size: a.size,
|
|
59
|
-
type: a.type,
|
|
60
|
-
}));
|
|
61
|
-
const inputs = collector.getTrackedInputs().map((i) => ({
|
|
62
|
-
path: i.path,
|
|
63
|
-
hash: i.hash,
|
|
64
|
-
source: i.source,
|
|
65
|
-
}));
|
|
66
|
-
const lineage = collector.getRecords().map((r) => ({
|
|
67
|
-
outputPath: r.outputPath,
|
|
68
|
-
outputHash: r.outputHash,
|
|
69
|
-
producer: r.producer.type,
|
|
70
|
-
scriptPath: r.scriptPath,
|
|
71
|
-
inputs: r.inputs.map((i) => ({ path: i.path, hash: i.hash, source: i.source })),
|
|
72
|
-
}));
|
|
73
|
-
const path = indexPath(sessionPath, input);
|
|
74
|
-
const prior = await readIndex(path);
|
|
75
|
-
const merged = {
|
|
76
|
-
resourceId: input.resourceId,
|
|
77
|
-
runId,
|
|
78
|
-
stepId,
|
|
79
|
-
updatedAt: new Date().toISOString(),
|
|
80
|
-
artifacts: mergeBy(prior?.artifacts ?? [], entries, (e) => e.path),
|
|
81
|
-
inputs: mergeBy(prior?.inputs ?? [], inputs, (i) => i.path),
|
|
82
|
-
lineage: mergeBy(prior?.lineage ?? [], lineage, (l) => l.outputPath),
|
|
83
|
-
};
|
|
84
|
-
await mkdir(dirname(path), { recursive: true });
|
|
85
|
-
await writeFile(path, JSON.stringify(merged, null, 2));
|
|
86
|
-
// No external identity store in the cloud-free configuration.
|
|
87
|
-
return { registered: [], failed: [], failedCount: 0 };
|
|
88
|
-
},
|
|
89
|
-
// Bytes already live in the local session tree — nothing to upload.
|
|
90
|
-
async sync() { },
|
|
91
|
-
};
|
|
92
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Identifier validation — safe patterns for path-embedded IDs.
|
|
3
|
-
*/
|
|
4
|
-
/** Pattern for IDs safe to embed in filesystem paths. */
|
|
5
|
-
export declare const SAFE_ID_PATTERN: RegExp;
|
|
6
|
-
/** Zod refinement for safe path identifiers. */
|
|
7
|
-
export declare function isSafePathId(value: string): boolean;
|
|
8
|
-
export declare const SAFE_ID_MESSAGE = "Must be alphanumeric with hyphens/underscores, no path separators";
|
package/dist/lib/identifiers.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Identifier validation — safe patterns for path-embedded IDs.
|
|
3
|
-
*/
|
|
4
|
-
/** Pattern for IDs safe to embed in filesystem paths. */
|
|
5
|
-
export const SAFE_ID_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
|
|
6
|
-
/** Zod refinement for safe path identifiers. */
|
|
7
|
-
export function isSafePathId(value) {
|
|
8
|
-
return SAFE_ID_PATTERN.test(value) && !value.includes("..");
|
|
9
|
-
}
|
|
10
|
-
export const SAFE_ID_MESSAGE = "Must be alphanumeric with hyphens/underscores, no path separators";
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Mime-type detection for artifact registration.
|
|
3
|
-
*
|
|
4
|
-
* Registration payloads sent to the storage backend carry a `mimeType` per file. The storage backend
|
|
5
|
-
* persists it on the artifact row and uses it as the S3 object's
|
|
6
|
-
* `Content-Type` when the artifact is later synced — without it, S3 stores
|
|
7
|
-
* `application/octet-stream` and downloads serve as opaque binary regardless
|
|
8
|
-
* of file extension.
|
|
9
|
-
*
|
|
10
|
-
* The `mime` package's mime-db backing doesn't include a few science-domain
|
|
11
|
-
* extensions (`.py`, `.R`, `.Rmd`, `.RData`, `.rds`) that browsers populate
|
|
12
|
-
* in `File.type` from their bundled tables, so we extend a custom Mime
|
|
13
|
-
* instance with those cases. Returned types align with the frontend's browser-side
|
|
14
|
-
* detection so a Python script uploaded directly and one synced from a
|
|
15
|
-
* sandbox both end up with the same `text/x-python`.
|
|
16
|
-
*/
|
|
17
|
-
export declare function detectMimeType(pathOrFilename: string): string;
|
package/dist/lib/mime-detect.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Mime-type detection for artifact registration.
|
|
3
|
-
*
|
|
4
|
-
* Registration payloads sent to the storage backend carry a `mimeType` per file. The storage backend
|
|
5
|
-
* persists it on the artifact row and uses it as the S3 object's
|
|
6
|
-
* `Content-Type` when the artifact is later synced — without it, S3 stores
|
|
7
|
-
* `application/octet-stream` and downloads serve as opaque binary regardless
|
|
8
|
-
* of file extension.
|
|
9
|
-
*
|
|
10
|
-
* The `mime` package's mime-db backing doesn't include a few science-domain
|
|
11
|
-
* extensions (`.py`, `.R`, `.Rmd`, `.RData`, `.rds`) that browsers populate
|
|
12
|
-
* in `File.type` from their bundled tables, so we extend a custom Mime
|
|
13
|
-
* instance with those cases. Returned types align with the frontend's browser-side
|
|
14
|
-
* detection so a Python script uploaded directly and one synced from a
|
|
15
|
-
* sandbox both end up with the same `text/x-python`.
|
|
16
|
-
*/
|
|
17
|
-
import { Mime } from "mime";
|
|
18
|
-
import standard from "mime/types/standard.js";
|
|
19
|
-
import other from "mime/types/other.js";
|
|
20
|
-
const mime = new Mime(standard, other, {
|
|
21
|
-
"text/x-python": ["py"],
|
|
22
|
-
"text/x-r-source": ["R", "r"],
|
|
23
|
-
"text/x-r-markdown": ["Rmd", "rmd"],
|
|
24
|
-
"application/x-rdata": ["RData", "Rdata", "rds"],
|
|
25
|
-
});
|
|
26
|
-
const FALLBACK = "application/octet-stream";
|
|
27
|
-
export function detectMimeType(pathOrFilename) {
|
|
28
|
-
return mime.getType(pathOrFilename) ?? FALLBACK;
|
|
29
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Streaming HTTP download helper with optional ranged-GET parallelism.
|
|
3
|
-
*
|
|
4
|
-
* Per-stream working memory is bounded at ~64 KiB regardless of file size —
|
|
5
|
-
* bodies are never materialized as Buffers. When the caller supplies the
|
|
6
|
-
* total size and it exceeds `partSize`, the download is split into N ranged
|
|
7
|
-
* GETs that write into a pre-allocated file at their respective offsets.
|
|
8
|
-
*/
|
|
9
|
-
export interface StreamDownloadOpts {
|
|
10
|
-
/** Total file size. Required for ranged-parallel downloads. */
|
|
11
|
-
size?: number;
|
|
12
|
-
/** Bytes per range. Falls back to single-GET when size <= partSize. */
|
|
13
|
-
partSize?: number;
|
|
14
|
-
/** Max ranges in flight. */
|
|
15
|
-
concurrency?: number;
|
|
16
|
-
/** Max retries per range or per whole-file stream. */
|
|
17
|
-
maxRetries?: number;
|
|
18
|
-
/** Abort signal for cancellation. */
|
|
19
|
-
signal?: AbortSignal;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Download a URL to `destPath`, streaming the body to disk.
|
|
23
|
-
*
|
|
24
|
-
* Creates the destination file (truncating any existing content). On success
|
|
25
|
-
* the file exists at `destPath`; on failure it may be partially written —
|
|
26
|
-
* callers should use a temp path + rename pattern if atomicity matters.
|
|
27
|
-
*/
|
|
28
|
-
export declare function streamDownload(url: string, destPath: string, opts?: StreamDownloadOpts): Promise<void>;
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Streaming HTTP download helper with optional ranged-GET parallelism.
|
|
3
|
-
*
|
|
4
|
-
* Per-stream working memory is bounded at ~64 KiB regardless of file size —
|
|
5
|
-
* bodies are never materialized as Buffers. When the caller supplies the
|
|
6
|
-
* total size and it exceeds `partSize`, the download is split into N ranged
|
|
7
|
-
* GETs that write into a pre-allocated file at their respective offsets.
|
|
8
|
-
*/
|
|
9
|
-
import { createWriteStream } from "node:fs";
|
|
10
|
-
import { open as fsOpen } from "node:fs/promises";
|
|
11
|
-
import { Readable } from "node:stream";
|
|
12
|
-
import { pipeline } from "node:stream/promises";
|
|
13
|
-
import { mapConcurrent, sleep } from "./async-utils.js";
|
|
14
|
-
const DEFAULT_PART_SIZE = 32 * 1024 * 1024; // 32 MiB
|
|
15
|
-
const DEFAULT_CONCURRENCY = 4;
|
|
16
|
-
const DEFAULT_MAX_RETRIES = 3;
|
|
17
|
-
const BASE_DELAY_MS = 500;
|
|
18
|
-
/**
|
|
19
|
-
* Download a URL to `destPath`, streaming the body to disk.
|
|
20
|
-
*
|
|
21
|
-
* Creates the destination file (truncating any existing content). On success
|
|
22
|
-
* the file exists at `destPath`; on failure it may be partially written —
|
|
23
|
-
* callers should use a temp path + rename pattern if atomicity matters.
|
|
24
|
-
*/
|
|
25
|
-
export async function streamDownload(url, destPath, opts = {}) {
|
|
26
|
-
const size = opts.size;
|
|
27
|
-
const partSize = opts.partSize ?? DEFAULT_PART_SIZE;
|
|
28
|
-
const concurrency = opts.concurrency ?? DEFAULT_CONCURRENCY;
|
|
29
|
-
const maxRetries = opts.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
30
|
-
if (!size || size <= partSize) {
|
|
31
|
-
await fetchStreamToFile(url, destPath, "w", undefined, maxRetries, opts.signal);
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
// Pre-allocate the file so per-range streams can write at correct offsets.
|
|
35
|
-
const fh = await fsOpen(destPath, "w");
|
|
36
|
-
try {
|
|
37
|
-
await fh.truncate(size);
|
|
38
|
-
}
|
|
39
|
-
finally {
|
|
40
|
-
await fh.close();
|
|
41
|
-
}
|
|
42
|
-
const totalParts = Math.ceil(size / partSize);
|
|
43
|
-
await mapConcurrent(Array.from({ length: totalParts }, (_, i) => i), concurrency, async (i) => {
|
|
44
|
-
const start = i * partSize;
|
|
45
|
-
const end = Math.min(start + partSize, size) - 1;
|
|
46
|
-
await fetchRangeToFile(url, destPath, start, end, maxRetries, opts.signal);
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
async function fetchStreamToFile(url, destPath, flags, start, maxRetries, signal) {
|
|
50
|
-
let lastError = "";
|
|
51
|
-
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
52
|
-
try {
|
|
53
|
-
const res = await fetch(url, { signal });
|
|
54
|
-
if (!res.ok) {
|
|
55
|
-
lastError = `HTTP ${res.status}`;
|
|
56
|
-
if (res.status >= 500 && attempt < maxRetries - 1) {
|
|
57
|
-
await sleep(BASE_DELAY_MS * 2 ** attempt);
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
throw new Error(lastError);
|
|
61
|
-
}
|
|
62
|
-
if (!res.body)
|
|
63
|
-
throw new Error("response body is null");
|
|
64
|
-
const writer = createWriteStream(destPath, start !== undefined ? { flags, start } : { flags });
|
|
65
|
-
await pipeline(Readable.fromWeb(res.body), writer);
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
catch (err) {
|
|
69
|
-
lastError = err instanceof Error ? err.message : String(err);
|
|
70
|
-
if (attempt < maxRetries - 1) {
|
|
71
|
-
await sleep(BASE_DELAY_MS * 2 ** attempt);
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
throw new Error(`download failed after ${maxRetries} attempts: ${lastError}`);
|
|
77
|
-
}
|
|
78
|
-
async function fetchRangeToFile(url, destPath, start, end, maxRetries, signal) {
|
|
79
|
-
let lastError = "";
|
|
80
|
-
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
81
|
-
try {
|
|
82
|
-
const res = await fetch(url, {
|
|
83
|
-
headers: { Range: `bytes=${start}-${end}` },
|
|
84
|
-
signal,
|
|
85
|
-
});
|
|
86
|
-
// 206 is the expected success; 200 means the server ignored Range — treat
|
|
87
|
-
// as fatal since it would overwrite other ranges.
|
|
88
|
-
if (res.status !== 206) {
|
|
89
|
-
lastError = `HTTP ${res.status}`;
|
|
90
|
-
if (res.status >= 500 && attempt < maxRetries - 1) {
|
|
91
|
-
await sleep(BASE_DELAY_MS * 2 ** attempt);
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
throw new Error(res.status === 200 ? `server ignored Range header (HTTP 200) — parallel download would clobber` : lastError);
|
|
95
|
-
}
|
|
96
|
-
if (!res.body)
|
|
97
|
-
throw new Error("response body is null");
|
|
98
|
-
const writer = createWriteStream(destPath, { flags: "r+", start });
|
|
99
|
-
await pipeline(Readable.fromWeb(res.body), writer);
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
catch (err) {
|
|
103
|
-
lastError = err instanceof Error ? err.message : String(err);
|
|
104
|
-
if (attempt < maxRetries - 1) {
|
|
105
|
-
await sleep(BASE_DELAY_MS * 2 ** attempt);
|
|
106
|
-
continue;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
throw new Error(`range ${start}-${end} failed after ${maxRetries} attempts: ${lastError}`);
|
|
111
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hono middleware for W3C Trace Context extraction.
|
|
3
|
-
*
|
|
4
|
-
* Hono's HTTP server is not auto-instrumented by OTEL (which patches Node's
|
|
5
|
-
* `http` module, not Hono's request handling). This middleware manually
|
|
6
|
-
* extracts the `traceparent` header from incoming requests, creates an OTEL
|
|
7
|
-
* server span, and wraps the handler in `context.with()` so the OtelBridge
|
|
8
|
-
* and any downstream code see the correct parent span via `context.active()`.
|
|
9
|
-
*/
|
|
10
|
-
import type { MiddlewareHandler } from "hono";
|
|
11
|
-
export declare const traceContextMiddleware: MiddlewareHandler;
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hono middleware for W3C Trace Context extraction.
|
|
3
|
-
*
|
|
4
|
-
* Hono's HTTP server is not auto-instrumented by OTEL (which patches Node's
|
|
5
|
-
* `http` module, not Hono's request handling). This middleware manually
|
|
6
|
-
* extracts the `traceparent` header from incoming requests, creates an OTEL
|
|
7
|
-
* server span, and wraps the handler in `context.with()` so the OtelBridge
|
|
8
|
-
* and any downstream code see the correct parent span via `context.active()`.
|
|
9
|
-
*/
|
|
10
|
-
import { trace, context, propagation, SpanKind, SpanStatusCode } from "@opentelemetry/api";
|
|
11
|
-
const tracer = trace.getTracer("cortex.http");
|
|
12
|
-
/**
|
|
13
|
-
* Middleware that extracts W3C trace context from incoming HTTP headers and
|
|
14
|
-
* creates a server span. Must be registered before all other middleware so
|
|
15
|
-
* the OTEL context is available throughout the request lifecycle.
|
|
16
|
-
*/
|
|
17
|
-
const SKIP_TRACE_PATHS = new Set(["/healthz", "/readyz"]);
|
|
18
|
-
export const traceContextMiddleware = async (c, next) => {
|
|
19
|
-
if (SKIP_TRACE_PATHS.has(c.req.path)) {
|
|
20
|
-
return next();
|
|
21
|
-
}
|
|
22
|
-
const carrier = {};
|
|
23
|
-
for (const [key, value] of c.req.raw.headers) {
|
|
24
|
-
carrier[key] = value;
|
|
25
|
-
}
|
|
26
|
-
const parentCtx = propagation.extract(context.active(), carrier);
|
|
27
|
-
const span = tracer.startSpan(`${c.req.method} ${c.req.path}`, {
|
|
28
|
-
kind: SpanKind.SERVER,
|
|
29
|
-
attributes: {
|
|
30
|
-
"http.method": c.req.method,
|
|
31
|
-
"http.target": c.req.path,
|
|
32
|
-
},
|
|
33
|
-
}, parentCtx);
|
|
34
|
-
const spanCtx = trace.setSpan(parentCtx, span);
|
|
35
|
-
try {
|
|
36
|
-
await context.with(spanCtx, () => next());
|
|
37
|
-
span.setAttribute("http.status_code", c.res.status);
|
|
38
|
-
}
|
|
39
|
-
catch (err) {
|
|
40
|
-
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
41
|
-
if (err instanceof Error) {
|
|
42
|
-
span.recordException(err);
|
|
43
|
-
}
|
|
44
|
-
throw err;
|
|
45
|
-
}
|
|
46
|
-
finally {
|
|
47
|
-
span.end();
|
|
48
|
-
}
|
|
49
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Per-model capability gates for harness provider calls.
|
|
3
|
-
*
|
|
4
|
-
* The harness `ChatRequest` is a passthrough of `MessageCreateParamsBase`,
|
|
5
|
-
* so callers already pass per-call overrides (`temperature`, `thinking`,
|
|
6
|
-
* tool config, …) as native fields. This module is the silent drop-on-reject
|
|
7
|
-
* gate at the provider edge: model-rejected fields are stripped before they
|
|
8
|
-
* hit the wire so the call still succeeds (e.g. `acceptsTemperature`).
|
|
9
|
-
*
|
|
10
|
-
* Classification is pattern-based on the bare model name (no provider
|
|
11
|
-
* prefix — the harness `createAnthropicProvider` already knows it is
|
|
12
|
-
* Anthropic). No network calls, no runtime probing.
|
|
13
|
-
*/
|
|
14
|
-
import type { Message } from "./types.js";
|
|
15
|
-
/**
|
|
16
|
-
* Anthropic Opus/Sonnet/Haiku 4.7+ reject `temperature` with HTTP 400.
|
|
17
|
-
* 4.6 and earlier accept it.
|
|
18
|
-
*/
|
|
19
|
-
export declare function anthropicAcceptsTemperature(modelName: string): boolean;
|
|
20
|
-
/**
|
|
21
|
-
* The model's true maximum output-token ceiling — the `max_tokens` the
|
|
22
|
-
* Anthropic provider sets per call (the API requires the field). Pattern-
|
|
23
|
-
* matched on the bare model name (no provider prefix). Ceilings per the
|
|
24
|
-
* current Anthropic model reference: Opus 4.x → 128K, Sonnet 4.6 → 64K,
|
|
25
|
-
* Haiku 4.5 → 64K.
|
|
26
|
-
*/
|
|
27
|
-
export declare function maxOutputTokens(modelName: string): number;
|
|
28
|
-
/**
|
|
29
|
-
* Map an OpenAI `finish_reason` into the Anthropic `stop_reason` the harness
|
|
30
|
-
* loop branches on (see the harness-providers spec — every provider adapts into Anthropic shape).
|
|
31
|
-
* The imminent `openai.ts` adapter is the first caller.
|
|
32
|
-
*/
|
|
33
|
-
export declare function mapOpenAiFinishReason(finishReason: string | null): Message["stop_reason"];
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Per-model capability gates for harness provider calls.
|
|
3
|
-
*
|
|
4
|
-
* The harness `ChatRequest` is a passthrough of `MessageCreateParamsBase`,
|
|
5
|
-
* so callers already pass per-call overrides (`temperature`, `thinking`,
|
|
6
|
-
* tool config, …) as native fields. This module is the silent drop-on-reject
|
|
7
|
-
* gate at the provider edge: model-rejected fields are stripped before they
|
|
8
|
-
* hit the wire so the call still succeeds (e.g. `acceptsTemperature`).
|
|
9
|
-
*
|
|
10
|
-
* Classification is pattern-based on the bare model name (no provider
|
|
11
|
-
* prefix — the harness `createAnthropicProvider` already knows it is
|
|
12
|
-
* Anthropic). No network calls, no runtime probing.
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* Anthropic Opus/Sonnet/Haiku 4.7+ reject `temperature` with HTTP 400.
|
|
16
|
-
* 4.6 and earlier accept it.
|
|
17
|
-
*/
|
|
18
|
-
export function anthropicAcceptsTemperature(modelName) {
|
|
19
|
-
return !/^claude-(opus|sonnet|haiku)-4-([7-9]|\d{2,})\b/.test(modelName.toLowerCase());
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* The model's true maximum output-token ceiling — the `max_tokens` the
|
|
23
|
-
* Anthropic provider sets per call (the API requires the field). Pattern-
|
|
24
|
-
* matched on the bare model name (no provider prefix). Ceilings per the
|
|
25
|
-
* current Anthropic model reference: Opus 4.x → 128K, Sonnet 4.6 → 64K,
|
|
26
|
-
* Haiku 4.5 → 64K.
|
|
27
|
-
*/
|
|
28
|
-
export function maxOutputTokens(modelName) {
|
|
29
|
-
const name = modelName.toLowerCase();
|
|
30
|
-
if (/^claude-opus-4-/.test(name))
|
|
31
|
-
return 128_000;
|
|
32
|
-
if (/^claude-sonnet-4-/.test(name))
|
|
33
|
-
return 64_000;
|
|
34
|
-
if (/^claude-haiku-4-/.test(name))
|
|
35
|
-
return 64_000;
|
|
36
|
-
// Unknown model — a generous default broadly accepted by current models;
|
|
37
|
-
// the loop recovers from truncation, so erring high is cheap.
|
|
38
|
-
return 32_768;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Map an OpenAI `finish_reason` into the Anthropic `stop_reason` the harness
|
|
42
|
-
* loop branches on (see the harness-providers spec — every provider adapts into Anthropic shape).
|
|
43
|
-
* The imminent `openai.ts` adapter is the first caller.
|
|
44
|
-
*/
|
|
45
|
-
export function mapOpenAiFinishReason(finishReason) {
|
|
46
|
-
switch (finishReason) {
|
|
47
|
-
case "length":
|
|
48
|
-
return "max_tokens";
|
|
49
|
-
case "tool_calls":
|
|
50
|
-
return "tool_use";
|
|
51
|
-
case "stop":
|
|
52
|
-
return "end_turn";
|
|
53
|
-
case "content_filter":
|
|
54
|
-
return "refusal";
|
|
55
|
-
default:
|
|
56
|
-
return "end_turn";
|
|
57
|
-
}
|
|
58
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Render an AnalysisStep into the user-content prompt the sandbox agent
|
|
3
|
-
* receives as its initial message.
|
|
4
|
-
*
|
|
5
|
-
* The planner writes the bulk of a step's instructions into structured
|
|
6
|
-
* fields (`constraints`, `acceptance_criteria`, `context`, `caveats`,
|
|
7
|
-
* `description`) alongside the one-line `question`. The execution path
|
|
8
|
-
* forwards a single `prompt` string to the sandbox agent, so every
|
|
9
|
-
* instruction-bearing field must be folded into that string here — otherwise
|
|
10
|
-
* the agent runs against the bare question and improvises the rest.
|
|
11
|
-
*
|
|
12
|
-
* `STEP_PROMPT_INSTRUCTION_FIELDS` / `STEP_PROMPT_NON_INSTRUCTION_FIELDS`
|
|
13
|
-
* partition every AnalysisStep field so the field-coverage guard test can
|
|
14
|
-
* fail when a new field is added to the schema without a deliberate decision
|
|
15
|
-
* about whether the agent needs to see it.
|
|
16
|
-
*/
|
|
17
|
-
import type { AnalysisStep } from "./workflow-state.js";
|
|
18
|
-
/** Fields whose content is agent-facing and MUST appear in the rendered prompt. */
|
|
19
|
-
export declare const STEP_PROMPT_INSTRUCTION_FIELDS: readonly ["name", "question", "description", "context", "constraints", "acceptance_criteria", "caveats"];
|
|
20
|
-
/**
|
|
21
|
-
* Fields deliberately excluded from the prompt: identity/DAG structure
|
|
22
|
-
* threaded separately through the workflow input, execution knobs, and
|
|
23
|
-
* result fields populated after the step runs.
|
|
24
|
-
*/
|
|
25
|
-
export declare const STEP_PROMPT_NON_INSTRUCTION_FIELDS: readonly ["id", "track", "step_type", "depends_on", "status", "resources", "agent", "timeout", "maxSteps", "summary", "artifactIds", "error"];
|
|
26
|
-
/**
|
|
27
|
-
* Compose the agent's initial prompt from a plan step. Only the `question`
|
|
28
|
-
* is guaranteed present; the remaining instruction fields are appended as
|
|
29
|
-
* dedicated sections when populated. Empty strings and empty arrays are
|
|
30
|
-
* skipped so a sparse step renders cleanly.
|
|
31
|
-
*/
|
|
32
|
-
export declare function renderStepPrompt(step: AnalysisStep): string;
|