@inflexa-ai/harness 0.28.1 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/dist/agents/conversation-agent.js +7 -4
  2. package/dist/agents/report-session-agent.js +1 -1
  3. package/dist/agents/sandbox/data-profiler.js +0 -1
  4. package/dist/agents/sandbox/immune-profiling-agent.js +3 -1
  5. package/dist/agents/sandbox/network-agent.js +0 -1
  6. package/dist/agents/sandbox/types.d.ts +1 -1
  7. package/dist/agents/sandbox/types.js +1 -1
  8. package/dist/app/data-profile-orientation.d.ts +52 -27
  9. package/dist/app/data-profile-orientation.js +331 -92
  10. package/dist/app/data-profile-view.d.ts +70 -0
  11. package/dist/app/data-profile-view.js +123 -0
  12. package/dist/app/synthesize-run.js +1 -1
  13. package/dist/config/resource-limits.d.ts +1 -1
  14. package/dist/config/resource-limits.js +1 -1
  15. package/dist/contracts/data-profile.d.ts +276 -25
  16. package/dist/contracts/index.d.ts +3 -1
  17. package/dist/contracts/index.js +1 -0
  18. package/dist/contracts/profile-vocabulary.d.ts +103 -0
  19. package/dist/contracts/profile-vocabulary.js +449 -0
  20. package/dist/contracts/schemas/chat-parts.d.ts +12 -12
  21. package/dist/contracts/severity.d.ts +2 -2
  22. package/dist/contracts/target-dossier.d.ts +91 -91
  23. package/dist/data/safety-panel-schema.d.ts +4 -4
  24. package/dist/execution/input-signature.d.ts +16 -3
  25. package/dist/execution/input-signature.js +0 -0
  26. package/dist/execution/post-step-pipeline.js +1 -1
  27. package/dist/execution/staged-input.d.ts +4 -4
  28. package/dist/index.d.ts +7 -2
  29. package/dist/index.js +14 -0
  30. package/dist/input-scan/clustering.d.ts +63 -0
  31. package/dist/input-scan/clustering.js +208 -0
  32. package/dist/input-scan/companions.d.ts +30 -0
  33. package/dist/input-scan/companions.js +138 -0
  34. package/dist/input-scan/decoder/container_readout.py +171 -0
  35. package/dist/input-scan/detect-sets.d.ts +24 -0
  36. package/dist/input-scan/detect-sets.js +279 -0
  37. package/dist/input-scan/enrich.d.ts +62 -19
  38. package/dist/input-scan/enrich.js +132 -187
  39. package/dist/input-scan/formats.d.ts +13 -5
  40. package/dist/input-scan/formats.js +13 -5
  41. package/dist/input-scan/index.d.ts +10 -4
  42. package/dist/input-scan/index.js +7 -4
  43. package/dist/input-scan/markers.d.ts +21 -0
  44. package/dist/input-scan/markers.js +89 -0
  45. package/dist/input-scan/menu.d.ts +127 -0
  46. package/dist/input-scan/menu.js +0 -0
  47. package/dist/input-scan/quarantine.d.ts +17 -0
  48. package/dist/input-scan/quarantine.js +69 -0
  49. package/dist/input-scan/readout-budget.d.ts +32 -0
  50. package/dist/input-scan/readout-budget.js +61 -0
  51. package/dist/input-scan/readout.d.ts +33 -0
  52. package/dist/input-scan/readout.js +336 -0
  53. package/dist/input-scan/scan.d.ts +5 -4
  54. package/dist/input-scan/scan.js +5 -5
  55. package/dist/input-scan/set-types.d.ts +209 -0
  56. package/dist/input-scan/set-types.js +15 -0
  57. package/dist/input-scan/templates.d.ts +93 -0
  58. package/dist/input-scan/templates.js +369 -0
  59. package/dist/input-scan/tokens.d.ts +94 -0
  60. package/dist/input-scan/tokens.js +267 -0
  61. package/dist/input-scan/tuning.d.ts +55 -0
  62. package/dist/input-scan/tuning.js +55 -0
  63. package/dist/input-scan/types.d.ts +2 -2
  64. package/dist/loop/run-agent.d.ts +13 -1
  65. package/dist/loop/run-agent.js +2 -1
  66. package/dist/prompts/SOUL.d.ts +2 -2
  67. package/dist/prompts/SOUL.js +17 -1
  68. package/dist/prompts/conversation.d.ts +1 -1
  69. package/dist/prompts/conversation.js +45 -71
  70. package/dist/prompts/planner.js +57 -10
  71. package/dist/prompts/report-session.d.ts +1 -1
  72. package/dist/prompts/report-session.js +3 -2
  73. package/dist/prompts/sandbox/bulk-transcriptomics-agent.d.ts +1 -1
  74. package/dist/prompts/sandbox/bulk-transcriptomics-agent.js +3 -1
  75. package/dist/prompts/sandbox/data-profiler.d.ts +10 -1
  76. package/dist/prompts/sandbox/data-profiler.js +197 -53
  77. package/dist/prompts/sandbox/dna-methylation-agent.d.ts +1 -1
  78. package/dist/prompts/sandbox/dna-methylation-agent.js +18 -12
  79. package/dist/prompts/sandbox/immune-profiling-agent.d.ts +1 -1
  80. package/dist/prompts/sandbox/immune-profiling-agent.js +6 -2
  81. package/dist/prompts/sandbox/metabolomics-agent.d.ts +1 -1
  82. package/dist/prompts/sandbox/metabolomics-agent.js +8 -4
  83. package/dist/prompts/sandbox/microbiome-agent.d.ts +1 -1
  84. package/dist/prompts/sandbox/microbiome-agent.js +12 -6
  85. package/dist/prompts/sandbox/network-agent.d.ts +1 -1
  86. package/dist/prompts/sandbox/network-agent.js +9 -6
  87. package/dist/prompts/sandbox/spatial-omics-agent.d.ts +1 -1
  88. package/dist/prompts/sandbox/spatial-omics-agent.js +4 -2
  89. package/dist/prompts/sandbox-standards.d.ts +1 -1
  90. package/dist/prompts/sandbox-standards.js +10 -7
  91. package/dist/providers/ai-sdk.js +34 -1
  92. package/dist/providers/reasoning.d.ts +65 -0
  93. package/dist/providers/reasoning.js +81 -0
  94. package/dist/providers/types.d.ts +14 -0
  95. package/dist/schemas/data-profile-schemas.d.ts +947 -84
  96. package/dist/schemas/data-profile-schemas.js +300 -115
  97. package/dist/schemas/run-synthesis.d.ts +4 -4
  98. package/dist/state/data-profile.d.ts +1 -1
  99. package/dist/state/index.d.ts +1 -1
  100. package/dist/state/vector-store.d.ts +13 -0
  101. package/dist/state/vector-store.js +8 -0
  102. package/dist/tasks/data-profile-absorb.d.ts +78 -0
  103. package/dist/tasks/data-profile-absorb.js +285 -0
  104. package/dist/tasks/data-profile-index.d.ts +34 -25
  105. package/dist/tasks/data-profile-index.js +160 -59
  106. package/dist/tasks/data-profile-resolve.d.ts +72 -0
  107. package/dist/tasks/data-profile-resolve.js +639 -0
  108. package/dist/tasks/data-profile.d.ts +16 -5
  109. package/dist/tasks/data-profile.js +270 -131
  110. package/dist/tools/bio/chembl.d.ts +1 -1
  111. package/dist/tools/bio/chembl.js +15 -10
  112. package/dist/tools/bio/comptox.js +5 -1
  113. package/dist/tools/bio/drug-gene-interactions.js +5 -2
  114. package/dist/tools/bio/gene-disease-evidence.d.ts +19 -9
  115. package/dist/tools/bio/gene-disease-evidence.js +78 -22
  116. package/dist/tools/bio/gene-preclinical-profile.d.ts +33 -13
  117. package/dist/tools/bio/gene-preclinical-profile.js +63 -22
  118. package/dist/tools/bio/lookup-annotation.d.ts +1 -0
  119. package/dist/tools/bio/lookup-annotation.js +28 -10
  120. package/dist/tools/bio/opentargets.d.ts +10 -2
  121. package/dist/tools/bio/opentargets.js +42 -13
  122. package/dist/tools/bio/pubchem.js +5 -2
  123. package/dist/tools/bio/pubmed.js +9 -3
  124. package/dist/tools/bio/search-clinical-trials.d.ts +25 -25
  125. package/dist/tools/bio/search-clinical-trials.js +56 -18
  126. package/dist/tools/bio/search-faers.d.ts +26 -6
  127. package/dist/tools/bio/search-faers.js +70 -18
  128. package/dist/tools/bio/search-gene.d.ts +19 -3
  129. package/dist/tools/bio/search-gene.js +69 -12
  130. package/dist/tools/bio/search-geo-datasets.js +4 -1
  131. package/dist/tools/bio/search-interactions.js +6 -2
  132. package/dist/tools/bio/target-safety.d.ts +2 -2
  133. package/dist/tools/bio/target-safety.js +3 -2
  134. package/dist/tools/lib/cbioportal-client.js +25 -6
  135. package/dist/tools/lib/chembl-client.d.ts +3 -1
  136. package/dist/tools/lib/chembl-client.js +6 -1
  137. package/dist/tools/lib/gwas-catalog-client.d.ts +7 -6
  138. package/dist/tools/lib/gwas-catalog-client.js +18 -6
  139. package/dist/tools/lib/openfda-client.d.ts +7 -5
  140. package/dist/tools/lib/openfda-client.js +17 -9
  141. package/dist/tools/lib/opentargets-client.d.ts +20 -0
  142. package/dist/tools/lib/opentargets-client.js +45 -0
  143. package/dist/tools/lib/pathway-client.d.ts +7 -0
  144. package/dist/tools/lib/pathway-client.js +68 -1
  145. package/dist/tools/research/context7-docs.js +3 -3
  146. package/dist/tools/research/generate-analogy-report.js +2 -2
  147. package/dist/tools/research/generate-plan.d.ts +3 -0
  148. package/dist/tools/research/generate-plan.js +64 -5
  149. package/dist/tools/research/inspect-data-profile.d.ts +48 -22
  150. package/dist/tools/research/inspect-data-profile.js +73 -54
  151. package/dist/tools/research/resolve-citation.js +8 -3
  152. package/dist/tools/research/search-arxiv.js +8 -3
  153. package/dist/tools/research/search-semantic-scholar.js +10 -4
  154. package/dist/tools/workspace/scan-inputs.d.ts +4 -4
  155. package/dist/tools/workspace/scan-inputs.js +13 -14
  156. package/dist/tools/workspace/workspace-search.d.ts +11 -2
  157. package/dist/tools/workspace/workspace-search.js +44 -16
  158. package/dist/workflows/sandbox-step.d.ts +6 -0
  159. package/dist/workflows/sandbox-step.js +31 -14
  160. package/dist/workflows/target-assessment/assemblers/safety.d.ts +1 -1
  161. package/dist/workflows/target-assessment/phase4-assemble.d.ts +38 -38
  162. package/dist/workflows/target-assessment/schemas.d.ts +12 -12
  163. package/dist/workflows/target-assessment/steps/phase2-aggregate.d.ts +6 -6
  164. package/dist/workflows/target-assessment/steps/phase3-aggregate.d.ts +6 -6
  165. package/dist/workflows/target-assessment/synthesis/index.d.ts +12 -12
  166. package/package.json +5 -3
  167. package/dist/input-scan/coverage.d.ts +0 -22
  168. package/dist/input-scan/coverage.js +0 -85
