@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
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ReferenceArtifactPathSchema, ReferenceDatasetSchema, ReferenceSha256Schema } from "./catalog.js";
|
|
3
|
+
/** Schema version for installation receipts shared by all embedders. */
|
|
4
|
+
export const REFERENCE_INSTALL_RECEIPT_VERSION = 1;
|
|
5
|
+
/**
|
|
6
|
+
* What was actually written to disk for one artifact. The size and digest are
|
|
7
|
+
* *observed at install*, never copied from the catalog — for a `pinned`
|
|
8
|
+
* artifact they equal the catalog's (the install would have failed otherwise),
|
|
9
|
+
* and for an `unpinned` one they are the only record of what the mutable
|
|
10
|
+
* upstream served, which is what `verify` later checks the files against.
|
|
11
|
+
*/
|
|
12
|
+
const ReferenceReceiptArtifactSchema = z.object({
|
|
13
|
+
path: ReferenceArtifactPathSchema,
|
|
14
|
+
bytes: z.number().int().nonnegative(),
|
|
15
|
+
sha256: ReferenceSha256Schema,
|
|
16
|
+
integrity: z.enum(["pinned", "unpinned"]),
|
|
17
|
+
});
|
|
18
|
+
/** Optional metadata describing one activated reference dataset version. */
|
|
19
|
+
export const ReferenceInstallReceiptSchema = z
|
|
20
|
+
.object({
|
|
21
|
+
version: z.literal(REFERENCE_INSTALL_RECEIPT_VERSION),
|
|
22
|
+
datasetId: ReferenceDatasetSchema.shape.id,
|
|
23
|
+
datasetVersion: ReferenceDatasetSchema.shape.version,
|
|
24
|
+
activatedAt: z.iso.datetime({ offset: true }),
|
|
25
|
+
artifacts: z.array(ReferenceReceiptArtifactSchema).min(1),
|
|
26
|
+
})
|
|
27
|
+
.superRefine((receipt, ctx) => {
|
|
28
|
+
const paths = new Set();
|
|
29
|
+
for (const [index, artifact] of receipt.artifacts.entries()) {
|
|
30
|
+
if (paths.has(artifact.path)) {
|
|
31
|
+
ctx.addIssue({ code: "custom", message: `Duplicate receipt artifact path: ${artifact.path}`, path: ["artifacts", index, "path"] });
|
|
32
|
+
}
|
|
33
|
+
paths.add(artifact.path);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
/** Parse optional/untrusted receipt metadata; invalid receipts are ignored. */
|
|
37
|
+
export function parseReferenceInstallReceipt(input) {
|
|
38
|
+
const result = ReferenceInstallReceiptSchema.safeParse(input);
|
|
39
|
+
return result.success ? result.data : undefined;
|
|
40
|
+
}
|
|
@@ -15,7 +15,7 @@ export const ProfilerFileSchema = z.object({
|
|
|
15
15
|
.describe("Semantic data type: count-matrix, normalized-expression, variants, alignments, " +
|
|
16
16
|
"clinical-metadata, clinical-sdtm, clinical-adam, clinical-response, " +
|
|
17
17
|
"pharmacokinetic-data, adverse-events, safety-labs, " +
|
|
18
|
-
"molecular-structures, annotations"),
|
|
18
|
+
"molecular-structures, annotations, document (paper PDF, README, methods doc)"),
|
|
19
19
|
format: z.string().describe("File format (e.g. CSV, TSV, h5ad, MTX, VCF, BAM, SDF, FASTQ)"),
|
|
20
20
|
rows: z.number().nullish(),
|
|
21
21
|
cols: z.number().nullish(),
|
|
@@ -43,7 +43,7 @@ export const OrganismSchema = z.object({
|
|
|
43
43
|
source: SubjectSourceEnum,
|
|
44
44
|
confidence: z
|
|
45
45
|
.enum(["high", "medium", "low"])
|
|
46
|
-
.describe("high: explicit organism column or paper/README statement. " +
|
|
46
|
+
.describe("high: explicit user-context statement, an organism column, or a paper/README statement. " +
|
|
47
47
|
"medium: filename convention or accession lookup. " +
|
|
48
48
|
"low: inferred from gene IDs or other indirect signals, OR sources disagree (in which case also record the conflict in qualityAssessment.concerns)."),
|
|
49
49
|
notes: z.string().optional().describe("Brief note when source is 'inferred' or confidence is 'low' (one sentence)."),
|
|
@@ -51,7 +51,9 @@ export const OrganismSchema = z.object({
|
|
|
51
51
|
export const ProfilerOutputSchema = z.object({
|
|
52
52
|
files: z.array(ProfilerFileSchema),
|
|
53
53
|
analysisSummary: z.string().describe("Narrative overview of the dataset — structure, content, analytical potential, and limitations"),
|
|
54
|
-
domain: z
|
|
54
|
+
domain: z
|
|
55
|
+
.string()
|
|
56
|
+
.describe("Scientific domain (e.g. transcriptomics, proteomics, genomics, cheminformatics, clinical, imaging, metabolomics, multi-omics)"),
|
|
55
57
|
subtype: z.string().optional().describe("Specific subtype within domain (e.g. bulk-rna-seq, single-cell, LC-MS/MS, whole-genome-sequencing)"),
|
|
56
58
|
organism: OrganismSchema.nullable().describe("Subject organism, identified from any input (metadata files, paper PDFs, READMEs, filenames, accession patterns). " +
|
|
57
59
|
"Set to null ONLY when no input identifies the organism — never guess. " +
|
|
@@ -11,6 +11,13 @@ export declare const PlanStepSchema: z.ZodObject<{
|
|
|
11
11
|
id: z.ZodString;
|
|
12
12
|
context: z.ZodOptional<z.ZodString>;
|
|
13
13
|
description: z.ZodOptional<z.ZodString>;
|
|
14
|
+
track: z.ZodString;
|
|
15
|
+
step_type: z.ZodString;
|
|
16
|
+
question: z.ZodString;
|
|
17
|
+
constraints: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
18
|
+
acceptance_criteria: z.ZodArray<z.ZodString>;
|
|
19
|
+
caveats: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
20
|
+
depends_on: z.ZodArray<z.ZodString>;
|
|
14
21
|
resources: z.ZodNonOptional<z.ZodOptional<z.ZodObject<{
|
|
15
22
|
cpu: z.ZodNumber;
|
|
16
23
|
memoryGb: z.ZodNumber;
|
|
@@ -18,13 +25,6 @@ export declare const PlanStepSchema: z.ZodObject<{
|
|
|
18
25
|
count: z.ZodNumber;
|
|
19
26
|
}, z.core.$strip>>;
|
|
20
27
|
}, z.core.$strip>>>;
|
|
21
|
-
constraints: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
22
|
-
track: z.ZodString;
|
|
23
|
-
step_type: z.ZodString;
|
|
24
|
-
question: z.ZodString;
|
|
25
|
-
acceptance_criteria: z.ZodArray<z.ZodString>;
|
|
26
|
-
caveats: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
27
|
-
depends_on: z.ZodArray<z.ZodString>;
|
|
28
28
|
agent: z.ZodEnum<{
|
|
29
29
|
[x: string]: string;
|
|
30
30
|
}>;
|
|
@@ -43,6 +43,13 @@ export declare const PlannerPlanSchema: z.ZodObject<{
|
|
|
43
43
|
id: z.ZodString;
|
|
44
44
|
context: z.ZodOptional<z.ZodString>;
|
|
45
45
|
description: z.ZodOptional<z.ZodString>;
|
|
46
|
+
track: z.ZodString;
|
|
47
|
+
step_type: z.ZodString;
|
|
48
|
+
question: z.ZodString;
|
|
49
|
+
constraints: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
50
|
+
acceptance_criteria: z.ZodArray<z.ZodString>;
|
|
51
|
+
caveats: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
52
|
+
depends_on: z.ZodArray<z.ZodString>;
|
|
46
53
|
resources: z.ZodNonOptional<z.ZodOptional<z.ZodObject<{
|
|
47
54
|
cpu: z.ZodNumber;
|
|
48
55
|
memoryGb: z.ZodNumber;
|
|
@@ -50,13 +57,6 @@ export declare const PlannerPlanSchema: z.ZodObject<{
|
|
|
50
57
|
count: z.ZodNumber;
|
|
51
58
|
}, z.core.$strip>>;
|
|
52
59
|
}, z.core.$strip>>>;
|
|
53
|
-
constraints: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
54
|
-
track: z.ZodString;
|
|
55
|
-
step_type: z.ZodString;
|
|
56
|
-
question: z.ZodString;
|
|
57
|
-
acceptance_criteria: z.ZodArray<z.ZodString>;
|
|
58
|
-
caveats: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
59
|
-
depends_on: z.ZodArray<z.ZodString>;
|
|
60
60
|
agent: z.ZodEnum<{
|
|
61
61
|
[x: string]: string;
|
|
62
62
|
}>;
|
|
@@ -84,6 +84,13 @@ export declare const PlanningAgentOutputSchema: z.ZodObject<{
|
|
|
84
84
|
id: z.ZodString;
|
|
85
85
|
context: z.ZodOptional<z.ZodString>;
|
|
86
86
|
description: z.ZodOptional<z.ZodString>;
|
|
87
|
+
track: z.ZodString;
|
|
88
|
+
step_type: z.ZodString;
|
|
89
|
+
question: z.ZodString;
|
|
90
|
+
constraints: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
91
|
+
acceptance_criteria: z.ZodArray<z.ZodString>;
|
|
92
|
+
caveats: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
93
|
+
depends_on: z.ZodArray<z.ZodString>;
|
|
87
94
|
resources: z.ZodNonOptional<z.ZodOptional<z.ZodObject<{
|
|
88
95
|
cpu: z.ZodNumber;
|
|
89
96
|
memoryGb: z.ZodNumber;
|
|
@@ -91,13 +98,6 @@ export declare const PlanningAgentOutputSchema: z.ZodObject<{
|
|
|
91
98
|
count: z.ZodNumber;
|
|
92
99
|
}, z.core.$strip>>;
|
|
93
100
|
}, z.core.$strip>>>;
|
|
94
|
-
constraints: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
95
|
-
track: z.ZodString;
|
|
96
|
-
step_type: z.ZodString;
|
|
97
|
-
question: z.ZodString;
|
|
98
|
-
acceptance_criteria: z.ZodArray<z.ZodString>;
|
|
99
|
-
caveats: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
100
|
-
depends_on: z.ZodArray<z.ZodString>;
|
|
101
101
|
agent: z.ZodEnum<{
|
|
102
102
|
[x: string]: string;
|
|
103
103
|
}>;
|
|
@@ -19,13 +19,19 @@ export const PlanStepSchema = AnalysisStepSchema.omit({
|
|
|
19
19
|
})
|
|
20
20
|
.required({ agent: true, resources: true })
|
|
21
21
|
.extend({
|
|
22
|
-
agent: z.enum(plannableAgentIds).describe("Sandbox agent ID
|
|
22
|
+
agent: z.enum(plannableAgentIds).describe("Sandbox agent ID, routed by the step's primary data object. Must be one of the available agents."),
|
|
23
23
|
});
|
|
24
24
|
/** Plan schema for planner output — uses PlanStepSchema for steps and requires
|
|
25
25
|
* a concise title (optional on the persistence schema for historical plans). */
|
|
26
26
|
export const PlannerPlanSchema = AnalysisPlanSchema.extend({
|
|
27
|
-
title: z
|
|
28
|
-
|
|
27
|
+
title: z
|
|
28
|
+
.string()
|
|
29
|
+
.min(1)
|
|
30
|
+
.max(80)
|
|
31
|
+
.describe('Concise plan name (3–8 words) naming the analysis by what it does — e.g. "AD lesional vs control DE + pathways", ' +
|
|
32
|
+
'"scRNA immune deconvolution". Ground it in the actual research question and conditions; it is shown as the run\'s heading in chat. ' +
|
|
33
|
+
'Not a generic name like "Transcriptomics analysis".'),
|
|
34
|
+
steps: z.array(PlanStepSchema).describe("The steps of the plan, as a DAG wired by depends_on."),
|
|
29
35
|
});
|
|
30
36
|
/** Hydrate slim planner output into a full AnalysisPlan with execution-time defaults. */
|
|
31
37
|
export function hydratePlanSteps(plannerPlan) {
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
* Produced by the synthesis step after all sandbox steps complete.
|
|
5
5
|
* Combines computational findings from step summaries with literature
|
|
6
6
|
* evidence from the literature-reviewer agent.
|
|
7
|
+
*
|
|
8
|
+
* This schema is the synthesizer's output contract: it is emitted as the
|
|
9
|
+
* `submit_synthesis` tool's arg schema, so every field's meaning must live in
|
|
10
|
+
* `.describe()` — a JSDoc comment here reaches no model.
|
|
7
11
|
*/
|
|
8
12
|
import { z } from "zod";
|
|
9
13
|
export declare const LiteratureReferenceSchema: z.ZodObject<{
|
|
@@ -27,11 +31,11 @@ export declare const SynthesizedFindingSchema: z.ZodObject<{
|
|
|
27
31
|
low: "low";
|
|
28
32
|
}>;
|
|
29
33
|
noveltyStatus: z.ZodEnum<{
|
|
30
|
-
expected: "expected";
|
|
31
34
|
novel: "novel";
|
|
32
35
|
confirmed: "confirmed";
|
|
33
36
|
partially_confirmed: "partially_confirmed";
|
|
34
37
|
contradicted: "contradicted";
|
|
38
|
+
expected: "expected";
|
|
35
39
|
}>;
|
|
36
40
|
literatureInterpretation: z.ZodString;
|
|
37
41
|
references: z.ZodArray<z.ZodObject<{
|
|
@@ -53,7 +57,6 @@ export declare const SynthesizedFindingSchema: z.ZodObject<{
|
|
|
53
57
|
"clinical-evidence": "clinical-evidence";
|
|
54
58
|
}>;
|
|
55
59
|
actionType: z.ZodOptional<z.ZodEnum<{
|
|
56
|
-
none: "none";
|
|
57
60
|
"therapeutic-target": "therapeutic-target";
|
|
58
61
|
"predictive-biomarker": "predictive-biomarker";
|
|
59
62
|
"prognostic-biomarker": "prognostic-biomarker";
|
|
@@ -62,6 +65,7 @@ export declare const SynthesizedFindingSchema: z.ZodObject<{
|
|
|
62
65
|
"resistance-mechanism": "resistance-mechanism";
|
|
63
66
|
"patient-stratification": "patient-stratification";
|
|
64
67
|
"mechanism-of-action": "mechanism-of-action";
|
|
68
|
+
none: "none";
|
|
65
69
|
}>>;
|
|
66
70
|
rationale: z.ZodString;
|
|
67
71
|
}, z.core.$strip>>;
|
|
@@ -88,11 +92,11 @@ export declare const RunSynthesisSchema: z.ZodObject<{
|
|
|
88
92
|
low: "low";
|
|
89
93
|
}>;
|
|
90
94
|
noveltyStatus: z.ZodEnum<{
|
|
91
|
-
expected: "expected";
|
|
92
95
|
novel: "novel";
|
|
93
96
|
confirmed: "confirmed";
|
|
94
97
|
partially_confirmed: "partially_confirmed";
|
|
95
98
|
contradicted: "contradicted";
|
|
99
|
+
expected: "expected";
|
|
96
100
|
}>;
|
|
97
101
|
literatureInterpretation: z.ZodString;
|
|
98
102
|
references: z.ZodArray<z.ZodObject<{
|
|
@@ -114,7 +118,6 @@ export declare const RunSynthesisSchema: z.ZodObject<{
|
|
|
114
118
|
"clinical-evidence": "clinical-evidence";
|
|
115
119
|
}>;
|
|
116
120
|
actionType: z.ZodOptional<z.ZodEnum<{
|
|
117
|
-
none: "none";
|
|
118
121
|
"therapeutic-target": "therapeutic-target";
|
|
119
122
|
"predictive-biomarker": "predictive-biomarker";
|
|
120
123
|
"prognostic-biomarker": "prognostic-biomarker";
|
|
@@ -123,6 +126,7 @@ export declare const RunSynthesisSchema: z.ZodObject<{
|
|
|
123
126
|
"resistance-mechanism": "resistance-mechanism";
|
|
124
127
|
"patient-stratification": "patient-stratification";
|
|
125
128
|
"mechanism-of-action": "mechanism-of-action";
|
|
129
|
+
none: "none";
|
|
126
130
|
}>>;
|
|
127
131
|
rationale: z.ZodString;
|
|
128
132
|
}, z.core.$strip>>;
|
|
@@ -4,35 +4,51 @@
|
|
|
4
4
|
* Produced by the synthesis step after all sandbox steps complete.
|
|
5
5
|
* Combines computational findings from step summaries with literature
|
|
6
6
|
* evidence from the literature-reviewer agent.
|
|
7
|
+
*
|
|
8
|
+
* This schema is the synthesizer's output contract: it is emitted as the
|
|
9
|
+
* `submit_synthesis` tool's arg schema, so every field's meaning must live in
|
|
10
|
+
* `.describe()` — a JSDoc comment here reaches no model.
|
|
7
11
|
*/
|
|
8
12
|
import { z } from "zod";
|
|
9
13
|
export const LiteratureReferenceSchema = z.object({
|
|
10
|
-
pmid: z.string(),
|
|
11
|
-
citation: z.string(),
|
|
12
|
-
relevance: z.string(),
|
|
13
|
-
concordance: z
|
|
14
|
+
pmid: z.string().describe("Numeric PubMed ID. Must come from a literature_reviewer response — never invented."),
|
|
15
|
+
citation: z.string().describe('Short citation for the paper, e.g. "Smith 2020".'),
|
|
16
|
+
relevance: z.string().describe("Why this paper matters to the finding — what it establishes, challenges, or contextualizes."),
|
|
17
|
+
concordance: z
|
|
18
|
+
.enum(["supports", "contradicts", "extends", "contextualizes"])
|
|
19
|
+
.describe("How the paper relates to the finding. " +
|
|
20
|
+
"supports: the paper directly supports the finding. " +
|
|
21
|
+
"contradicts: the paper reports a conflicting result. " +
|
|
22
|
+
"extends: the paper builds on the finding in another context. " +
|
|
23
|
+
"contextualizes: the paper provides background but does not directly address the finding."),
|
|
14
24
|
});
|
|
15
25
|
export const SynthesizedFindingSchema = z.object({
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
stepId: z.string().describe("Which step produced this finding. Must be a stepId present in the input summaries."),
|
|
27
|
+
title: z.string().describe("Finding title from the step summary."),
|
|
28
|
+
description: z.string().describe("Finding description from the step summary."),
|
|
29
|
+
confidence: z
|
|
30
|
+
.enum(["high", "medium", "low"])
|
|
31
|
+
.describe("Confidence from the step summary — reflect the summary's own stated confidence, not a re-assessment. " +
|
|
32
|
+
"If the summary states none, use medium; use high only for findings the summary treats as robust."),
|
|
33
|
+
noveltyStatus: z
|
|
34
|
+
.enum(["novel", "confirmed", "partially_confirmed", "contradicted", "expected"])
|
|
35
|
+
.describe("Novelty assessment based on literature review. " +
|
|
36
|
+
"novel: the literature does not describe this result in this context. " +
|
|
37
|
+
"confirmed: the literature independently establishes this result. " +
|
|
38
|
+
"partially_confirmed: the literature supports related but not identical claims (e.g. same gene, different tissue). " +
|
|
39
|
+
"contradicted: the literature reports the opposite direction or effect. " +
|
|
40
|
+
"expected: a standard, well-known result (housekeeping genes, canonical QC outcomes) — not a discovery."),
|
|
41
|
+
literatureInterpretation: z.string().describe("How this finding relates to existing literature."),
|
|
42
|
+
references: z.array(LiteratureReferenceSchema).describe("Supporting or contradicting references."),
|
|
31
43
|
translationalRelevance: z
|
|
32
44
|
.object({
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
45
|
+
stage: z
|
|
46
|
+
.enum(["discovery", "preclinical-validation", "biomarker-candidate", "clinical-evidence"])
|
|
47
|
+
.describe("How close this finding is to clinical application. " +
|
|
48
|
+
"discovery: novel biology with no direct clinical path yet. " +
|
|
49
|
+
"preclinical-validation: known target/pathway with existing preclinical evidence but no clinical data in this context. " +
|
|
50
|
+
"biomarker-candidate: measurable, differential, with a biologically plausible mechanism linking it to outcome. " +
|
|
51
|
+
"clinical-evidence: supported by or directly relevant to clinical trial data or approved therapeutics."),
|
|
36
52
|
actionType: z
|
|
37
53
|
.enum([
|
|
38
54
|
"therapeutic-target",
|
|
@@ -45,43 +61,63 @@ export const SynthesizedFindingSchema = z.object({
|
|
|
45
61
|
"mechanism-of-action",
|
|
46
62
|
"none",
|
|
47
63
|
])
|
|
48
|
-
.optional()
|
|
49
|
-
|
|
50
|
-
|
|
64
|
+
.optional()
|
|
65
|
+
.describe("What type of translational action this finding supports. " +
|
|
66
|
+
"therapeutic-target: gene/protein/pathway suitable for drug intervention. " +
|
|
67
|
+
"predictive-biomarker: differentiates treatment responders from non-responders (requires treatment x marker interaction evidence). " +
|
|
68
|
+
"prognostic-biomarker: predicts outcome regardless of treatment. " +
|
|
69
|
+
"pharmacodynamic-biomarker: measures target engagement or drug effect over time. " +
|
|
70
|
+
"safety-signal: suggests potential toxicity, adverse effect, or off-target liability. " +
|
|
71
|
+
"resistance-mechanism: explains non-response or acquired resistance. " +
|
|
72
|
+
"patient-stratification: enables subgroup identification for enrichment strategies. " +
|
|
73
|
+
"mechanism-of-action: illuminates how a drug or intervention works. " +
|
|
74
|
+
"none: biological value but no direct translational path."),
|
|
75
|
+
rationale: z
|
|
76
|
+
.string()
|
|
77
|
+
.describe("ONE sentence on why this stage and action type were assigned. " +
|
|
78
|
+
"Must reference specific evidence (existing drugs, clinical trials, biomarker properties, literature)."),
|
|
51
79
|
})
|
|
52
|
-
.optional()
|
|
80
|
+
.optional()
|
|
81
|
+
.describe("Translational proximity and actionability. Populate only for findings with genuine translational implications — " +
|
|
82
|
+
"omit for purely technical or methodological findings."),
|
|
53
83
|
});
|
|
54
84
|
export const BiologicalThemeSchema = z.object({
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
85
|
+
name: z
|
|
86
|
+
.string()
|
|
87
|
+
.describe('Theme name — a conclusion, not a topic label. "ECM remodeling drives the NAFLD-to-NASH transition" is a theme; ' +
|
|
88
|
+
'"Differential expression results" is not.'),
|
|
89
|
+
findings: z
|
|
90
|
+
.array(z.object({ stepId: z.string(), title: z.string() }))
|
|
91
|
+
.describe("Findings that contribute to this theme. Each entry must match an entry in findings[] by stepId + title."),
|
|
92
|
+
narrative: z.string().describe("How these findings connect into a coherent biological story — 3-5 sentences connecting them, not restating them."),
|
|
61
93
|
});
|
|
62
94
|
export const RunSynthesisSchema = z.object({
|
|
63
|
-
runId: z.string(),
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
themes: z
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
95
|
+
runId: z.string().describe("The run being synthesized. Must equal the runId given in the prompt."),
|
|
96
|
+
overview: z
|
|
97
|
+
.string()
|
|
98
|
+
.describe("2-4 sentences: the run's scope, the top-line result, and the most important takeaway. " +
|
|
99
|
+
"An abstract's conclusion, not its body — do NOT enumerate counts, gene lists, or per-step results."),
|
|
100
|
+
conclusions: z
|
|
101
|
+
.string()
|
|
102
|
+
.describe("The PRIMARY interpretive section — the 'so what' — as connected prose (3-5 paragraphs). " +
|
|
103
|
+
"What the run establishes and what is novel vs confirmatory; what is actionable translationally (therapeutic-target candidates, " +
|
|
104
|
+
"biomarker candidates, safety signals, resistance mechanisms); how findings connect into a biological story; where computational " +
|
|
105
|
+
"predictions agree or disagree with clinical evidence; and an honest assessment of the translational distance."),
|
|
106
|
+
findings: z
|
|
107
|
+
.array(SynthesizedFindingSchema)
|
|
108
|
+
.describe("SELECTIVE — only novel, contradicted, high-impact, or unexpected results that warrant individual attention. " +
|
|
109
|
+
"NOT a per-step catalog. Target 3-7 for a typical run."),
|
|
110
|
+
themes: z
|
|
111
|
+
.array(BiologicalThemeSchema)
|
|
112
|
+
.describe("Cross-step biological themes. Target 2-4. Return fewer (or zero) rather than forcing findings that do not converge."),
|
|
113
|
+
limitations: z
|
|
114
|
+
.array(z.string())
|
|
115
|
+
.describe("Concrete methodological and translational caveats — not generic disclaimers. " + "Each names what it affects and why it matters. Target 3-6."),
|
|
116
|
+
keyReferences: z
|
|
117
|
+
.array(z.object({
|
|
118
|
+
pmid: z.string().describe("Numeric PubMed ID. Must already appear in at least one finding's references[]."),
|
|
119
|
+
citation: z.string().describe('Short citation for the paper, e.g. "Smith 2020".'),
|
|
120
|
+
description: z.string().describe("What the paper establishes and why it is key to this run."),
|
|
121
|
+
}))
|
|
122
|
+
.describe("The 5-10 most important papers across all findings. Prioritize those that directly validate, contradict, or extend the findings — do not pad with background citations."),
|
|
87
123
|
});
|
|
@@ -5,6 +5,12 @@
|
|
|
5
5
|
* and the completion schemas that validate LLM structured output.
|
|
6
6
|
*/
|
|
7
7
|
import { z } from "zod";
|
|
8
|
+
/**
|
|
9
|
+
* A step of an analysis plan. `PlanStepSchema` (schemas/plan-schemas.ts) narrows
|
|
10
|
+
* this into the planner's output contract and emits it as the `validate_plan` /
|
|
11
|
+
* `submit_plan` arg schema — so each field's meaning belongs in `.describe()`,
|
|
12
|
+
* not in a comment the model never sees.
|
|
13
|
+
*/
|
|
8
14
|
export declare const AnalysisStepSchema: z.ZodObject<{
|
|
9
15
|
id: z.ZodString;
|
|
10
16
|
name: z.ZodString;
|
|
@@ -220,8 +226,8 @@ export declare const SuspensionPayloadSchema: z.ZodObject<{
|
|
|
220
226
|
message: z.ZodOptional<z.ZodString>;
|
|
221
227
|
severity: z.ZodOptional<z.ZodEnum<{
|
|
222
228
|
error: "error";
|
|
223
|
-
warning: "warning";
|
|
224
229
|
info: "info";
|
|
230
|
+
warning: "warning";
|
|
225
231
|
}>>;
|
|
226
232
|
content: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
227
233
|
type: z.ZodLiteral<"markdown">;
|
|
@@ -6,17 +6,27 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
// ── Plan structures ─────────────────────────────────────────────────
|
|
9
|
+
/**
|
|
10
|
+
* A step of an analysis plan. `PlanStepSchema` (schemas/plan-schemas.ts) narrows
|
|
11
|
+
* this into the planner's output contract and emits it as the `validate_plan` /
|
|
12
|
+
* `submit_plan` arg schema — so each field's meaning belongs in `.describe()`,
|
|
13
|
+
* not in a comment the model never sees.
|
|
14
|
+
*/
|
|
9
15
|
export const AnalysisStepSchema = z.object({
|
|
10
|
-
id: z.string().describe("Step ID in format T{track}S{step}"),
|
|
11
|
-
name: z.string(),
|
|
12
|
-
track: z.string(),
|
|
13
|
-
step_type: z.string(),
|
|
14
|
-
question: z
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
id: z.string().describe("Step ID in format T{track}S{step} (e.g. T1S1, T1S2, T2S1). Unique within the plan and usable as a directory-name segment."),
|
|
17
|
+
name: z.string().describe("Short human-readable step name."),
|
|
18
|
+
track: z.string().describe("The track this step belongs to. Steps in the same track share a logical theme; steps in different tracks are independent."),
|
|
19
|
+
step_type: z.string().describe('Short label for the kind of work the step does (e.g. "analysis").'),
|
|
20
|
+
question: z
|
|
21
|
+
.string()
|
|
22
|
+
.describe("The specific question this step answers, framed with the actual condition names and comparisons from the experimental design."),
|
|
23
|
+
context: z.string().optional().describe("Background the sandbox agent needs to do the work."),
|
|
24
|
+
constraints: z.array(z.string()).optional().describe("Requirements the sandbox agent must follow exactly — not suggestions."),
|
|
25
|
+
acceptance_criteria: z.array(z.string()).describe("What the result must satisfy for the step to count as successful."),
|
|
26
|
+
caveats: z.array(z.string()).optional().describe("Pitfalls the sandbox agent should watch for."),
|
|
27
|
+
depends_on: z
|
|
28
|
+
.array(z.string())
|
|
29
|
+
.describe("IDs of steps in this plan that must complete before this one runs. Empty when the step has no prerequisites. The graph must be acyclic."),
|
|
20
30
|
status: z.enum(["pending", "running", "completed", "failed", "skipped"]).default("pending"),
|
|
21
31
|
// Optional on the persistence schema so historical plans (pre-resources)
|
|
22
32
|
// still parse on the read side. `PlanStepSchema` re-requires it for planner
|
|
@@ -24,16 +34,17 @@ export const AnalysisStepSchema = z.object({
|
|
|
24
34
|
// resources (no silent default) and clamps to cluster limits before use.
|
|
25
35
|
resources: z
|
|
26
36
|
.object({
|
|
27
|
-
cpu: z.number(),
|
|
28
|
-
memoryGb: z.number(),
|
|
29
|
-
gpu: z.object({ count: z.number() }).optional(),
|
|
37
|
+
cpu: z.number().describe("CPU cores the step needs."),
|
|
38
|
+
memoryGb: z.number().describe("Memory in GB the step needs."),
|
|
39
|
+
gpu: z.object({ count: z.number() }).optional().describe("GPUs the step needs. Omit unless the step genuinely requires one."),
|
|
30
40
|
})
|
|
31
|
-
.optional()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe("Resources the step needs. Ground the estimate in the actual data size — see the resource-estimation rules."),
|
|
32
43
|
// Execution fields
|
|
33
44
|
agent: z.string().optional().describe("Assigned sandbox agent name from registry"),
|
|
34
45
|
timeout: z.number().optional().describe("Execution timeout in seconds (falls back to image default)"),
|
|
35
46
|
maxSteps: z.number().describe("Max LLM agentic steps for sandbox agent"),
|
|
36
|
-
description: z.string().optional().describe("Human-readable description of what the step
|
|
47
|
+
description: z.string().optional().describe("Human-readable description of what the step produces."),
|
|
37
48
|
// Step result fields (populated during execution)
|
|
38
49
|
summary: z.string().optional().describe("Execution result summary"),
|
|
39
50
|
artifactIds: z.array(z.string()).optional().describe("Artifact IDs produced by this step"),
|
|
@@ -43,11 +54,14 @@ export const AnalysisPlanSchema = z.object({
|
|
|
43
54
|
// Optional on the persistence schema so historical plans (pre-title) still
|
|
44
55
|
// parse on the read side. `PlannerPlanSchema` re-requires it for new plans.
|
|
45
56
|
title: z.string().optional().describe("Concise human-readable plan name"),
|
|
46
|
-
analytical_narrative: z
|
|
57
|
+
analytical_narrative: z
|
|
58
|
+
.string()
|
|
59
|
+
.describe("Brief narrative of the logical flow: why these steps, in this order, address the research question. " +
|
|
60
|
+
"Reference the data characteristics that informed the choices."),
|
|
47
61
|
steps: z.array(AnalysisStepSchema),
|
|
48
|
-
created_at: z.string(),
|
|
49
|
-
omicsType: z.string().optional().describe("
|
|
50
|
-
omicsSubtype: z.string().optional().describe("
|
|
62
|
+
created_at: z.string().describe("ISO-8601 timestamp for when the plan was created."),
|
|
63
|
+
omicsType: z.string().optional().describe("Omics data type detected from the data context (e.g. transcriptomics, proteomics, metabolomics)."),
|
|
64
|
+
omicsSubtype: z.string().optional().describe("Subtype detected from the data context (e.g. bulk-rna-seq, single-cell, microarray)."),
|
|
51
65
|
});
|
|
52
66
|
// ── Suspension Payload ──────────────────────────────────────────────
|
|
53
67
|
/**
|
|
@@ -44,6 +44,19 @@ export interface InputArtifactMeta {
|
|
|
44
44
|
*/
|
|
45
45
|
export declare function queryInputArtifacts(pool: Querier, analysisId: string, paths: string[]): Promise<InputArtifactMeta[]>;
|
|
46
46
|
export declare function queryUnsyncedStepArtifacts(pool: Querier, resourceId: string, runId: string, stepId: string): Promise<ArtifactRow[]>;
|
|
47
|
+
/** One registered step output, as a downstream consumer needs to name it. */
|
|
48
|
+
export interface StepArtifactRef {
|
|
49
|
+
/** Workspace-root-relative path (`runs/{runId}/{stepId}/output/de.csv`). */
|
|
50
|
+
path: string;
|
|
51
|
+
fileType: string | null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The artifacts a completed step registered, most consequential first. Ordered
|
|
55
|
+
* by artifact kind (outputs, then figures, notebooks, scripts, logs) and then by
|
|
56
|
+
* path, so a `limit` truncates the tail of the list rather than an arbitrary
|
|
57
|
+
* slice of it — and so the same call replays to the same rows.
|
|
58
|
+
*/
|
|
59
|
+
export declare function queryStepArtifactPaths(pool: Querier, resourceId: string, runId: string, stepId: string, limit: number): Promise<StepArtifactRef[]>;
|
|
47
60
|
/** Count step-output artifacts produced by a run — for the run-completed card. */
|
|
48
61
|
export declare function countArtifactsForRun(pool: Querier, analysisId: string, runId: string): Promise<number>;
|
|
49
62
|
export declare function updateArtifactId(pool: Querier, resourceId: string, path: string, artifactId: string, fileType?: string | null): Promise<void>;
|
package/dist/state/artifacts.js
CHANGED
|
@@ -121,6 +121,33 @@ export async function queryUnsyncedStepArtifacts(pool, resourceId, runId, stepId
|
|
|
121
121
|
});
|
|
122
122
|
return result.rows.map(mapArtifactRow);
|
|
123
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* The artifacts a completed step registered, most consequential first. Ordered
|
|
126
|
+
* by artifact kind (outputs, then figures, notebooks, scripts, logs) and then by
|
|
127
|
+
* path, so a `limit` truncates the tail of the list rather than an arbitrary
|
|
128
|
+
* slice of it — and so the same call replays to the same rows.
|
|
129
|
+
*/
|
|
130
|
+
export async function queryStepArtifactPaths(pool, resourceId, runId, stepId, limit) {
|
|
131
|
+
if (limit <= 0)
|
|
132
|
+
return [];
|
|
133
|
+
const result = await pool.query({
|
|
134
|
+
text: `SELECT path, file_type
|
|
135
|
+
FROM cortex_artifacts
|
|
136
|
+
WHERE analysis_id = $1 AND source_run = $2 AND source_step = $3
|
|
137
|
+
AND role = 'step_output'
|
|
138
|
+
ORDER BY CASE file_type
|
|
139
|
+
WHEN 'output' THEN 0
|
|
140
|
+
WHEN 'figure' THEN 1
|
|
141
|
+
WHEN 'notebook' THEN 2
|
|
142
|
+
WHEN 'script' THEN 3
|
|
143
|
+
ELSE 4
|
|
144
|
+
END,
|
|
145
|
+
path
|
|
146
|
+
LIMIT $4`,
|
|
147
|
+
values: [resourceId, runId, stepId, limit],
|
|
148
|
+
});
|
|
149
|
+
return result.rows.map((r) => ({ path: r.path, fileType: r.file_type ?? null }));
|
|
150
|
+
}
|
|
124
151
|
/** Count step-output artifacts produced by a run — for the run-completed card. */
|
|
125
152
|
export async function countArtifactsForRun(pool, analysisId, runId) {
|
|
126
153
|
const result = await pool.query({
|