@inflexa-ai/harness 0.35.8 → 0.36.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.
- package/dist/auth/types.d.ts +5 -14
- package/dist/auth/types.js +3 -10
- package/dist/billing/usage-recorder.d.ts +1 -1
- package/dist/contracts/analogy-report.d.ts +1 -1
- package/dist/contracts/analogy-report.js +1 -1
- package/dist/contracts/chat-parts.d.ts +2 -3
- package/dist/contracts/index.d.ts +0 -4
- package/dist/contracts/index.js +0 -2
- package/dist/index.d.ts +0 -7
- package/dist/index.js +0 -21
- package/dist/lib/metrics.d.ts +1 -1
- package/dist/lib/otel-spans.d.ts +0 -2
- package/dist/lib/otel-spans.js +0 -2
- package/dist/loop/genai-spans.d.ts +14 -0
- package/dist/loop/genai-spans.js +35 -0
- package/dist/loop/run-agent.d.ts +1 -1
- package/dist/loop/run-agent.js +37 -4
- package/dist/runtime/assemble.d.ts +0 -3
- package/dist/runtime/assemble.js +0 -3
- package/dist/state/index.d.ts +0 -2
- package/dist/state/index.js +0 -1
- package/dist/state/init.js +1 -60
- package/dist/state/purge-analysis.d.ts +1 -2
- package/dist/state/purge-analysis.js +1 -2
- package/dist/tasks/regulatory-corpus-boot-refresh.js +1 -1
- package/dist/tools/bio/gene-preclinical-profile.d.ts +1 -3
- package/dist/tools/bio/gene-preclinical-profile.js +1 -3
- package/dist/tools/lib/chembl-client.d.ts +1 -4
- package/dist/tools/lib/chembl-client.js +1 -4
- package/dist/tools/lib/clinical-benchmarks-client.d.ts +1 -1
- package/dist/tools/lib/clinical-benchmarks-client.js +1 -1
- package/dist/tools/lib/clinical-trials-client.d.ts +0 -3
- package/dist/tools/lib/clinical-trials-client.js +0 -3
- package/dist/tools/lib/identifier-resolver.d.ts +5 -7
- package/dist/tools/lib/identifier-resolver.js +5 -7
- package/dist/tools/lib/iuphar-client.d.ts +1 -3
- package/dist/tools/lib/iuphar-client.js +1 -3
- package/dist/tools/lib/opentargets-client.d.ts +1 -1
- package/dist/tools/lib/opentargets-client.js +1 -1
- package/dist/tools/lib/protein-family-normalize.d.ts +5 -7
- package/dist/tools/lib/protein-family-normalize.js +5 -7
- package/dist/tools/lib/uniprot-client.d.ts +0 -7
- package/dist/tools/lib/uniprot-client.js +2 -9
- package/package.json +1 -1
- package/dist/contracts/target-assessment-row.d.ts +0 -85
- package/dist/contracts/target-assessment-row.js +0 -37
- package/dist/contracts/target-dossier.d.ts +0 -12423
- package/dist/contracts/target-dossier.js +0 -1282
- package/dist/prompts/target-assessment/briefs/executive-recommendation.d.ts +0 -1
- package/dist/prompts/target-assessment/briefs/executive-recommendation.js +0 -85
- package/dist/prompts/target-assessment/briefs/index.d.ts +0 -4
- package/dist/prompts/target-assessment/briefs/index.js +0 -4
- package/dist/prompts/target-assessment/briefs/liability-bullets.d.ts +0 -1
- package/dist/prompts/target-assessment/briefs/liability-bullets.js +0 -114
- package/dist/prompts/target-assessment/briefs/target-organ-liabilities.d.ts +0 -1
- package/dist/prompts/target-assessment/briefs/target-organ-liabilities.js +0 -37
- package/dist/prompts/target-assessment/briefs/translational-commentary.d.ts +0 -1
- package/dist/prompts/target-assessment/briefs/translational-commentary.js +0 -23
- package/dist/prompts/target-assessment/drugs-in-class.d.ts +0 -1
- package/dist/prompts/target-assessment/drugs-in-class.js +0 -29
- package/dist/prompts/target-assessment/investigation/adversarial-critique.d.ts +0 -1
- package/dist/prompts/target-assessment/investigation/adversarial-critique.js +0 -67
- package/dist/prompts/target-assessment/investigation/claim-reverification.d.ts +0 -1
- package/dist/prompts/target-assessment/investigation/claim-reverification.js +0 -49
- package/dist/prompts/target-assessment/investigation/index.d.ts +0 -3
- package/dist/prompts/target-assessment/investigation/index.js +0 -3
- package/dist/prompts/target-assessment/investigation/mechanism-proposal.d.ts +0 -1
- package/dist/prompts/target-assessment/investigation/mechanism-proposal.js +0 -49
- package/dist/prompts/target-assessment/modulator-triage.d.ts +0 -1
- package/dist/prompts/target-assessment/modulator-triage.js +0 -31
- package/dist/prompts/target-assessment/off-target-annotator.d.ts +0 -1
- package/dist/prompts/target-assessment/off-target-annotator.js +0 -28
- package/dist/prompts/target-assessment/tox-voice/core.d.ts +0 -1
- package/dist/prompts/target-assessment/tox-voice/core.js +0 -74
- package/dist/prompts/target-assessment/tox-voice/critique.d.ts +0 -7
- package/dist/prompts/target-assessment/tox-voice/critique.js +0 -109
- package/dist/prompts/target-assessment/tox-voice/exemplars.d.ts +0 -8
- package/dist/prompts/target-assessment/tox-voice/exemplars.js +0 -24
- package/dist/prompts/target-assessment/tox-voice/index.d.ts +0 -4
- package/dist/prompts/target-assessment/tox-voice/index.js +0 -4
- package/dist/prompts/target-assessment/tox-voice/vocabulary.d.ts +0 -18
- package/dist/prompts/target-assessment/tox-voice/vocabulary.js +0 -61
- package/dist/state/target-assessments.d.ts +0 -68
- package/dist/state/target-assessments.js +0 -222
- package/dist/workflows/execute-target-assessment.d.ts +0 -118
- package/dist/workflows/execute-target-assessment.js +0 -631
- package/dist/workflows/target-assessment/assemblers/index.d.ts +0 -5
- package/dist/workflows/target-assessment/assemblers/index.js +0 -4
- package/dist/workflows/target-assessment/assemblers/literature.d.ts +0 -281
- package/dist/workflows/target-assessment/assemblers/literature.js +0 -971
- package/dist/workflows/target-assessment/assemblers/orchestrator.d.ts +0 -118
- package/dist/workflows/target-assessment/assemblers/orchestrator.js +0 -945
- package/dist/workflows/target-assessment/assemblers/safety.d.ts +0 -374
- package/dist/workflows/target-assessment/assemblers/safety.js +0 -1068
- package/dist/workflows/target-assessment/assemblers/trials.d.ts +0 -30
- package/dist/workflows/target-assessment/assemblers/trials.js +0 -75
- package/dist/workflows/target-assessment/collectors/index.d.ts +0 -114
- package/dist/workflows/target-assessment/collectors/index.js +0 -538
- package/dist/workflows/target-assessment/coverage.d.ts +0 -97
- package/dist/workflows/target-assessment/coverage.js +0 -86
- package/dist/workflows/target-assessment/decisions/index.d.ts +0 -86
- package/dist/workflows/target-assessment/decisions/index.js +0 -127
- package/dist/workflows/target-assessment/fanout/index.d.ts +0 -32
- package/dist/workflows/target-assessment/fanout/index.js +0 -156
- package/dist/workflows/target-assessment/investigation/index.d.ts +0 -97
- package/dist/workflows/target-assessment/investigation/index.js +0 -419
- package/dist/workflows/target-assessment/lib/approval-precedents.d.ts +0 -73
- package/dist/workflows/target-assessment/lib/approval-precedents.js +0 -185
- package/dist/workflows/target-assessment/lib/citation-validator.d.ts +0 -46
- package/dist/workflows/target-assessment/lib/citation-validator.js +0 -316
- package/dist/workflows/target-assessment/lib/clinical-consequence-annotator.d.ts +0 -65
- package/dist/workflows/target-assessment/lib/clinical-consequence-annotator.js +0 -174
- package/dist/workflows/target-assessment/lib/clinical-evidence-attribution.d.ts +0 -44
- package/dist/workflows/target-assessment/lib/clinical-evidence-attribution.js +0 -152
- package/dist/workflows/target-assessment/lib/compute-derived.d.ts +0 -20
- package/dist/workflows/target-assessment/lib/compute-derived.js +0 -261
- package/dist/workflows/target-assessment/lib/compute-selectivity.d.ts +0 -15
- package/dist/workflows/target-assessment/lib/compute-selectivity.js +0 -18
- package/dist/workflows/target-assessment/lib/dedup-modulators.d.ts +0 -37
- package/dist/workflows/target-assessment/lib/dedup-modulators.js +0 -157
- package/dist/workflows/target-assessment/lib/evidence-conflict-detector.d.ts +0 -17
- package/dist/workflows/target-assessment/lib/evidence-conflict-detector.js +0 -100
- package/dist/workflows/target-assessment/lib/expression-constants.d.ts +0 -21
- package/dist/workflows/target-assessment/lib/expression-constants.js +0 -21
- package/dist/workflows/target-assessment/lib/family-complex-supplement.d.ts +0 -20
- package/dist/workflows/target-assessment/lib/family-complex-supplement.js +0 -36
- package/dist/workflows/target-assessment/lib/fda-label-safety.d.ts +0 -72
- package/dist/workflows/target-assessment/lib/fda-label-safety.js +0 -166
- package/dist/workflows/target-assessment/lib/heterodimer-filter.d.ts +0 -30
- package/dist/workflows/target-assessment/lib/heterodimer-filter.js +0 -44
- package/dist/workflows/target-assessment/lib/hpo-organ-map.d.ts +0 -34
- package/dist/workflows/target-assessment/lib/hpo-organ-map.js +0 -63
- package/dist/workflows/target-assessment/lib/impc-organ-map.d.ts +0 -19
- package/dist/workflows/target-assessment/lib/impc-organ-map.js +0 -39
- package/dist/workflows/target-assessment/lib/intended-polypharm-filter.d.ts +0 -4
- package/dist/workflows/target-assessment/lib/intended-polypharm-filter.js +0 -24
- package/dist/workflows/target-assessment/lib/llm-step.d.ts +0 -80
- package/dist/workflows/target-assessment/lib/llm-step.js +0 -101
- package/dist/workflows/target-assessment/lib/meddra-organ-map.d.ts +0 -40
- package/dist/workflows/target-assessment/lib/meddra-organ-map.js +0 -138
- package/dist/workflows/target-assessment/lib/recommendation-quality-gates.d.ts +0 -17
- package/dist/workflows/target-assessment/lib/recommendation-quality-gates.js +0 -99
- package/dist/workflows/target-assessment/lib/recommendation-sanitizer.d.ts +0 -2
- package/dist/workflows/target-assessment/lib/recommendation-sanitizer.js +0 -51
- package/dist/workflows/target-assessment/lib/regulatory-actions.d.ts +0 -25
- package/dist/workflows/target-assessment/lib/regulatory-actions.js +0 -176
- package/dist/workflows/target-assessment/lib/safety-corroboration.d.ts +0 -44
- package/dist/workflows/target-assessment/lib/safety-corroboration.js +0 -273
- package/dist/workflows/target-assessment/lib/structured-llm.d.ts +0 -61
- package/dist/workflows/target-assessment/lib/structured-llm.js +0 -102
- package/dist/workflows/target-assessment/lib/target-identity-filter.d.ts +0 -59
- package/dist/workflows/target-assessment/lib/target-identity-filter.js +0 -95
- package/dist/workflows/target-assessment/lib/therapeutic-programs.d.ts +0 -20
- package/dist/workflows/target-assessment/lib/therapeutic-programs.js +0 -68
- package/dist/workflows/target-assessment/metrics.d.ts +0 -16
- package/dist/workflows/target-assessment/metrics.js +0 -30
- package/dist/workflows/target-assessment/phase4-assemble.d.ts +0 -3182
- package/dist/workflows/target-assessment/phase4-assemble.js +0 -39
- package/dist/workflows/target-assessment/phase5-persist.d.ts +0 -59
- package/dist/workflows/target-assessment/phase5-persist.js +0 -349
- package/dist/workflows/target-assessment/progress-stream.d.ts +0 -75
- package/dist/workflows/target-assessment/progress-stream.js +0 -110
- package/dist/workflows/target-assessment/progress.d.ts +0 -39
- package/dist/workflows/target-assessment/progress.js +0 -77
- package/dist/workflows/target-assessment/schemas.d.ts +0 -970
- package/dist/workflows/target-assessment/schemas.js +0 -318
- package/dist/workflows/target-assessment/steps/collectors/pathways.d.ts +0 -15
- package/dist/workflows/target-assessment/steps/collectors/pathways.js +0 -58
- package/dist/workflows/target-assessment/steps/fanout/aes-for-one-class-drug-step.d.ts +0 -34
- package/dist/workflows/target-assessment/steps/fanout/aes-for-one-class-drug-step.js +0 -31
- package/dist/workflows/target-assessment/steps/fanout/aes-for-one-trial-step.d.ts +0 -57
- package/dist/workflows/target-assessment/steps/fanout/aes-for-one-trial-step.js +0 -54
- package/dist/workflows/target-assessment/steps/fanout/faers-for-one-modulator-step.d.ts +0 -35
- package/dist/workflows/target-assessment/steps/fanout/faers-for-one-modulator-step.js +0 -32
- package/dist/workflows/target-assessment/steps/fanout/index.d.ts +0 -14
- package/dist/workflows/target-assessment/steps/fanout/index.js +0 -10
- package/dist/workflows/target-assessment/steps/fanout/polypharm-for-one-modulator-step.d.ts +0 -29
- package/dist/workflows/target-assessment/steps/fanout/polypharm-for-one-modulator-step.js +0 -29
- package/dist/workflows/target-assessment/steps/phase2-aggregate.d.ts +0 -657
- package/dist/workflows/target-assessment/steps/phase2-aggregate.js +0 -34
- package/dist/workflows/target-assessment/steps/phase3-aggregate.d.ts +0 -806
- package/dist/workflows/target-assessment/steps/phase3-aggregate.js +0 -16
- package/dist/workflows/target-assessment/steps/synthesis/diagnostics.d.ts +0 -28
- package/dist/workflows/target-assessment/steps/synthesis/diagnostics.js +0 -27
- package/dist/workflows/target-assessment/sub-workflows/index.d.ts +0 -15
- package/dist/workflows/target-assessment/sub-workflows/index.js +0 -11
- package/dist/workflows/target-assessment/sub-workflows/per-class-drug-aes.d.ts +0 -41
- package/dist/workflows/target-assessment/sub-workflows/per-class-drug-aes.js +0 -12
- package/dist/workflows/target-assessment/sub-workflows/per-modulator-faers.d.ts +0 -41
- package/dist/workflows/target-assessment/sub-workflows/per-modulator-faers.js +0 -12
- package/dist/workflows/target-assessment/sub-workflows/per-modulator-polypharm.d.ts +0 -37
- package/dist/workflows/target-assessment/sub-workflows/per-modulator-polypharm.js +0 -12
- package/dist/workflows/target-assessment/sub-workflows/per-trial-aes.d.ts +0 -66
- package/dist/workflows/target-assessment/sub-workflows/per-trial-aes.js +0 -12
- package/dist/workflows/target-assessment/synthesis/index.d.ts +0 -607
- package/dist/workflows/target-assessment/synthesis/index.js +0 -354
- package/dist/workflows/target-assessment/synthesis-probes.d.ts +0 -56
- package/dist/workflows/target-assessment/synthesis-probes.js +0 -320
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared coverage discriminator for target-assessment workflow steps.
|
|
3
|
-
*
|
|
4
|
-
* Per design §6, every collector / decision / fan-out / synthesis step
|
|
5
|
-
* MUST wrap its body in try/catch and return a `{ coverage, ... }` shape
|
|
6
|
-
* instead of throwing. Only Phase 0 (target resolution) is allowed to
|
|
7
|
-
* throw — that legitimately aborts the workflow.
|
|
8
|
-
*
|
|
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.
|
|
14
|
-
*/
|
|
15
|
-
import { z } from "zod";
|
|
16
|
-
export const SerializedErrorSchema = z.object({
|
|
17
|
-
message: z.string(),
|
|
18
|
-
name: z.string().optional(),
|
|
19
|
-
stack: z.string().optional(),
|
|
20
|
-
});
|
|
21
|
-
/**
|
|
22
|
-
* Build the schema for a `{ coverage, data, error? }` step output.
|
|
23
|
-
*
|
|
24
|
-
* Use as: `outputSchema: withCoverage(MyDataSchema)` where `MyDataSchema`
|
|
25
|
-
* is the shape of the Phase-1 / Phase-2 / etc. payload for this step.
|
|
26
|
-
*/
|
|
27
|
-
export function withCoverage(dataSchema) {
|
|
28
|
-
return z.discriminatedUnion("coverage", [
|
|
29
|
-
z.object({
|
|
30
|
-
coverage: z.literal("available"),
|
|
31
|
-
data: dataSchema,
|
|
32
|
-
}),
|
|
33
|
-
z.object({
|
|
34
|
-
coverage: z.literal("queried_no_data"),
|
|
35
|
-
error: SerializedErrorSchema.optional(),
|
|
36
|
-
}),
|
|
37
|
-
z.object({
|
|
38
|
-
coverage: z.literal("not_loaded"),
|
|
39
|
-
reason: z.string().optional(),
|
|
40
|
-
}),
|
|
41
|
-
]);
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Convenience wrapper for `{ rows: T[] }` payloads. Maps an empty rows
|
|
45
|
-
* array to `coverage: "queried_no_data"` so the dossier discriminator's
|
|
46
|
-
* "available ≡ we have data" invariant holds without per-callsite
|
|
47
|
-
* length checks. Use at any assembler callsite that emits a `rows`
|
|
48
|
-
* shape from a query that may legitimately return zero items.
|
|
49
|
-
*/
|
|
50
|
-
export function coverageFromRows(rows, opts) {
|
|
51
|
-
if (rows.length === 0) {
|
|
52
|
-
return {
|
|
53
|
-
coverage: "queried_no_data",
|
|
54
|
-
error: { message: opts?.reason ?? "no rows returned" },
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
return { coverage: "available", data: { rows } };
|
|
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
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phase-2 decision functions for the harness DBOS workflow.
|
|
3
|
-
*
|
|
4
|
-
* `modulatorTriage` selects up to 8 ChEMBL modulators for downstream
|
|
5
|
-
* fan-out; `drugsInClass` identifies clinically-advanced drugs in the
|
|
6
|
-
* class. Both are single-shot, structured-output LLM calls — no tools,
|
|
7
|
-
* no multi-step reasoning. Each function is `(input, deps) => Promise<CoverageEnvelope<...>>`.
|
|
8
|
-
*
|
|
9
|
-
* Coverage envelope is the failure mode: an LLM throw (non-402) → the
|
|
10
|
-
* function returns `coverage: "queried_no_data"`. A billing-gateway 402 reaches
|
|
11
|
-
* here as a `RunLlmStepResult` with `kind: "budget-exceeded"`; the caller
|
|
12
|
-
* stops scheduling because the workflow has self-cancelled.
|
|
13
|
-
*/
|
|
14
|
-
import { z } from "zod";
|
|
15
|
-
import type { AgentSession } from "../../../auth/types.js";
|
|
16
|
-
import type { AgentChat } from "../../../providers/types.js";
|
|
17
|
-
import type { Phase1Bundle } from "../schemas.js";
|
|
18
|
-
import { BUDGET_EXCEEDED_SENTINEL } from "../lib/llm-step.js";
|
|
19
|
-
export declare const ModulatorTriageOutputSchema: z.ZodObject<{
|
|
20
|
-
shortlist: z.ZodArray<z.ZodObject<{
|
|
21
|
-
moleculeChemblId: z.ZodString;
|
|
22
|
-
preferredName: z.ZodString;
|
|
23
|
-
maxPhase: z.ZodNullable<z.ZodNumber>;
|
|
24
|
-
firstApproval: z.ZodNullable<z.ZodNumber>;
|
|
25
|
-
rationale: z.ZodString;
|
|
26
|
-
}, z.core.$strip>>;
|
|
27
|
-
notes: z.ZodString;
|
|
28
|
-
dropped_synonyms: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
29
|
-
chemblId: z.ZodString;
|
|
30
|
-
reason: z.ZodEnum<{
|
|
31
|
-
same_active_substance: "same_active_substance";
|
|
32
|
-
ambiguous_name_synonym: "ambiguous_name_synonym";
|
|
33
|
-
}>;
|
|
34
|
-
keptId: z.ZodNullable<z.ZodString>;
|
|
35
|
-
}, z.core.$strip>>>;
|
|
36
|
-
}, z.core.$strip>;
|
|
37
|
-
export type ModulatorTriageOutput = z.infer<typeof ModulatorTriageOutputSchema>;
|
|
38
|
-
export declare const DrugsInClassOutputSchema: z.ZodObject<{
|
|
39
|
-
drugs: z.ZodArray<z.ZodObject<{
|
|
40
|
-
moleculeChemblId: z.ZodString;
|
|
41
|
-
preferredName: z.ZodString;
|
|
42
|
-
maxPhase: z.ZodNullable<z.ZodNumber>;
|
|
43
|
-
firstApproval: z.ZodNullable<z.ZodNumber>;
|
|
44
|
-
moleculeType: z.ZodNullable<z.ZodString>;
|
|
45
|
-
sources: z.ZodArray<z.ZodEnum<{
|
|
46
|
-
dgidb: "dgidb";
|
|
47
|
-
drugbank: "drugbank";
|
|
48
|
-
chembl: "chembl";
|
|
49
|
-
}>>;
|
|
50
|
-
}, z.core.$strip>>;
|
|
51
|
-
total: z.ZodNumber;
|
|
52
|
-
truncated: z.ZodBoolean;
|
|
53
|
-
}, z.core.$strip>;
|
|
54
|
-
export type DrugsInClassOutput = z.infer<typeof DrugsInClassOutputSchema>;
|
|
55
|
-
interface CoverageAvailable<T> {
|
|
56
|
-
readonly coverage: "available";
|
|
57
|
-
readonly data: T;
|
|
58
|
-
}
|
|
59
|
-
interface CoverageQueriedNoData {
|
|
60
|
-
readonly coverage: "queried_no_data";
|
|
61
|
-
readonly error?: {
|
|
62
|
-
message: string;
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
type CoverageEnvelope<T> = CoverageAvailable<T> | CoverageQueriedNoData;
|
|
66
|
-
export interface DecisionAgentDeps {
|
|
67
|
-
readonly chatProvider: AgentChat;
|
|
68
|
-
readonly session: AgentSession;
|
|
69
|
-
/** Billing-gateway model id — e.g. `env.TARGET_ASSESSMENT_DECISION_MODEL`. */
|
|
70
|
-
readonly model: string;
|
|
71
|
-
/** Attempt counter — bumped on resume so a 402-cancelled call lands a fresh DBOS step slot. */
|
|
72
|
-
readonly attempt: number;
|
|
73
|
-
}
|
|
74
|
-
export type ModulatorTriageResult = CoverageEnvelope<ModulatorTriageOutput & {
|
|
75
|
-
dropped_synonyms?: unknown;
|
|
76
|
-
}> | {
|
|
77
|
-
readonly kind: "budget-exceeded";
|
|
78
|
-
readonly sentinel: typeof BUDGET_EXCEEDED_SENTINEL;
|
|
79
|
-
};
|
|
80
|
-
export declare function modulatorTriage(input: Phase1Bundle, deps: DecisionAgentDeps): Promise<ModulatorTriageResult>;
|
|
81
|
-
export type DrugsInClassResult = CoverageEnvelope<DrugsInClassOutput> | {
|
|
82
|
-
readonly kind: "budget-exceeded";
|
|
83
|
-
readonly sentinel: typeof BUDGET_EXCEEDED_SENTINEL;
|
|
84
|
-
};
|
|
85
|
-
export declare function drugsInClass(input: Phase1Bundle, deps: DecisionAgentDeps): Promise<DrugsInClassResult>;
|
|
86
|
-
export {};
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phase-2 decision functions for the harness DBOS workflow.
|
|
3
|
-
*
|
|
4
|
-
* `modulatorTriage` selects up to 8 ChEMBL modulators for downstream
|
|
5
|
-
* fan-out; `drugsInClass` identifies clinically-advanced drugs in the
|
|
6
|
-
* class. Both are single-shot, structured-output LLM calls — no tools,
|
|
7
|
-
* no multi-step reasoning. Each function is `(input, deps) => Promise<CoverageEnvelope<...>>`.
|
|
8
|
-
*
|
|
9
|
-
* Coverage envelope is the failure mode: an LLM throw (non-402) → the
|
|
10
|
-
* function returns `coverage: "queried_no_data"`. A billing-gateway 402 reaches
|
|
11
|
-
* here as a `RunLlmStepResult` with `kind: "budget-exceeded"`; the caller
|
|
12
|
-
* stops scheduling because the workflow has self-cancelled.
|
|
13
|
-
*/
|
|
14
|
-
import { z } from "zod";
|
|
15
|
-
import { drugsInClassPrompt } from "../../../prompts/target-assessment/drugs-in-class.js";
|
|
16
|
-
import { modulatorTriagePrompt } from "../../../prompts/target-assessment/modulator-triage.js";
|
|
17
|
-
import { dedupModulatorsByParent } from "../lib/dedup-modulators.js";
|
|
18
|
-
import { structuredLlmCall } from "../lib/structured-llm.js";
|
|
19
|
-
// ── Output schemas ────────────────────────────────────────────────────
|
|
20
|
-
export const ModulatorTriageOutputSchema = z.object({
|
|
21
|
-
shortlist: z.array(z.object({
|
|
22
|
-
moleculeChemblId: z.string(),
|
|
23
|
-
preferredName: z.string(),
|
|
24
|
-
maxPhase: z.number().nullable(),
|
|
25
|
-
firstApproval: z.number().nullable(),
|
|
26
|
-
rationale: z.string(),
|
|
27
|
-
})),
|
|
28
|
-
notes: z.string(),
|
|
29
|
-
dropped_synonyms: z
|
|
30
|
-
.array(z.object({
|
|
31
|
-
chemblId: z.string(),
|
|
32
|
-
reason: z.enum(["same_active_substance", "ambiguous_name_synonym"]),
|
|
33
|
-
keptId: z.string().nullable(),
|
|
34
|
-
}))
|
|
35
|
-
.default([]),
|
|
36
|
-
});
|
|
37
|
-
export const DrugsInClassOutputSchema = z.object({
|
|
38
|
-
drugs: z.array(z.object({
|
|
39
|
-
moleculeChemblId: z.string(),
|
|
40
|
-
preferredName: z.string(),
|
|
41
|
-
maxPhase: z.number().nullable(),
|
|
42
|
-
firstApproval: z.number().nullable(),
|
|
43
|
-
moleculeType: z.string().nullable(),
|
|
44
|
-
sources: z.array(z.enum(["chembl", "dgidb", "drugbank"])),
|
|
45
|
-
})),
|
|
46
|
-
total: z.number(),
|
|
47
|
-
truncated: z.boolean(),
|
|
48
|
-
});
|
|
49
|
-
function fail(message) {
|
|
50
|
-
return { coverage: "queried_no_data", error: { message } };
|
|
51
|
-
}
|
|
52
|
-
function failFromErr(err) {
|
|
53
|
-
return fail(err instanceof Error ? err.message : String(err));
|
|
54
|
-
}
|
|
55
|
-
export async function modulatorTriage(input, deps) {
|
|
56
|
-
const modulators = input.collectors.chemblModulators;
|
|
57
|
-
if (modulators.coverage !== "available" || modulators.data.modulators.length === 0) {
|
|
58
|
-
return fail("no modulators to triage");
|
|
59
|
-
}
|
|
60
|
-
const { kept, dropped } = dedupModulatorsByParent(modulators.data.modulators);
|
|
61
|
-
if (kept.length === 0) {
|
|
62
|
-
return fail("no modulators after dedup");
|
|
63
|
-
}
|
|
64
|
-
const prompt = [
|
|
65
|
-
`Target: ${input.resolved.geneSymbol} (${input.resolved.canonicalId})`,
|
|
66
|
-
`ChEMBL target id: ${modulators.data.targetChemblId ?? "unknown"}`,
|
|
67
|
-
``,
|
|
68
|
-
`Modulators (${kept.length}, deduped from ${modulators.data.modulators.length}):`,
|
|
69
|
-
JSON.stringify(kept, null, 2),
|
|
70
|
-
].join("\n");
|
|
71
|
-
try {
|
|
72
|
-
const result = await structuredLlmCall({
|
|
73
|
-
stepName: `ta-decision:modulator-triage:${deps.attempt}`,
|
|
74
|
-
agentId: "modulator-triage",
|
|
75
|
-
provider: deps.chatProvider,
|
|
76
|
-
session: deps.session,
|
|
77
|
-
system: modulatorTriagePrompt,
|
|
78
|
-
prompt,
|
|
79
|
-
schema: ModulatorTriageOutputSchema,
|
|
80
|
-
model: deps.model,
|
|
81
|
-
});
|
|
82
|
-
if (result.kind === "budget-exceeded") {
|
|
83
|
-
return { kind: "budget-exceeded", sentinel: result.sentinel };
|
|
84
|
-
}
|
|
85
|
-
return {
|
|
86
|
-
coverage: "available",
|
|
87
|
-
data: { ...result.value, dropped_synonyms: dropped },
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
catch (err) {
|
|
91
|
-
return failFromErr(err);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
export async function drugsInClass(input, deps) {
|
|
95
|
-
const modulators = input.collectors.chemblModulators;
|
|
96
|
-
if (modulators.coverage !== "available" || modulators.data.modulators.length === 0) {
|
|
97
|
-
return fail("no modulators in class");
|
|
98
|
-
}
|
|
99
|
-
const { kept } = dedupModulatorsByParent(modulators.data.modulators);
|
|
100
|
-
if (kept.length === 0) {
|
|
101
|
-
return fail("no modulators after dedup");
|
|
102
|
-
}
|
|
103
|
-
const prompt = [
|
|
104
|
-
`Target: ${input.resolved.geneSymbol}`,
|
|
105
|
-
`ChEMBL modulators (max_phase ≥ 2, deduped by active substance):`,
|
|
106
|
-
JSON.stringify(kept, null, 2),
|
|
107
|
-
].join("\n");
|
|
108
|
-
try {
|
|
109
|
-
const result = await structuredLlmCall({
|
|
110
|
-
stepName: `ta-decision:drugs-in-class:${deps.attempt}`,
|
|
111
|
-
agentId: "drugs-in-class",
|
|
112
|
-
provider: deps.chatProvider,
|
|
113
|
-
session: deps.session,
|
|
114
|
-
system: drugsInClassPrompt,
|
|
115
|
-
prompt,
|
|
116
|
-
schema: DrugsInClassOutputSchema,
|
|
117
|
-
model: deps.model,
|
|
118
|
-
});
|
|
119
|
-
if (result.kind === "budget-exceeded") {
|
|
120
|
-
return { kind: "budget-exceeded", sentinel: result.sentinel };
|
|
121
|
-
}
|
|
122
|
-
return { coverage: "available", data: result.value };
|
|
123
|
-
}
|
|
124
|
-
catch (err) {
|
|
125
|
-
return failFromErr(err);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phase-3 fan-out item functions for the harness DBOS workflow.
|
|
3
|
-
*
|
|
4
|
-
* Each function operates on one item (one modulator, one trial, one class
|
|
5
|
-
* drug) and returns a coverage envelope. The DBOS workflow body iterates
|
|
6
|
-
* the item list and dispatches each via `DBOS.runStep` with a deterministic
|
|
7
|
-
* step name `"ta-fanout:{kind}:{itemKey}"`. The `withHost` semaphore inside
|
|
8
|
-
* each body caps openFDA / ChEMBL / ctgov in-flight at 4.
|
|
9
|
-
*
|
|
10
|
-
* No throws — coverage envelope is the failure mode. Recovery replays the
|
|
11
|
-
* cached envelope from the DBOS step cache.
|
|
12
|
-
*/
|
|
13
|
-
import type { Logger } from "../../../lib/logger.js";
|
|
14
|
-
import type { SerializedError } from "../coverage.js";
|
|
15
|
-
import type { ClassDrugItem, PerClassDrugAEsItem } from "../steps/fanout/aes-for-one-class-drug-step.js";
|
|
16
|
-
import type { PerTrialAEsItem, TrialItem } from "../steps/fanout/aes-for-one-trial-step.js";
|
|
17
|
-
import type { ModulatorItem, PerModulatorFaersItem } from "../steps/fanout/faers-for-one-modulator-step.js";
|
|
18
|
-
import type { PerModulatorPolypharmItem, PolypharmInputItem } from "../steps/fanout/polypharm-for-one-modulator-step.js";
|
|
19
|
-
export type { ClassDrugItem, ModulatorItem, PerClassDrugAEsItem, PerModulatorFaersItem, PerModulatorPolypharmItem, PerTrialAEsItem, PolypharmInputItem, TrialItem, };
|
|
20
|
-
type CoverageAvailable<T> = {
|
|
21
|
-
coverage: "available";
|
|
22
|
-
data: T;
|
|
23
|
-
};
|
|
24
|
-
type CoverageQueriedNoData = {
|
|
25
|
-
coverage: "queried_no_data";
|
|
26
|
-
error?: SerializedError;
|
|
27
|
-
};
|
|
28
|
-
type CoverageEnvelope<T> = CoverageAvailable<T> | CoverageQueriedNoData;
|
|
29
|
-
export declare function faersForOneModulator(item: ModulatorItem): Promise<CoverageEnvelope<PerModulatorFaersItem>>;
|
|
30
|
-
export declare function polypharmForOneModulator(item: PolypharmInputItem, logger?: Logger): Promise<CoverageEnvelope<PerModulatorPolypharmItem>>;
|
|
31
|
-
export declare function aesForOneTrial(item: TrialItem): Promise<CoverageEnvelope<PerTrialAEsItem>>;
|
|
32
|
-
export declare function aesForOneClassDrug(item: ClassDrugItem): Promise<CoverageEnvelope<PerClassDrugAEsItem>>;
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phase-3 fan-out item functions for the harness DBOS workflow.
|
|
3
|
-
*
|
|
4
|
-
* Each function operates on one item (one modulator, one trial, one class
|
|
5
|
-
* drug) and returns a coverage envelope. The DBOS workflow body iterates
|
|
6
|
-
* the item list and dispatches each via `DBOS.runStep` with a deterministic
|
|
7
|
-
* step name `"ta-fanout:{kind}:{itemKey}"`. The `withHost` semaphore inside
|
|
8
|
-
* each body caps openFDA / ChEMBL / ctgov in-flight at 4.
|
|
9
|
-
*
|
|
10
|
-
* No throws — coverage envelope is the failure mode. Recovery replays the
|
|
11
|
-
* cached envelope from the DBOS step cache.
|
|
12
|
-
*/
|
|
13
|
-
import { withHost } from "../../../lib/host-concurrency.js";
|
|
14
|
-
import { getModulatorOnTargetPchembl, getModulatorPolypharmacology } from "../../../tools/lib/chembl-client.js";
|
|
15
|
-
import { getTrialDetails } from "../../../tools/lib/clinical-trials-client.js";
|
|
16
|
-
import { getFaersByDrug, getFaersSeriousness } from "../../../tools/lib/openfda-client.js";
|
|
17
|
-
function fail(message) {
|
|
18
|
-
return { coverage: "queried_no_data", error: { message } };
|
|
19
|
-
}
|
|
20
|
-
function failFromErr(err) {
|
|
21
|
-
return fail(err instanceof Error ? err.message : String(err));
|
|
22
|
-
}
|
|
23
|
-
// ── Per-modulator FAERS ──────────────────────────────────────────────
|
|
24
|
-
export async function faersForOneModulator(item) {
|
|
25
|
-
const probe = item.preferredName;
|
|
26
|
-
if (!probe) {
|
|
27
|
-
return fail(`no preferred name for ${item.moleculeChemblId}`);
|
|
28
|
-
}
|
|
29
|
-
try {
|
|
30
|
-
const [byDrug, seriousness] = await Promise.all([
|
|
31
|
-
withHost("openfda", () => getFaersByDrug(probe, { limit: 10 })),
|
|
32
|
-
withHost("openfda", () => getFaersSeriousness(probe)),
|
|
33
|
-
]);
|
|
34
|
-
const total = byDrug.totalReports ?? 0;
|
|
35
|
-
if (total === 0 && byDrug.adverseEvents.length === 0) {
|
|
36
|
-
return fail(`FAERS returned no reports for ${probe}`);
|
|
37
|
-
}
|
|
38
|
-
if (seriousness !== null &&
|
|
39
|
-
seriousness.totalReports >= 1000 &&
|
|
40
|
-
seriousness.fatalCount === 0 &&
|
|
41
|
-
seriousness.hospitalizationCount === 0 &&
|
|
42
|
-
seriousness.lifeThreateningCount === 0 &&
|
|
43
|
-
seriousness.disablingCount === 0 &&
|
|
44
|
-
seriousness.congenitalAnomalyCount === 0 &&
|
|
45
|
-
seriousness.otherSeriousCount === 0) {
|
|
46
|
-
return fail(`FAERS seriousness all-zero across ${seriousness.totalReports} reports for ${probe}; openFDA seriousness fields not reliably populated`);
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
coverage: "available",
|
|
50
|
-
data: {
|
|
51
|
-
moleculeChemblId: item.moleculeChemblId,
|
|
52
|
-
preferredName: probe,
|
|
53
|
-
totalReports: byDrug.totalReports ?? null,
|
|
54
|
-
topReactions: byDrug.adverseEvents,
|
|
55
|
-
seriousness,
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
catch (err) {
|
|
60
|
-
return failFromErr(err);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
// ── Per-modulator polypharmacology ──────────────────────────────────
|
|
64
|
-
export async function polypharmForOneModulator(item, logger) {
|
|
65
|
-
try {
|
|
66
|
-
const [hits, primaryPchembl] = await Promise.all([
|
|
67
|
-
withHost("chembl", () => getModulatorPolypharmacology(item.moleculeChemblId, {
|
|
68
|
-
minPchembl: 5,
|
|
69
|
-
excludeTargetChemblId: item.primaryTargetChemblId ?? undefined,
|
|
70
|
-
limit: 200,
|
|
71
|
-
})),
|
|
72
|
-
item.primaryTargetChemblId
|
|
73
|
-
? withHost("chembl", () => getModulatorOnTargetPchembl(item.moleculeChemblId, item.primaryTargetChemblId, logger))
|
|
74
|
-
: Promise.resolve(null),
|
|
75
|
-
]);
|
|
76
|
-
if (hits.length === 0) {
|
|
77
|
-
return fail(`no polypharm hits for ${item.moleculeChemblId}`);
|
|
78
|
-
}
|
|
79
|
-
return {
|
|
80
|
-
coverage: "available",
|
|
81
|
-
data: {
|
|
82
|
-
moleculeChemblId: item.moleculeChemblId,
|
|
83
|
-
preferredName: item.preferredName,
|
|
84
|
-
primaryPchembl,
|
|
85
|
-
hits: hits.map((h) => ({
|
|
86
|
-
targetChemblId: h.targetChemblId,
|
|
87
|
-
targetName: h.targetName,
|
|
88
|
-
assayChemblId: h.assayChemblId,
|
|
89
|
-
pchemblValue: h.pchemblValue,
|
|
90
|
-
standardType: h.standardType,
|
|
91
|
-
standardValue: h.standardValue,
|
|
92
|
-
standardUnits: h.standardUnits,
|
|
93
|
-
})),
|
|
94
|
-
},
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
catch (err) {
|
|
98
|
-
return failFromErr(err);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
// ── Per-trial AEs ────────────────────────────────────────────────────
|
|
102
|
-
export async function aesForOneTrial(item) {
|
|
103
|
-
try {
|
|
104
|
-
const details = await withHost("ctgov", () => getTrialDetails(item.nctId));
|
|
105
|
-
if (!details) {
|
|
106
|
-
return fail(`no details for ${item.nctId}`);
|
|
107
|
-
}
|
|
108
|
-
if (details.adverseEvents.length === 0 && details.outcomes.length === 0) {
|
|
109
|
-
return fail(`no AE/outcome rows for ${item.nctId}`);
|
|
110
|
-
}
|
|
111
|
-
return {
|
|
112
|
-
coverage: "available",
|
|
113
|
-
data: {
|
|
114
|
-
nctId: item.nctId,
|
|
115
|
-
title: item.title,
|
|
116
|
-
whyStopped: details.whyStopped,
|
|
117
|
-
outcomes: details.outcomes,
|
|
118
|
-
groups: details.adverseEventGroups,
|
|
119
|
-
events: details.adverseEvents,
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
catch (err) {
|
|
124
|
-
return failFromErr(err);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
// ── Per-class-drug AEs ───────────────────────────────────────────────
|
|
128
|
-
export async function aesForOneClassDrug(item) {
|
|
129
|
-
const probe = item.preferredName;
|
|
130
|
-
if (!probe) {
|
|
131
|
-
return fail(`no preferred name for ${item.moleculeChemblId}`);
|
|
132
|
-
}
|
|
133
|
-
try {
|
|
134
|
-
const [byDrug, seriousness] = await Promise.all([
|
|
135
|
-
withHost("openfda", () => getFaersByDrug(probe, { limit: 10 })),
|
|
136
|
-
withHost("openfda", () => getFaersSeriousness(probe)),
|
|
137
|
-
]);
|
|
138
|
-
const total = byDrug.totalReports ?? 0;
|
|
139
|
-
if (total === 0 && byDrug.adverseEvents.length === 0) {
|
|
140
|
-
return fail(`FAERS returned no reports for ${probe}`);
|
|
141
|
-
}
|
|
142
|
-
return {
|
|
143
|
-
coverage: "available",
|
|
144
|
-
data: {
|
|
145
|
-
moleculeChemblId: item.moleculeChemblId,
|
|
146
|
-
preferredName: probe,
|
|
147
|
-
totalReports: byDrug.totalReports ?? null,
|
|
148
|
-
topReactions: byDrug.adverseEvents,
|
|
149
|
-
seriousness,
|
|
150
|
-
},
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
catch (err) {
|
|
154
|
-
return failFromErr(err);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
@@ -1,97 +0,0 @@
|
|
|
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 };
|