@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
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The report version store -- the append-only record of report versions.
|
|
3
|
+
*
|
|
4
|
+
* A version is one immutable row. It holds the block document, the pinned
|
|
5
|
+
* snapshot, and the anchor. The store records a version and reads a version. It
|
|
6
|
+
* never updates a recorded row, thus a correction is a new version.
|
|
7
|
+
*
|
|
8
|
+
* A thread holds at most one version, and a named unique constraint on the thread
|
|
9
|
+
* id enforces it. The record reads nothing before the insert. A second record for
|
|
10
|
+
* one thread trips the constraint, and the store maps that trip to the typed
|
|
11
|
+
* refusal thread_already_holds_version.
|
|
12
|
+
*
|
|
13
|
+
* The store keeps the snapshot and the anchor as given, and it never pins a
|
|
14
|
+
* snapshot. A read parses the stored document and the stored snapshot with the
|
|
15
|
+
* current schemas. A row that fails a parse reads as a typed error, and it does
|
|
16
|
+
* not crash. An absent row reads as a normal absence.
|
|
17
|
+
*
|
|
18
|
+
* A version outlives its thread. The anchor columns sit on the row, thus a
|
|
19
|
+
* deleted thread leaves a recorded version in place. Only a purge of the analysis
|
|
20
|
+
* removes the version, through the analysis-id cascade.
|
|
21
|
+
*/
|
|
22
|
+
import { type ResultAsync } from "neverthrow";
|
|
23
|
+
import type { Pool } from "pg";
|
|
24
|
+
import { type ReportDocument } from "../contracts/report-blocks.js";
|
|
25
|
+
import { type DbError } from "../lib/db-result.js";
|
|
26
|
+
import type { Logger } from "../lib/logger.js";
|
|
27
|
+
import type { ReportSnapshot } from "../report-model/reference-resolver.js";
|
|
28
|
+
import { type SchemaIssue } from "./snapshot-parse.js";
|
|
29
|
+
export type { SchemaIssue };
|
|
30
|
+
/** The anchor and the payload of a version to record. */
|
|
31
|
+
export interface RecordVersionInput {
|
|
32
|
+
/** The block document. It rides as `unknown`, and the record parses it. */
|
|
33
|
+
readonly document: unknown;
|
|
34
|
+
/** The pinned snapshot, stored as given. */
|
|
35
|
+
readonly snapshot: ReportSnapshot;
|
|
36
|
+
readonly analysisId: string;
|
|
37
|
+
readonly threadId: string;
|
|
38
|
+
/** The parent conversation thread of the anchor, or `null` when a root has none. */
|
|
39
|
+
readonly parentThreadId: string | null;
|
|
40
|
+
/** The parent transcript position of the anchor, or `null` beside a null parent thread. */
|
|
41
|
+
readonly parentSeq: number | null;
|
|
42
|
+
/** The earlier version that this one reuses. The parent must belong to the same analysis. */
|
|
43
|
+
readonly parentVersionId?: string;
|
|
44
|
+
}
|
|
45
|
+
/** The stable reference of a freshly recorded version. */
|
|
46
|
+
export interface RecordedVersionRef {
|
|
47
|
+
readonly versionId: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A record the store refuses as data, before or in place of a row. Distinct from
|
|
51
|
+
* `DbError`: the request describes a version that the store will not write.
|
|
52
|
+
*
|
|
53
|
+
* The store parses the document and the snapshot before any row. The store
|
|
54
|
+
* refuses a malformed document or a malformed snapshot here as typed data, and
|
|
55
|
+
* no row lands.
|
|
56
|
+
*
|
|
57
|
+
* A second record for one thread is `thread_already_holds_version`. The unique
|
|
58
|
+
* constraint on the thread id trips, and the record maps that one constraint by
|
|
59
|
+
* its name. Every other constraint trip stays a `DbError`.
|
|
60
|
+
*
|
|
61
|
+
* A `parentVersionId` naming no row is not one of these -- the self foreign key
|
|
62
|
+
* refuses an unknown parent id, and `tryMutation` classifies that refusal as the
|
|
63
|
+
* `constraint_violation` variant of `DbError`.
|
|
64
|
+
*/
|
|
65
|
+
export type RecordVersionError = {
|
|
66
|
+
readonly type: "malformed_document";
|
|
67
|
+
readonly op: string;
|
|
68
|
+
readonly issues: readonly SchemaIssue[];
|
|
69
|
+
} | {
|
|
70
|
+
readonly type: "malformed_snapshot";
|
|
71
|
+
readonly op: string;
|
|
72
|
+
readonly issues: readonly SchemaIssue[];
|
|
73
|
+
} | {
|
|
74
|
+
readonly type: "parent_analysis_mismatch";
|
|
75
|
+
readonly op: string;
|
|
76
|
+
readonly analysisId: string;
|
|
77
|
+
readonly parentVersionId: string;
|
|
78
|
+
readonly parentAnalysisId: string;
|
|
79
|
+
} | {
|
|
80
|
+
readonly type: "thread_already_holds_version";
|
|
81
|
+
readonly op: string;
|
|
82
|
+
readonly threadId: string;
|
|
83
|
+
} | DbError;
|
|
84
|
+
/**
|
|
85
|
+
* A stored row that a read cannot parse with the current schemas. It names the
|
|
86
|
+
* version id and the part that failed, and it carries the reduced issues.
|
|
87
|
+
*/
|
|
88
|
+
export type VersionReadError = {
|
|
89
|
+
readonly type: "corrupt_version";
|
|
90
|
+
readonly op: string;
|
|
91
|
+
readonly versionId: string;
|
|
92
|
+
readonly part: "document" | "snapshot";
|
|
93
|
+
readonly issues: readonly SchemaIssue[];
|
|
94
|
+
};
|
|
95
|
+
/** One recorded version, as the store gives it back. */
|
|
96
|
+
export interface RecordedVersion {
|
|
97
|
+
readonly versionId: string;
|
|
98
|
+
readonly analysisId: string;
|
|
99
|
+
readonly threadId: string;
|
|
100
|
+
readonly parentThreadId: string | null;
|
|
101
|
+
readonly parentSeq: number | null;
|
|
102
|
+
/** The earlier version that this one reuses, or `null` when it has none. */
|
|
103
|
+
readonly parentVersionId: string | null;
|
|
104
|
+
readonly document: ReportDocument;
|
|
105
|
+
readonly snapshot: ReportSnapshot;
|
|
106
|
+
readonly createdAt: Date;
|
|
107
|
+
}
|
|
108
|
+
export interface ReportVersionStore {
|
|
109
|
+
/**
|
|
110
|
+
* Record a version. The record parses the document, refuses a malformed value
|
|
111
|
+
* as data with no row, and refuses a parent from a different analysis. It reads
|
|
112
|
+
* nothing before the insert. A second record for one thread refuses with
|
|
113
|
+
* thread_already_holds_version. The snapshot and the anchor store as given.
|
|
114
|
+
*/
|
|
115
|
+
record(input: RecordVersionInput): ResultAsync<RecordedVersionRef, RecordVersionError>;
|
|
116
|
+
/** One version by its id, or `null` when no row holds it. */
|
|
117
|
+
getVersion(versionId: string): ResultAsync<RecordedVersion | null, DbError | VersionReadError>;
|
|
118
|
+
/** The one version of a thread, or `null` for a thread with no version. */
|
|
119
|
+
getThreadVersion(threadId: string): ResultAsync<RecordedVersion | null, DbError | VersionReadError>;
|
|
120
|
+
}
|
|
121
|
+
export interface ReportVersionStoreDeps {
|
|
122
|
+
readonly pool: Pool;
|
|
123
|
+
readonly logger?: Logger;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Create a `ReportVersionStore` bound to a Postgres pool. The
|
|
127
|
+
* `cortex_report_versions` table is provisioned by the state-init DDL.
|
|
128
|
+
*/
|
|
129
|
+
export declare function createReportVersionStore({ pool }: ReportVersionStoreDeps): ReportVersionStore;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The report version store -- the append-only record of report versions.
|
|
3
|
+
*
|
|
4
|
+
* A version is one immutable row. It holds the block document, the pinned
|
|
5
|
+
* snapshot, and the anchor. The store records a version and reads a version. It
|
|
6
|
+
* never updates a recorded row, thus a correction is a new version.
|
|
7
|
+
*
|
|
8
|
+
* A thread holds at most one version, and a named unique constraint on the thread
|
|
9
|
+
* id enforces it. The record reads nothing before the insert. A second record for
|
|
10
|
+
* one thread trips the constraint, and the store maps that trip to the typed
|
|
11
|
+
* refusal thread_already_holds_version.
|
|
12
|
+
*
|
|
13
|
+
* The store keeps the snapshot and the anchor as given, and it never pins a
|
|
14
|
+
* snapshot. A read parses the stored document and the stored snapshot with the
|
|
15
|
+
* current schemas. A row that fails a parse reads as a typed error, and it does
|
|
16
|
+
* not crash. An absent row reads as a normal absence.
|
|
17
|
+
*
|
|
18
|
+
* A version outlives its thread. The anchor columns sit on the row, thus a
|
|
19
|
+
* deleted thread leaves a recorded version in place. Only a purge of the analysis
|
|
20
|
+
* removes the version, through the analysis-id cascade.
|
|
21
|
+
*/
|
|
22
|
+
import { randomUUID } from "node:crypto";
|
|
23
|
+
import { err, errAsync, ok } from "neverthrow";
|
|
24
|
+
import { ReportDocumentSchema } from "../contracts/report-blocks.js";
|
|
25
|
+
import { tryMutation, tryQuery } from "../lib/db-result.js";
|
|
26
|
+
import { parseSnapshot, reduceIssues } from "./snapshot-parse.js";
|
|
27
|
+
/**
|
|
28
|
+
* The name of the unique constraint on thread_id. Postgres reports it on a
|
|
29
|
+
* duplicate-thread refusal, and the record matches it to map the trip to the
|
|
30
|
+
* thread_already_holds_version refusal.
|
|
31
|
+
*/
|
|
32
|
+
const THREAD_UNIQUE_CONSTRAINT = "cortex_report_versions_one_per_thread";
|
|
33
|
+
const _assertRecordError = true;
|
|
34
|
+
const _assertReadError = true;
|
|
35
|
+
/**
|
|
36
|
+
* The full row projection every read shares. `parent_seq` is a bigint, thus the
|
|
37
|
+
* driver hands it back as text, and `rowToVersion` is the single place that turns
|
|
38
|
+
* it into a number.
|
|
39
|
+
*/
|
|
40
|
+
const VERSION_COLUMNS = "version_id, analysis_id, thread_id, parent_thread_id, parent_seq::text AS parent_seq, parent_version_id, document, snapshot, created_at";
|
|
41
|
+
/**
|
|
42
|
+
* The insert. The row carries no ordinal, thus the statement writes the given
|
|
43
|
+
* columns directly. `created_at` takes the column default.
|
|
44
|
+
*/
|
|
45
|
+
const INSERT_SQL = `INSERT INTO cortex_report_versions
|
|
46
|
+
(version_id, analysis_id, thread_id, parent_thread_id, parent_seq,
|
|
47
|
+
parent_version_id, document, snapshot)
|
|
48
|
+
VALUES ($1, $2, $3, $4, $5::bigint, $6, $7::jsonb, $8::jsonb)`;
|
|
49
|
+
function rowToVersion(row) {
|
|
50
|
+
const document = ReportDocumentSchema.safeParse(row.document);
|
|
51
|
+
if (!document.success) {
|
|
52
|
+
return err({ type: "corrupt_version", op: "report-versions.read", versionId: row.version_id, part: "document", issues: reduceIssues(document.error) });
|
|
53
|
+
}
|
|
54
|
+
const snapshot = parseSnapshot(row.snapshot);
|
|
55
|
+
if (snapshot.isErr()) {
|
|
56
|
+
return err({ type: "corrupt_version", op: "report-versions.read", versionId: row.version_id, part: "snapshot", issues: snapshot.error });
|
|
57
|
+
}
|
|
58
|
+
return ok({
|
|
59
|
+
versionId: row.version_id,
|
|
60
|
+
analysisId: row.analysis_id,
|
|
61
|
+
threadId: row.thread_id,
|
|
62
|
+
parentThreadId: row.parent_thread_id,
|
|
63
|
+
parentSeq: row.parent_seq === null ? null : Number(row.parent_seq),
|
|
64
|
+
parentVersionId: row.parent_version_id,
|
|
65
|
+
document: document.data,
|
|
66
|
+
snapshot: snapshot.value,
|
|
67
|
+
createdAt: row.created_at,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Map an insert failure to a record refusal. A trip of the thread constraint is
|
|
72
|
+
* thread_already_holds_version. Every other DbError stays unchanged.
|
|
73
|
+
*/
|
|
74
|
+
function mapInsertError(error, threadId) {
|
|
75
|
+
if (error.type === "constraint_violation" && error.constraint === THREAD_UNIQUE_CONSTRAINT) {
|
|
76
|
+
return { type: "thread_already_holds_version", op: "report-versions.record", threadId };
|
|
77
|
+
}
|
|
78
|
+
return error;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Create a `ReportVersionStore` bound to a Postgres pool. The
|
|
82
|
+
* `cortex_report_versions` table is provisioned by the state-init DDL.
|
|
83
|
+
*/
|
|
84
|
+
export function createReportVersionStore({ pool }) {
|
|
85
|
+
/**
|
|
86
|
+
* The analysis scope of a parent version, or `null` when no such row exists.
|
|
87
|
+
* Absence is not a verdict here: an unknown parent id falls through to the
|
|
88
|
+
* insert, where the self foreign key refuses it as a `DbError`.
|
|
89
|
+
*/
|
|
90
|
+
function parentAnalysis(parentVersionId) {
|
|
91
|
+
return tryQuery("report-versions.record.parentScope", () => pool.query({
|
|
92
|
+
text: "SELECT analysis_id FROM cortex_report_versions WHERE version_id = $1",
|
|
93
|
+
values: [parentVersionId],
|
|
94
|
+
})).map(({ rows }) => rows[0]?.analysis_id ?? null);
|
|
95
|
+
}
|
|
96
|
+
function record(input) {
|
|
97
|
+
const parsed = ReportDocumentSchema.safeParse(input.document);
|
|
98
|
+
if (!parsed.success) {
|
|
99
|
+
return errAsync({ type: "malformed_document", op: "report-versions.record", issues: reduceIssues(parsed.error) });
|
|
100
|
+
}
|
|
101
|
+
const document = parsed.data;
|
|
102
|
+
// The parse guards the row against a caller bug. The store stores the given
|
|
103
|
+
// value, thus the parse changes no value.
|
|
104
|
+
const parsedSnapshot = parseSnapshot(input.snapshot);
|
|
105
|
+
if (parsedSnapshot.isErr()) {
|
|
106
|
+
return errAsync({ type: "malformed_snapshot", op: "report-versions.record", issues: parsedSnapshot.error });
|
|
107
|
+
}
|
|
108
|
+
const insert = () => {
|
|
109
|
+
const versionId = randomUUID();
|
|
110
|
+
return tryMutation("report-versions.record.insert", async () => {
|
|
111
|
+
await pool.query({
|
|
112
|
+
text: INSERT_SQL,
|
|
113
|
+
values: [
|
|
114
|
+
versionId,
|
|
115
|
+
input.analysisId,
|
|
116
|
+
input.threadId,
|
|
117
|
+
input.parentThreadId,
|
|
118
|
+
input.parentSeq,
|
|
119
|
+
input.parentVersionId ?? null,
|
|
120
|
+
JSON.stringify(document),
|
|
121
|
+
JSON.stringify(input.snapshot),
|
|
122
|
+
],
|
|
123
|
+
});
|
|
124
|
+
return { versionId };
|
|
125
|
+
}).mapErr((error) => mapInsertError(error, input.threadId));
|
|
126
|
+
};
|
|
127
|
+
if (input.parentVersionId === undefined) {
|
|
128
|
+
return insert();
|
|
129
|
+
}
|
|
130
|
+
const parentVersionId = input.parentVersionId;
|
|
131
|
+
return parentAnalysis(parentVersionId).andThen((parentAnalysisId) => {
|
|
132
|
+
if (parentAnalysisId !== null && parentAnalysisId !== input.analysisId) {
|
|
133
|
+
return errAsync({
|
|
134
|
+
type: "parent_analysis_mismatch",
|
|
135
|
+
op: "report-versions.record",
|
|
136
|
+
analysisId: input.analysisId,
|
|
137
|
+
parentVersionId,
|
|
138
|
+
parentAnalysisId,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
return insert();
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
function getVersion(versionId) {
|
|
145
|
+
return tryQuery("report-versions.getVersion", () => pool.query({
|
|
146
|
+
text: `SELECT ${VERSION_COLUMNS} FROM cortex_report_versions WHERE version_id = $1`,
|
|
147
|
+
values: [versionId],
|
|
148
|
+
})).andThen(({ rows }) => {
|
|
149
|
+
const row = rows[0];
|
|
150
|
+
if (!row)
|
|
151
|
+
return ok(null);
|
|
152
|
+
return rowToVersion(row);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
function getThreadVersion(threadId) {
|
|
156
|
+
return tryQuery("report-versions.getThreadVersion", () => pool.query({
|
|
157
|
+
text: `SELECT ${VERSION_COLUMNS} FROM cortex_report_versions WHERE thread_id = $1`,
|
|
158
|
+
values: [threadId],
|
|
159
|
+
})).andThen(({ rows }) => {
|
|
160
|
+
const row = rows[0];
|
|
161
|
+
if (!row)
|
|
162
|
+
return ok(null);
|
|
163
|
+
return rowToVersion(row);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
return { record, getVersion, getThreadVersion };
|
|
167
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one parse of a stored report snapshot, shared by the two stores.
|
|
3
|
+
*
|
|
4
|
+
* The session-state store and the version store each hold a snapshot column, and
|
|
5
|
+
* each reads it back the same way. A path such as `__proto__` is an ordinary
|
|
6
|
+
* artifact key of the ledger, and the pin keeps it as an own member of a
|
|
7
|
+
* null-prototype map (`report-model/pin-snapshot.ts`). Each object-shaped schema
|
|
8
|
+
* of zod drops such a key, thus a store that parsed the map through one would
|
|
9
|
+
* resolve a reference to that artifact before a reload and refuse it as absent
|
|
10
|
+
* after one. The walk reads the own keys of the stored map, and it parses each
|
|
11
|
+
* value on its own, thus the two stores agree on the key set.
|
|
12
|
+
*/
|
|
13
|
+
import { type Result } from "neverthrow";
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
import type { ReportSnapshot } from "../report-model/reference-resolver.js";
|
|
16
|
+
/** One reduced schema issue -- the dotted path and the message, without the rest. */
|
|
17
|
+
export interface SchemaIssue {
|
|
18
|
+
readonly path: string;
|
|
19
|
+
readonly message: string;
|
|
20
|
+
}
|
|
21
|
+
/** Reduce a zod error to the dotted path and the message of each issue. */
|
|
22
|
+
export declare function reduceIssues(error: z.ZodError): SchemaIssue[];
|
|
23
|
+
/**
|
|
24
|
+
* Parse a stored snapshot.
|
|
25
|
+
*
|
|
26
|
+
* The artifacts map never goes through a zod object schema, for the reason that
|
|
27
|
+
* the module header gives: a zod object drops a `__proto__` key and the pin keeps
|
|
28
|
+
* it. The walk reads the own keys of the stored map, and it parses each value on
|
|
29
|
+
* its own.
|
|
30
|
+
*
|
|
31
|
+
* The `ReportSnapshot` return type ties this parse to the type of the reference
|
|
32
|
+
* model, thus a change to one shows as a compile error here.
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseSnapshot(stored: unknown): Result<ReportSnapshot, SchemaIssue[]>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one parse of a stored report snapshot, shared by the two stores.
|
|
3
|
+
*
|
|
4
|
+
* The session-state store and the version store each hold a snapshot column, and
|
|
5
|
+
* each reads it back the same way. A path such as `__proto__` is an ordinary
|
|
6
|
+
* artifact key of the ledger, and the pin keeps it as an own member of a
|
|
7
|
+
* null-prototype map (`report-model/pin-snapshot.ts`). Each object-shaped schema
|
|
8
|
+
* of zod drops such a key, thus a store that parsed the map through one would
|
|
9
|
+
* resolve a reference to that artifact before a reload and refuse it as absent
|
|
10
|
+
* after one. The walk reads the own keys of the stored map, and it parses each
|
|
11
|
+
* value on its own, thus the two stores agree on the key set.
|
|
12
|
+
*/
|
|
13
|
+
import { err, ok } from "neverthrow";
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
/**
|
|
16
|
+
* One pinned artifact of a stored snapshot. The value carries the content hash, an
|
|
17
|
+
* optional file type, and optional rows.
|
|
18
|
+
*/
|
|
19
|
+
const ArtifactSnapshotSchema = z.object({
|
|
20
|
+
hash: z.string(),
|
|
21
|
+
fileType: z.string().nullable().optional(),
|
|
22
|
+
rows: z.array(z.record(z.string(), z.union([z.string(), z.number()]))).optional(),
|
|
23
|
+
});
|
|
24
|
+
/** The citation list of a stored snapshot. A snapshot with no list reads as an absent field. */
|
|
25
|
+
const CitationsSchema = z.array(z.string()).optional();
|
|
26
|
+
/** Reduce a zod error to the dotted path and the message of each issue. */
|
|
27
|
+
export function reduceIssues(error) {
|
|
28
|
+
return error.issues.map((issue) => ({
|
|
29
|
+
path: issue.path.map((segment) => String(segment)).join("."),
|
|
30
|
+
message: issue.message,
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
/** Put a prefix before the path of each issue, thus a nested parse names the key that failed. */
|
|
34
|
+
function prefixIssues(prefix, issues) {
|
|
35
|
+
return issues.map((issue) => ({
|
|
36
|
+
path: issue.path === "" ? prefix : `${prefix}.${issue.path}`,
|
|
37
|
+
message: issue.message,
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
/** A stored map is a plain object. An array and a null carry no own key that a map read can use. */
|
|
41
|
+
function isPlainRecord(value) {
|
|
42
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Parse a stored snapshot.
|
|
46
|
+
*
|
|
47
|
+
* The artifacts map never goes through a zod object schema, for the reason that
|
|
48
|
+
* the module header gives: a zod object drops a `__proto__` key and the pin keeps
|
|
49
|
+
* it. The walk reads the own keys of the stored map, and it parses each value on
|
|
50
|
+
* its own.
|
|
51
|
+
*
|
|
52
|
+
* The `ReportSnapshot` return type ties this parse to the type of the reference
|
|
53
|
+
* model, thus a change to one shows as a compile error here.
|
|
54
|
+
*/
|
|
55
|
+
export function parseSnapshot(stored) {
|
|
56
|
+
if (!isPlainRecord(stored)) {
|
|
57
|
+
return err([{ path: "", message: "the stored snapshot is not an object" }]);
|
|
58
|
+
}
|
|
59
|
+
if (!isPlainRecord(stored.artifacts)) {
|
|
60
|
+
return err([{ path: "artifacts", message: "the artifacts map is not an object" }]);
|
|
61
|
+
}
|
|
62
|
+
const citations = CitationsSchema.safeParse(stored.citations);
|
|
63
|
+
if (!citations.success) {
|
|
64
|
+
return err(prefixIssues("citations", reduceIssues(citations.error)));
|
|
65
|
+
}
|
|
66
|
+
// The map takes a null prototype, the same as the pin, thus a path such as
|
|
67
|
+
// `__proto__` stays an ordinary entry and never reaches a prototype slot.
|
|
68
|
+
const artifacts = Object.create(null);
|
|
69
|
+
const issues = [];
|
|
70
|
+
for (const [path, value] of Object.entries(stored.artifacts)) {
|
|
71
|
+
const parsed = ArtifactSnapshotSchema.safeParse(value);
|
|
72
|
+
if (!parsed.success) {
|
|
73
|
+
issues.push(...prefixIssues(`artifacts.${path}`, reduceIssues(parsed.error)));
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
artifacts[path] = parsed.data;
|
|
77
|
+
}
|
|
78
|
+
if (issues.length > 0) {
|
|
79
|
+
return err(issues);
|
|
80
|
+
}
|
|
81
|
+
return citations.data === undefined ? ok({ artifacts }) : ok({ artifacts, citations: citations.data });
|
|
82
|
+
}
|
|
@@ -272,6 +272,7 @@ export async function runDataProfileBody(input, deps) {
|
|
|
272
272
|
id: "submit_profile",
|
|
273
273
|
description: "Submit the profiling results. Call this tool once after completing " + "all profiling work — it validates and records your findings.",
|
|
274
274
|
inputSchema: ProfilerOutputSchema,
|
|
275
|
+
describeCall: "none",
|
|
275
276
|
execute: async (input) => {
|
|
276
277
|
capturedProfile = input;
|
|
277
278
|
return ok({ status: "accepted" });
|
|
@@ -2,7 +2,7 @@ import type { Pool } from "pg";
|
|
|
2
2
|
import { type AgentSession } from "../auth/types.js";
|
|
3
3
|
import type { ResourcePolicy, ResourceSpec } from "../config/resource-limits.js";
|
|
4
4
|
import type { Logger } from "../lib/logger.js";
|
|
5
|
-
import type
|
|
5
|
+
import { type ChatProvider } from "../providers/types.js";
|
|
6
6
|
export declare const AD_HOC_ROUTER_AGENT_ID = "adhoc-router";
|
|
7
7
|
export declare const AD_HOC_ROUTER_TIMEOUT_MS = 10000;
|
|
8
8
|
export declare const AD_HOC_FALLBACK_AGENT_ID = "scientific-executor";
|
|
@@ -18,7 +18,12 @@ export interface AdHocRouterDeps {
|
|
|
18
18
|
readonly pool: Pool;
|
|
19
19
|
readonly resourcePolicy?: ResourcePolicy;
|
|
20
20
|
readonly logger?: Logger;
|
|
21
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Test seam that sets an explicit deadline. An explicit value overrides the
|
|
23
|
+
* derived deadline. The derived deadline is the maximum of
|
|
24
|
+
* {@link AD_HOC_ROUTER_TIMEOUT_MS} and the request-timeout limit that the
|
|
25
|
+
* provider advertises.
|
|
26
|
+
*/
|
|
22
27
|
readonly timeoutMs?: number;
|
|
23
28
|
}
|
|
24
29
|
export declare function defaultAdHocResources(policy?: ResourcePolicy): ResourceSpec;
|
|
@@ -6,6 +6,7 @@ import { DATA_PROFILE_ORIENTATION_MAX_CHARS, buildDataProfileOrientation } from
|
|
|
6
6
|
import { createNoopLogger } from "../lib/console-logger.js";
|
|
7
7
|
import { unwrapOrThrow } from "../lib/result.js";
|
|
8
8
|
import { resourceEstimationSection } from "../prompts/planner.js";
|
|
9
|
+
import { effectiveDeadlineMs } from "../providers/types.js";
|
|
9
10
|
import { loadDataProfileStatus } from "../state/index.js";
|
|
10
11
|
export const AD_HOC_ROUTER_AGENT_ID = "adhoc-router";
|
|
11
12
|
export const AD_HOC_ROUTER_TIMEOUT_MS = 10_000;
|
|
@@ -72,7 +73,7 @@ export async function routeAdHocRequest(deps, input) {
|
|
|
72
73
|
const catalog = PLANNABLE_AGENT_CATALOG.map((agent) => `- ${agent.id}: capabilities [${agent.capabilities.join(", ")}]; suitable for [${agent.suitableFor.join(", ")}]`).join("\n");
|
|
73
74
|
const orientation = await profileOrientation(deps.pool, input.analysisId, logger);
|
|
74
75
|
const controller = new AbortController();
|
|
75
|
-
const timer = setTimeout(() => controller.abort(new Error("ad hoc routing timed out")), deps.
|
|
76
|
+
const timer = setTimeout(() => controller.abort(new Error("ad hoc routing timed out")), effectiveDeadlineMs(deps.provider, AD_HOC_ROUTER_TIMEOUT_MS, deps.timeoutMs));
|
|
76
77
|
const signal = AbortSignal.any([input.signal, controller.signal]);
|
|
77
78
|
let raw;
|
|
78
79
|
let failure;
|
package/dist/tools/bio/chembl.js
CHANGED
|
@@ -118,6 +118,7 @@ export const chemblTool = defineTool({
|
|
|
118
118
|
"compounds here first. If ChEMBL misses the compound, resolve it via pubchem action='compound' and bridge back with pubchem action='crossrefs'.\n" +
|
|
119
119
|
"An empty array is valid no-data, not an error — do not retry the same call.",
|
|
120
120
|
inputSchema,
|
|
121
|
+
describeCall: "none",
|
|
121
122
|
execute: async ({ action, query, searchType, chemblId, idType, activityType, limit }) => {
|
|
122
123
|
switch (action) {
|
|
123
124
|
case "compounds":
|
|
@@ -106,6 +106,7 @@ export function createComptoxTool(deps) {
|
|
|
106
106
|
"This is environmental/industrial-chemical data: for drug-like compounds prefer PubChem or ChEMBL — dataset 'chemical' returns " +
|
|
107
107
|
"`detail.pubchemCid` to bridge back.",
|
|
108
108
|
inputSchema,
|
|
109
|
+
describeCall: "none",
|
|
109
110
|
execute: async (input) => {
|
|
110
111
|
const headers = getEpaCcteHeaders(deps.apiKey);
|
|
111
112
|
const resolved = await resolveDtxsid(input.query, headers);
|
|
@@ -119,6 +119,7 @@ export function createDrugGeneInteractionsTool(deps) {
|
|
|
119
119
|
"not be reached (a missing DRUGBANK_API_KEY lands here — tell the user and proceed with DGIdb). A `found: false` entry means the identifier " +
|
|
120
120
|
"is not in DGIdb at all, usually a non-HUGO symbol or a brand name. Neither is worth retrying unchanged.",
|
|
121
121
|
inputSchema,
|
|
122
|
+
describeCall: "none",
|
|
122
123
|
execute: async (input) => {
|
|
123
124
|
const inputs = typeof input.query === "string" ? [input.query] : input.query;
|
|
124
125
|
const selected = input.sources ?? ["dgidb"];
|
|
@@ -118,6 +118,7 @@ export function createGeneDiseaseEvidenceTool(deps) {
|
|
|
118
118
|
"could not be reached (a missing DISGENET_API_KEY lands here — tell the user and proceed with the other two); 'not_applicable' means that " +
|
|
119
119
|
"corpus has no lookup for this queryType. Only 'no_data' is evidence of absence, and none is worth retrying unchanged.",
|
|
120
120
|
inputSchema,
|
|
121
|
+
describeCall: "none",
|
|
121
122
|
execute: async (input) => {
|
|
122
123
|
const applicable = applicableSources(input.queryType);
|
|
123
124
|
const requested = input.sources ?? applicable;
|
|
@@ -105,6 +105,7 @@ export const genePreclinicalProfileTool = defineTool({
|
|
|
105
105
|
"SPARSE OUTPUT IS VALID NO-DATA, not an error — do not retry. A null humanEnsemblId means the symbol did not resolve; a null mouseMarkerSymbol " +
|
|
106
106
|
"with no phenotype terms means the gene has not been IMPC-phenotyped, which is common.",
|
|
107
107
|
inputSchema,
|
|
108
|
+
describeCall: "none",
|
|
108
109
|
execute: async ({ geneSymbol, include, species, minRank, tissueLimit, phenotypeLimit }) => {
|
|
109
110
|
const halves = include ?? ["expression", "knockout"];
|
|
110
111
|
const wantExpression = halves.includes("expression");
|
package/dist/tools/bio/keys.d.ts
CHANGED
|
@@ -19,8 +19,9 @@ export interface BioToolKeys {
|
|
|
19
19
|
* The NCBI-backed literature tool, built from the shared key slice.
|
|
20
20
|
*
|
|
21
21
|
* `pubmed` is the consolidated literature tool (search / details / fulltext
|
|
22
|
-
* behind one `action`). ClinVar
|
|
23
|
-
* corpora behind
|
|
22
|
+
* behind one `action`). ClinVar reaches a caller through
|
|
23
|
+
* `gene_disease_evidence`, as one of the corpora behind it, and it needs the
|
|
24
|
+
* same NCBI key.
|
|
24
25
|
*/
|
|
25
26
|
export declare function createNcbiTools(keys: BioToolKeys): {
|
|
26
27
|
pubmed: Tool;
|
package/dist/tools/bio/keys.js
CHANGED
|
@@ -6,8 +6,9 @@ import { createPubMedTool } from "./pubmed.js";
|
|
|
6
6
|
* The NCBI-backed literature tool, built from the shared key slice.
|
|
7
7
|
*
|
|
8
8
|
* `pubmed` is the consolidated literature tool (search / details / fulltext
|
|
9
|
-
* behind one `action`). ClinVar
|
|
10
|
-
* corpora behind
|
|
9
|
+
* behind one `action`). ClinVar reaches a caller through
|
|
10
|
+
* `gene_disease_evidence`, as one of the corpora behind it, and it needs the
|
|
11
|
+
* same NCBI key.
|
|
11
12
|
*/
|
|
12
13
|
export function createNcbiTools(keys) {
|
|
13
14
|
return {
|
|
@@ -122,6 +122,7 @@ export const lookupAnnotationTool = defineTool({
|
|
|
122
122
|
"search_interactions({action:'enrichment'}), which does the statistics.\n" +
|
|
123
123
|
"An empty terms / annotations / pathways array is valid no-data — do not retry the same input.",
|
|
124
124
|
inputSchema,
|
|
125
|
+
describeCall: "none",
|
|
125
126
|
execute: async ({ vocabulary, query, goId, geneProductId, taxonId, organism, includeGenes, limit }) => {
|
|
126
127
|
const cap = limit ?? DEFAULT_LIMIT;
|
|
127
128
|
if (vocabulary !== "go") {
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* opentargets — one tool over the Open Targets Platform: target-disease
|
|
3
3
|
* association evidence, read from a gene or from a disease.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Curated safety liabilities are not served here: `target_safety` owns them,
|
|
6
|
+
* because it pairs them with the local secondary-pharmacology panel and
|
|
7
|
+
* resolves the Ensembl id they need.
|
|
8
8
|
*
|
|
9
9
|
* The input is a flat object with an `action` discriminator — not a
|
|
10
10
|
* `z.discriminatedUnion`, which `defineTool` rejects (model tool calling needs
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* opentargets — one tool over the Open Targets Platform: target-disease
|
|
3
3
|
* association evidence, read from a gene or from a disease.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Curated safety liabilities are not served here: `target_safety` owns them,
|
|
6
|
+
* because it pairs them with the local secondary-pharmacology panel and
|
|
7
|
+
* resolves the Ensembl id they need.
|
|
8
8
|
*
|
|
9
9
|
* The input is a flat object with an `action` discriminator — not a
|
|
10
10
|
* `z.discriminatedUnion`, which `defineTool` rejects (model tool calling needs
|
|
@@ -62,6 +62,7 @@ export const openTargetsTool = defineTool({
|
|
|
62
62
|
"disease name silently returns an EMPTY result rather than an error — resolve a symbol to its ENSG id with search_gene first.\n" +
|
|
63
63
|
"NO-DATA IS FINAL — do not retry the same id. Empty associations mean no evidence, or an unresolvable id.",
|
|
64
64
|
inputSchema,
|
|
65
|
+
describeCall: "none",
|
|
65
66
|
execute: async (input) => {
|
|
66
67
|
const limit = input.limit ?? DEFAULT_LIMIT;
|
|
67
68
|
switch (input.action) {
|
|
@@ -76,6 +76,7 @@ export const pubchemTool = defineTool({
|
|
|
76
76
|
"then chembl action='mechanism' / 'bioactivity' there for curated activity data. " +
|
|
77
77
|
"An empty results / crossRefs / assays array is valid no-data (no match; the CID is in no external registry; the compound was never screened) — do not retry.",
|
|
78
78
|
inputSchema,
|
|
79
|
+
describeCall: "none",
|
|
79
80
|
execute: async (input) => {
|
|
80
81
|
switch (input.action) {
|
|
81
82
|
case "compound":
|
|
@@ -39,6 +39,7 @@ export const searchClinicalTrialsTool = defineTool({
|
|
|
39
39
|
"landscape. Set true for the full protocol prose, and narrow `limit` when you do: a full summary runs to several thousand characters " +
|
|
40
40
|
"per trial."),
|
|
41
41
|
}),
|
|
42
|
+
describeCall: "none",
|
|
42
43
|
execute: async ({ query, phase, status, limit = 10, includeSummaries = false }) => {
|
|
43
44
|
const result = await searchTrials(query, { phase, status, limit });
|
|
44
45
|
const trials = includeSummaries
|
|
@@ -23,6 +23,7 @@ export const searchFaersTool = defineTool({
|
|
|
23
23
|
.describe("Max distinct adverse-reaction terms to return, most-reported first (default 15, max 100). totalReports covers the whole drug regardless."),
|
|
24
24
|
serious: z.boolean().default(false).describe("When true, count only reports flagged serious (death, hospitalization, life-threatening, disabling)."),
|
|
25
25
|
}),
|
|
26
|
+
describeCall: "none",
|
|
26
27
|
execute: async ({ drugName, limit = 15, serious = false }) => {
|
|
27
28
|
const result = await getFaersByDrug(drugName, { limit, serious });
|
|
28
29
|
return ok({
|
|
@@ -63,6 +63,7 @@ export const searchGeoDatasetsTool = defineTool({
|
|
|
63
63
|
.default(10)
|
|
64
64
|
.describe("Max datasets to return (default 10, max 50). totalFound reports the true match count regardless."),
|
|
65
65
|
}),
|
|
66
|
+
describeCall: "none",
|
|
66
67
|
execute: async ({ query, organism, datasetType = "gse", limit = 10 }) => {
|
|
67
68
|
let searchQuery = query;
|
|
68
69
|
// Escape backslashes first, then quotes, so a `\` in the organism value
|
|
@@ -35,6 +35,7 @@ export const searchInteractionsTool = defineTool({
|
|
|
35
35
|
.describe(`Max records returned — partners, network edges, or enriched terms depending on action (default ${DEFAULT_LIMIT}, max 500). ` +
|
|
36
36
|
"Rows are ordered best-first (score descending for interactions, FDR ascending for enrichment), so the default keeps the strongest."),
|
|
37
37
|
}),
|
|
38
|
+
describeCall: "none",
|
|
38
39
|
execute: async ({ identifiers, species, action, minScore, limit }) => {
|
|
39
40
|
if (action === "enrichment") {
|
|
40
41
|
return ok(await getEnrichment(identifiers, species, { limit }));
|