@@ -29,25 +29,49 @@ function indexName(analysisId) {
29
29
  }
30
30
  return name;
31
31
  }
32
+ /** Entry types that address a pattern spanning many files, never a single one. */
33
+ const PATTERN_TYPES = new Set(["input-group", "input-dimension", "input-kind"]);
34
+ /**
35
+ * The workspace path a hit addresses, or `undefined` for a pattern entry. Resolved here,
36
+ * once, across every index era — group/dimension/kind entries and previous-era entity
37
+ * entries (`entity` in metadata) are patterns; everything else is a file whose path is
38
+ * stamped in metadata or, on rows older than the stamp, is the id minus the resource
39
+ * segment. The consumer branches on presence, nothing else.
40
+ */
41
+ export function fileTargetOf(id, metadata) {
42
+ const meta = metadata && typeof metadata === "object" ? metadata : {};
43
+ const type = typeof meta.type === "string" ? meta.type : undefined;
44
+ if (type !== undefined && PATTERN_TYPES.has(type))
45
+ return undefined;
46
+ if (type === "input" && meta.entity !== undefined)
47
+ return undefined;
48
+ if (typeof meta.path === "string")
49
+ return meta.path;
50
+ return id.replace(/^\/[^/]+\//, "");
51
+ }
32
52
  export function createWorkspaceSearchTool(pool, embedding) {
33
53
  return defineTool({
34
54
  id: "workspace_search",
35
55
  description: "Semantic search over the analysis workspace. Returns ranked entries with descriptions " +
36
- "and metadata; read a file separately to see its contents. Indexed entries are exactly " +
37
- 'five types, and `type` restricts results to one of them: "input-kind" (a KIND of input ' +
38
- "data — a repeating set the data profiler named, carrying its count and a pathPattern " +
39
- 'matching its members), "input" (one entity the dataset is about — a subject, sample, or ' +
40
- 'other axis value — with the kinds of file it carries), "output" (files a step produced), ' +
41
- '"summary" (a step\'s summary), "synthesis" (a run\'s literature-grounded synthesis). ' +
42
- "For output/summary/synthesis the entry id IS the workspace path; for the two input types " +
43
- "it is not, because a kind and an entity each span many files — search input-kind for a " +
44
- "set's pathPattern, then list the tree for its members.",
56
+ "and metadata; read a file separately to see its contents. `type` restricts results to one " +
57
+ 'entry type: "input-group" (a GROUP of input data the data profiler declared, carrying its ' +
58
+ 'derived count, its display pattern, and its slots), "input-dimension" (something that VARIES ' +
59
+ "across the dataset — subject, timepoint, batch — with the observations evidencing it), " +
60
+ '"input" (one input file the profiler annotated individually, or, on a profile of the ' +
61
+ 'previous era, one entity the dataset is about), "output" (files a step produced), ' +
62
+ '"summary" (a step\'s summary), "synthesis" (a run\'s literature-grounded synthesis), ' +
63
+ '"input-kind" (a repeating set, on a profile of the previous era). ' +
64
+ "A hit carrying `path` is a FILE — read that path to see its contents. A hit without " +
65
+ "`path` is a PATTERN spanning many files (a group, a dimension, an entity): use its " +
66
+ "metadata, e.g. search input-group for a group's display pattern, then list the tree for " +
67
+ "its members. Most input files carry no entry of their own — find them through their " +
68
+ "group and the listing tools.",
45
69
  inputSchema: z.object({
46
70
  query: z.string().min(1).describe("What to search for, in natural language"),
47
71
  type: z
48
- .enum(["input-kind", "input", "output", "summary", "synthesis"])
72
+ .enum(["input-group", "input-dimension", "input", "input-kind", "output", "summary", "synthesis"])
49
73
  .optional()
50
- .describe('Restrict results to one entry type: "input-kind", "input", "output", "summary", or "synthesis"'),
74
+ .describe('Restrict results to one entry type: "input-group", "input-dimension", "input", "input-kind", "output", "summary", or "synthesis"'),
51
75
  limit: z.number().int().min(1).max(50).default(8).describe("Maximum number of results to return"),
52
76
  }),
53
77
  describeCall: ({ query, type }) => (type === undefined ? query : `${query} (${type})`),
@@ -77,11 +101,15 @@ export function createWorkspaceSearchTool(pool, embedding) {
77
101
  // exist. That is absence, not a failure: recover into ok([]).
78
102
  isUndefinedTable(e.cause) ? okAsync([]) : err(e)));
79
103
  return ok({
80
- results: rows.map((r) => ({
81
- id: r.id,
82
- score: r.score,
83
- metadata: r.metadata,
84
- })),
104
+ results: rows.map((r) => {
105
+ const path = fileTargetOf(r.id, r.metadata);
106
+ return {
107
+ id: r.id,
108
+ score: r.score,
109
+ ...(path !== undefined ? { path } : {}),
110
+ metadata: r.metadata,
111
+ };
112
+ }),
85
113
  });
86
114
  },
87
115
  });
