@inflexa-ai/harness 0.30.3 → 0.31.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/contracts/target-dossier.d.ts +61 -61
- package/dist/execution/run-synthesis.js +7 -2
- package/dist/lib/zod-issues.d.ts +8 -0
- package/dist/lib/zod-issues.js +13 -0
- package/dist/literature/sources/semantic-scholar.d.ts +34 -0
- package/dist/literature/sources/semantic-scholar.js +15 -4
- package/dist/tools/bio/chembl.js +4 -3
- package/dist/tools/bio/drug-gene-interactions.d.ts +2 -14
- package/dist/tools/bio/drug-gene-interactions.js +10 -18
- package/dist/tools/bio/gene-disease-evidence.d.ts +3 -1
- package/dist/tools/bio/gene-disease-evidence.js +12 -9
- package/dist/tools/bio/keys.js +1 -0
- package/dist/tools/bio/lookup-annotation.d.ts +43 -0
- package/dist/tools/bio/lookup-annotation.js +19 -4
- package/dist/tools/bio/pubchem.js +5 -3
- package/dist/tools/bio/search-clinical-trials.js +5 -4
- package/dist/tools/bio/search-geo-datasets.d.ts +39 -9
- package/dist/tools/bio/search-geo-datasets.js +38 -20
- package/dist/tools/lib/api-utils.d.ts +27 -2
- package/dist/tools/lib/api-utils.js +43 -3
- package/dist/tools/lib/bgee-client.d.ts +16 -0
- package/dist/tools/lib/bgee-client.js +16 -5
- package/dist/tools/lib/cbioportal-client.d.ts +20 -0
- package/dist/tools/lib/cbioportal-client.js +16 -8
- package/dist/tools/lib/chembl-client.d.ts +105 -3
- package/dist/tools/lib/chembl-client.js +196 -84
- package/dist/tools/lib/clinical-benchmarks-client.d.ts +5 -0
- package/dist/tools/lib/clinical-benchmarks-client.js +5 -0
- package/dist/tools/lib/clinical-trials-client.d.ts +131 -2
- package/dist/tools/lib/clinical-trials-client.js +32 -6
- package/dist/tools/lib/clinvar-client.d.ts +35 -0
- package/dist/tools/lib/clinvar-client.js +34 -28
- package/dist/tools/lib/ctx-ops.d.ts +106 -35
- package/dist/tools/lib/ctx-ops.js +135 -69
- package/dist/tools/lib/dgidb-client.d.ts +73 -0
- package/dist/tools/lib/dgidb-client.js +25 -13
- package/dist/tools/lib/disgenet-client.d.ts +117 -24
- package/dist/tools/lib/disgenet-client.js +127 -34
- package/dist/tools/lib/disgenet-config.d.ts +1 -1
- package/dist/tools/lib/disgenet-config.js +5 -3
- package/dist/tools/lib/drugbank-client.d.ts +57 -58
- package/dist/tools/lib/drugbank-client.js +69 -64
- package/dist/tools/lib/drugbank-config.d.ts +6 -1
- package/dist/tools/lib/drugbank-config.js +6 -1
- package/dist/tools/lib/ema-client.d.ts +53 -0
- package/dist/tools/lib/ema-client.js +19 -7
- package/dist/tools/lib/ensembl-client.d.ts +4 -0
- package/dist/tools/lib/ensembl-client.js +4 -0
- package/dist/tools/lib/gwas-catalog-client.d.ts +64 -1
- package/dist/tools/lib/gwas-catalog-client.js +21 -6
- package/dist/tools/lib/identifier-resolver.d.ts +17 -1
- package/dist/tools/lib/identifier-resolver.js +13 -4
- package/dist/tools/lib/impc-client.d.ts +4 -0
- package/dist/tools/lib/impc-client.js +4 -0
- package/dist/tools/lib/iuphar-client.d.ts +10 -5
- package/dist/tools/lib/iuphar-client.js +49 -13
- package/dist/tools/lib/monarch-client.d.ts +4 -0
- package/dist/tools/lib/monarch-client.js +4 -0
- package/dist/tools/lib/openfda-client.d.ts +34 -0
- package/dist/tools/lib/openfda-client.js +22 -8
- package/dist/tools/lib/opentargets-client.d.ts +99 -4
- package/dist/tools/lib/opentargets-client.js +97 -37
- package/dist/tools/lib/pathway-client.d.ts +45 -0
- package/dist/tools/lib/pathway-client.js +88 -8
- package/dist/tools/lib/pharmgkb-client.d.ts +35 -1
- package/dist/tools/lib/pharmgkb-client.js +22 -6
- package/dist/tools/lib/pharmgkb-config.d.ts +8 -1
- package/dist/tools/lib/pharmgkb-config.js +8 -1
- package/dist/tools/lib/pubchem-client.d.ts +22 -0
- package/dist/tools/lib/pubchem-client.js +36 -33
- package/dist/tools/lib/pubchem-ops.d.ts +85 -5
- package/dist/tools/lib/pubchem-ops.js +96 -68
- package/dist/tools/lib/pubmed-client.d.ts +4 -0
- package/dist/tools/lib/pubmed-client.js +4 -0
- package/dist/tools/lib/string-client.d.ts +52 -0
- package/dist/tools/lib/string-client.js +12 -7
- package/dist/tools/lib/uniprot-client.d.ts +4 -0
- package/dist/tools/lib/uniprot-client.js +4 -0
- package/dist/tools/research/context7-docs.d.ts +23 -0
- package/dist/tools/research/context7-docs.js +49 -9
- package/dist/tools/research/search-github-repos.d.ts +4 -0
- package/dist/tools/research/search-github-repos.js +4 -0
- package/dist/workflows/execute-target-assessment.js +4 -4
- package/dist/workflows/target-assessment/assemblers/orchestrator.d.ts +2 -1
- package/dist/workflows/target-assessment/assemblers/orchestrator.js +3 -3
- package/dist/workflows/target-assessment/collectors/index.d.ts +8 -2
- package/dist/workflows/target-assessment/collectors/index.js +37 -10
- package/dist/workflows/target-assessment/fanout/index.d.ts +2 -1
- package/dist/workflows/target-assessment/fanout/index.js +2 -2
- package/dist/workflows/target-assessment/lib/safety-corroboration.js +2 -2
- package/dist/workflows/target-assessment/lib/target-identity-filter.d.ts +3 -2
- package/dist/workflows/target-assessment/lib/target-identity-filter.js +16 -5
- package/dist/workflows/target-assessment/phase4-assemble.d.ts +61 -60
- package/dist/workflows/target-assessment/phase4-assemble.js +2 -2
- package/dist/workflows/target-assessment/schemas.d.ts +2 -8
- package/dist/workflows/target-assessment/schemas.js +8 -2
- package/dist/workflows/target-assessment/steps/phase2-aggregate.d.ts +1 -4
- package/dist/workflows/target-assessment/steps/phase3-aggregate.d.ts +1 -4
- package/package.json +1 -1
- package/dist/agents/sandbox/__fixtures__/deps.d.ts +0 -23
- package/dist/agents/sandbox/__fixtures__/deps.js +0 -102
- package/dist/citations/__fixtures__/resolver.d.ts +0 -3
- package/dist/citations/__fixtures__/resolver.js +0 -9
- package/dist/loop/__fixtures__/scripted-provider.d.ts +0 -31
- package/dist/loop/__fixtures__/scripted-provider.js +0 -81
- package/dist/providers/__fixtures__/session.d.ts +0 -17
- package/dist/providers/__fixtures__/session.js +0 -20
- package/dist/tools/__fixtures__/tool-context.d.ts +0 -13
- package/dist/tools/__fixtures__/tool-context.js +0 -22
|
@@ -21,9 +21,11 @@ const inputSchema = z
|
|
|
21
21
|
.describe("Which PubChem lookup to run. " +
|
|
22
22
|
"'compound' — resolve `query` (in the namespace named by `searchBy`) to a compound. Returns results[]: identity (cid, canonicalSmiles, inchi, inchiKey, iupacName, " +
|
|
23
23
|
"molecularFormula) and computed properties (molecularWeight, xlogp, tpsa, hbondDonorCount, hbondAcceptorCount, rotatableBondCount, complexity). " +
|
|
24
|
-
"'crossrefs' — external registry ids for a `cid`. Returns crossRefs[]: a flat list of { source, id }
|
|
25
|
-
"
|
|
26
|
-
"
|
|
24
|
+
"'crossrefs' — external registry ids for a `cid`. Returns crossRefs[]: a flat list of { source, id } entries. `source` names the registry that the id pattern " +
|
|
25
|
+
"identifies — ChEMBL, ChEBI, DrugBank, KEGG, HMDB, CAS, PDB or UNII — and it is null for an id of any other registry; filter by `source` for the one you want. " +
|
|
26
|
+
"This is the bridge out of PubChem. " +
|
|
27
|
+
"'assays' — bioassay screening summaries for a `cid`; answers 'has this compound ever been screened, and against what?'. Returns assays[]: aid, assayName, targetName " +
|
|
28
|
+
"(the target accession, for example a UniProt or PDB id), " +
|
|
27
29
|
"activityOutcome (Active / Inactive / Inconclusive / Unspecified), activityValue. Broad HTS screening coverage, NOT curated potency — for numbers you intend to quote " +
|
|
28
30
|
"(IC50/Ki), prefer chembl action='bioactivity'."),
|
|
29
31
|
query: z
|
|
@@ -26,8 +26,8 @@ export const searchClinicalTrialsTool = defineTool({
|
|
|
26
26
|
"read a result, as opposed to finding a trial.\n" +
|
|
27
27
|
"ACCEPTED IDENTIFIERS: `query` is free text matched across the whole study record, so a gene symbol ('KRAS'), a drug or brand name ('imatinib', " +
|
|
28
28
|
"'Gleevec'), a condition ('melanoma') or an NCT ID ('NCT00000102') all work. `nctId` takes one NCT ID and nothing else.\n" +
|
|
29
|
-
"`
|
|
30
|
-
"
|
|
29
|
+
"`status` is an optional server-side filter and `phase` narrows the returned page. Omit both to see the full landscape. totalFound reports the true " +
|
|
30
|
+
"match count of `query` plus `status`, thus it can exceed the trials that a phase-narrowed answer carries.\n" +
|
|
31
31
|
"ABSENCE IS NORMAL. An empty trials array is a valid 'nothing matched' (often an over-narrow filter) and a null trial from 'details' means the " +
|
|
32
32
|
"registry holds no such NCT ID — report it and move on, do not retry the identical call. A trial with no posted results carries empty outcomes " +
|
|
33
33
|
"and adverse events, which means unreported, never zero.",
|
|
@@ -45,8 +45,9 @@ export const searchClinicalTrialsTool = defineTool({
|
|
|
45
45
|
phase: z
|
|
46
46
|
.enum(["EARLY_PHASE1", "PHASE1", "PHASE2", "PHASE3", "PHASE4"])
|
|
47
47
|
.optional()
|
|
48
|
-
.describe("'search' only. Optional exact phase filter
|
|
49
|
-
"excluded when this is set)."
|
|
48
|
+
.describe("'search' only. Optional exact phase filter, applied to the returned page rather than to the whole query. Omit for all phases " +
|
|
49
|
+
"(observational and expanded-access studies carry no phase and are excluded when this is set). A narrow phase over a broad query " +
|
|
50
|
+
"can give fewer trials than `limit` asks for, even when the registry holds more."),
|
|
50
51
|
status: z
|
|
51
52
|
.enum(["RECRUITING", "ACTIVE_NOT_RECRUITING", "COMPLETED", "NOT_YET_RECRUITING", "TERMINATED", "WITHDRAWN", "SUSPENDED"])
|
|
52
53
|
.optional()
|
|
@@ -1,6 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* searchGeoDatasets — search NCBI GEO for public gene expression datasets.
|
|
3
3
|
*/
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
export declare const GeoEsearchResponseSchema: z.ZodObject<{
|
|
6
|
+
esearchresult: z.ZodOptional<z.ZodObject<{
|
|
7
|
+
idlist: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
8
|
+
count: z.ZodOptional<z.ZodString>;
|
|
9
|
+
}, z.core.$strip>>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
/** One dataset row, as the tool returns it. */
|
|
12
|
+
export interface GeoDataset {
|
|
13
|
+
accession: string;
|
|
14
|
+
title: string;
|
|
15
|
+
summary: string;
|
|
16
|
+
platform: string | null;
|
|
17
|
+
sampleCount: number | null;
|
|
18
|
+
organism: string | null;
|
|
19
|
+
pubmedIds: (string | number)[];
|
|
20
|
+
}
|
|
21
|
+
export declare const GeoEsummaryResponseSchema: z.ZodObject<{
|
|
22
|
+
result: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCatch<z.ZodOptional<z.ZodObject<{
|
|
23
|
+
accession: z.ZodOptional<z.ZodString>;
|
|
24
|
+
gse: z.ZodOptional<z.ZodString>;
|
|
25
|
+
title: z.ZodOptional<z.ZodString>;
|
|
26
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
27
|
+
gpl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
28
|
+
n_samples: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
|
|
29
|
+
taxon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
30
|
+
pubmedids: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
|
|
31
|
+
error: z.ZodOptional<z.ZodString>;
|
|
32
|
+
}, z.core.$strip>>>>>;
|
|
33
|
+
}, z.core.$strip>;
|
|
34
|
+
/**
|
|
35
|
+
* Map one esummary answer onto the dataset rows.
|
|
36
|
+
*
|
|
37
|
+
* `ids` is the id list of the search, and it names the order of the rows. The
|
|
38
|
+
* function is pure, thus the golden-fixture table exercises it against a stored
|
|
39
|
+
* payload.
|
|
40
|
+
*/
|
|
41
|
+
export declare function mapGeoDatasets(ids: string[], summary: z.infer<typeof GeoEsummaryResponseSchema>): GeoDataset[];
|
|
4
42
|
export declare const searchGeoDatasetsTool: import("../define-tool.js").Tool<{
|
|
5
43
|
query: string;
|
|
6
44
|
datasetType: "gse" | "gds";
|
|
@@ -8,13 +46,5 @@ export declare const searchGeoDatasetsTool: import("../define-tool.js").Tool<{
|
|
|
8
46
|
organism?: string | undefined;
|
|
9
47
|
}, {
|
|
10
48
|
totalFound: number;
|
|
11
|
-
datasets:
|
|
12
|
-
accession: string;
|
|
13
|
-
title: string;
|
|
14
|
-
summary: string;
|
|
15
|
-
platform: string | null;
|
|
16
|
-
sampleCount: number | null;
|
|
17
|
-
organism: string | null;
|
|
18
|
-
pubmedIds: (string | number)[];
|
|
19
|
-
}[];
|
|
49
|
+
datasets: GeoDataset[];
|
|
20
50
|
}>;
|
|
@@ -10,7 +10,7 @@ const ESEARCH_BASE = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils";
|
|
|
10
10
|
// optional because the API omits absent values; the mapping in `execute` keys
|
|
11
11
|
// off the esearch `idlist` (request context) and reshapes each summary, so the
|
|
12
12
|
// schemas model only the raw wire.
|
|
13
|
-
const GeoEsearchResponseSchema = z.object({
|
|
13
|
+
export const GeoEsearchResponseSchema = z.object({
|
|
14
14
|
esearchresult: z
|
|
15
15
|
.object({
|
|
16
16
|
idlist: z.array(z.string()).optional(),
|
|
@@ -18,24 +18,58 @@ const GeoEsearchResponseSchema = z.object({
|
|
|
18
18
|
})
|
|
19
19
|
.optional(),
|
|
20
20
|
});
|
|
21
|
+
// `gpl` is the platform accession, as a bare number string ("20301"). esummary
|
|
22
|
+
// serves no `platform` key at any level. `error` marks the 200-with-error form:
|
|
23
|
+
// esummary answers HTTP 200 for an unknown uid and puts `{"uid": …, "error": …}`
|
|
24
|
+
// under that key, which carries no dataset.
|
|
21
25
|
const GeoDatasetSummarySchema = z.object({
|
|
22
26
|
accession: z.string().optional(),
|
|
23
27
|
gse: z.string().optional(),
|
|
24
28
|
title: z.string().optional(),
|
|
25
29
|
summary: z.string().optional(),
|
|
26
30
|
gpl: z.string().nullable().optional(),
|
|
27
|
-
platform: z.string().nullable().optional(),
|
|
28
31
|
n_samples: z.union([z.string(), z.number()]).optional(),
|
|
29
32
|
taxon: z.string().nullable().optional(),
|
|
30
33
|
pubmedids: z.array(z.union([z.string(), z.number()])).optional(),
|
|
34
|
+
error: z.string().optional(),
|
|
31
35
|
});
|
|
32
36
|
// The esummary `result` object mixes a `uids` string array in with the
|
|
33
37
|
// numeric-keyed dataset summaries; `.catch(undefined)` on the record value lets
|
|
34
38
|
// that `uids` entry (and any drifted summary) fall through as undefined rather
|
|
35
39
|
// than rejecting the whole response — the mapping reads only the numeric ids.
|
|
36
|
-
const GeoEsummaryResponseSchema = z.object({
|
|
40
|
+
export const GeoEsummaryResponseSchema = z.object({
|
|
37
41
|
result: z.record(z.string(), GeoDatasetSummarySchema.optional().catch(undefined)).optional(),
|
|
38
42
|
});
|
|
43
|
+
/**
|
|
44
|
+
* Map one esummary answer onto the dataset rows.
|
|
45
|
+
*
|
|
46
|
+
* `ids` is the id list of the search, and it names the order of the rows. The
|
|
47
|
+
* function is pure, thus the golden-fixture table exercises it against a stored
|
|
48
|
+
* payload.
|
|
49
|
+
*/
|
|
50
|
+
export function mapGeoDatasets(ids, summary) {
|
|
51
|
+
const result = summary?.result ?? {};
|
|
52
|
+
const datasets = [];
|
|
53
|
+
for (const id of ids) {
|
|
54
|
+
const r = result[id];
|
|
55
|
+
if (!r)
|
|
56
|
+
continue;
|
|
57
|
+
// An error record carries no dataset. Without this guard it becomes a
|
|
58
|
+
// row of empty strings with a fabricated accession.
|
|
59
|
+
if (r.error !== undefined)
|
|
60
|
+
continue;
|
|
61
|
+
datasets.push({
|
|
62
|
+
accession: r.accession ?? r.gse ?? `GDS${id}`,
|
|
63
|
+
title: r.title ?? "",
|
|
64
|
+
summary: (r.summary ?? "").slice(0, 300),
|
|
65
|
+
platform: r.gpl ?? null,
|
|
66
|
+
sampleCount: r.n_samples ? Number(r.n_samples) : null,
|
|
67
|
+
organism: r.taxon ?? null,
|
|
68
|
+
pubmedIds: r.pubmedids ?? [],
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return datasets;
|
|
72
|
+
}
|
|
39
73
|
export const searchGeoDatasetsTool = defineTool({
|
|
40
74
|
id: "search_geo_datasets",
|
|
41
75
|
description: "Search the NCBI Gene Expression Omnibus (GEO) — the public functional-genomics repository of the U.S. National Library of Medicine — for " +
|
|
@@ -88,23 +122,7 @@ export const searchGeoDatasetsTool = defineTool({
|
|
|
88
122
|
const summaryRes = await apiFetchValidated(summaryUrl, GeoEsummaryResponseSchema);
|
|
89
123
|
if (summaryRes.isErr())
|
|
90
124
|
throw new Error(describeApiError(summaryRes.error));
|
|
91
|
-
const
|
|
92
|
-
const datasets = ids
|
|
93
|
-
.map((id) => {
|
|
94
|
-
const r = result[id];
|
|
95
|
-
if (!r)
|
|
96
|
-
return null;
|
|
97
|
-
return {
|
|
98
|
-
accession: r.accession ?? r.gse ?? `GDS${id}`,
|
|
99
|
-
title: r.title ?? "",
|
|
100
|
-
summary: (r.summary ?? "").slice(0, 300),
|
|
101
|
-
platform: r.gpl ?? r.platform ?? null,
|
|
102
|
-
sampleCount: r.n_samples ? Number(r.n_samples) : null,
|
|
103
|
-
organism: r.taxon ?? null,
|
|
104
|
-
pubmedIds: r.pubmedids ?? [],
|
|
105
|
-
};
|
|
106
|
-
})
|
|
107
|
-
.filter((d) => d !== null);
|
|
125
|
+
const datasets = mapGeoDatasets(ids, summaryRes.value);
|
|
108
126
|
const totalFound = Number(searchRes.value?.esearchresult?.count) || datasets.length;
|
|
109
127
|
return ok({ totalFound, datasets });
|
|
110
128
|
},
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared HTTP fetch helper for bioinformatics API tools.
|
|
3
3
|
*
|
|
4
|
-
* Provides retry-with-backoff for rate-limited
|
|
4
|
+
* Provides retry-with-backoff for a rate-limited or a transiently-broken API
|
|
5
|
+
* (429/502/503/504), request
|
|
5
6
|
* timeouts, and tab-delimited text parsing. `apiFetch` is the external-call
|
|
6
7
|
* boundary, so it is where a throw becomes a `Result`: it returns a
|
|
7
8
|
* `ResultAsync<T, ApiError>` rather than throwing — callers branch on
|
|
@@ -35,7 +36,7 @@ export type ApiError = {
|
|
|
35
36
|
readonly issues: string;
|
|
36
37
|
};
|
|
37
38
|
/**
|
|
38
|
-
* Fetch a URL with retry on 429/503, exponential backoff, and timeout.
|
|
39
|
+
* Fetch a URL with retry on 429/502/503/504, exponential backoff, and timeout.
|
|
39
40
|
* `err` carries the structured failure; a non-ok HTTP status is reported as
|
|
40
41
|
* `http_status` so callers can branch on a concrete code (a 404 is usually an
|
|
41
42
|
* expected "not found" → a data variant; see `isUnexpectedApiError`).
|
|
@@ -73,6 +74,30 @@ export declare function describeApiError(e: ApiError): string;
|
|
|
73
74
|
* throwing (or returning `err`).
|
|
74
75
|
*/
|
|
75
76
|
export declare function isUnexpectedApiError(e: ApiError): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Read a number that a provider serializes as a JSON string.
|
|
79
|
+
*
|
|
80
|
+
* A Tastypie `decimal` field (ChEMBL `max_phase`, `standard_value`,
|
|
81
|
+
* `pchembl_value`) and the eutils `esearch` counts arrive as strings, and the
|
|
82
|
+
* same value arrives as a number from a different serializer of the same
|
|
83
|
+
* provider. One helper answers for both encodings, thus no call site invents its
|
|
84
|
+
* own rule.
|
|
85
|
+
*
|
|
86
|
+
* A value that is not a finite number gives `null`. As a result a caller never
|
|
87
|
+
* sees `NaN`, which compares false against itself and poisons every downstream
|
|
88
|
+
* threshold.
|
|
89
|
+
*/
|
|
90
|
+
export declare function parseWireNumber(value: string | number | null | undefined): number | null;
|
|
91
|
+
/**
|
|
92
|
+
* The schema form of `parseWireNumber`, for a field that a provider serializes
|
|
93
|
+
* as a string or as a number.
|
|
94
|
+
*
|
|
95
|
+
* The helper accepts neither `null` nor an omission, because absence is a
|
|
96
|
+
* per-provider policy and no field is widened without evidence. A caller
|
|
97
|
+
* composes `.nullable()`, `.optional()`, or both, per the policy of its
|
|
98
|
+
* provider.
|
|
99
|
+
*/
|
|
100
|
+
export declare const zWireNumber: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<number | null, string | number>>;
|
|
76
101
|
/**
|
|
77
102
|
* Parse tab-separated text into rows of columns (e.g., KEGG responses).
|
|
78
103
|
* Filters out empty lines.
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared HTTP fetch helper for bioinformatics API tools.
|
|
3
3
|
*
|
|
4
|
-
* Provides retry-with-backoff for rate-limited
|
|
4
|
+
* Provides retry-with-backoff for a rate-limited or a transiently-broken API
|
|
5
|
+
* (429/502/503/504), request
|
|
5
6
|
* timeouts, and tab-delimited text parsing. `apiFetch` is the external-call
|
|
6
7
|
* boundary, so it is where a throw becomes a `Result`: it returns a
|
|
7
8
|
* `ResultAsync<T, ApiError>` rather than throwing — callers branch on
|
|
8
9
|
* `isErr()` and read `value` / `error` (see `result.ts` for the house rules).
|
|
9
10
|
*/
|
|
10
11
|
import { ResultAsync, err, ok } from "neverthrow";
|
|
12
|
+
import { z } from "zod";
|
|
11
13
|
import { sleep } from "../../lib/async-utils.js";
|
|
12
|
-
|
|
14
|
+
// 502 and 504 sit here next to 429 and 503 because a gateway in front of a bio
|
|
15
|
+
// provider answers with one of them while the origin restarts, and it sends an
|
|
16
|
+
// HTML body. That answer is transient, thus a retry gets the real payload.
|
|
17
|
+
const RETRYABLE_STATUSES = new Set([429, 502, 503, 504]);
|
|
13
18
|
/**
|
|
14
|
-
* Fetch a URL with retry on 429/503, exponential backoff, and timeout.
|
|
19
|
+
* Fetch a URL with retry on 429/502/503/504, exponential backoff, and timeout.
|
|
15
20
|
* `err` carries the structured failure; a non-ok HTTP status is reported as
|
|
16
21
|
* `http_status` so callers can branch on a concrete code (a 404 is usually an
|
|
17
22
|
* expected "not found" → a data variant; see `isUnexpectedApiError`).
|
|
@@ -116,6 +121,41 @@ export function describeApiError(e) {
|
|
|
116
121
|
export function isUnexpectedApiError(e) {
|
|
117
122
|
return !(e.type === "http_status" && e.status >= 400 && e.status < 500);
|
|
118
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Read a number that a provider serializes as a JSON string.
|
|
126
|
+
*
|
|
127
|
+
* A Tastypie `decimal` field (ChEMBL `max_phase`, `standard_value`,
|
|
128
|
+
* `pchembl_value`) and the eutils `esearch` counts arrive as strings, and the
|
|
129
|
+
* same value arrives as a number from a different serializer of the same
|
|
130
|
+
* provider. One helper answers for both encodings, thus no call site invents its
|
|
131
|
+
* own rule.
|
|
132
|
+
*
|
|
133
|
+
* A value that is not a finite number gives `null`. As a result a caller never
|
|
134
|
+
* sees `NaN`, which compares false against itself and poisons every downstream
|
|
135
|
+
* threshold.
|
|
136
|
+
*/
|
|
137
|
+
export function parseWireNumber(value) {
|
|
138
|
+
if (value === null || value === undefined)
|
|
139
|
+
return null;
|
|
140
|
+
if (typeof value === "number")
|
|
141
|
+
return Number.isFinite(value) ? value : null;
|
|
142
|
+
const trimmed = value.trim();
|
|
143
|
+
// `Number("")` and `Number(" ")` give 0, thus an empty string must not reach it.
|
|
144
|
+
if (trimmed === "")
|
|
145
|
+
return null;
|
|
146
|
+
const parsed = Number(trimmed);
|
|
147
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The schema form of `parseWireNumber`, for a field that a provider serializes
|
|
151
|
+
* as a string or as a number.
|
|
152
|
+
*
|
|
153
|
+
* The helper accepts neither `null` nor an omission, because absence is a
|
|
154
|
+
* per-provider policy and no field is widened without evidence. A caller
|
|
155
|
+
* composes `.nullable()`, `.optional()`, or both, per the policy of its
|
|
156
|
+
* provider.
|
|
157
|
+
*/
|
|
158
|
+
export const zWireNumber = z.union([z.string(), z.number()]).transform((value) => parseWireNumber(value));
|
|
119
159
|
/**
|
|
120
160
|
* Parse tab-separated text into rows of columns (e.g., KEGG responses).
|
|
121
161
|
* Filters out empty lines.
|
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
* lookups for the configured non-human species (Ensembl REST), then
|
|
6
6
|
* queries Bgee per (species, ortholog ENSG) for tissue-level expression
|
|
7
7
|
* calls. Returns a per-species table of tissue × expression-rank.
|
|
8
|
+
*
|
|
9
|
+
* Absence policy: Bgee and the Ensembl calls in this file omit the key of an
|
|
10
|
+
* absent value, and neither one sends an explicit `null`. Thus a maybe-absent
|
|
11
|
+
* field carries `.optional()`, not `.nullable()`.
|
|
8
12
|
*/
|
|
13
|
+
import { z } from "zod";
|
|
9
14
|
export declare const SUPPORTED_SPECIES: readonly ["homo_sapiens", "mus_musculus", "rattus_norvegicus", "canis_lupus_familiaris", "macaca_mulatta"];
|
|
10
15
|
export type SupportedSpecies = (typeof SUPPORTED_SPECIES)[number];
|
|
11
16
|
export declare const SPECIES_TAXON: Record<SupportedSpecies, number>;
|
|
@@ -31,6 +36,17 @@ export interface MultiSpeciesExpression {
|
|
|
31
36
|
notFound: string[];
|
|
32
37
|
}
|
|
33
38
|
export declare function bucketRank(expressionState: string, score: number | null): ExpressionRank;
|
|
39
|
+
export declare const EnsemblLookupSchema: z.ZodObject<{
|
|
40
|
+
id: z.ZodOptional<z.ZodString>;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
export declare const EnsemblHomologyResponseSchema: z.ZodObject<{
|
|
43
|
+
data: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
44
|
+
homologies: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
45
|
+
id: z.ZodOptional<z.ZodString>;
|
|
46
|
+
type: z.ZodOptional<z.ZodString>;
|
|
47
|
+
}, z.core.$strip>>>;
|
|
48
|
+
}, z.core.$strip>>>;
|
|
49
|
+
}, z.core.$strip>;
|
|
34
50
|
export declare function parseExpressionResponse(raw: unknown): TissueRow[];
|
|
35
51
|
/** Fetch multi-species expression for a human gene symbol. */
|
|
36
52
|
export declare function getMultiSpeciesExpression(geneSymbol: string, species?: SupportedSpecies[]): Promise<MultiSpeciesExpression>;
|
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
* lookups for the configured non-human species (Ensembl REST), then
|
|
6
6
|
* queries Bgee per (species, ortholog ENSG) for tissue-level expression
|
|
7
7
|
* calls. Returns a per-species table of tissue × expression-rank.
|
|
8
|
+
*
|
|
9
|
+
* Absence policy: Bgee and the Ensembl calls in this file omit the key of an
|
|
10
|
+
* absent value, and neither one sends an explicit `null`. Thus a maybe-absent
|
|
11
|
+
* field carries `.optional()`, not `.nullable()`.
|
|
8
12
|
*/
|
|
9
13
|
import { z } from "zod";
|
|
10
14
|
import { apiFetchValidated, describeApiError, isUnexpectedApiError } from "./api-utils.js";
|
|
@@ -51,8 +55,8 @@ const BgeeExpressionResponseSchema = z.object({
|
|
|
51
55
|
data: z.object({ calls: z.array(BgeeCallSchema).optional() }).optional(),
|
|
52
56
|
});
|
|
53
57
|
// Ensembl REST response shapes consumed by the ortholog-resolution path.
|
|
54
|
-
const EnsemblLookupSchema = z.object({ id: z.string().optional() });
|
|
55
|
-
const EnsemblHomologyResponseSchema = z.object({
|
|
58
|
+
export const EnsemblLookupSchema = z.object({ id: z.string().optional() });
|
|
59
|
+
export const EnsemblHomologyResponseSchema = z.object({
|
|
56
60
|
data: z.array(z.object({ homologies: z.array(z.object({ id: z.string().optional(), type: z.string().optional() })).optional() })).optional(),
|
|
57
61
|
});
|
|
58
62
|
export function parseExpressionResponse(raw) {
|
|
@@ -102,8 +106,15 @@ async function resolveHumanEnsembl(symbol) {
|
|
|
102
106
|
return null;
|
|
103
107
|
return res.value.id;
|
|
104
108
|
}
|
|
105
|
-
|
|
106
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Resolve the ortholog of one human gene in one other species.
|
|
111
|
+
*
|
|
112
|
+
* The route keys on the Ensembl gene id, and never on the symbol. The symbol
|
|
113
|
+
* route serves the identical envelope, but it answers HTTP 503 under load while
|
|
114
|
+
* the id route answers. Thus the caller resolves the id first.
|
|
115
|
+
*/
|
|
116
|
+
async function resolveOrtholog(humanEnsemblId, targetSpecies) {
|
|
117
|
+
const url = `${ENSEMBL_BASE}/homology/id/homo_sapiens/${encodeURIComponent(humanEnsemblId)}` + `?type=orthologues;target_species=${targetSpecies};format=condensed`;
|
|
107
118
|
const res = await apiFetchValidated(url, EnsemblHomologyResponseSchema, { headers: ENSEMBL_HEADERS });
|
|
108
119
|
if (res.isErr()) {
|
|
109
120
|
if (isUnexpectedApiError(res.error))
|
|
@@ -133,7 +144,7 @@ export async function getMultiSpeciesExpression(geneSymbol, species = [...SUPPOR
|
|
|
133
144
|
const idEntries = await Promise.all(species.map(async (sp) => {
|
|
134
145
|
if (sp === "homo_sapiens")
|
|
135
146
|
return { sp, id: humanEnsemblId };
|
|
136
|
-
const id = await resolveOrtholog(
|
|
147
|
+
const id = await resolveOrtholog(humanEnsemblId, sp);
|
|
137
148
|
return { sp, id };
|
|
138
149
|
}));
|
|
139
150
|
const bySpecies = [];
|
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
* the public cBioPortal REST API for mutation occurrence across all curated
|
|
6
6
|
* cancer studies, then aggregates by cancer type to produce the spec's
|
|
7
7
|
* "where is the target broken in human disease, and how often" view.
|
|
8
|
+
*
|
|
9
|
+
* Absence policy: cBioPortal omits the key of an absent value, and it never
|
|
10
|
+
* sends an explicit `null`. Thus a maybe-absent field carries `.optional()`,
|
|
11
|
+
* not `.nullable()`.
|
|
8
12
|
*/
|
|
13
|
+
import { z } from "zod";
|
|
9
14
|
export interface CancerStudy {
|
|
10
15
|
studyId: string;
|
|
11
16
|
cancerType: string;
|
|
@@ -19,6 +24,21 @@ export interface MutationFrequency {
|
|
|
19
24
|
frequency: number;
|
|
20
25
|
studies: string[];
|
|
21
26
|
}
|
|
27
|
+
export declare const RawMutationRowSchema: z.ZodObject<{
|
|
28
|
+
studyId: z.ZodString;
|
|
29
|
+
sampleId: z.ZodString;
|
|
30
|
+
}, z.core.$strip>;
|
|
31
|
+
export declare const RawCancerStudySchema: z.ZodObject<{
|
|
32
|
+
studyId: z.ZodString;
|
|
33
|
+
cancerTypeId: z.ZodOptional<z.ZodString>;
|
|
34
|
+
cancerType: z.ZodOptional<z.ZodObject<{
|
|
35
|
+
id: z.ZodOptional<z.ZodString>;
|
|
36
|
+
name: z.ZodOptional<z.ZodString>;
|
|
37
|
+
}, z.core.$strip>>;
|
|
38
|
+
name: z.ZodOptional<z.ZodString>;
|
|
39
|
+
description: z.ZodOptional<z.ZodString>;
|
|
40
|
+
allSampleCount: z.ZodOptional<z.ZodNumber>;
|
|
41
|
+
}, z.core.$strip>;
|
|
22
42
|
/**
|
|
23
43
|
* Compute somatic mutation frequencies for a target across all curated
|
|
24
44
|
* cancer studies in cBioPortal, grouped by cancer type. Returns one row
|
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
* the public cBioPortal REST API for mutation occurrence across all curated
|
|
6
6
|
* cancer studies, then aggregates by cancer type to produce the spec's
|
|
7
7
|
* "where is the target broken in human disease, and how often" view.
|
|
8
|
+
*
|
|
9
|
+
* Absence policy: cBioPortal omits the key of an absent value, and it never
|
|
10
|
+
* sends an explicit `null`. Thus a maybe-absent field carries `.optional()`,
|
|
11
|
+
* not `.nullable()`.
|
|
8
12
|
*/
|
|
9
13
|
import { z } from "zod";
|
|
10
14
|
import { apiFetchValidated, describeApiError } from "./api-utils.js";
|
|
@@ -19,10 +23,11 @@ const RawMolecularProfileSchema = z.object({
|
|
|
19
23
|
studyId: z.string(),
|
|
20
24
|
molecularAlterationType: z.string().optional(),
|
|
21
25
|
});
|
|
22
|
-
|
|
26
|
+
// One mutation row of `mutations/fetch`. The aggregation counts the distinct
|
|
27
|
+
// samples of a study, thus it reads only the two key fields of the row.
|
|
28
|
+
export const RawMutationRowSchema = z.object({
|
|
23
29
|
studyId: z.string(),
|
|
24
30
|
sampleId: z.string(),
|
|
25
|
-
mutationCount: z.number().optional(),
|
|
26
31
|
});
|
|
27
32
|
const RawSampleListSchema = z.object({
|
|
28
33
|
sampleListId: z.string().optional(),
|
|
@@ -30,10 +35,13 @@ const RawSampleListSchema = z.object({
|
|
|
30
35
|
category: z.string().optional(),
|
|
31
36
|
sampleCount: z.number().optional(),
|
|
32
37
|
});
|
|
33
|
-
const RawCancerStudySchema = z.object({
|
|
38
|
+
export const RawCancerStudySchema = z.object({
|
|
34
39
|
studyId: z.string(),
|
|
35
40
|
cancerTypeId: z.string().optional(),
|
|
36
|
-
|
|
41
|
+
// The nested block keys its identifier as `id`. The `projection=DETAILED`
|
|
42
|
+
// answer carries the block, and `projection=SUMMARY` omits it, thus the
|
|
43
|
+
// top-level `cancerTypeId` stays the fallback.
|
|
44
|
+
cancerType: z.object({ id: z.string().optional(), name: z.string().optional() }).optional(),
|
|
37
45
|
name: z.string().optional(),
|
|
38
46
|
description: z.string().optional(),
|
|
39
47
|
/** The denominator of a study. The sample-list SUMMARY projection carries no count. */
|
|
@@ -77,11 +85,11 @@ async function listMutationProfiles() {
|
|
|
77
85
|
throw new Error(describeApiError(res.error));
|
|
78
86
|
return (res.value ?? []).filter((p) => p.molecularAlterationType === "MUTATION_EXTENDED");
|
|
79
87
|
}
|
|
80
|
-
async function
|
|
88
|
+
async function fetchMutationRowsForGene(entrezGeneId, profileIds) {
|
|
81
89
|
if (profileIds.length === 0)
|
|
82
90
|
return [];
|
|
83
91
|
const url = `${CBIOPORTAL_BASE}/mutations/fetch?projection=SUMMARY`;
|
|
84
|
-
const res = await apiFetchValidated(url, z.array(
|
|
92
|
+
const res = await apiFetchValidated(url, z.array(RawMutationRowSchema), {
|
|
85
93
|
method: "POST",
|
|
86
94
|
headers: { ...HEADERS, "Content-Type": "application/json" },
|
|
87
95
|
body: JSON.stringify({
|
|
@@ -132,7 +140,7 @@ export async function getSomaticMutationFrequencies(geneSymbol, options = {}) {
|
|
|
132
140
|
const studyById = new Map();
|
|
133
141
|
for (const s of studies)
|
|
134
142
|
studyById.set(s.studyId, s);
|
|
135
|
-
const mutations = await
|
|
143
|
+
const mutations = await fetchMutationRowsForGene(entrezGeneId, profileIds);
|
|
136
144
|
const mutatedStudySamples = new Map();
|
|
137
145
|
for (const m of mutations) {
|
|
138
146
|
if (!mutatedStudySamples.has(m.studyId))
|
|
@@ -145,7 +153,7 @@ export async function getSomaticMutationFrequencies(geneSymbol, options = {}) {
|
|
|
145
153
|
const sampleCount = study?.allSampleCount ?? 0;
|
|
146
154
|
if (sampleCount === 0)
|
|
147
155
|
continue;
|
|
148
|
-
const cancerTypeId = study?.cancerType?.
|
|
156
|
+
const cancerTypeId = study?.cancerType?.id ?? study?.cancerTypeId ?? "unknown";
|
|
149
157
|
const cancerTypeName = study?.cancerType?.name ?? typeNames.get(cancerTypeId) ?? cancerTypeId;
|
|
150
158
|
if (!byCancerType.has(cancerTypeId)) {
|
|
151
159
|
byCancerType.set(cancerTypeId, {
|
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
* Pure async client functions for the ChEMBL REST API.
|
|
3
3
|
*
|
|
4
4
|
* Used directly by target-assessment workflow steps and by tool wrappers.
|
|
5
|
+
*
|
|
6
|
+
* Absence policy: ChEMBL sends an explicit `null` for an absent value, and it
|
|
7
|
+
* never omits the key. Thus a maybe-absent field carries `.nullable()`, not
|
|
8
|
+
* `.optional()`.
|
|
5
9
|
*/
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import type { Logger } from "../../lib/logger.js";
|
|
6
12
|
export interface ChemblCompound {
|
|
7
13
|
chemblId: string;
|
|
8
14
|
preferredCompoundName: string | null;
|
|
@@ -65,6 +71,92 @@ export interface ChemblPolypharmHit {
|
|
|
65
71
|
standardUnits: string | null;
|
|
66
72
|
pchemblValue: number | null;
|
|
67
73
|
}
|
|
74
|
+
export declare const TargetSearchResponseSchema: z.ZodObject<{
|
|
75
|
+
targets: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
76
|
+
target_chembl_id: z.ZodOptional<z.ZodString>;
|
|
77
|
+
pref_name: z.ZodOptional<z.ZodString>;
|
|
78
|
+
target_type: z.ZodOptional<z.ZodString>;
|
|
79
|
+
organism: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
80
|
+
target_components: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
81
|
+
accession: z.ZodOptional<z.ZodString>;
|
|
82
|
+
target_component_synonyms: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
83
|
+
syn_type: z.ZodOptional<z.ZodString>;
|
|
84
|
+
component_synonym: z.ZodOptional<z.ZodString>;
|
|
85
|
+
}, z.core.$strip>>>;
|
|
86
|
+
}, z.core.$strip>>>;
|
|
87
|
+
}, z.core.$strip>>>;
|
|
88
|
+
}, z.core.$strip>;
|
|
89
|
+
export declare const ActivitiesResponseSchema: z.ZodObject<{
|
|
90
|
+
activities: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
91
|
+
activity_id: z.ZodOptional<z.ZodNumber>;
|
|
92
|
+
molecule_chembl_id: z.ZodOptional<z.ZodString>;
|
|
93
|
+
target_chembl_id: z.ZodOptional<z.ZodString>;
|
|
94
|
+
standard_type: z.ZodOptional<z.ZodString>;
|
|
95
|
+
standard_value: z.ZodOptional<z.ZodNullable<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<number | null, string | number>>>>;
|
|
96
|
+
standard_units: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
97
|
+
assay_chembl_id: z.ZodOptional<z.ZodString>;
|
|
98
|
+
assay_type: z.ZodOptional<z.ZodString>;
|
|
99
|
+
pchembl_value: z.ZodOptional<z.ZodNullable<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<number | null, string | number>>>>;
|
|
100
|
+
}, z.core.$strip>>>;
|
|
101
|
+
}, z.core.$strip>;
|
|
102
|
+
export declare const MechanismsResponseSchema: z.ZodObject<{
|
|
103
|
+
mechanisms: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
104
|
+
mechanism_of_action: z.ZodOptional<z.ZodString>;
|
|
105
|
+
action_type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
106
|
+
target_chembl_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
107
|
+
molecule_chembl_id: z.ZodOptional<z.ZodString>;
|
|
108
|
+
}, z.core.$strip>>>;
|
|
109
|
+
}, z.core.$strip>;
|
|
110
|
+
export declare const DrugIndicationsResponseSchema: z.ZodObject<{
|
|
111
|
+
drug_indications: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
112
|
+
molecule_chembl_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
113
|
+
mesh_heading: z.ZodOptional<z.ZodString>;
|
|
114
|
+
efo_term: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
115
|
+
max_phase_for_ind: z.ZodOptional<z.ZodNullable<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<number | null, string | number>>>>;
|
|
116
|
+
}, z.core.$strip>>>;
|
|
117
|
+
}, z.core.$strip>;
|
|
118
|
+
export declare const MoleculeSearchResponseSchema: z.ZodObject<{
|
|
119
|
+
molecules: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
120
|
+
molecule_chembl_id: z.ZodOptional<z.ZodString>;
|
|
121
|
+
pref_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
122
|
+
max_phase: z.ZodOptional<z.ZodNullable<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<number | null, string | number>>>>;
|
|
123
|
+
molecule_type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
124
|
+
first_approval: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
125
|
+
molecule_hierarchy: z.ZodOptional<z.ZodObject<{
|
|
126
|
+
parent_chembl_id: z.ZodOptional<z.ZodString>;
|
|
127
|
+
}, z.core.$strip>>;
|
|
128
|
+
}, z.core.$strip>>>;
|
|
129
|
+
}, z.core.$strip>;
|
|
130
|
+
export declare const MoleculeStructuresResponseSchema: z.ZodObject<{
|
|
131
|
+
molecule_structures: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
132
|
+
standard_inchi_key: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
133
|
+
}, z.core.$strip>>>;
|
|
134
|
+
}, z.core.$strip>;
|
|
135
|
+
export declare const CompoundsResponseSchema: z.ZodObject<{
|
|
136
|
+
molecules: z.ZodOptional<z.ZodArray<z.ZodPipe<z.ZodObject<{
|
|
137
|
+
molecule_chembl_id: z.ZodOptional<z.ZodString>;
|
|
138
|
+
pref_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
139
|
+
molecule_structures: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
140
|
+
canonical_smiles: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
141
|
+
}, z.core.$strip>>>;
|
|
142
|
+
molecule_properties: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
143
|
+
full_mwt: z.ZodOptional<z.ZodNullable<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<number | null, string | number>>>>;
|
|
144
|
+
alogp: z.ZodOptional<z.ZodNullable<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>, z.ZodTransform<number | null, string | number>>>>;
|
|
145
|
+
full_molformula: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
146
|
+
}, z.core.$strip>>>;
|
|
147
|
+
}, z.core.$strip>, z.ZodTransform<ChemblCompound, {
|
|
148
|
+
molecule_chembl_id?: string | undefined;
|
|
149
|
+
pref_name?: string | null | undefined;
|
|
150
|
+
molecule_structures?: {
|
|
151
|
+
canonical_smiles?: string | null | undefined;
|
|
152
|
+
} | null | undefined;
|
|
153
|
+
molecule_properties?: {
|
|
154
|
+
full_mwt?: number | null | undefined;
|
|
155
|
+
alogp?: number | null | undefined;
|
|
156
|
+
full_molformula?: string | null | undefined;
|
|
157
|
+
} | null | undefined;
|
|
158
|
+
}>>>>;
|
|
159
|
+
}, z.core.$strip>;
|
|
68
160
|
/** Search ChEMBL for compounds by target, compound name, or SMILES. */
|
|
69
161
|
export declare function searchCompounds(query: string, searchType: CompoundSearchType, limit?: number): Promise<ChemblCompound[]>;
|
|
70
162
|
export declare function searchTargets(query: string, limit?: number): Promise<ChemblTarget[]>;
|
|
@@ -75,6 +167,16 @@ export declare function getBioactivity(chemblId: string, type: BioactivityIdType
|
|
|
75
167
|
limit?: number;
|
|
76
168
|
}): Promise<ChemblActivity[]>;
|
|
77
169
|
export declare function getMechanism(chemblId: string): Promise<ChemblMechanism[]>;
|
|
170
|
+
/**
|
|
171
|
+
* Approved drugs by name or by disease term.
|
|
172
|
+
*
|
|
173
|
+
* The `drug` resource of ChEMBL has no search endpoint, and it carries neither a
|
|
174
|
+
* name nor an indication. The molecule name search runs first, because an
|
|
175
|
+
* `icontains` read of `drug_indication` captures a drug name that is a substring
|
|
176
|
+
* of a disease term ("insulin" matches "insulin resistance"). A query that
|
|
177
|
+
* names no molecule falls through to the indication read, which answers
|
|
178
|
+
* highest-phase first and can carry a clinical-stage molecule below approval.
|
|
179
|
+
*/
|
|
78
180
|
export declare function getDrugInfo(query: string, limit?: number): Promise<ChemblDrug[]>;
|
|
79
181
|
/**
|
|
80
182
|
* Fetch all clinical-stage modulators (max_phase ≥ 2 by default) for a target.
|
|
@@ -83,7 +185,7 @@ export declare function getDrugInfo(query: string, limit?: number): Promise<Chem
|
|
|
83
185
|
export declare function getTargetModulators(targetChemblId: string, options?: {
|
|
84
186
|
minPhase?: number;
|
|
85
187
|
limit?: number;
|
|
86
|
-
}): Promise<ChemblModulator[]>;
|
|
188
|
+
}, logger?: Logger): Promise<ChemblModulator[]>;
|
|
87
189
|
/**
|
|
88
190
|
* Fetch off-target binding hits for a modulator: every target the molecule
|
|
89
191
|
* has been measured against (excluding the primary target), with potency.
|
|
@@ -102,7 +204,7 @@ export declare function getModulatorPolypharmacology(moleculeChemblId: string, o
|
|
|
102
204
|
* Used by the polypharm fanout step so the assembler's computeSelectivity
|
|
103
205
|
* can produce real fold values instead of selectivity_unknown.
|
|
104
206
|
*/
|
|
105
|
-
export declare function getModulatorOnTargetPchembl(modulatorChemblId: string, targetChemblId: string): Promise<number | null>;
|
|
207
|
+
export declare function getModulatorOnTargetPchembl(modulatorChemblId: string, targetChemblId: string, logger?: Logger): Promise<number | null>;
|
|
106
208
|
/**
|
|
107
209
|
* Secondary path: fetch clinical-stage small molecules via the activity table.
|
|
108
210
|
*
|
|
@@ -121,7 +223,7 @@ export declare function getModulatorsViaActivity(args: {
|
|
|
121
223
|
max_phase_min?: number;
|
|
122
224
|
molecule_type?: string;
|
|
123
225
|
limit?: number;
|
|
124
|
-
}): Promise<ChemblModulator[]>;
|
|
226
|
+
}, logger?: Logger): Promise<ChemblModulator[]>;
|
|
125
227
|
/**
|
|
126
228
|
* Fetch the canonical InChI key for a ChEMBL molecule. Returns null when
|
|
127
229
|
* ChEMBL has no recorded structure (typical for peptide/protein entries
|