@inflexa-ai/harness 0.29.0 → 0.30.1

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 (93) 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/config/resource-limits.d.ts +1 -1
  9. package/dist/config/resource-limits.js +1 -1
  10. package/dist/contracts/schemas/chat-parts.d.ts +12 -12
  11. package/dist/contracts/severity.d.ts +2 -2
  12. package/dist/contracts/target-dossier.d.ts +70 -70
  13. package/dist/data/safety-panel-schema.d.ts +4 -4
  14. package/dist/index.d.ts +2 -1
  15. package/dist/index.js +9 -0
  16. package/dist/loop/run-agent.d.ts +14 -1
  17. package/dist/loop/run-agent.js +6 -1
  18. package/dist/prompts/SOUL.d.ts +2 -2
  19. package/dist/prompts/SOUL.js +17 -1
  20. package/dist/prompts/conversation.d.ts +1 -1
  21. package/dist/prompts/conversation.js +43 -71
  22. package/dist/prompts/planner.js +57 -10
  23. package/dist/prompts/sandbox/bulk-transcriptomics-agent.d.ts +1 -1
  24. package/dist/prompts/sandbox/bulk-transcriptomics-agent.js +3 -1
  25. package/dist/prompts/sandbox/dna-methylation-agent.d.ts +1 -1
  26. package/dist/prompts/sandbox/dna-methylation-agent.js +18 -12
  27. package/dist/prompts/sandbox/immune-profiling-agent.d.ts +1 -1
  28. package/dist/prompts/sandbox/immune-profiling-agent.js +6 -2
  29. package/dist/prompts/sandbox/metabolomics-agent.d.ts +1 -1
  30. package/dist/prompts/sandbox/metabolomics-agent.js +8 -4
  31. package/dist/prompts/sandbox/microbiome-agent.d.ts +1 -1
  32. package/dist/prompts/sandbox/microbiome-agent.js +12 -6
  33. package/dist/prompts/sandbox/network-agent.d.ts +1 -1
  34. package/dist/prompts/sandbox/network-agent.js +9 -6
  35. package/dist/prompts/sandbox/spatial-omics-agent.d.ts +1 -1
  36. package/dist/prompts/sandbox/spatial-omics-agent.js +4 -2
  37. package/dist/providers/ai-sdk.js +4 -0
  38. package/dist/providers/reasoning.d.ts +35 -0
  39. package/dist/providers/reasoning.js +34 -0
  40. package/dist/providers/types.d.ts +26 -0
  41. package/dist/schemas/data-profile-schemas.d.ts +4 -4
  42. package/dist/schemas/run-synthesis.d.ts +4 -4
  43. package/dist/tools/bio/chembl.d.ts +1 -1
  44. package/dist/tools/bio/chembl.js +15 -10
  45. package/dist/tools/bio/comptox.js +5 -1
  46. package/dist/tools/bio/drug-gene-interactions.js +5 -2
  47. package/dist/tools/bio/gene-disease-evidence.d.ts +19 -9
  48. package/dist/tools/bio/gene-disease-evidence.js +78 -22
  49. package/dist/tools/bio/gene-preclinical-profile.d.ts +33 -13
  50. package/dist/tools/bio/gene-preclinical-profile.js +63 -22
  51. package/dist/tools/bio/lookup-annotation.d.ts +1 -0
  52. package/dist/tools/bio/lookup-annotation.js +28 -10
  53. package/dist/tools/bio/opentargets.d.ts +10 -2
  54. package/dist/tools/bio/opentargets.js +42 -13
  55. package/dist/tools/bio/pubchem.js +5 -2
  56. package/dist/tools/bio/pubmed.js +9 -3
  57. package/dist/tools/bio/search-clinical-trials.d.ts +25 -25
  58. package/dist/tools/bio/search-clinical-trials.js +56 -18
  59. package/dist/tools/bio/search-faers.d.ts +26 -6
  60. package/dist/tools/bio/search-faers.js +70 -18
  61. package/dist/tools/bio/search-gene.d.ts +19 -3
  62. package/dist/tools/bio/search-gene.js +69 -12
  63. package/dist/tools/bio/search-geo-datasets.js +4 -1
  64. package/dist/tools/bio/search-interactions.js +6 -2
  65. package/dist/tools/bio/target-safety.d.ts +2 -2
  66. package/dist/tools/bio/target-safety.js +3 -2
  67. package/dist/tools/lib/cbioportal-client.js +25 -6
  68. package/dist/tools/lib/chembl-client.d.ts +3 -1
  69. package/dist/tools/lib/chembl-client.js +6 -1
  70. package/dist/tools/lib/gwas-catalog-client.d.ts +7 -6
  71. package/dist/tools/lib/gwas-catalog-client.js +18 -6
  72. package/dist/tools/lib/openfda-client.d.ts +7 -5
  73. package/dist/tools/lib/openfda-client.js +17 -9
  74. package/dist/tools/lib/opentargets-client.d.ts +20 -0
  75. package/dist/tools/lib/opentargets-client.js +45 -0
  76. package/dist/tools/lib/pathway-client.d.ts +7 -0
  77. package/dist/tools/lib/pathway-client.js +68 -1
  78. package/dist/tools/research/context7-docs.js +3 -3
  79. package/dist/tools/research/generate-analogy-report.js +2 -2
  80. package/dist/tools/research/generate-plan.d.ts +3 -0
  81. package/dist/tools/research/generate-plan.js +64 -5
  82. package/dist/tools/research/resolve-citation.js +8 -3
  83. package/dist/tools/research/search-arxiv.js +8 -3
  84. package/dist/tools/research/search-semantic-scholar.js +10 -4
  85. package/dist/workflows/sandbox-step.d.ts +6 -0
  86. package/dist/workflows/sandbox-step.js +31 -14
  87. package/dist/workflows/target-assessment/assemblers/safety.d.ts +1 -1
  88. package/dist/workflows/target-assessment/phase4-assemble.d.ts +17 -17
  89. package/dist/workflows/target-assessment/schemas.d.ts +12 -12
  90. package/dist/workflows/target-assessment/steps/phase2-aggregate.d.ts +6 -6
  91. package/dist/workflows/target-assessment/steps/phase3-aggregate.d.ts +6 -6
  92. package/dist/workflows/target-assessment/synthesis/index.d.ts +12 -12
  93. package/package.json +1 -1