@@ -106,6 +106,12 @@ export interface SandboxStepInput {
106
106
  * declare it explicitly.
107
107
  */
108
108
  export declare const DEFAULT_STEP_TIMEOUT_SECONDS = 3600;
109
+ /**
110
+ * Deterministic `blocked_reason` for a loop that spent every iteration and
111
+ * persisted no output files (see the harness-sandbox-agents spec). Fixed prose,
112
+ * never model output — the summarizer does not run on this path.
113
+ */
114
+ export declare const CAPPED_OUT_EMPTY_REASON = "The step hit its iteration cap with no output files persisted.";
109
115
  export type SandboxStepStatus = "complete" | "failed" | "canceled" | "blocked";
110
116
  /**
111
117
  * DBOS message topic the child uses to notify the parent that it is
@@ -46,6 +46,12 @@ import { createBlockerHolder } from "../tools/sandbox/report-blocker.js";
46
46
  * declare it explicitly.
47
47
  */
48
48
  export const DEFAULT_STEP_TIMEOUT_SECONDS = 3600;
49
+ /**
50
+ * Deterministic `blocked_reason` for a loop that spent every iteration and
51
+ * persisted no output files (see the harness-sandbox-agents spec). Fixed prose,
52
+ * never model output — the summarizer does not run on this path.
53
+ */
54
+ export const CAPPED_OUT_EMPTY_REASON = "The step hit its iteration cap with no output files persisted.";
49
55
  /**
50
56
  * DBOS message topic the child uses to notify the parent that it is
51
57
  * about to self-cancel because of a 402 budget-exceeded error. The
@@ -427,20 +433,36 @@ export async function runSandboxStepBody(input, deps) {
427
433
  usage: stepUsage,
428
434
  });
429
435
  }
436
+ // Manifest walk, hoisted above the blocked branch so the capped-out
437
+ // predicate can read it. The call is inline (not `DBOS.runStep`-wrapped),
438
+ // so the hoist shifts no function id (see the harness-durable-runtime spec).
439
+ const manifest = await safeRunValue(logger, () => walkStepArtifacts({
440
+ writePrefix,
441
+ stepId: input.stepId,
442
+ runId: input.runId,
443
+ }), "post-step.walk", []);
430
444
  // Blocker (see the harness-sandbox-agents spec): the agent declared it cannot fulfil the step. A
431
445
  // blocked step has no deliverables — skip the artifact post-step pipeline,
432
446
  // mark `blocked` (carrying the reason), emit the blocked part, and return a
433
447
  // terminal-failure status so the parent's fail-fast cascade fires.
448
+ //
449
+ // The capped-out empty case routes into the same branch: a loop that spent
450
+ // every iteration and persisted nothing has no deliverables, and a green
451
+ // status would attest an empty step. A blocker outcome keeps its own
452
+ // reason. A capped-out step WITH artifacts stays on the completed path,
453
+ // because partial output is real output.
434
454
  const blockerOutcome = blockerHolder.outcome;
435
- if (blockerOutcome) {
455
+ const cappedOutEmpty = hitMaxSteps && manifest.length === 0;
456
+ if (blockerOutcome || cappedOutEmpty) {
457
+ const blockedReason = blockerOutcome?.reason ?? CAPPED_OUT_EMPTY_REASON;
436
458
  await tryTeardown(logger, deps, sandbox);
437
459
  const durationMs = (await DBOS.now()) - startedAt;
438
460
  await DBOS.runStep(async () => {
439
461
  unwrapOrThrow(await updateStepExecution(deps.pool, input.runId, input.stepId, {
440
462
  status: "blocked",
441
463
  durationMs,
442
- error: blockerOutcome.reason,
443
- blockedReason: blockerOutcome.reason,
464
+ error: blockedReason,
465
+ blockedReason,
444
466
  attempts: 1,
445
467
  lastErrorClass: "blocked",
446
468
  finishReason,
@@ -453,21 +475,21 @@ export async function runSandboxStepBody(input, deps) {
453
475
  runId: input.runId,
454
476
  stepId: input.stepId,
455
477
  agentId: input.agentId,
456
- reason: blockerOutcome.reason,
478
+ reason: blockedReason,
457
479
  });
458
480
  await emitActivity("failed", "Step blocked");
459
481
  return {
460
482
  status: "blocked",
461
483
  durationMs,
462
484
  finishReason,
463
- error: blockerOutcome.reason,
485
+ error: blockedReason,
464
486
  ...(stepUsage ? { usage: stepUsage } : {}),
465
487
  };
466
488
  }
467
- // (4-8) post-step — the body is the explicit composition: walk the artifact
468
- // tree once, then thread each stage's typed output into the next. Helpers
469
- // run inline (not `DBOS.runStep`-wrapped), so a replay re-executes this
470
- // section. Each helper is best-effort (`safeRun*` logs + degrades) so a
489
+ // (4-8) post-step — the body is the explicit composition: the manifest from
490
+ // the single walk above threads each stage's typed output into the next.
491
+ // Helpers run inline (not `DBOS.runStep`-wrapped), so a replay re-executes
492
+ // this section. Each helper is best-effort (`safeRun*` logs + degrades) so a
471
493
  // single failure never fails the step.
472
494
  const postCtx = {
473
495
  input,
@@ -478,11 +500,6 @@ export async function runSandboxStepBody(input, deps) {
478
500
  lineageCollector,
479
501
  };
480
502
  await emitActivity("generating-metadata", "Describing output files");
481
- const manifest = await safeRunValue(logger, () => walkStepArtifacts({
482
- writePrefix,
483
- stepId: input.stepId,
484
- runId: input.runId,
485
- }), "post-step.walk", []);
486
503
  // The two post-step LLM producers are wrapped in `DBOS.runStep` so their
487
504
  // outputs are checkpointed (see the harness-durable-runtime spec): the conditional terminal emits they
488
505
  // gate (`data-step-summary`, file-tree) stay replay-stable and the billed
@@ -319,7 +319,7 @@ export declare function aggregateClassPrecedent(phase2: Phase2Bundle, fanout: Fa
319
319
  } | null;
320
320
  export declare function buildOrganRollup(faers: ReturnType<typeof aggregateFaersAcrossModulators>, trialAes: ReturnType<typeof aggregateTrialAes>, offTarget: OffTargetPanelRows | null, classP: ReturnType<typeof aggregateClassPrecedent>, regulatoryActions?: RegulatoryActionRow[] | null): {
321
321
  organ: "hematologic" | "metabolic" | "immune" | "hepatic" | "musculoskeletal" | "cns" | "renal" | "reproductive" | "respiratory" | "cardiac" | "vascular" | "pns" | "gi" | "pancreas" | "endocrine_thyroid" | "dermatologic" | "ocular" | "oncology";
322
- risk_level: "high" | "medium" | "low";
322
+ risk_level: "low" | "medium" | "high";
323
323
  signal_type_count: number;
324
324
  signals: {
325
325
  chembl_polypharm_count: number;
@@ -124,6 +124,27 @@ export declare const Phase4OutputSchema: z.ZodObject<{
124
124
  coverage: z.ZodLiteral<"not_loaded">;
125
125
  reason: z.ZodOptional<z.ZodString>;
126
126
  }, z.core.$strip>], "coverage">;
127
+ entity: z.ZodObject<{
128
+ canonicalId: z.ZodString;
129
+ symbol: z.ZodString;
130
+ displayName: z.ZodString;
131
+ entityType: z.ZodEnum<{
132
+ gene: "gene";
133
+ rna: "rna";
134
+ protein: "protein";
135
+ complex: "complex";
136
+ }>;
137
+ ontology: z.ZodString;
138
+ identifiers: z.ZodObject<{
139
+ hgnc: z.ZodOptional<z.ZodString>;
140
+ ensembl: z.ZodOptional<z.ZodString>;
141
+ uniprot: z.ZodOptional<z.ZodString>;
142
+ chembl: z.ZodOptional<z.ZodString>;
143
+ ncbiGene: z.ZodOptional<z.ZodString>;
144
+ }, z.core.$strip>;
145
+ synonyms: z.ZodDefault<z.ZodArray<z.ZodString>>;
146
+ proteinFamily: z.ZodOptional<z.ZodString>;
147
+ }, z.core.$strip>;
127
148
  off_target_panel: z.ZodDiscriminatedUnion<[z.ZodObject<{
128
149
  coverage: z.ZodLiteral<"available">;
129
150
  data: z.ZodObject<{
@@ -347,27 +368,6 @@ export declare const Phase4OutputSchema: z.ZodObject<{
347
368
  inferred_therapeutic_area: z.ZodNullable<z.ZodString>;
348
369
  no_liabilities_disclosure: z.ZodOptional<z.ZodString>;
349
370
  }, z.core.$strict>;
350
- entity: z.ZodObject<{
351
- canonicalId: z.ZodString;
352
- symbol: z.ZodString;
353
- displayName: z.ZodString;
354
- entityType: z.ZodEnum<{
355
- gene: "gene";
356
- rna: "rna";
357
- protein: "protein";
358
- complex: "complex";
359
- }>;
360
- ontology: z.ZodString;
361
- identifiers: z.ZodObject<{
362
- hgnc: z.ZodOptional<z.ZodString>;
363
- ensembl: z.ZodOptional<z.ZodString>;
364
- uniprot: z.ZodOptional<z.ZodString>;
365
- chembl: z.ZodOptional<z.ZodString>;
366
- ncbiGene: z.ZodOptional<z.ZodString>;
367
- }, z.core.$strip>;
368
- synonyms: z.ZodDefault<z.ZodArray<z.ZodString>>;
369
- proteinFamily: z.ZodOptional<z.ZodString>;
370
- }, z.core.$strip>;
371
371
  indications: z.ZodDiscriminatedUnion<[z.ZodObject<{
372
372
  coverage: z.ZodLiteral<"available">;
373
373
  data: z.ZodObject<{
@@ -442,9 +442,9 @@ export declare const Phase4OutputSchema: z.ZodObject<{
442
442
  start_date: z.ZodNullable<z.ZodString>;
443
443
  completion_date: z.ZodNullable<z.ZodString>;
444
444
  match_confidence: z.ZodEnum<{
445
- high: "high";
446
- medium: "medium";
447
445
  low: "low";
446
+ medium: "medium";
447
+ high: "high";
448
448
  off_target: "off_target";
449
449
  }>;
450
450
  attribution: z.ZodObject<{
@@ -499,9 +499,9 @@ export declare const Phase4OutputSchema: z.ZodObject<{
499
499
  start_date: z.ZodNullable<z.ZodString>;
500
500
  completion_date: z.ZodNullable<z.ZodString>;
501
501
  match_confidence: z.ZodEnum<{
502
- high: "high";
503
- medium: "medium";
504
502
  low: "low";
503
+ medium: "medium";
504
+ high: "high";
505
505
  off_target: "off_target";
506
506
  }>;
507
507
  attribution: z.ZodObject<{
@@ -855,9 +855,9 @@ export declare const Phase4OutputSchema: z.ZodObject<{
855
855
  oncology: "oncology";
856
856
  }>;
857
857
  risk_level: z.ZodEnum<{
858
- high: "high";
859
- medium: "medium";
860
858
  low: "low";
859
+ medium: "medium";
860
+ high: "high";
861
861
  }>;
862
862
  signal_type_count: z.ZodNumber;
863
863
  signals: z.ZodObject<{
@@ -1409,9 +1409,9 @@ export declare const Phase4OutputSchema: z.ZodObject<{
1409
1409
  trail: z.ZodString;
1410
1410
  mechanism_hypothesis: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1411
1411
  severity: z.ZodEnum<{
1412
- high: "high";
1413
- medium: "medium";
1414
1412
  low: "low";
1413
+ medium: "medium";
1414
+ high: "high";
1415
1415
  }>;
1416
1416
  support: z.ZodDiscriminatedUnion<[z.ZodObject<{
1417
1417
  state: z.ZodLiteral<"scored">;
@@ -2462,11 +2462,11 @@ export declare const Phase4OutputSchema: z.ZodObject<{
2462
2462
  dog: "dog";
2463
2463
  }>;
2464
2464
  rank: z.ZodEnum<{
2465
+ low: "low";
2466
+ medium: "medium";
2467
+ high: "high";
2465
2468
  no_data: "no_data";
2466
2469
  absent: "absent";
2467
- high: "high";
2468
- medium: "medium";
2469
- low: "low";
2470
2470
  not_loaded: "not_loaded";
2471
2471
  }>;
2472
2472
  }, z.core.$strip>>;
@@ -2800,9 +2800,9 @@ export declare const Phase4OutputSchema: z.ZodObject<{
2800
2800
  start_date: z.ZodOptional<z.ZodString>;
2801
2801
  completion_date: z.ZodOptional<z.ZodString>;
2802
2802
  match_confidence: z.ZodEnum<{
2803
- high: "high";
2804
- medium: "medium";
2805
2803
  low: "low";
2804
+ medium: "medium";
2805
+ high: "high";
2806
2806
  }>;
2807
2807
  relevance_basis: z.ZodDiscriminatedUnion<[z.ZodObject<{
2808
2808
  kind: z.ZodLiteral<"drug_in_class_match">;
@@ -2869,9 +2869,9 @@ export declare const Phase4OutputSchema: z.ZodObject<{
2869
2869
  start_date: z.ZodOptional<z.ZodString>;
2870
2870
  completion_date: z.ZodOptional<z.ZodString>;
2871
2871
  match_confidence: z.ZodEnum<{
2872
- high: "high";
2873
- medium: "medium";
2874
2872
  low: "low";
2873
+ medium: "medium";
2874
+ high: "high";
2875
2875
  }>;
2876
2876
  relevance_basis: z.ZodDiscriminatedUnion<[z.ZodObject<{
2877
2877
  kind: z.ZodLiteral<"drug_in_class_match">;
@@ -3122,9 +3122,9 @@ export declare const Phase4OutputSchema: z.ZodObject<{
3122
3122
  insufficient_evidence: "insufficient_evidence";
3123
3123
  }>;
3124
3124
  confidence: z.ZodEnum<{
3125
- high: "high";
3126
- medium: "medium";
3127
3125
  low: "low";
3126
+ medium: "medium";
3127
+ high: "high";
3128
3128
  }>;
3129
3129
  rationale: z.ZodString;
3130
3130
  key_strengths: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -17,8 +17,8 @@ export declare const ResolvedTargetSchema: z.ZodObject<{
17
17
  goal: z.ZodNullable<z.ZodString>;
18
18
  canonicalId: z.ZodString;
19
19
  canonicalOntology: z.ZodEnum<{
20
- ensembl: "ensembl";
21
20
  hgnc: "hgnc";
21
+ ensembl: "ensembl";
22
22
  }>;
23
23
  geneSymbol: z.ZodString;
24
24
  approvedName: z.ZodString;
@@ -249,10 +249,10 @@ export declare const ExpressionMultiSpeciesBundleSchema: z.ZodObject<{
249
249
  tissues: z.ZodArray<z.ZodObject<{
250
250
  tissue: z.ZodString;
251
251
  rank: z.ZodEnum<{
252
- absent: "absent";
253
- high: "high";
254
- medium: "medium";
255
252
  low: "low";
253
+ medium: "medium";
254
+ high: "high";
255
+ absent: "absent";
256
256
  }>;
257
257
  expressionScore: z.ZodNullable<z.ZodNumber>;
258
258
  }, z.core.$strip>>;
@@ -400,9 +400,9 @@ export declare const TherapeuticProgramsBundleSchema: z.ZodObject<{
400
400
  }, z.core.$strip>>;
401
401
  }, z.core.$strip>>;
402
402
  confidence: z.ZodEnum<{
403
- high: "high";
404
- medium: "medium";
405
403
  low: "low";
404
+ medium: "medium";
405
+ high: "high";
406
406
  }>;
407
407
  }, z.core.$strip>>;
408
408
  }, z.core.$strip>;
@@ -432,8 +432,8 @@ export declare const Phase1BundleSchema: z.ZodObject<{
432
432
  goal: z.ZodNullable<z.ZodString>;
433
433
  canonicalId: z.ZodString;
434
434
  canonicalOntology: z.ZodEnum<{
435
- ensembl: "ensembl";
436
435
  hgnc: "hgnc";
436
+ ensembl: "ensembl";
437
437
  }>;
438
438
  geneSymbol: z.ZodString;
439
439
  approvedName: z.ZodString;
@@ -688,10 +688,10 @@ export declare const Phase1BundleSchema: z.ZodObject<{
688
688
  tissues: z.ZodArray<z.ZodObject<{
689
689
  tissue: z.ZodString;
690
690
  rank: z.ZodEnum<{
691
- absent: "absent";
692
- high: "high";
693
- medium: "medium";
694
691
  low: "low";
692
+ medium: "medium";
693
+ high: "high";
694
+ absent: "absent";
695
695
  }>;
696
696
  expressionScore: z.ZodNullable<z.ZodNumber>;
697
697
  }, z.core.$strip>>;
@@ -954,9 +954,9 @@ export declare const Phase1BundleSchema: z.ZodObject<{
954
954
  }, z.core.$strip>>;
955
955
  }, z.core.$strip>>;
956
956
  confidence: z.ZodEnum<{
957
- high: "high";
958
- medium: "medium";
959
957
  low: "low";
958
+ medium: "medium";
959
+ high: "high";
960
960
  }>;
961
961
  }, z.core.$strip>>;
962
962
  }, z.core.$strip>;
@@ -18,8 +18,8 @@ export declare const Phase2BundleSchema: z.ZodObject<{
18
18
  goal: z.ZodNullable<z.ZodString>;
19
19
  canonicalId: z.ZodString;
20
20
  canonicalOntology: z.ZodEnum<{
21
- ensembl: "ensembl";
22
21
  hgnc: "hgnc";
22
+ ensembl: "ensembl";
23
23
  }>;
24
24
  geneSymbol: z.ZodString;
25
25
  approvedName: z.ZodString;
@@ -274,10 +274,10 @@ export declare const Phase2BundleSchema: z.ZodObject<{
274
274
  tissues: z.ZodArray<z.ZodObject<{
275
275
  tissue: z.ZodString;
276
276
  rank: z.ZodEnum<{
277
- absent: "absent";
278
- high: "high";
279
- medium: "medium";
280
277
  low: "low";
278
+ medium: "medium";
279
+ high: "high";
280
+ absent: "absent";
281
281
  }>;
282
282
  expressionScore: z.ZodNullable<z.ZodNumber>;
283
283
  }, z.core.$strip>>;
@@ -540,9 +540,9 @@ export declare const Phase2BundleSchema: z.ZodObject<{
540
540
  }, z.core.$strip>>;
541
541
  }, z.core.$strip>>;
542
542
  confidence: z.ZodEnum<{
543
- high: "high";
544
- medium: "medium";
545
543
  low: "low";
544
+ medium: "medium";
545
+ high: "high";
546
546
  }>;
547
547
  }, z.core.$strip>>;
548
548
  }, z.core.$strip>;
@@ -11,8 +11,8 @@ export declare const Phase3BundleSchema: z.ZodObject<{
11
11
  goal: z.ZodNullable<z.ZodString>;
12
12
  canonicalId: z.ZodString;
13
13
  canonicalOntology: z.ZodEnum<{
14
- ensembl: "ensembl";
15
14
  hgnc: "hgnc";
15
+ ensembl: "ensembl";
16
16
  }>;
17
17
  geneSymbol: z.ZodString;
18
18
  approvedName: z.ZodString;
@@ -267,10 +267,10 @@ export declare const Phase3BundleSchema: z.ZodObject<{
267
267
  tissues: z.ZodArray<z.ZodObject<{
268
268
  tissue: z.ZodString;
269
269
  rank: z.ZodEnum<{
270
- absent: "absent";
271
- high: "high";
272
- medium: "medium";
273
270
  low: "low";
271
+ medium: "medium";
272
+ high: "high";
273
+ absent: "absent";
274
274
  }>;
275
275
  expressionScore: z.ZodNullable<z.ZodNumber>;
276
276
  }, z.core.$strip>>;
@@ -533,9 +533,9 @@ export declare const Phase3BundleSchema: z.ZodObject<{
533
533
  }, z.core.$strip>>;
534
534
  }, z.core.$strip>>;
535
535
  confidence: z.ZodEnum<{
536
- high: "high";
537
- medium: "medium";
538
536
  low: "low";
537
+ medium: "medium";
538
+ high: "high";
539
539
  }>;
540
540
  }, z.core.$strip>>;
541
541
  }, z.core.$strip>;
@@ -24,9 +24,9 @@ export declare const LiabilityBulletsOutputSchema: z.ZodObject<{
24
24
  bullets: z.ZodArray<z.ZodObject<{
25
25
  organ_or_axis: z.ZodString;
26
26
  severity: z.ZodEnum<{
27
- high: "high";
28
- medium: "medium";
29
27
  low: "low";
28
+ medium: "medium";
29
+ high: "high";
30
30
  }>;
31
31
  text: z.ZodString;
32
32
  evidence_pointer: z.ZodString;
@@ -66,9 +66,9 @@ export declare const SafetyFlagsTrailOutputSchema: z.ZodObject<{
66
66
  oncology: "oncology";
67
67
  }>;
68
68
  severity: z.ZodEnum<{
69
- high: "high";
70
- medium: "medium";
71
69
  low: "low";
70
+ medium: "medium";
71
+ high: "high";
72
72
  }>;
73
73
  trail: z.ZodString;
74
74
  mechanism_hypothesis: z.ZodNullable<z.ZodString>;
@@ -109,9 +109,9 @@ export declare const DossierRecommendationOutputSchema: z.ZodObject<{
109
109
  insufficient_evidence: "insufficient_evidence";
110
110
  }>;
111
111
  confidence: z.ZodEnum<{
112
- high: "high";
113
- medium: "medium";
114
112
  low: "low";
113
+ medium: "medium";
114
+ high: "high";
115
115
  }>;
116
116
  rationale: z.ZodString;
117
117
  key_strengths: z.ZodArray<z.ZodString>;
@@ -146,9 +146,9 @@ export declare const LiabilityBulletsStepOutputSchema: z.ZodDiscriminatedUnion<[
146
146
  bullets: z.ZodArray<z.ZodObject<{
147
147
  organ_or_axis: z.ZodString;
148
148
  severity: z.ZodEnum<{
149
- high: "high";
150
- medium: "medium";
151
149
  low: "low";
150
+ medium: "medium";
151
+ high: "high";
152
152
  }>;
153
153
  text: z.ZodString;
154
154
  evidence_pointer: z.ZodString;
@@ -269,9 +269,9 @@ export declare const SafetyFlagsTrailStepOutputSchema: z.ZodDiscriminatedUnion<[
269
269
  oncology: "oncology";
270
270
  }>;
271
271
  severity: z.ZodEnum<{
272
- high: "high";
273
- medium: "medium";
274
272
  low: "low";
273
+ medium: "medium";
274
+ high: "high";
275
275
  }>;
276
276
  trail: z.ZodString;
277
277
  mechanism_hypothesis: z.ZodNullable<z.ZodString>;
@@ -461,9 +461,9 @@ export declare const DossierRecommendationStepOutputSchema: z.ZodDiscriminatedUn
461
461
  insufficient_evidence: "insufficient_evidence";
462
462
  }>;
463
463
  confidence: z.ZodEnum<{
464
- high: "high";
465
- medium: "medium";
466
464
  low: "low";
465
+ medium: "medium";
466
+ high: "high";
467
467
  }>;
468
468
  rationale: z.ZodString;
469
469
  key_strengths: z.ZodArray<z.ZodString>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inflexa-ai/harness",
3
- "version": "0.28.1",
3
+ "version": "0.30.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",
@@ -33,15 +33,17 @@
33
33
  "directory": "harness"
34
34
  },
35
35
  "scripts": {
36
- "build": "tsc -p tsconfig.json",
36
+ "build": "tsc -p tsconfig.json && node scripts/copy-assets.mjs",
37
37
  "design:fixture": "bun scripts/render-fixture.ts",
38
38
  "format": "prettier --write src/",
39
39
  "format:file": "prettier --write",
40
40
  "lint": "eslint .",
41
- "prepare": "tsc -p tsconfig.json",
41
+ "lint:python": "ruff check src/input-scan/decoder && ruff format --check src/input-scan/decoder",
42
+ "prepare": "tsc -p tsconfig.json && node scripts/copy-assets.mjs",
42
43
  "prepublishOnly": "bun run build && bun run smoke",
43
44
  "smoke": "node scripts/smoke.mjs",
44
45
  "test:full": "bash scripts/test-full.sh",
46
+ "test:python": "python3 -m pytest src/input-scan/decoder -q",
45
47
  "typecheck": "tsc --noEmit"
46
48
  },
47
49
  "dependencies": {
@@ -1,22 +0,0 @@
1
- /**
2
- * Profile coverage — how much of the scanned tree the agent's kinds actually describe.
3
- *
4
- * Measured against the SUBMITTED kinds, never against the scan's own shapes. Computed
5
- * from the shapes it would report only whether the scan grouped its own observations,
6
- * which is always yes; measured against the kinds it is a real check, and it is the
7
- * check that was missing when a profile covering 49 of 3513 files read as complete and
8
- * fresh.
9
- *
10
- * Deterministic by construction: matching declared patterns against a known file set
11
- * requires no judgement, and a coverage figure a model self-reported would not be a
12
- * check at all.
13
- */
14
- export interface ProfileCoverage {
15
- /** Files matching at least one declared kind pattern. */
16
- readonly matched: number;
17
- readonly unmatched: number;
18
- readonly total: number;
19
- readonly unmatchedSample: string[];
20
- }
21
- /** Coverage of a scanned file set by a set of declared kind patterns. */
22
- export declare function computeCoverage(paths: readonly string[], patterns: readonly string[]): ProfileCoverage;