@inflexa-ai/harness 0.17.0 → 0.19.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/report-builder.d.ts +2 -0
- package/dist/agents/report-builder.js +2 -0
- package/dist/agents/report-session-agent.d.ts +56 -0
- package/dist/agents/report-session-agent.js +72 -0
- package/dist/app/report-session-runtime.d.ts +72 -0
- package/dist/app/report-session-runtime.js +157 -0
- package/dist/app/spawn-report-session.d.ts +85 -0
- package/dist/app/spawn-report-session.js +83 -0
- package/dist/contracts/chat-events.d.ts +9 -0
- package/dist/contracts/index.d.ts +6 -2
- package/dist/contracts/index.js +3 -1
- package/dist/contracts/organ-system.d.ts +49 -0
- package/dist/contracts/organ-system.js +67 -0
- package/dist/contracts/report-blocks.d.ts +564 -0
- package/dist/contracts/report-blocks.js +117 -0
- package/dist/contracts/report-reference.d.ts +459 -0
- package/dist/contracts/report-reference.js +256 -0
- package/dist/contracts/schemas/chat-events.d.ts +2 -0
- package/dist/contracts/schemas/chat-events.js +2 -0
- package/dist/contracts/severity.d.ts +15 -0
- package/dist/contracts/severity.js +10 -0
- package/dist/contracts/target-dossier.d.ts +8675 -12972
- package/dist/contracts/target-dossier.js +534 -591
- package/dist/data/safety-panel-schema.d.ts +18 -5
- package/dist/data/safety-panel-schema.js +4 -4
- package/dist/execution/artifact-metadata.js +1 -0
- package/dist/execution/report-runner.js +1 -3
- package/dist/execution/run-synthesis.js +2 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +19 -0
- package/dist/lib/async-utils.d.ts +16 -4
- package/dist/lib/async-utils.js +20 -15
- package/dist/lib/host-concurrency.js +1 -0
- package/dist/loop/__fixtures__/scripted-provider.js +23 -2
- package/dist/loop/run-agent.js +58 -10
- package/dist/loop/tool-detail.d.ts +40 -0
- package/dist/loop/tool-detail.js +35 -3
- package/dist/loop/types.d.ts +13 -0
- package/dist/memory/thread-history.d.ts +10 -0
- package/dist/memory/thread-history.js +12 -1
- package/dist/memory/thread-store.d.ts +4 -4
- package/dist/memory/thread-store.js +18 -9
- package/dist/prompts/report-session.d.ts +1 -0
- package/dist/prompts/report-session.js +89 -0
- package/dist/prompts/target-assessment/briefs/executive-recommendation.d.ts +1 -1
- package/dist/prompts/target-assessment/briefs/executive-recommendation.js +5 -5
- package/dist/prompts/target-assessment/briefs/liability-bullets.d.ts +1 -1
- package/dist/prompts/target-assessment/briefs/liability-bullets.js +1 -1
- package/dist/prompts/target-assessment/briefs/target-organ-liabilities.d.ts +1 -1
- package/dist/prompts/target-assessment/briefs/target-organ-liabilities.js +11 -3
- package/dist/prompts/target-assessment/investigation/adversarial-critique.d.ts +1 -0
- package/dist/prompts/target-assessment/investigation/adversarial-critique.js +67 -0
- package/dist/prompts/target-assessment/investigation/claim-reverification.d.ts +1 -0
- package/dist/prompts/target-assessment/investigation/claim-reverification.js +49 -0
- package/dist/prompts/target-assessment/investigation/index.d.ts +3 -0
- package/dist/prompts/target-assessment/investigation/index.js +3 -0
- package/dist/prompts/target-assessment/investigation/mechanism-proposal.d.ts +1 -0
- package/dist/prompts/target-assessment/investigation/mechanism-proposal.js +49 -0
- package/dist/prompts/target-assessment/tox-voice/index.d.ts +1 -1
- package/dist/prompts/target-assessment/tox-voice/vocabulary.d.ts +8 -5
- package/dist/prompts/target-assessment/tox-voice/vocabulary.js +9 -20
- package/dist/providers/__fixtures__/session.d.ts +5 -4
- package/dist/providers/__fixtures__/session.js +4 -4
- package/dist/providers/ai-sdk.d.ts +77 -0
- package/dist/providers/ai-sdk.js +149 -19
- package/dist/providers/errors.d.ts +14 -0
- package/dist/providers/errors.js +103 -18
- package/dist/providers/types.d.ts +16 -0
- package/dist/providers/types.js +10 -1
- package/dist/report-model/block-walk.d.ts +56 -0
- package/dist/report-model/block-walk.js +89 -0
- package/dist/report-model/draft-finish.d.ts +60 -0
- package/dist/report-model/draft-finish.js +56 -0
- package/dist/report-model/draft-operations.d.ts +125 -0
- package/dist/report-model/draft-operations.js +341 -0
- package/dist/report-model/draft-read.d.ts +59 -0
- package/dist/report-model/draft-read.js +109 -0
- package/dist/report-model/draft.d.ts +51 -0
- package/dist/report-model/draft.js +32 -0
- package/dist/report-model/fixture-resolver.d.ts +8 -0
- package/dist/report-model/fixture-resolver.js +252 -0
- package/dist/report-model/pin-snapshot.d.ts +30 -0
- package/dist/report-model/pin-snapshot.js +40 -0
- package/dist/report-model/reference-resolver.d.ts +113 -0
- package/dist/report-model/reference-resolver.js +60 -0
- package/dist/report-model/structural-validation.d.ts +22 -0
- package/dist/report-model/structural-validation.js +68 -0
- package/dist/report-model/validate.d.ts +72 -0
- package/dist/report-model/validate.js +95 -0
- package/dist/report-render/chart.d.ts +33 -0
- package/dist/report-render/chart.js +538 -0
- package/dist/report-render/page.d.ts +127 -0
- package/dist/report-render/page.js +307 -0
- package/dist/report-render/references.d.ts +32 -0
- package/dist/report-render/references.js +44 -0
- package/dist/report-render/render.d.ts +25 -0
- package/dist/report-render/render.js +125 -0
- package/dist/report-render/script-json.d.ts +13 -0
- package/dist/report-render/script-json.js +15 -0
- package/dist/report-render/types.d.ts +39 -0
- package/dist/report-render/types.js +10 -0
- package/dist/report-render/value-bridge.d.ts +62 -0
- package/dist/report-render/value-bridge.js +82 -0
- package/dist/report-render/views/chart-view.d.ts +11 -0
- package/dist/report-render/views/chart-view.js +23 -0
- package/dist/report-render/views/page-view.d.ts +20 -0
- package/dist/report-render/views/page-view.js +49 -0
- package/dist/report-render/views/prose.d.ts +28 -0
- package/dist/report-render/views/prose.js +75 -0
- package/dist/report-render/views/references-view.d.ts +20 -0
- package/dist/report-render/views/references-view.js +64 -0
- package/dist/report-render/views/values.d.ts +42 -0
- package/dist/report-render/views/values.js +43 -0
- package/dist/runtime/assemble.d.ts +15 -0
- package/dist/runtime/assemble.js +28 -6
- package/dist/runtime/boot.d.ts +3 -3
- package/dist/runtime/boot.js +15 -4
- package/dist/runtime/dbos.d.ts +4 -4
- package/dist/state/artifacts.d.ts +16 -0
- package/dist/state/artifacts.js +18 -0
- package/dist/state/init.js +54 -0
- package/dist/state/purge-analysis.js +2 -0
- package/dist/state/report-session-state.d.ts +112 -0
- package/dist/state/report-session-state.js +150 -0
- package/dist/state/report-versions.d.ts +129 -0
- package/dist/state/report-versions.js +167 -0
- package/dist/state/snapshot-parse.d.ts +34 -0
- package/dist/state/snapshot-parse.js +82 -0
- package/dist/tasks/data-profile.js +1 -0
- package/dist/tools/ad-hoc-router.d.ts +7 -2
- package/dist/tools/ad-hoc-router.js +2 -1
- package/dist/tools/bio/chembl.js +1 -0
- package/dist/tools/bio/comptox.js +1 -0
- package/dist/tools/bio/drug-gene-interactions.js +1 -0
- package/dist/tools/bio/gene-disease-evidence.js +1 -0
- package/dist/tools/bio/gene-preclinical-profile.js +1 -0
- package/dist/tools/bio/keys.d.ts +3 -2
- package/dist/tools/bio/keys.js +3 -2
- package/dist/tools/bio/lookup-annotation.js +1 -0
- package/dist/tools/bio/opentargets.d.ts +3 -3
- package/dist/tools/bio/opentargets.js +4 -3
- package/dist/tools/bio/pubchem.js +1 -0
- package/dist/tools/bio/search-clinical-trials.js +1 -0
- package/dist/tools/bio/search-faers.js +1 -0
- package/dist/tools/bio/search-geo-datasets.js +1 -0
- package/dist/tools/bio/search-interactions.js +1 -0
- package/dist/tools/bio/target-safety.d.ts +4 -6
- package/dist/tools/bio/target-safety.js +7 -6
- package/dist/tools/define-tool.d.ts +19 -12
- package/dist/tools/define-tool.js +4 -2
- package/dist/tools/display/show-user.js +1 -0
- package/dist/tools/iterate-report.js +2 -0
- package/dist/tools/lib/chembl-client.d.ts +2 -0
- package/dist/tools/lib/chembl-client.js +1 -0
- package/dist/tools/lib/monarch-client.d.ts +42 -0
- package/dist/tools/lib/monarch-client.js +100 -0
- package/dist/tools/report/build-report.js +1 -0
- package/dist/tools/report/mint-preview-url.js +1 -0
- package/dist/tools/report/preview-snapshot.js +1 -0
- package/dist/tools/report/submit-report.js +1 -0
- package/dist/tools/report/version-fs.js +4 -0
- package/dist/tools/report-authoring/authoring-tools.d.ts +241 -0
- package/dist/tools/report-authoring/authoring-tools.js +460 -0
- package/dist/tools/report-session/index.d.ts +8 -0
- package/dist/tools/report-session/index.js +8 -0
- package/dist/tools/report-session/preview-report.d.ts +90 -0
- package/dist/tools/report-session/preview-report.js +245 -0
- package/dist/tools/research/context7-docs.js +2 -0
- package/dist/tools/research/generate-analogy-report.js +1 -0
- package/dist/tools/research/generate-plan.js +7 -2
- package/dist/tools/research/inspect-data-profile.js +4 -0
- package/dist/tools/research/literature-reviewer.js +1 -0
- package/dist/tools/research/search-arxiv.js +1 -0
- package/dist/tools/research/search-github-repos.js +1 -0
- package/dist/tools/research/search-semantic-scholar.js +1 -0
- package/dist/tools/sandbox/list-available-packages.js +23 -0
- package/dist/tools/sandbox/list-available-refs.js +36 -0
- package/dist/tools/sandbox/report-blocker.js +1 -0
- package/dist/tools/sandbox/skills.js +2 -0
- package/dist/tools/workspace/file-stat.js +1 -0
- package/dist/tools/workspace/show-file.js +2 -0
- package/dist/tools/workspace/show-plan.js +1 -0
- package/dist/workflows/execute-analysis.d.ts +5 -1
- package/dist/workflows/execute-analysis.js +5 -5
- package/dist/workflows/execute-target-assessment.d.ts +13 -2
- package/dist/workflows/execute-target-assessment.js +78 -16
- package/dist/workflows/target-assessment/assemblers/index.d.ts +1 -1
- package/dist/workflows/target-assessment/assemblers/index.js +1 -1
- package/dist/workflows/target-assessment/assemblers/literature.d.ts +9 -27
- package/dist/workflows/target-assessment/assemblers/literature.js +32 -48
- package/dist/workflows/target-assessment/assemblers/orchestrator.d.ts +17 -9
- package/dist/workflows/target-assessment/assemblers/orchestrator.js +195 -85
- package/dist/workflows/target-assessment/assemblers/safety.d.ts +70 -48
- package/dist/workflows/target-assessment/assemblers/safety.js +125 -42
- package/dist/workflows/target-assessment/collectors/index.d.ts +5 -2
- package/dist/workflows/target-assessment/collectors/index.js +48 -5
- package/dist/workflows/target-assessment/coverage.d.ts +43 -27
- package/dist/workflows/target-assessment/coverage.js +33 -29
- package/dist/workflows/target-assessment/fanout/index.js +1 -0
- package/dist/workflows/target-assessment/investigation/index.d.ts +97 -0
- package/dist/workflows/target-assessment/investigation/index.js +419 -0
- package/dist/workflows/target-assessment/lib/approval-precedents.d.ts +26 -5
- package/dist/workflows/target-assessment/lib/approval-precedents.js +95 -29
- package/dist/workflows/target-assessment/lib/citation-validator.js +1 -1
- package/dist/workflows/target-assessment/lib/clinical-consequence-annotator.d.ts +2 -2
- package/dist/workflows/target-assessment/lib/clinical-evidence-attribution.d.ts +2 -3
- package/dist/workflows/target-assessment/lib/clinical-evidence-attribution.js +0 -4
- package/dist/workflows/target-assessment/lib/compute-derived.d.ts +6 -5
- package/dist/workflows/target-assessment/lib/compute-derived.js +14 -5
- package/dist/workflows/target-assessment/lib/family-complex-supplement.d.ts +5 -6
- package/dist/workflows/target-assessment/lib/family-complex-supplement.js +2 -3
- package/dist/workflows/target-assessment/lib/fda-label-safety.d.ts +72 -0
- package/dist/workflows/target-assessment/lib/fda-label-safety.js +166 -0
- package/dist/workflows/target-assessment/lib/heterodimer-filter.d.ts +0 -9
- package/dist/workflows/target-assessment/lib/heterodimer-filter.js +0 -10
- package/dist/workflows/target-assessment/lib/hpo-organ-map.d.ts +34 -0
- package/dist/workflows/target-assessment/lib/hpo-organ-map.js +63 -0
- package/dist/workflows/target-assessment/lib/impc-organ-map.d.ts +19 -0
- package/dist/workflows/target-assessment/lib/impc-organ-map.js +39 -0
- package/dist/workflows/target-assessment/lib/meddra-organ-map.d.ts +24 -14
- package/dist/workflows/target-assessment/lib/meddra-organ-map.js +59 -47
- package/dist/workflows/target-assessment/lib/recommendation-sanitizer.js +1 -1
- package/dist/workflows/target-assessment/lib/regulatory-actions.d.ts +2 -3
- package/dist/workflows/target-assessment/lib/regulatory-actions.js +33 -4
- package/dist/workflows/target-assessment/lib/safety-corroboration.d.ts +44 -0
- package/dist/workflows/target-assessment/lib/safety-corroboration.js +273 -0
- package/dist/workflows/target-assessment/lib/target-identity-filter.d.ts +5 -7
- package/dist/workflows/target-assessment/lib/target-identity-filter.js +5 -7
- package/dist/workflows/target-assessment/metrics.d.ts +1 -6
- package/dist/workflows/target-assessment/metrics.js +1 -13
- package/dist/workflows/target-assessment/phase4-assemble.d.ts +2147 -807
- package/dist/workflows/target-assessment/phase4-assemble.js +19 -19
- package/dist/workflows/target-assessment/phase5-persist.d.ts +20 -21
- package/dist/workflows/target-assessment/phase5-persist.js +56 -173
- package/dist/workflows/target-assessment/schemas.d.ts +46 -1
- package/dist/workflows/target-assessment/schemas.js +19 -0
- package/dist/workflows/target-assessment/steps/fanout/polypharm-for-one-modulator-step.d.ts +1 -0
- package/dist/workflows/target-assessment/steps/fanout/polypharm-for-one-modulator-step.js +2 -0
- package/dist/workflows/target-assessment/steps/phase2-aggregate.d.ts +26 -62
- package/dist/workflows/target-assessment/steps/phase2-aggregate.js +0 -4
- package/dist/workflows/target-assessment/steps/phase3-aggregate.d.ts +27 -154
- package/dist/workflows/target-assessment/steps/phase3-aggregate.js +0 -6
- package/dist/workflows/target-assessment/steps/synthesis/diagnostics.d.ts +0 -6
- package/dist/workflows/target-assessment/steps/synthesis/diagnostics.js +0 -18
- package/dist/workflows/target-assessment/sub-workflows/per-modulator-polypharm.d.ts +1 -0
- package/dist/workflows/target-assessment/synthesis/index.d.ts +52 -5
- package/dist/workflows/target-assessment/synthesis/index.js +4 -1
- package/dist/workflows/target-assessment/synthesis-probes.d.ts +3 -3
- package/package.json +4 -1
|
@@ -27,6 +27,7 @@ import { searchFailedTrials, searchTrialsForTarget } from "../../../tools/lib/cl
|
|
|
27
27
|
import { filterInformative, searchClinvar } from "../../../tools/lib/clinvar-client.js";
|
|
28
28
|
import { getKoPhenotypeProfile } from "../../../tools/lib/impc-client.js";
|
|
29
29
|
import { getFamilyHeterodimers } from "../../../tools/lib/iuphar-client.js";
|
|
30
|
+
import { getGenePhenotypeProfile } from "../../../tools/lib/monarch-client.js";
|
|
30
31
|
import { getFaersByDrug, getFaersSeriousness } from "../../../tools/lib/openfda-client.js";
|
|
31
32
|
import { getBaselineExpression, getTargetSafetyLiabilities, searchTargetAssociations } from "../../../tools/lib/opentargets-client.js";
|
|
32
33
|
import { getPathwayMemberships } from "../../../tools/lib/pathway-client.js";
|
|
@@ -316,7 +317,48 @@ export async function collectImpc(input) {
|
|
|
316
317
|
return fail(err);
|
|
317
318
|
}
|
|
318
319
|
}
|
|
319
|
-
// ── 10.
|
|
320
|
+
// ── 10. Monarch Initiative ───────────────────────────────────────────
|
|
321
|
+
export async function collectMonarch(input) {
|
|
322
|
+
// Monarch resolves prefixed identifiers; HGNC is its native gene namespace
|
|
323
|
+
// and NCBI Gene is the fallback it also indexes.
|
|
324
|
+
const geneCurie = input.ids.hgnc ?? (input.ids.entrez ? `NCBIGene:${input.ids.entrez}` : null);
|
|
325
|
+
if (!geneCurie) {
|
|
326
|
+
return {
|
|
327
|
+
coverage: "not_loaded",
|
|
328
|
+
reason: "no HGNC or NCBI Gene id resolved",
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
try {
|
|
332
|
+
const profile = await withHost("monarch", () => getGenePhenotypeProfile(geneCurie));
|
|
333
|
+
if (profile.phenotypes.length === 0) {
|
|
334
|
+
return {
|
|
335
|
+
coverage: "queried_no_data",
|
|
336
|
+
error: {
|
|
337
|
+
message: `Monarch holds no human phenotype associations for ${geneCurie}`,
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
coverage: "available",
|
|
343
|
+
data: {
|
|
344
|
+
geneCurie: profile.geneCurie,
|
|
345
|
+
phenotypes: profile.phenotypes.map((p) => ({
|
|
346
|
+
hpoId: p.hpoId,
|
|
347
|
+
label: p.label,
|
|
348
|
+
ancestorIds: p.ancestorIds,
|
|
349
|
+
publications: p.publications,
|
|
350
|
+
diseaseContext: p.diseaseContext,
|
|
351
|
+
frequencyPercent: p.frequencyPercent,
|
|
352
|
+
primaryKnowledgeSource: p.primaryKnowledgeSource,
|
|
353
|
+
})),
|
|
354
|
+
},
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
catch (err) {
|
|
358
|
+
return fail(err);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
// ── 11. Open Targets ─────────────────────────────────────────────────
|
|
320
362
|
export async function collectOpenTargets(input) {
|
|
321
363
|
const ensemblId = input.ids.ensembl;
|
|
322
364
|
if (!ensemblId) {
|
|
@@ -351,7 +393,7 @@ export async function collectOpenTargets(input) {
|
|
|
351
393
|
return fail(err);
|
|
352
394
|
}
|
|
353
395
|
}
|
|
354
|
-
// ──
|
|
396
|
+
// ── 12. Pathways (Reactome + KEGG via the unified client) ────────────
|
|
355
397
|
export async function collectPathways(input) {
|
|
356
398
|
try {
|
|
357
399
|
const raw = await withHost("reactome", () => getPathwayMemberships(input.geneSymbol));
|
|
@@ -380,7 +422,7 @@ export async function collectPathways(input) {
|
|
|
380
422
|
return fail(err);
|
|
381
423
|
}
|
|
382
424
|
}
|
|
383
|
-
// ──
|
|
425
|
+
// ── 13. PubMed index ─────────────────────────────────────────────────
|
|
384
426
|
export async function collectPubmedIndex(input, ctx) {
|
|
385
427
|
const query = `"${input.geneSymbol}"[Gene]`;
|
|
386
428
|
try {
|
|
@@ -407,7 +449,7 @@ export async function collectPubmedIndex(input, ctx) {
|
|
|
407
449
|
return fail(err);
|
|
408
450
|
}
|
|
409
451
|
}
|
|
410
|
-
// ──
|
|
452
|
+
// ── 14. STRING PPI ───────────────────────────────────────────────────
|
|
411
453
|
export async function collectStringPpi(input) {
|
|
412
454
|
try {
|
|
413
455
|
const partners = await withHost("string", () => getInteractionPartners([input.geneSymbol], {
|
|
@@ -429,7 +471,7 @@ export async function collectStringPpi(input) {
|
|
|
429
471
|
return fail(err);
|
|
430
472
|
}
|
|
431
473
|
}
|
|
432
|
-
// ──
|
|
474
|
+
// ── 15. Therapeutic programs (non-ChEMBL curated set) ────────────────
|
|
433
475
|
export async function collectTherapeuticPrograms(input) {
|
|
434
476
|
const programs = findTherapeuticProgramsForTarget({
|
|
435
477
|
geneSymbol: input.geneSymbol,
|
|
@@ -460,6 +502,7 @@ export const COLLECTOR_MANIFEST = [
|
|
|
460
502
|
{ id: "faers-by-target", run: collectFaersByTarget },
|
|
461
503
|
{ id: "family-complexes", run: collectFamilyComplexes },
|
|
462
504
|
{ id: "impc", run: collectImpc },
|
|
505
|
+
{ id: "monarch", run: collectMonarch },
|
|
463
506
|
{ id: "opentargets", run: collectOpenTargets },
|
|
464
507
|
{ id: "pathways", run: collectPathways },
|
|
465
508
|
{ id: "pubmed-index", run: collectPubmedIndex },
|
|
@@ -6,29 +6,19 @@
|
|
|
6
6
|
* instead of throwing. Only Phase 0 (target resolution) is allowed to
|
|
7
7
|
* throw — that legitimately aborts the workflow.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* - "not_loaded" — the upstream was never queried (feature flag,
|
|
15
|
-
* config disable, or upstream skipped because a
|
|
16
|
-
* precondition was not met).
|
|
9
|
+
* `CoverageSchema` in `contracts/target-dossier.ts` is the one enumeration of
|
|
10
|
+
* the coverage states, and the helpers below emit its members. A step envelope
|
|
11
|
+
* carries the three states a step can reach on its own; `filtered` is a
|
|
12
|
+
* judgement one of our own filters makes, so only the assembler helpers below
|
|
13
|
+
* produce it.
|
|
17
14
|
*/
|
|
18
15
|
import { z } from "zod";
|
|
19
|
-
export declare const CoverageSchema: z.ZodEnum<{
|
|
20
|
-
available: "available";
|
|
21
|
-
queried_no_data: "queried_no_data";
|
|
22
|
-
not_loaded: "not_loaded";
|
|
23
|
-
}>;
|
|
24
|
-
export type Coverage = z.infer<typeof CoverageSchema>;
|
|
25
16
|
export declare const SerializedErrorSchema: z.ZodObject<{
|
|
26
17
|
message: z.ZodString;
|
|
27
18
|
name: z.ZodOptional<z.ZodString>;
|
|
28
19
|
stack: z.ZodOptional<z.ZodString>;
|
|
29
20
|
}, z.core.$strip>;
|
|
30
21
|
export type SerializedError = z.infer<typeof SerializedErrorSchema>;
|
|
31
|
-
export declare function serializeError(err: unknown): SerializedError;
|
|
32
22
|
/**
|
|
33
23
|
* Build the schema for a `{ coverage, data, error? }` step output.
|
|
34
24
|
*
|
|
@@ -49,18 +39,6 @@ export declare function withCoverage<TData extends z.ZodTypeAny>(dataSchema: TDa
|
|
|
49
39
|
coverage: z.ZodLiteral<"not_loaded">;
|
|
50
40
|
reason: z.ZodOptional<z.ZodString>;
|
|
51
41
|
}, z.core.$strip>], "coverage">;
|
|
52
|
-
/**
|
|
53
|
-
* Run a step body with the standard try/catch envelope. If the body
|
|
54
|
-
* resolves, returns `{ coverage: "available", data }`. If it throws,
|
|
55
|
-
* returns `{ coverage: "queried_no_data", error: serializeError(err) }`.
|
|
56
|
-
*/
|
|
57
|
-
export declare function runWithCoverage<T>(body: () => Promise<T>): Promise<{
|
|
58
|
-
coverage: "available";
|
|
59
|
-
data: T;
|
|
60
|
-
} | {
|
|
61
|
-
coverage: "queried_no_data";
|
|
62
|
-
error: SerializedError;
|
|
63
|
-
}>;
|
|
64
42
|
/**
|
|
65
43
|
* Convenience wrapper for `{ rows: T[] }` payloads. Maps an empty rows
|
|
66
44
|
* array to `coverage: "queried_no_data"` so the dossier discriminator's
|
|
@@ -79,3 +57,41 @@ export declare function coverageFromRows<T>(rows: T[], opts?: {
|
|
|
79
57
|
coverage: "queried_no_data";
|
|
80
58
|
error: SerializedError;
|
|
81
59
|
};
|
|
60
|
+
/**
|
|
61
|
+
* Build a dossier-section envelope for a row list one of our own filters
|
|
62
|
+
* narrowed.
|
|
63
|
+
*
|
|
64
|
+
* A filter is not the same as an empty upstream, and the difference is the
|
|
65
|
+
* whole point of the four-state contract. Deciding coverage from the source
|
|
66
|
+
* and then filtering the payload loses it: a section whose every row our
|
|
67
|
+
* threshold discarded reports a clean `available` holding nothing, which reads
|
|
68
|
+
* as "the source had nothing to say".
|
|
69
|
+
*
|
|
70
|
+
* So the decision is made once, from both counts:
|
|
71
|
+
* - nothing survived and something was dropped → `filtered`, naming the
|
|
72
|
+
* filter and the count it discarded, with no `data`;
|
|
73
|
+
* - some survived and some were dropped → `available` carrying
|
|
74
|
+
* `dropped_count`, so the section does not overstate its completeness;
|
|
75
|
+
* - nothing survived and nothing was dropped → `queried_no_data`: the list
|
|
76
|
+
* was empty before any filter of ours ran.
|
|
77
|
+
*/
|
|
78
|
+
export declare function coverageFromFilteredRows<TData>(args: {
|
|
79
|
+
data: TData;
|
|
80
|
+
retainedCount: number;
|
|
81
|
+
droppedCount: number;
|
|
82
|
+
/** What ran, in a reader's terms — carried verbatim on the `filtered` branch. */
|
|
83
|
+
filter: string;
|
|
84
|
+
/** Why the source itself held nothing, used only when no filter dropped anything. */
|
|
85
|
+
emptyReason: string;
|
|
86
|
+
}): {
|
|
87
|
+
coverage: "available";
|
|
88
|
+
data: TData;
|
|
89
|
+
dropped_count?: number;
|
|
90
|
+
} | {
|
|
91
|
+
coverage: "filtered";
|
|
92
|
+
filter: string;
|
|
93
|
+
dropped_count: number;
|
|
94
|
+
} | {
|
|
95
|
+
coverage: "queried_no_data";
|
|
96
|
+
error: SerializedError;
|
|
97
|
+
};
|
|
@@ -6,28 +6,18 @@
|
|
|
6
6
|
* instead of throwing. Only Phase 0 (target resolution) is allowed to
|
|
7
7
|
* throw — that legitimately aborts the workflow.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* - "not_loaded" — the upstream was never queried (feature flag,
|
|
15
|
-
* config disable, or upstream skipped because a
|
|
16
|
-
* precondition was not met).
|
|
9
|
+
* `CoverageSchema` in `contracts/target-dossier.ts` is the one enumeration of
|
|
10
|
+
* the coverage states, and the helpers below emit its members. A step envelope
|
|
11
|
+
* carries the three states a step can reach on its own; `filtered` is a
|
|
12
|
+
* judgement one of our own filters makes, so only the assembler helpers below
|
|
13
|
+
* produce it.
|
|
17
14
|
*/
|
|
18
15
|
import { z } from "zod";
|
|
19
|
-
export const CoverageSchema = z.enum(["available", "queried_no_data", "not_loaded"]);
|
|
20
16
|
export const SerializedErrorSchema = z.object({
|
|
21
17
|
message: z.string(),
|
|
22
18
|
name: z.string().optional(),
|
|
23
19
|
stack: z.string().optional(),
|
|
24
20
|
});
|
|
25
|
-
export function serializeError(err) {
|
|
26
|
-
if (err instanceof Error) {
|
|
27
|
-
return { message: err.message, name: err.name, stack: err.stack };
|
|
28
|
-
}
|
|
29
|
-
return { message: String(err) };
|
|
30
|
-
}
|
|
31
21
|
/**
|
|
32
22
|
* Build the schema for a `{ coverage, data, error? }` step output.
|
|
33
23
|
*
|
|
@@ -50,20 +40,6 @@ export function withCoverage(dataSchema) {
|
|
|
50
40
|
}),
|
|
51
41
|
]);
|
|
52
42
|
}
|
|
53
|
-
/**
|
|
54
|
-
* Run a step body with the standard try/catch envelope. If the body
|
|
55
|
-
* resolves, returns `{ coverage: "available", data }`. If it throws,
|
|
56
|
-
* returns `{ coverage: "queried_no_data", error: serializeError(err) }`.
|
|
57
|
-
*/
|
|
58
|
-
export async function runWithCoverage(body) {
|
|
59
|
-
try {
|
|
60
|
-
const data = await body();
|
|
61
|
-
return { coverage: "available", data };
|
|
62
|
-
}
|
|
63
|
-
catch (err) {
|
|
64
|
-
return { coverage: "queried_no_data", error: serializeError(err) };
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
43
|
/**
|
|
68
44
|
* Convenience wrapper for `{ rows: T[] }` payloads. Maps an empty rows
|
|
69
45
|
* array to `coverage: "queried_no_data"` so the dossier discriminator's
|
|
@@ -80,3 +56,31 @@ export function coverageFromRows(rows, opts) {
|
|
|
80
56
|
}
|
|
81
57
|
return { coverage: "available", data: { rows } };
|
|
82
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Build a dossier-section envelope for a row list one of our own filters
|
|
61
|
+
* narrowed.
|
|
62
|
+
*
|
|
63
|
+
* A filter is not the same as an empty upstream, and the difference is the
|
|
64
|
+
* whole point of the four-state contract. Deciding coverage from the source
|
|
65
|
+
* and then filtering the payload loses it: a section whose every row our
|
|
66
|
+
* threshold discarded reports a clean `available` holding nothing, which reads
|
|
67
|
+
* as "the source had nothing to say".
|
|
68
|
+
*
|
|
69
|
+
* So the decision is made once, from both counts:
|
|
70
|
+
* - nothing survived and something was dropped → `filtered`, naming the
|
|
71
|
+
* filter and the count it discarded, with no `data`;
|
|
72
|
+
* - some survived and some were dropped → `available` carrying
|
|
73
|
+
* `dropped_count`, so the section does not overstate its completeness;
|
|
74
|
+
* - nothing survived and nothing was dropped → `queried_no_data`: the list
|
|
75
|
+
* was empty before any filter of ours ran.
|
|
76
|
+
*/
|
|
77
|
+
export function coverageFromFilteredRows(args) {
|
|
78
|
+
const { data, retainedCount, droppedCount, filter, emptyReason } = args;
|
|
79
|
+
if (retainedCount > 0) {
|
|
80
|
+
return droppedCount > 0 ? { coverage: "available", data, dropped_count: droppedCount } : { coverage: "available", data };
|
|
81
|
+
}
|
|
82
|
+
if (droppedCount > 0) {
|
|
83
|
+
return { coverage: "filtered", filter, dropped_count: droppedCount };
|
|
84
|
+
}
|
|
85
|
+
return { coverage: "queried_no_data", error: { message: emptyReason } };
|
|
86
|
+
}
|
|
@@ -85,6 +85,7 @@ export async function polypharmForOneModulator(item) {
|
|
|
85
85
|
hits: hits.map((h) => ({
|
|
86
86
|
targetChemblId: h.targetChemblId,
|
|
87
87
|
targetName: h.targetName,
|
|
88
|
+
assayChemblId: h.assayChemblId,
|
|
88
89
|
pchemblValue: h.pchemblValue,
|
|
89
90
|
standardType: h.standardType,
|
|
90
91
|
standardValue: h.standardValue,
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The claim-investigation phase.
|
|
3
|
+
*
|
|
4
|
+
* Corroboration says which organs several sources agree on. Agreement is not
|
|
5
|
+
* adjudication: sources that all re-import one curation agree perfectly and are
|
|
6
|
+
* wrong together. This phase interrogates each corroborated organ claim —
|
|
7
|
+
* propose a mechanism, argue against it, re-verify, converge — and records what
|
|
8
|
+
* survived, plus every candidate it did not get to and why.
|
|
9
|
+
*
|
|
10
|
+
* Three LLM steps per round, chosen per step rather than uniformly:
|
|
11
|
+
*
|
|
12
|
+
* - **propose** and **re-verify** are single-shot structured extractions
|
|
13
|
+
* (`structuredLlmCall`). Everything they reason over is already in the
|
|
14
|
+
* prompt; a retrieval surface would only let them ground an answer in
|
|
15
|
+
* something the run never collected.
|
|
16
|
+
* - **critique** is a real agent loop (`runToTerminal` over `runAgent`) with a
|
|
17
|
+
* literature tool and a `defineTool` terminal recorder. Disconfirmation is a
|
|
18
|
+
* search task: the dossier is assembled to state what the run found, not to
|
|
19
|
+
* refute it, so a critic confined to it can only observe that the evidence
|
|
20
|
+
* is thin — which is the rubber stamp this step exists to avoid.
|
|
21
|
+
*
|
|
22
|
+
* Nothing here scores a claim. The verdict is a four-word vocabulary the model
|
|
23
|
+
* states, no threshold decides survival, and no claim is removed from the
|
|
24
|
+
* dossier by anything this phase concludes.
|
|
25
|
+
*
|
|
26
|
+
* Durability arrives through the injected `runStep` seam and through
|
|
27
|
+
* `structuredLlmCall`'s own attempt-named steps; this module imports no
|
|
28
|
+
* durability engine.
|
|
29
|
+
*/
|
|
30
|
+
import type { ClaimInvestigation, DossierBody, SafetyCorroboration } from "@inflexa-ai/harness/contracts/target-dossier.js";
|
|
31
|
+
import type { AgentSession } from "../../../auth/types.js";
|
|
32
|
+
import type { UsageRecorder } from "../../../billing/usage-recorder.js";
|
|
33
|
+
import type { Logger } from "../../../lib/logger.js";
|
|
34
|
+
import type { RunStep } from "../../../loop/types.js";
|
|
35
|
+
import type { AgentChat } from "../../../providers/types.js";
|
|
36
|
+
import { type Tool } from "../../../tools/define-tool.js";
|
|
37
|
+
import { BUDGET_EXCEEDED_SENTINEL } from "../lib/llm-step.js";
|
|
38
|
+
/**
|
|
39
|
+
* The bounds the phase runs under.
|
|
40
|
+
*
|
|
41
|
+
* These are configuration with stated defaults, not clinical constants: nothing
|
|
42
|
+
* about biology says six claims or two rounds. They exist to bound cost and to
|
|
43
|
+
* guarantee termination, the section reports the values in force, and an
|
|
44
|
+
* embedder that wants a deeper pass sets its own.
|
|
45
|
+
*/
|
|
46
|
+
export interface ClaimInvestigationConfig {
|
|
47
|
+
/** Corroborated organ claims investigated per run; the rest are reported as budget-cut. */
|
|
48
|
+
readonly claimBudget: number;
|
|
49
|
+
/** Propose → critique → re-verify rounds a single claim may run. */
|
|
50
|
+
readonly roundBound: number;
|
|
51
|
+
/** Iteration budget for the adversarial critic's tool-using loop. */
|
|
52
|
+
readonly criticMaxIterations: number;
|
|
53
|
+
}
|
|
54
|
+
export declare const DEFAULT_CLAIM_INVESTIGATION_CONFIG: ClaimInvestigationConfig;
|
|
55
|
+
export interface ClaimInvestigationDeps {
|
|
56
|
+
/** Operational logging seam; omitted falls back to no-op. */
|
|
57
|
+
readonly logger?: Logger;
|
|
58
|
+
readonly chatProvider: AgentChat;
|
|
59
|
+
/** Session for the phase; each step derives its own sub-agent session from it. */
|
|
60
|
+
readonly session: AgentSession;
|
|
61
|
+
readonly model: string;
|
|
62
|
+
/** Attempt counter — bumped on resume so a cancelled call lands a fresh durable slot. */
|
|
63
|
+
readonly attempt: number;
|
|
64
|
+
/** Durability seam for the critic's agent loop. */
|
|
65
|
+
readonly runStep: RunStep;
|
|
66
|
+
/** Retrieval surface the adversarial critic searches for disconfirming records. */
|
|
67
|
+
readonly critiqueTools: readonly Tool[];
|
|
68
|
+
/** Overrides for {@link DEFAULT_CLAIM_INVESTIGATION_CONFIG}. */
|
|
69
|
+
readonly config?: Partial<ClaimInvestigationConfig>;
|
|
70
|
+
/** LLM usage-accounting seam for the critic loop; omitted falls back to the no-op recorder. */
|
|
71
|
+
readonly usageRecorder?: UsageRecorder;
|
|
72
|
+
readonly signal?: AbortSignal;
|
|
73
|
+
}
|
|
74
|
+
export interface ClaimInvestigationInput {
|
|
75
|
+
/** The run's corroboration record — the source of candidate claims. */
|
|
76
|
+
readonly corroboration: SafetyCorroboration;
|
|
77
|
+
/** The assembled dossier body, read for per-organ risk context and completeness. */
|
|
78
|
+
readonly dossier: DossierBody;
|
|
79
|
+
}
|
|
80
|
+
/** The sentinel an LLM step returns once it has self-cancelled the workflow on a 402. */
|
|
81
|
+
export interface BudgetExceeded {
|
|
82
|
+
readonly kind: "budget-exceeded";
|
|
83
|
+
readonly sentinel: typeof BUDGET_EXCEEDED_SENTINEL;
|
|
84
|
+
}
|
|
85
|
+
export type ClaimInvestigationResult = ClaimInvestigation | BudgetExceeded;
|
|
86
|
+
declare function isBudgetCancel<T>(value: T | BudgetExceeded): value is BudgetExceeded;
|
|
87
|
+
/**
|
|
88
|
+
* Interrogate the run's corroborated organ claims.
|
|
89
|
+
*
|
|
90
|
+
* Coverage is the honest account of what happened: `not_loaded` when there was
|
|
91
|
+
* no corroboration record to work from, `queried_no_data` when the fold produced
|
|
92
|
+
* no corroborated organ, and `available` once at least one candidate reached the
|
|
93
|
+
* phase — including when every one of them ended up in `not_investigated`, since
|
|
94
|
+
* that list is what the section has to say in that case.
|
|
95
|
+
*/
|
|
96
|
+
export declare function investigateClaims(input: ClaimInvestigationInput, deps: ClaimInvestigationDeps): Promise<ClaimInvestigationResult>;
|
|
97
|
+
export { isBudgetCancel as isClaimInvestigationBudgetExceeded };
|