@inflexa-ai/harness 0.13.0 → 0.14.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/agents/conversation-agent.js +23 -16
- package/dist/agents/sandbox/cheminformatics-agent.js +1 -1
- package/dist/agents/sandbox/chromatin-agent.js +1 -1
- package/dist/agents/sandbox/dna-methylation-agent.js +1 -1
- package/dist/agents/sandbox/drug-repurposing-agent.js +5 -10
- package/dist/agents/sandbox/enrichment-agent.js +1 -1
- package/dist/agents/sandbox/genomic-variant-agent.js +1 -11
- package/dist/agents/sandbox/immune-profiling-agent.js +1 -1
- package/dist/agents/sandbox/multi-omics-integration-agent.js +1 -1
- package/dist/agents/sandbox/network-agent.js +1 -1
- package/dist/agents/sandbox/pkpd-clinical-response-agent.js +3 -6
- package/dist/agents/sandbox/scientific-executor.js +1 -1
- package/dist/agents/sandbox/shared.js +7 -13
- package/dist/agents/sandbox/translational-safety-agent.js +4 -7
- package/dist/agents/sandbox/types.d.ts +5 -5
- package/dist/agents/sandbox/types.js +4 -4
- package/dist/app/chat-turn.js +4 -1
- package/dist/app/message-assembly.d.ts +5 -2
- package/dist/app/message-assembly.js +7 -2
- package/dist/app/run-activity.d.ts +13 -0
- package/dist/app/run-activity.js +51 -0
- package/dist/contracts/target-dossier.d.ts +10 -10
- package/dist/execution/report-runner.js +1 -1
- package/dist/execution/run-event-parts.d.ts +44 -0
- package/dist/execution/run-event-parts.js +0 -0
- package/dist/execution/run-event-stream.d.ts +91 -0
- package/dist/execution/run-event-stream.js +212 -0
- package/dist/execution/run-synthesis.js +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +20 -1
- package/dist/input-sanitization.d.ts +14 -4
- package/dist/input-sanitization.js +27 -4
- package/dist/lib/storage.js +4 -1
- package/dist/loop/budget-exceeded.d.ts +18 -2
- package/dist/loop/budget-exceeded.js +49 -2
- package/dist/loop/run-agent.d.ts +22 -1
- package/dist/loop/run-agent.js +91 -25
- package/dist/loop/run-to-terminal.d.ts +22 -4
- package/dist/loop/run-to-terminal.js +20 -4
- package/dist/memory/ai-sdk-message-storage.d.ts +37 -4
- package/dist/memory/ai-sdk-message-storage.js +45 -4
- package/dist/memory/content-to-cortex.js +19 -3
- package/dist/memory/message-backfill.js +1 -1
- package/dist/memory/thread-history.js +34 -8
- package/dist/prompts/conversation.d.ts +1 -1
- package/dist/prompts/conversation.js +15 -6
- package/dist/prompts/literature-reviewer.d.ts +1 -1
- package/dist/prompts/literature-reviewer.js +16 -14
- package/dist/prompts/planner.js +15 -20
- package/dist/prompts/sandbox/drug-repurposing-agent.d.ts +1 -1
- package/dist/prompts/sandbox/drug-repurposing-agent.js +31 -22
- package/dist/prompts/sandbox/multi-omics-integration-agent.d.ts +1 -1
- package/dist/prompts/sandbox/multi-omics-integration-agent.js +9 -10
- package/dist/prompts/sandbox/pkpd-clinical-response-agent.d.ts +1 -1
- package/dist/prompts/sandbox/pkpd-clinical-response-agent.js +8 -7
- package/dist/prompts/sandbox/translational-safety-agent.d.ts +1 -1
- package/dist/prompts/sandbox/translational-safety-agent.js +20 -14
- package/dist/prompts/synthesis-agent.d.ts +1 -1
- package/dist/prompts/synthesis-agent.js +7 -7
- package/dist/providers/errors.d.ts +7 -0
- package/dist/providers/errors.js +88 -3
- package/dist/runtime/pools.d.ts +15 -1
- package/dist/runtime/pools.js +15 -1
- package/dist/sandbox/sandbox-step-translate.d.ts +15 -2
- package/dist/sandbox/sandbox-step-translate.js +17 -2
- package/dist/schemas/workflow-state.d.ts +2 -2
- package/dist/schemas/workflow-state.js +2 -2
- package/dist/state/data-profile.d.ts +53 -1
- package/dist/state/data-profile.js +66 -6
- package/dist/state/index.d.ts +3 -3
- package/dist/state/index.js +2 -2
- package/dist/state/init.js +37 -2
- package/dist/state/runs.d.ts +39 -0
- package/dist/state/runs.js +103 -0
- package/dist/tasks/data-profile-activity.d.ts +87 -0
- package/dist/tasks/data-profile-activity.js +56 -0
- package/dist/tasks/data-profile.js +66 -4
- package/dist/tools/bio/chembl.d.ts +1 -1
- package/dist/tools/bio/chembl.js +51 -54
- package/dist/tools/bio/comptox.js +35 -33
- package/dist/tools/bio/drug-gene-interactions.d.ts +76 -0
- package/dist/tools/bio/drug-gene-interactions.js +175 -0
- package/dist/tools/bio/gene-disease-evidence.d.ts +61 -0
- package/dist/tools/bio/gene-disease-evidence.js +187 -0
- package/dist/tools/bio/gene-preclinical-profile.d.ts +58 -0
- package/dist/tools/bio/gene-preclinical-profile.js +125 -0
- package/dist/tools/bio/index.d.ts +23 -16
- package/dist/tools/bio/index.js +29 -22
- package/dist/tools/bio/keys.d.ts +16 -9
- package/dist/tools/bio/keys.js +22 -13
- package/dist/tools/bio/lookup-annotation.d.ts +48 -0
- package/dist/tools/bio/lookup-annotation.js +173 -0
- package/dist/tools/bio/opentargets.d.ts +7 -11
- package/dist/tools/bio/opentargets.js +24 -35
- package/dist/tools/bio/pubchem.js +6 -4
- package/dist/tools/bio/pubmed.d.ts +15 -7
- package/dist/tools/bio/pubmed.js +79 -20
- package/dist/tools/bio/search-clinical-trials.d.ts +20 -1
- package/dist/tools/bio/search-clinical-trials.js +26 -5
- package/dist/tools/bio/search-faers.js +9 -3
- package/dist/tools/bio/search-gene.d.ts +0 -1
- package/dist/tools/bio/search-gene.js +4 -5
- package/dist/tools/bio/search-geo-datasets.js +10 -4
- package/dist/tools/bio/search-interactions.d.ts +8 -4
- package/dist/tools/bio/search-interactions.js +28 -12
- package/dist/tools/bio/target-safety.d.ts +59 -0
- package/dist/tools/bio/target-safety.js +191 -0
- package/dist/tools/execute-analysis.d.ts +1 -0
- package/dist/tools/execute-analysis.js +5 -5
- package/dist/tools/lib/dgidb-client.d.ts +49 -0
- package/dist/tools/lib/dgidb-client.js +168 -0
- package/dist/tools/lib/disgenet-client.d.ts +56 -0
- package/dist/tools/lib/disgenet-client.js +59 -0
- package/dist/tools/lib/drugbank-client.d.ts +83 -0
- package/dist/tools/lib/drugbank-client.js +95 -0
- package/dist/tools/lib/ensembl-client.d.ts +4 -1
- package/dist/tools/lib/ensembl-client.js +5 -3
- package/dist/tools/lib/gwas-catalog-client.d.ts +60 -0
- package/dist/tools/lib/gwas-catalog-client.js +136 -0
- package/dist/tools/lib/pharmgkb-client.d.ts +22 -0
- package/dist/tools/lib/pharmgkb-client.js +32 -0
- package/dist/tools/lib/pubmed-client.d.ts +57 -4
- package/dist/tools/lib/pubmed-client.js +57 -3
- package/dist/tools/lib/string-client.d.ts +25 -4
- package/dist/tools/lib/string-client.js +22 -5
- package/dist/tools/research/generate-plan.d.ts +16 -9
- package/dist/tools/research/generate-plan.js +405 -85
- package/dist/tools/research/inspect-data-profile.d.ts +31 -6
- package/dist/tools/research/inspect-data-profile.js +23 -7
- package/dist/tools/research/inspect-run.d.ts +33 -15
- package/dist/tools/research/inspect-run.js +155 -66
- package/dist/tools/research/literature-reviewer.js +7 -11
- package/dist/workflows/execute-analysis.d.ts +63 -0
- package/dist/workflows/execute-analysis.js +73 -2
- package/dist/workflows/sandbox-step.js +1 -11
- package/dist/workflows/target-assessment/decisions/index.d.ts +1 -1
- package/dist/workflows/target-assessment/phase4-assemble.d.ts +1 -1
- package/dist/workflows/target-assessment/steps/phase2-aggregate.d.ts +2 -2
- package/dist/workflows/target-assessment/steps/phase3-aggregate.d.ts +1 -1
- package/package.json +1 -1
- package/dist/tools/bio/check-safety-panel.d.ts +0 -35
- package/dist/tools/bio/check-safety-panel.js +0 -76
- package/dist/tools/bio/get-impc-ko-profile.d.ts +0 -9
- package/dist/tools/bio/get-impc-ko-profile.js +0 -23
- package/dist/tools/bio/lookup-go-term.d.ts +0 -31
- package/dist/tools/bio/lookup-go-term.js +0 -116
- package/dist/tools/bio/search-bgee-expression.d.ts +0 -10
- package/dist/tools/bio/search-bgee-expression.js +0 -30
- package/dist/tools/bio/search-clinvar.d.ts +0 -13
- package/dist/tools/bio/search-clinvar.js +0 -28
- package/dist/tools/bio/search-dgidb.d.ts +0 -53
- package/dist/tools/bio/search-dgidb.js +0 -213
- package/dist/tools/bio/search-disgenet.d.ts +0 -30
- package/dist/tools/bio/search-disgenet.js +0 -84
- package/dist/tools/bio/search-drugbank.d.ts +0 -38
- package/dist/tools/bio/search-drugbank.js +0 -109
- package/dist/tools/bio/search-gwas-catalog.d.ts +0 -33
- package/dist/tools/bio/search-gwas-catalog.js +0 -172
- package/dist/tools/bio/search-pathway.d.ts +0 -12
- package/dist/tools/bio/search-pathway.js +0 -32
- package/dist/tools/bio/search-pharmgkb.d.ts +0 -17
- package/dist/tools/bio/search-pharmgkb.js +0 -52
|
@@ -97,6 +97,52 @@ function emitProvenanceGuarded(deps, event) {
|
|
|
97
97
|
logger.error("emitProvenance threw", { runId: event.runId, event: event.type, ...logger.errorFields(err) });
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Build the whole-run snapshot from the workflow input and the scheduler's live step state.
|
|
102
|
+
*
|
|
103
|
+
* Pure, so every emission point produces an identically-shaped payload from one place — a second
|
|
104
|
+
* construction path is exactly how "a transition happened" acquires two definitions that drift.
|
|
105
|
+
* The human `name` joins through `input.planStepById` because `input.steps` is the scheduler's
|
|
106
|
+
* narrow `{id, depends_on}` projection and carries no plan vocabulary.
|
|
107
|
+
*/
|
|
108
|
+
function buildRunObservation(args) {
|
|
109
|
+
const { input, runId, status, stepStates } = args;
|
|
110
|
+
return {
|
|
111
|
+
runId,
|
|
112
|
+
analysisId: input.analysisId,
|
|
113
|
+
status,
|
|
114
|
+
steps: input.steps.map((s) => {
|
|
115
|
+
const rt = stepStates.get(s.id);
|
|
116
|
+
return {
|
|
117
|
+
id: s.id,
|
|
118
|
+
name: input.planStepById[s.id]?.name ?? s.id,
|
|
119
|
+
agent: input.agentByStepId[s.id] ?? "unknown",
|
|
120
|
+
// A step absent from the map has not been reached yet; `pending` is its honest state.
|
|
121
|
+
status: rt?.status ?? "pending",
|
|
122
|
+
...(rt?.durationMs !== undefined ? { durationMs: rt.durationMs } : {}),
|
|
123
|
+
...(rt?.error !== undefined ? { error: rt.error } : {}),
|
|
124
|
+
};
|
|
125
|
+
}),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Fire the optional run observer, isolating a throwing host callback from the workflow.
|
|
130
|
+
*
|
|
131
|
+
* Deliberately a sibling of {@link emitProvenanceGuarded} rather than a shared helper: the two
|
|
132
|
+
* seams carry unrelated payloads and must stay independently removable, and one shared guard would
|
|
133
|
+
* have to pick a single logger namespace, making it lie about whichever seam it is not named for.
|
|
134
|
+
*/
|
|
135
|
+
function observeRunGuarded(deps, observation) {
|
|
136
|
+
if (!deps.observeRun)
|
|
137
|
+
return;
|
|
138
|
+
const logger = (deps.logger ?? createNoopLogger()).named("executeAnalysis.observe");
|
|
139
|
+
try {
|
|
140
|
+
deps.observeRun(observation);
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
logger.error("observeRun threw", { runId: observation.runId, status: observation.status, ...logger.errorFields(err) });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
100
146
|
/**
|
|
101
147
|
* Project the sandbox-step input handed to each child. The parent owns the
|
|
102
148
|
* level computation and the seed (`prompt`, composed by `composeStepSeed` at
|
|
@@ -379,6 +425,10 @@ export async function runExecuteAnalysisBody(input, deps) {
|
|
|
379
425
|
stepCount: input.steps.length,
|
|
380
426
|
atMs: startedAtMs,
|
|
381
427
|
});
|
|
428
|
+
// Opening snapshot: every step pending. The scheduler's own map does not exist yet, and an
|
|
429
|
+
// empty one yields exactly that — so a host has the run's full shape before the first dispatch
|
|
430
|
+
// rather than learning the step list from whichever transition happens to land first.
|
|
431
|
+
observeRunGuarded(deps, buildRunObservation({ input, runId, status: "running", stepStates: new Map() }));
|
|
382
432
|
// (2-4) Scheduler loop + failure isolation + pause cascade.
|
|
383
433
|
const final = await runSchedulerLoop({
|
|
384
434
|
input,
|
|
@@ -490,6 +540,11 @@ export async function runExecuteAnalysisBody(input, deps) {
|
|
|
490
540
|
synthesisOutcome,
|
|
491
541
|
deps,
|
|
492
542
|
});
|
|
543
|
+
// Terminal snapshot, fired here rather than inside `collectAndComplete` because this is the
|
|
544
|
+
// first point where BOTH the derived final status and the scheduler's final step map are in
|
|
545
|
+
// hand. It precedes the budget self-cancel below on purpose: that branch raises out of the
|
|
546
|
+
// body, so an observer placed after it would never see a budget-paused run's last state.
|
|
547
|
+
observeRunGuarded(deps, buildRunObservation({ input, runId, status: result.status, stepStates: final.stepStates }));
|
|
493
548
|
// Synthesis failure takes priority over the budget-exceeded cascade: a run
|
|
494
549
|
// whose synthesis threw is definitively failed (ERROR), not a resumable
|
|
495
550
|
// budget pause. Only self-cancel when synthesis succeeded.
|
|
@@ -602,7 +657,14 @@ async function runSchedulerLoop(args) {
|
|
|
602
657
|
const rt = stepRuntime.get(s.id);
|
|
603
658
|
const entry = {
|
|
604
659
|
id: s.id,
|
|
605
|
-
|
|
660
|
+
// `input.steps` is the SCHEDULER's projection — `{id, depends_on}` and nothing
|
|
661
|
+
// else — so the human name has to be joined from the snapshotted plan step. A
|
|
662
|
+
// consumer reading `name` is reading it to say what the step is FOR, which the
|
|
663
|
+
// id (a `T{track}S{step}` slug) cannot answer. Falling back to the id keeps the
|
|
664
|
+
// field populated for a step missing from the snapshot rather than emitting an
|
|
665
|
+
// empty label; `planStepById` is complete by contract (dispatch throws on a
|
|
666
|
+
// miss), so the fallback is unreachable in practice.
|
|
667
|
+
name: input.planStepById[s.id]?.name ?? s.id,
|
|
606
668
|
agent: input.agentByStepId[s.id] ?? "unknown",
|
|
607
669
|
status: rt.status,
|
|
608
670
|
level: levels.get(s.id) ?? 0,
|
|
@@ -612,9 +674,18 @@ async function runSchedulerLoop(args) {
|
|
|
612
674
|
entry.durationMs = rt.durationMs;
|
|
613
675
|
if (rt.error !== undefined)
|
|
614
676
|
entry.error = rt.error;
|
|
677
|
+
// `artifactCount` and `summary` are declared on `DagStepState` and deliberately not
|
|
678
|
+
// set: the parent holds neither at snapshot time, and a placeholder would make a
|
|
679
|
+
// consumer's rendering confidently wrong rather than honestly incomplete.
|
|
615
680
|
return entry;
|
|
616
681
|
}),
|
|
617
682
|
});
|
|
683
|
+
// The host observer rides the DAG emission rather than getting its own instrumentation
|
|
684
|
+
// points: these call sites already ARE the complete set of run-state transitions, and a
|
|
685
|
+
// second set would drift from this one. Status is `running` here by construction — the
|
|
686
|
+
// scheduler loop only emits while it is still scheduling; the terminal snapshot is fired by
|
|
687
|
+
// the body once `collectAndComplete` has derived the final status.
|
|
688
|
+
observeRunGuarded(deps, buildRunObservation({ input, runId, status: "running", stepStates: stepRuntime }));
|
|
618
689
|
};
|
|
619
690
|
const dbosParentId = DBOS.workflowID ?? workflowId;
|
|
620
691
|
const dispatchReady = async () => {
|
|
@@ -841,7 +912,7 @@ async function runSchedulerLoop(args) {
|
|
|
841
912
|
});
|
|
842
913
|
}
|
|
843
914
|
await drainBudgetExceededNotifications(budgetExceededChildIds);
|
|
844
|
-
return { completed, failed, canceled, budgetExceeded, failureReason };
|
|
915
|
+
return { completed, failed, canceled, budgetExceeded, failureReason, stepStates: stepRuntime };
|
|
845
916
|
}
|
|
846
917
|
async function drainBudgetExceededNotifications(childIds) {
|
|
847
918
|
while (true) {
|
|
@@ -33,7 +33,7 @@ import { unwrapOrThrow } from "../lib/result.js";
|
|
|
33
33
|
import { isBudgetExceeded } from "../loop/budget-exceeded.js";
|
|
34
34
|
import { runAgent } from "../loop/run-agent.js";
|
|
35
35
|
import { durableStep } from "../loop/run-step.js";
|
|
36
|
-
import { activityForTool, applyTreeDelta, isChatDataPart, sandboxTreeDelta } from "../sandbox/sandbox-step-translate.js";
|
|
36
|
+
import { activityForTool, applyTreeDelta, isChatDataPart, sandboxTreeDelta, stepPartId } from "../sandbox/sandbox-step-translate.js";
|
|
37
37
|
import { forSubAgent } from "../auth/types.js";
|
|
38
38
|
import { walkStepArtifacts } from "../execution/post-step.js";
|
|
39
39
|
import { collectStepOutputs, generateStepFileMetadata, generateStepSummaryAndWrite, reconcileAndRegisterStepArtifacts, vectorIndexStepOutputs, } from "../execution/post-step-pipeline.js";
|
|
@@ -61,16 +61,6 @@ function nextFunctionIdFactory() {
|
|
|
61
61
|
let n = 0;
|
|
62
62
|
return () => `fn-${(n++).toString(36)}`;
|
|
63
63
|
}
|
|
64
|
-
/**
|
|
65
|
-
* Stable reconciliation id for a step's reconciling parts
|
|
66
|
-
* (`data-step-activity`, `data-step-file-tree`). One id per (runId, stepId)
|
|
67
|
-
* so the run-stream fold collapses every phase transition latest-wins onto
|
|
68
|
-
* a single frame. The client keys these by `stepId`, but the server fold
|
|
69
|
-
* keys by part `id`, so the id MUST be unique per step within the run.
|
|
70
|
-
*/
|
|
71
|
-
function stepPartId(kind, runId, stepId) {
|
|
72
|
-
return `${kind}-${runId}-${stepId}`;
|
|
73
|
-
}
|
|
74
64
|
/**
|
|
75
65
|
* Map an internal step failure to a user-safe string. Internal detail (file
|
|
76
66
|
* paths, content hashes, managed-root rejection reasons, stack traces) stays in the pod
|
|
@@ -43,9 +43,9 @@ export declare const DrugsInClassOutputSchema: z.ZodObject<{
|
|
|
43
43
|
firstApproval: z.ZodNullable<z.ZodNumber>;
|
|
44
44
|
moleculeType: z.ZodNullable<z.ZodString>;
|
|
45
45
|
sources: z.ZodArray<z.ZodEnum<{
|
|
46
|
-
chembl: "chembl";
|
|
47
46
|
dgidb: "dgidb";
|
|
48
47
|
drugbank: "drugbank";
|
|
48
|
+
chembl: "chembl";
|
|
49
49
|
}>>;
|
|
50
50
|
}, z.core.$strip>>;
|
|
51
51
|
total: z.ZodNumber;
|
|
@@ -1707,8 +1707,8 @@ export declare const Phase4OutputSchema: z.ZodObject<{
|
|
|
1707
1707
|
medium: "medium";
|
|
1708
1708
|
low: "low";
|
|
1709
1709
|
absent: "absent";
|
|
1710
|
-
not_loaded: "not_loaded";
|
|
1711
1710
|
no_data: "no_data";
|
|
1711
|
+
not_loaded: "not_loaded";
|
|
1712
1712
|
}>;
|
|
1713
1713
|
}, z.core.$strip>>;
|
|
1714
1714
|
per_species_coverage: z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
@@ -53,9 +53,9 @@ export declare const Phase2AggregateInputSchema: z.ZodObject<{
|
|
|
53
53
|
firstApproval: z.ZodNullable<z.ZodNumber>;
|
|
54
54
|
moleculeType: z.ZodNullable<z.ZodString>;
|
|
55
55
|
sources: z.ZodArray<z.ZodEnum<{
|
|
56
|
-
chembl: "chembl";
|
|
57
56
|
dgidb: "dgidb";
|
|
58
57
|
drugbank: "drugbank";
|
|
58
|
+
chembl: "chembl";
|
|
59
59
|
}>>;
|
|
60
60
|
}, z.core.$strip>>;
|
|
61
61
|
total: z.ZodNumber;
|
|
@@ -672,9 +672,9 @@ export declare const Phase2BundleSchema: z.ZodObject<{
|
|
|
672
672
|
firstApproval: z.ZodNullable<z.ZodNumber>;
|
|
673
673
|
moleculeType: z.ZodNullable<z.ZodString>;
|
|
674
674
|
sources: z.ZodArray<z.ZodEnum<{
|
|
675
|
-
chembl: "chembl";
|
|
676
675
|
dgidb: "dgidb";
|
|
677
676
|
drugbank: "drugbank";
|
|
677
|
+
chembl: "chembl";
|
|
678
678
|
}>>;
|
|
679
679
|
}, z.core.$strip>>;
|
|
680
680
|
total: z.ZodNumber;
|
|
@@ -757,9 +757,9 @@ export declare const Phase3BundleSchema: z.ZodObject<{
|
|
|
757
757
|
firstApproval: z.ZodNullable<z.ZodNumber>;
|
|
758
758
|
moleculeType: z.ZodNullable<z.ZodString>;
|
|
759
759
|
sources: z.ZodArray<z.ZodEnum<{
|
|
760
|
-
chembl: "chembl";
|
|
761
760
|
dgidb: "dgidb";
|
|
762
761
|
drugbank: "drugbank";
|
|
762
|
+
chembl: "chembl";
|
|
763
763
|
}>>;
|
|
764
764
|
}, z.core.$strip>>;
|
|
765
765
|
total: z.ZodNumber;
|
package/package.json
CHANGED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* checkSafetyPanel — look up identifiers against the curated
|
|
3
|
-
* secondary-pharmacology safety target panel.
|
|
4
|
-
*/
|
|
5
|
-
export declare const checkSafetyPanelTool: import("../define-tool.js").Tool<{
|
|
6
|
-
identifiers: string[];
|
|
7
|
-
identifier_type: "auto" | "gene_symbol" | "uniprot" | "chembl_id";
|
|
8
|
-
filter_organ?: "hematologic" | "metabolic" | "immune" | "hepatic" | "cns" | "renal" | "respiratory" | "cardiac" | "gi" | undefined;
|
|
9
|
-
}, {
|
|
10
|
-
matches: {
|
|
11
|
-
input: string;
|
|
12
|
-
matched_entry: {
|
|
13
|
-
chembl_id: string;
|
|
14
|
-
gene_symbol: string;
|
|
15
|
-
uniprot: string;
|
|
16
|
-
name: string;
|
|
17
|
-
organ_system: "hematologic" | "metabolic" | "immune" | "hepatic" | "cns" | "renal" | "respiratory" | "cardiac" | "gi";
|
|
18
|
-
clinical_consequence: string;
|
|
19
|
-
severity: "high" | "medium" | "low";
|
|
20
|
-
references: string[];
|
|
21
|
-
ensembl_gene_id?: string | undefined;
|
|
22
|
-
} | null;
|
|
23
|
-
}[];
|
|
24
|
-
summary: {
|
|
25
|
-
total_input: number;
|
|
26
|
-
matched: number;
|
|
27
|
-
by_severity: {
|
|
28
|
-
high: number;
|
|
29
|
-
medium: number;
|
|
30
|
-
low: number;
|
|
31
|
-
};
|
|
32
|
-
by_organ: Record<string, number>;
|
|
33
|
-
};
|
|
34
|
-
panel_version: string;
|
|
35
|
-
}>;
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* checkSafetyPanel — look up identifiers against the curated
|
|
3
|
-
* secondary-pharmacology safety target panel.
|
|
4
|
-
*/
|
|
5
|
-
import { ok } from "neverthrow";
|
|
6
|
-
import { z } from "zod";
|
|
7
|
-
import { CHEMBL_RE, ORGAN_SYSTEMS, SafetyPanelFileSchema, UNIPROT_RE } from "../../data/safety-panel-schema.js";
|
|
8
|
-
import panelData from "../../data/safety-panel.json" with { type: "json" };
|
|
9
|
-
import { defineTool } from "../define-tool.js";
|
|
10
|
-
const PANEL = SafetyPanelFileSchema.parse(panelData);
|
|
11
|
-
const BY_CHEMBL = new Map(PANEL.targets.map((t) => [t.chembl_id, t]));
|
|
12
|
-
const BY_GENE = new Map(PANEL.targets.map((t) => [t.gene_symbol, t]));
|
|
13
|
-
const BY_UNIPROT = new Map(PANEL.targets.map((t) => [t.uniprot, t]));
|
|
14
|
-
function detectType(id) {
|
|
15
|
-
if (CHEMBL_RE.test(id))
|
|
16
|
-
return "chembl_id";
|
|
17
|
-
if (UNIPROT_RE.test(id))
|
|
18
|
-
return "uniprot";
|
|
19
|
-
return "gene_symbol";
|
|
20
|
-
}
|
|
21
|
-
function lookup(id, type) {
|
|
22
|
-
switch (type) {
|
|
23
|
-
case "chembl_id":
|
|
24
|
-
return BY_CHEMBL.get(id) ?? null;
|
|
25
|
-
case "gene_symbol":
|
|
26
|
-
return BY_GENE.get(id.toUpperCase()) ?? null;
|
|
27
|
-
case "uniprot":
|
|
28
|
-
return BY_UNIPROT.get(id) ?? null;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
export const checkSafetyPanelTool = defineTool({
|
|
32
|
-
id: "check_safety_panel",
|
|
33
|
-
description: "Look up identifiers (ChEMBL ID, gene symbol, or UniProt accession) against the curated " +
|
|
34
|
-
"secondary-pharmacology safety target panel. Returns organ system, severity, and clinical " +
|
|
35
|
-
"consequence for each matched target. Use as a fast first-pass off-target liability check; " +
|
|
36
|
-
"for comprehensive assessment also call get-target-safety and search-toxcast.",
|
|
37
|
-
inputSchema: z.object({
|
|
38
|
-
identifiers: z.array(z.string().min(1)).min(0).max(200).describe("0-200 identifiers (ChEMBL IDs, gene symbols, or UniProt accessions)."),
|
|
39
|
-
identifier_type: z
|
|
40
|
-
.enum(["chembl_id", "gene_symbol", "uniprot", "auto"])
|
|
41
|
-
.default("auto")
|
|
42
|
-
.describe("Identifier interpretation. 'auto' detects per-input."),
|
|
43
|
-
filter_organ: z.enum(ORGAN_SYSTEMS).optional().describe("Restrict matches to this organ system."),
|
|
44
|
-
}),
|
|
45
|
-
execute: async ({ identifiers, identifier_type = "auto", filter_organ }) => {
|
|
46
|
-
const matches = identifiers.map((input) => {
|
|
47
|
-
const type = identifier_type === "auto" ? detectType(input) : identifier_type;
|
|
48
|
-
let entry = lookup(input, type);
|
|
49
|
-
if (entry && filter_organ && entry.organ_system !== filter_organ) {
|
|
50
|
-
entry = null;
|
|
51
|
-
}
|
|
52
|
-
return { input, matched_entry: entry };
|
|
53
|
-
});
|
|
54
|
-
const bySeverity = { high: 0, medium: 0, low: 0 };
|
|
55
|
-
const byOrgan = {};
|
|
56
|
-
let matched = 0;
|
|
57
|
-
for (const m of matches) {
|
|
58
|
-
if (!m.matched_entry)
|
|
59
|
-
continue;
|
|
60
|
-
matched++;
|
|
61
|
-
bySeverity[m.matched_entry.severity]++;
|
|
62
|
-
const o = m.matched_entry.organ_system;
|
|
63
|
-
byOrgan[o] = (byOrgan[o] ?? 0) + 1;
|
|
64
|
-
}
|
|
65
|
-
return ok({
|
|
66
|
-
matches,
|
|
67
|
-
summary: {
|
|
68
|
-
total_input: identifiers.length,
|
|
69
|
-
matched,
|
|
70
|
-
by_severity: bySeverity,
|
|
71
|
-
by_organ: byOrgan,
|
|
72
|
-
},
|
|
73
|
-
panel_version: PANEL.panel_version,
|
|
74
|
-
});
|
|
75
|
-
},
|
|
76
|
-
});
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* getImpcKoProfile tool — mouse knockout phenotype profile via IMPC Solr.
|
|
3
|
-
*/
|
|
4
|
-
import { buildViabilityCalls, derivedViability, parsePhenotypeResponse } from "../lib/impc-client.js";
|
|
5
|
-
export type { PhenotypeProfile, ViabilityCall, ViabilityCategory } from "../lib/impc-client.js";
|
|
6
|
-
export { buildViabilityCalls, derivedViability, parsePhenotypeResponse };
|
|
7
|
-
export declare const getImpcKoProfileTool: import("../define-tool.js").Tool<{
|
|
8
|
-
geneSymbol: string;
|
|
9
|
-
}, import("../lib/impc-client.js").KoPhenotypeProfile>;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* getImpcKoProfile tool — mouse knockout phenotype profile via IMPC Solr.
|
|
3
|
-
*/
|
|
4
|
-
import { ok } from "neverthrow";
|
|
5
|
-
import { z } from "zod";
|
|
6
|
-
import { defineTool } from "../define-tool.js";
|
|
7
|
-
import { buildViabilityCalls, derivedViability, getKoPhenotypeProfile, parsePhenotypeResponse } from "../lib/impc-client.js";
|
|
8
|
-
export { buildViabilityCalls, derivedViability, parsePhenotypeResponse };
|
|
9
|
-
export const getImpcKoProfileTool = defineTool({
|
|
10
|
-
id: "get_impc_ko_profile",
|
|
11
|
-
description: "Get the mouse-knockout phenotype profile for a gene from IMPC — the in-vivo loss-of-function evidence for target tractability and essentiality " +
|
|
12
|
-
"('what happens to PAX5 knockout mice?', 'is loss of CASP8 lethal?'). " +
|
|
13
|
-
"Takes a human gene symbol and maps it to the mouse ortholog itself. Returns a top-line pre-weaning viability call (lethal_pre_weaning | subviable | viable | null) with its " +
|
|
14
|
-
"per-zygosity breakdown, the significant MP phenotype terms ordered by best p-value, the affected organ systems ranked by phenotype count, and a sex-dimorphism flag. " +
|
|
15
|
-
"An all-empty profile (null mouseMarkerSymbol, null viability, no phenotype terms) means the gene has not been IMPC-phenotyped — common and valid. Do NOT retry on empty output.",
|
|
16
|
-
inputSchema: z.object({
|
|
17
|
-
geneSymbol: z
|
|
18
|
-
.string()
|
|
19
|
-
.min(1)
|
|
20
|
-
.describe("HUMAN gene symbol, e.g. 'BRCA1' — one gene per call. The mouse ortholog is resolved internally; do not pass a mouse symbol or an MGI ID."),
|
|
21
|
-
}),
|
|
22
|
-
execute: async ({ geneSymbol }) => ok(await getKoPhenotypeProfile(geneSymbol)),
|
|
23
|
-
});
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* lookupGoTerm — look up Gene Ontology terms via the QuickGO API (EBI).
|
|
3
|
-
*
|
|
4
|
-
* Supports direct ID lookup, keyword search, and gene annotation retrieval.
|
|
5
|
-
* Multiple modes can be combined in a single call.
|
|
6
|
-
*/
|
|
7
|
-
interface GoTerm {
|
|
8
|
-
id: string;
|
|
9
|
-
name: string;
|
|
10
|
-
definition?: string;
|
|
11
|
-
aspect?: string;
|
|
12
|
-
}
|
|
13
|
-
interface GoAnnotation {
|
|
14
|
-
geneProductId: string;
|
|
15
|
-
goId: string;
|
|
16
|
-
goName: string;
|
|
17
|
-
aspect?: string;
|
|
18
|
-
evidenceCode?: string;
|
|
19
|
-
qualifier?: string;
|
|
20
|
-
}
|
|
21
|
-
export declare const lookupGoTermTool: import("../define-tool.js").Tool<{
|
|
22
|
-
limit: number;
|
|
23
|
-
goId?: string | undefined;
|
|
24
|
-
query?: string | undefined;
|
|
25
|
-
geneProductId?: string | undefined;
|
|
26
|
-
taxonId?: number | undefined;
|
|
27
|
-
}, {
|
|
28
|
-
terms: GoTerm[] | undefined;
|
|
29
|
-
annotations: GoAnnotation[] | undefined;
|
|
30
|
-
}>;
|
|
31
|
-
export {};
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* lookupGoTerm — look up Gene Ontology terms via the QuickGO API (EBI).
|
|
3
|
-
*
|
|
4
|
-
* Supports direct ID lookup, keyword search, and gene annotation retrieval.
|
|
5
|
-
* Multiple modes can be combined in a single call.
|
|
6
|
-
*/
|
|
7
|
-
import { ok } from "neverthrow";
|
|
8
|
-
import { z } from "zod";
|
|
9
|
-
import { defineTool } from "../define-tool.js";
|
|
10
|
-
import { apiFetchValidated, describeApiError } from "../lib/api-utils.js";
|
|
11
|
-
const QUICKGO_BASE = "https://www.ebi.ac.uk/QuickGO/services";
|
|
12
|
-
const HEADERS = { Accept: "application/json" };
|
|
13
|
-
// QuickGO term response, validated at the fetch boundary. The `.transform`
|
|
14
|
-
// carries the (context-free) rename from the raw wire fields to the `GoTerm[]`
|
|
15
|
-
// we return, so parsing IS both the validation and the normalization — there
|
|
16
|
-
// is no separate raw interface or mapper to keep in sync.
|
|
17
|
-
const GoTermResponseSchema = z
|
|
18
|
-
.object({
|
|
19
|
-
results: z
|
|
20
|
-
.array(z.object({
|
|
21
|
-
id: z.string().optional(),
|
|
22
|
-
name: z.string().optional(),
|
|
23
|
-
definition: z.object({ text: z.string().optional() }).nullable().optional(),
|
|
24
|
-
aspect: z.string().optional(),
|
|
25
|
-
}))
|
|
26
|
-
.optional(),
|
|
27
|
-
})
|
|
28
|
-
.transform((res) => (res.results ?? []).map((t) => ({
|
|
29
|
-
id: t.id ?? "",
|
|
30
|
-
name: t.name ?? "",
|
|
31
|
-
definition: t.definition?.text ?? undefined,
|
|
32
|
-
aspect: t.aspect ?? undefined,
|
|
33
|
-
})));
|
|
34
|
-
const GoAnnotationResponseSchema = z
|
|
35
|
-
.object({
|
|
36
|
-
results: z
|
|
37
|
-
.array(z.object({
|
|
38
|
-
geneProductId: z.string().optional(),
|
|
39
|
-
goId: z.string().optional(),
|
|
40
|
-
goName: z.string().optional(),
|
|
41
|
-
goAspect: z.string().optional(),
|
|
42
|
-
goEvidence: z.string().optional(),
|
|
43
|
-
qualifier: z.string().optional(),
|
|
44
|
-
}))
|
|
45
|
-
.optional(),
|
|
46
|
-
})
|
|
47
|
-
.transform((res) => (res.results ?? []).map((a) => ({
|
|
48
|
-
geneProductId: a.geneProductId ?? "",
|
|
49
|
-
goId: a.goId ?? "",
|
|
50
|
-
goName: a.goName ?? "",
|
|
51
|
-
aspect: a.goAspect ?? undefined,
|
|
52
|
-
evidenceCode: a.goEvidence ?? undefined,
|
|
53
|
-
qualifier: a.qualifier ?? undefined,
|
|
54
|
-
})));
|
|
55
|
-
export const lookupGoTermTool = defineTool({
|
|
56
|
-
id: "lookup_go_term",
|
|
57
|
-
description: "Look up Gene Ontology terms from QuickGO (EBI). " +
|
|
58
|
-
"Can look up a term by GO ID, search by keyword, or retrieve GO annotations " +
|
|
59
|
-
"for a specific gene/protein. At least one of goId, query, or geneProductId must be provided.",
|
|
60
|
-
inputSchema: z
|
|
61
|
-
.object({
|
|
62
|
-
goId: z
|
|
63
|
-
.string()
|
|
64
|
-
.regex(/^GO:\d{7}$/)
|
|
65
|
-
.optional()
|
|
66
|
-
.describe("Specific GO term ID (e.g. 'GO:0008150')"),
|
|
67
|
-
query: z.string().optional().describe("Free-text search for GO terms (e.g. 'apoptotic process')"),
|
|
68
|
-
limit: z.number().int().min(1).max(100).default(10).describe("Maximum number of results per query type"),
|
|
69
|
-
geneProductId: z.string().optional().describe("UniProt ID to get annotations for (e.g. 'P04637')"),
|
|
70
|
-
taxonId: z.number().int().optional().describe("NCBI Taxon ID to filter annotations (9606 = human, 10090 = mouse)"),
|
|
71
|
-
})
|
|
72
|
-
.refine((d) => d.goId || d.query || d.geneProductId, {
|
|
73
|
-
message: "At least one of goId, query, or geneProductId is required",
|
|
74
|
-
}),
|
|
75
|
-
execute: async ({ goId, query, limit, geneProductId, taxonId }) => {
|
|
76
|
-
const tasks = [];
|
|
77
|
-
let terms;
|
|
78
|
-
let annotations;
|
|
79
|
-
if (goId) {
|
|
80
|
-
tasks.push((async () => {
|
|
81
|
-
const res = await apiFetchValidated(`${QUICKGO_BASE}/ontology/go/terms/${encodeURIComponent(goId)}`, GoTermResponseSchema, {
|
|
82
|
-
headers: HEADERS,
|
|
83
|
-
});
|
|
84
|
-
if (res.isErr())
|
|
85
|
-
throw new Error(`GO lookup: ${describeApiError(res.error)}`);
|
|
86
|
-
terms = res.value;
|
|
87
|
-
})());
|
|
88
|
-
}
|
|
89
|
-
if (query) {
|
|
90
|
-
tasks.push((async () => {
|
|
91
|
-
const params = new URLSearchParams({ query, limit: String(limit) });
|
|
92
|
-
const res = await apiFetchValidated(`${QUICKGO_BASE}/ontology/go/search?${params}`, GoTermResponseSchema, { headers: HEADERS });
|
|
93
|
-
if (res.isErr())
|
|
94
|
-
throw new Error(`GO search: ${describeApiError(res.error)}`);
|
|
95
|
-
const searchTerms = res.value;
|
|
96
|
-
terms = terms ? [...terms, ...searchTerms] : searchTerms;
|
|
97
|
-
})());
|
|
98
|
-
}
|
|
99
|
-
if (geneProductId) {
|
|
100
|
-
tasks.push((async () => {
|
|
101
|
-
const params = new URLSearchParams({
|
|
102
|
-
geneProductId,
|
|
103
|
-
limit: String(limit),
|
|
104
|
-
});
|
|
105
|
-
if (taxonId)
|
|
106
|
-
params.set("taxonId", String(taxonId));
|
|
107
|
-
const res = await apiFetchValidated(`${QUICKGO_BASE}/annotation/search?${params}`, GoAnnotationResponseSchema, { headers: HEADERS });
|
|
108
|
-
if (res.isErr())
|
|
109
|
-
throw new Error(`Annotations: ${describeApiError(res.error)}`);
|
|
110
|
-
annotations = res.value;
|
|
111
|
-
})());
|
|
112
|
-
}
|
|
113
|
-
await Promise.all(tasks);
|
|
114
|
-
return ok({ terms, annotations });
|
|
115
|
-
},
|
|
116
|
-
});
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* searchBgeeExpression tool — cross-species baseline gene expression.
|
|
3
|
-
*/
|
|
4
|
-
import { SUPPORTED_SPECIES, bucketRank, parseExpressionResponse } from "../lib/bgee-client.js";
|
|
5
|
-
export type { SupportedSpecies } from "../lib/bgee-client.js";
|
|
6
|
-
export { SUPPORTED_SPECIES, bucketRank, parseExpressionResponse };
|
|
7
|
-
export declare const searchBgeeExpressionTool: import("../define-tool.js").Tool<{
|
|
8
|
-
geneSymbol: string;
|
|
9
|
-
species: ("homo_sapiens" | "mus_musculus" | "rattus_norvegicus" | "canis_lupus_familiaris" | "macaca_mulatta")[];
|
|
10
|
-
}, import("../lib/bgee-client.js").MultiSpeciesExpression>;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* searchBgeeExpression tool — cross-species baseline gene expression.
|
|
3
|
-
*/
|
|
4
|
-
import { ok } from "neverthrow";
|
|
5
|
-
import { z } from "zod";
|
|
6
|
-
import { defineTool } from "../define-tool.js";
|
|
7
|
-
import { SUPPORTED_SPECIES, bucketRank, getMultiSpeciesExpression, parseExpressionResponse } from "../lib/bgee-client.js";
|
|
8
|
-
export { SUPPORTED_SPECIES, bucketRank, parseExpressionResponse };
|
|
9
|
-
export const searchBgeeExpressionTool = defineTool({
|
|
10
|
-
id: "search_bgee_expression",
|
|
11
|
-
description: "Get BASELINE (healthy, untreated) gene expression across species from Bgee — use it to judge tissue-of-action ('where is this target expressed?') and model-organism " +
|
|
12
|
-
"suitability ('is the mouse a fair surrogate for this gene?'). " +
|
|
13
|
-
"NOT for differential expression between conditions — that is the analysis pipeline's job, never this tool. " +
|
|
14
|
-
"Takes a human gene symbol and resolves the per-species orthologs itself, returning a per-species tissue table: each tissue carries an expression score, a gold/silver confidence, " +
|
|
15
|
-
"an expressed / not-expressed state, and a bucketed rank (absent | low | medium | high). Species with no ortholog are listed in notFound. " +
|
|
16
|
-
"Sparse output is valid no-data: dog and macaque coverage is thin, and a null humanEnsemblId means the symbol did not resolve. Do NOT retry on empty output.",
|
|
17
|
-
inputSchema: z.object({
|
|
18
|
-
geneSymbol: z
|
|
19
|
-
.string()
|
|
20
|
-
.min(1)
|
|
21
|
-
.describe("HUMAN gene symbol, e.g. 'BRCA1' — one gene per call. Ensembl IDs and non-human symbols are not accepted; the human symbol is resolved to an ENSG and orthologs are looked up per species."),
|
|
22
|
-
species: z
|
|
23
|
-
.array(z.enum(SUPPORTED_SPECIES))
|
|
24
|
-
.min(1)
|
|
25
|
-
.default([...SUPPORTED_SPECIES])
|
|
26
|
-
.describe("Species to fetch, any subset of: homo_sapiens, mus_musculus, rattus_norvegicus, canis_lupus_familiaris, macaca_mulatta. " +
|
|
27
|
-
"Defaults to all five — narrow it only when the cross-species comparison is not needed."),
|
|
28
|
-
}),
|
|
29
|
-
execute: async ({ geneSymbol, species }) => ok(await getMultiSpeciesExpression(geneSymbol, species)),
|
|
30
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* searchClinvar — search NCBI ClinVar for clinical significance of variants.
|
|
3
|
-
*/
|
|
4
|
-
export declare function createSearchClinvarTool(deps: {
|
|
5
|
-
ncbiApiKey?: string;
|
|
6
|
-
}): import("../define-tool.js").Tool<{
|
|
7
|
-
query: string;
|
|
8
|
-
limit: number;
|
|
9
|
-
clinicalSignificance?: "pathogenic" | "likely-pathogenic" | "benign" | "likely-benign" | "uncertain" | undefined;
|
|
10
|
-
}, {
|
|
11
|
-
totalFound: number;
|
|
12
|
-
variants: import("../lib/clinvar-client.js").ClinvarVariant[];
|
|
13
|
-
}>;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* searchClinvar — search NCBI ClinVar for clinical significance of variants.
|
|
3
|
-
*/
|
|
4
|
-
import { ok } from "neverthrow";
|
|
5
|
-
import { z } from "zod";
|
|
6
|
-
import { defineTool } from "../define-tool.js";
|
|
7
|
-
import { searchClinvar } from "../lib/clinvar-client.js";
|
|
8
|
-
export function createSearchClinvarTool(deps) {
|
|
9
|
-
return defineTool({
|
|
10
|
-
id: "search_clinvar",
|
|
11
|
-
description: "Search NCBI ClinVar for clinical significance of genetic variants. Returns pathogenicity classifications, associated conditions, and review status. Use to assess whether variants identified in omics data have known clinical significance.",
|
|
12
|
-
inputSchema: z.object({
|
|
13
|
-
query: z.string().describe("Gene symbol (e.g. BRCA1), variant (e.g. NM_007294.4:c.5266dupC), dbSNP rsID (e.g. rs80357906), or condition name"),
|
|
14
|
-
clinicalSignificance: z
|
|
15
|
-
.enum(["pathogenic", "likely-pathogenic", "benign", "likely-benign", "uncertain"])
|
|
16
|
-
.optional()
|
|
17
|
-
.describe("Filter by clinical significance"),
|
|
18
|
-
limit: z.number().int().min(1).max(100).default(20).describe("Max results to return"),
|
|
19
|
-
}),
|
|
20
|
-
execute: async ({ query, clinicalSignificance, limit = 20 }) => {
|
|
21
|
-
const { totalFound, variants } = await searchClinvar(deps.ncbiApiKey, query, {
|
|
22
|
-
clinicalSignificance,
|
|
23
|
-
limit,
|
|
24
|
-
});
|
|
25
|
-
return ok({ totalFound, variants });
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* searchDgidb tool — query drug-gene interactions via DGIdb GraphQL.
|
|
3
|
-
*
|
|
4
|
-
* DGIdb aggregates interactions from 30+ sources (ChEMBL, DrugBank, TTD,
|
|
5
|
-
* PharmGKB, GuideToPharmacology, CIViC, etc.). Free, no API key required.
|
|
6
|
-
*
|
|
7
|
-
* Two directions:
|
|
8
|
-
* - searchType="gene": input HUGO symbols, returns drugs interacting with each.
|
|
9
|
-
* - searchType="drug": input drug names/concept IDs, returns genes each acts on.
|
|
10
|
-
*/
|
|
11
|
-
import type { Logger } from "../../lib/logger.js";
|
|
12
|
-
interface Interaction {
|
|
13
|
-
geneName: string;
|
|
14
|
-
drugName: string;
|
|
15
|
-
drugConceptId?: string;
|
|
16
|
-
interactionTypes: {
|
|
17
|
-
type: string;
|
|
18
|
-
directionality?: string;
|
|
19
|
-
}[];
|
|
20
|
-
interactionScore?: number;
|
|
21
|
-
sourceCount: number;
|
|
22
|
-
sources: string[];
|
|
23
|
-
publicationCount: number;
|
|
24
|
-
pmids: string[];
|
|
25
|
-
attributes: {
|
|
26
|
-
name: string;
|
|
27
|
-
value: string;
|
|
28
|
-
}[];
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* A factory rather than a bare const (unlike its bio-leaf siblings) because it
|
|
32
|
-
* logs: DGIdb answers GraphQL partial errors alongside usable data, and an
|
|
33
|
-
* operator debugging odd interaction results needs to see them. `ToolContext`
|
|
34
|
-
* carries no deps by design, so a tool that logs is dep-bearing — the same
|
|
35
|
-
* reason `createSearchClinvarTool` takes its key that way.
|
|
36
|
-
*/
|
|
37
|
-
export declare function createSearchDgidbTool(deps?: {
|
|
38
|
-
readonly logger?: Logger;
|
|
39
|
-
}): import("../define-tool.js").Tool<{
|
|
40
|
-
query: string | string[];
|
|
41
|
-
searchType: "drug" | "gene";
|
|
42
|
-
minSources: number;
|
|
43
|
-
limit: number;
|
|
44
|
-
interactionTypes?: string[] | undefined;
|
|
45
|
-
sources?: string[] | undefined;
|
|
46
|
-
}, {
|
|
47
|
-
results: {
|
|
48
|
-
input: string;
|
|
49
|
-
found: boolean;
|
|
50
|
-
interactions: Interaction[];
|
|
51
|
-
}[];
|
|
52
|
-
}>;
|
|
53
|
-
export {};
|