@@ -35,6 +35,12 @@ import { defineTool } from "../define-tool.js";
35
35
  import { createListAvailablePackagesTool } from "../sandbox/list-available-packages.js";
36
36
  import { createListAvailableRefsTool } from "../sandbox/list-available-refs.js";
37
37
  import { createReportBlockerToolFor } from "../sandbox/report-blocker.js";
38
+ import { searchGeoDatasetsTool } from "../bio/search-geo-datasets.js";
39
+ import { createNcbiTools } from "../bio/keys.js";
40
+ import { queryDocsTool, resolveLibraryIdTool } from "./context7-docs.js";
41
+ import { searchArxivTool } from "./search-arxiv.js";
42
+ import { createSearchGithubReposTool } from "./search-github-repos.js";
43
+ import { createSearchSemanticScholarTool } from "./search-semantic-scholar.js";
38
44
  import { DATA_PROFILE_ORIENTATION_MAX_CHARS, buildDataProfileOrientation } from "../../app/data-profile-orientation.js";
39
45
  import { DEFAULT_SANDBOX_MAX_STEPS } from "../../config/resource-limits.js";
40
46
  import { plannerPrompt } from "../../prompts/planner.js";
@@ -49,10 +55,17 @@ import { insertPlan, loadDataProfileStatus, loadPlan } from "../../state/index.j
49
55
  /** Sub-agent identity for the planner — provenance only. */
50
56
  const PLANNER_AGENT_ID = "planner";
51
57
  /**
52
- * Budget for the planner's internal loop: one draft/submit attempt plus
53
- * correction retries and headroom.
58
+ * Budget for the planner's internal loop: the research phase, one draft/submit
59
+ * attempt, correction retries, and headroom.
60
+ *
61
+ * The number is deliberately far above what a plan costs. A well-grounded plan
62
+ * still costs two or three calls, because the prompt gates the research phase on
63
+ * what the seed does not already answer. What the ceiling must never do is stop
64
+ * a planner that is searching correctly. A capped run takes the forced wrap-up
65
+ * path and submits the plan that it had, not the plan that it was building.
66
+ * Thus the wall-clock guard, not this number, is what bounds the worst case.
54
67
  */
55
- const PLANNER_MAX_ITERATIONS = 13;
68
+ const PLANNER_MAX_ITERATIONS = 200;
56
69
  /** Wall-clock guard for a single plan-generation invocation. */
57
70
  const PLAN_TIMEOUT_MS = 600_000;
58
71
  // ── Diagnostic bounds ───────────────────────────────────────────────
@@ -71,7 +84,7 @@ const MAX_LOGGED_ISSUE_CHARS = 240;
71
84
  const MAX_LOGGED_REJECTIONS = 6;
72
85
  /** Excerpt of the planner's last words — the one artifact that explains a run ending on prose. */
73
86
  const MAX_LOGGED_PROSE_CHARS = 800;
74
- /** Tool-call trace length. The planner's whole budget is ~16 turns, so this rarely truncates. */
87
+ /** Tool-call trace length. A long research phase passes it, and `toolCallsTruncated` marks the record when it does. */
75
88
  const MAX_LOGGED_TOOL_CALLS = 48;
76
89
  /** Trim to `max`, marking the cut so a truncated value never reads as a complete one. */
77
90
  function bounded(value, max) {
@@ -629,6 +642,44 @@ const OUTCOME_LEVEL = {
629
642
  invalid_parent_plan: "warn",
630
643
  parent_plan_load_failed: "error",
631
644
  };
645
+ /**
646
+ * The search tools of the planner — built one time, not per invocation.
647
+ *
648
+ * The set answers the two questions that a seed cannot. "What did a study of
649
+ * this kind do before?" reaches the public dataset records and the literature.
650
+ * "What does this package actually give me?" reaches the developer docs. The
651
+ * planner reads its reference and package inventories from the seed, thus the
652
+ * docs pair is what turns a package name into a real function.
653
+ *
654
+ * A tool here never writes and never computes. Thus the worst outcome of a
655
+ * needless call is latency, and the prompt is what bounds that.
656
+ */
657
+ function buildPlannerSearchTools(deps) {
658
+ const bioKeys = deps.bioKeys;
659
+ const ncbi = createNcbiTools(bioKeys);
660
+ return [
661
+ // Comparable public studies — the design, the platform, and the sample
662
+ // count that a plan for the same assay must answer to.
663
+ searchGeoDatasetsTool,
664
+ // Prior methods, in three corpora that do not overlap: the biomedical
665
+ // literature, the statistics and machine-learning preprints, and the
666
+ // cross-field index that ranks a method paper best.
667
+ ncbi.pubmed,
668
+ searchArxivTool,
669
+ createSearchSemanticScholarTool({ ...(bioKeys.semanticScholar === undefined ? {} : { apiKey: bioKeys.semanticScholar }) }),
670
+ // The same approach as running code — a pipeline that someone published.
671
+ createSearchGithubReposTool({ githubToken: bioKeys.github }),
672
+ // The API of a staged package, so a step names a function that exists.
673
+ resolveLibraryIdTool,
674
+ queryDocsTool,
675
+ // The environment itself. The seed already carries a rendered census of
676
+ // both stores. These two tools are for the narrow second look: one
677
+ // collection of the reference store, or one package name that a step is
678
+ // about to import.
679
+ createListAvailableRefsTool(deps.refStorePath === undefined ? {} : { refStorePath: deps.refStorePath }),
680
+ createListAvailablePackagesTool(deps.packagesFile === undefined ? {} : { packagesFile: deps.packagesFile }),
681
+ ];
682
+ }
632
683
  /** Build the `generate_plan` tool bound to its provider and pool. */
633
684
  export function createGeneratePlanTool(deps) {
634
685
  const baseLogger = (deps.logger ?? createNoopLogger()).named("generate-plan");
@@ -806,11 +857,19 @@ export function createGeneratePlanTool(deps) {
806
857
  parentPlanId: input.parentPlanId ?? null,
807
858
  };
808
859
  const innerTools = buildInnerTools(holder, trace, persistCtx, deps.pool, deps.resourcePolicy, logger);
860
+ // Built here rather than at construction: a `describeCall` hook reads no
861
+ // dep, thus the tool must stay constructible from an empty bag. The tool
862
+ // definitions are identical across invocations, thus the request prefix
863
+ // that the cache keys on does not move.
864
+ const searchTools = buildPlannerSearchTools(deps);
809
865
  const planner = {
810
866
  id: PLANNER_AGENT_ID,
811
867
  systemPrompt: composeSystemPrompt(plannerInstructions(deps.resourcePolicy)),
812
868
  model: deps.conversation.model,
813
- tools: innerTools.terminal,
869
+ // The search tools come first, and the terminal tools come last.
870
+ // The order is the order of the prompt, and it is stable across
871
+ // every invocation, thus the cached request prefix holds.
872
+ tools: [...searchTools, ...innerTools.terminal],
814
873
  maxIterations: PLANNER_MAX_ITERATIONS,
815
874
  };
816
875
  // Merge the outer abort signal with a wall-clock timeout — either
@@ -4,10 +4,15 @@ import { defineTool } from "../define-tool.js";
4
4
  export function createResolveCitationTool(resolver) {
5
5
  return defineTool({
6
6
  id: "resolve_citation",
7
- description: "Verify one supplied citation against applicable bibliographic authorities. " +
8
- "Use this for 'does this reference exist and does its metadata agree?', not for topical literature discovery. " +
7
+ description: "Verify one supplied citation against the applicable bibliographic authorities — the DOI registry, Crossref, PubMed, arXiv and Semantic " +
8
+ "Scholar — and report where they agree. " +
9
+ "Use this for 'does this reference exist and does its metadata agree?', not for topical literature discovery: pubmed, " +
10
+ "search_semantic_scholar and search_arxiv are the discovery tools.\n" +
11
+ "ACCEPTED IDENTIFIERS: a DOI ('10.1038/nature12373'), a PMID ('23945592'), an arXiv ID ('2301.00001'), or raw bibliographic text. Each " +
12
+ "authority that the input cannot address is marked not_applicable rather than queried.\n" +
9
13
  "Returns source-labelled records, field comparisons, conflicts, coverage, and one of verified, metadata_mismatch, " +
10
- "not_found, unverifiable, or inconclusive. Source failure never becomes not_found.",
14
+ "not_found, unverifiable, or inconclusive. Source failure never becomes not_found — an unreachable authority reports unavailable, and " +
15
+ "not_found means the authorities that answered hold no such record.",
11
16
  inputSchema: CitationInputSchema,
12
17
  describeCall: ({ citation }) => `verify ${citation}`,
13
18
  execute: async (input, ctx) => ok(await resolver.resolveOne(input, { signal: ctx.signal })),
@@ -7,9 +7,14 @@ export { parseArxivAtom } from "../../literature/sources/arxiv.js";
7
7
  const source = createArxivSource({ maxRetries: 3, retryDelayMs: 1_000, timeoutMs: 90_000 });
8
8
  export const searchArxivTool = defineTool({
9
9
  id: "search_arxiv",
10
- description: "Search arXiv for preprints in ML, physics, math, control theory, " +
11
- "economics, and related quantitative fields. Returns id, title, " +
12
- "abstract, authors, publication date, arXiv categories, and URLs.",
10
+ description: "Search arXiv — the open preprint server of Cornell University — for work in machine learning, physics, math, quantitative biology, control " +
11
+ "theory, economics and the related quantitative fields. Returns id, title, abstract, authors, publication date, arXiv categories, and URLs.\n" +
12
+ "It carries PREPRINTS, thus a paper here may not be peer reviewed, and it is where a method appears months before a journal holds it. For the " +
13
+ "clinical and biomedical literature use pubmed, which indexes MEDLINE; for cross-domain coverage of any field use search_semantic_scholar.\n" +
14
+ "ACCEPTED IDENTIFIERS: free text in `query`, and arXiv category codes in `categories` ('cs.LG', 'q-bio.GN', 'math.OC'). An arXiv ID " +
15
+ "('2301.00001') also matches as free text.\n" +
16
+ "ABSENCE IS NORMAL: an empty papers array means arXiv holds nothing for the query, and `success: false` with an `error` string means the service " +
17
+ "could not be reached. Report either one and continue, do not retry unchanged.",
13
18
  inputSchema: z.object({
14
19
  query: z.string().describe('Free-text query. Example: "adaptive control feedback stabilization".'),
15
20
  categories: z
@@ -13,10 +13,16 @@ export function createSearchSemanticScholarTool(options = {}) {
13
13
  });
14
14
  return defineTool({
15
15
  id: "search_semantic_scholar",
16
- description: "Search Semantic Scholar for academic papers across all sciences " +
17
- "(biology, ML, physics, math, economics, engineering, etc.). Returns " +
18
- "paper id, title, abstract, year, venue, citation count, authors, and " +
19
- "external IDs (DOI, ArXiv). Best for cross-domain analogical search.",
16
+ description: "Search Semantic Scholar — the cross-disciplinary literature corpus of the Allen Institute for AI, which indexes over 200M papers across " +
17
+ "biology, medicine, machine learning, physics, math, economics and engineering. Returns paper id, title, abstract, year, venue, citation " +
18
+ "count, authors, and external IDs (DOI, arXiv). Its citation counts are what rank a field by influence, and its breadth is what makes it the " +
19
+ "tool for a cross-domain analogical search.\n" +
20
+ "For the clinical and biomedical literature alone, pubmed indexes MEDLINE more precisely; for preprints in the quantitative fields use " +
21
+ "search_arxiv.\n" +
22
+ "ACCEPTED IDENTIFIERS: free text in `query`. A DOI or an arXiv ID also matches as free text, and each result carries its DOI and arXiv ID " +
23
+ "back for a citation.\n" +
24
+ "ABSENCE IS NORMAL: an empty papers array means the corpus holds nothing for the query, and `success: false` with an `error` string means the " +
25
+ "service could not be reached (its unkeyed rate limit lands here). Report either one and continue, do not retry unchanged.",
20
26
  inputSchema: z.object({
21
27
  query: z
22
28
  .string()
@@ -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;
@@ -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.29.0",
3
+ "version": "0.30.1",
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",