@inflexa-ai/harness 0.30.3 → 0.31.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/dist/contracts/target-dossier.d.ts +61 -61
  2. package/dist/execution/run-synthesis.js +7 -2
  3. package/dist/lib/zod-issues.d.ts +8 -0
  4. package/dist/lib/zod-issues.js +13 -0
  5. package/dist/literature/sources/semantic-scholar.d.ts +34 -0
  6. package/dist/literature/sources/semantic-scholar.js +15 -4
  7. package/dist/prompts/briefing.d.ts +12 -1
  8. package/dist/prompts/briefing.js +27 -1
  9. package/dist/prompts/sandbox-standards.d.ts +1 -1
  10. package/dist/prompts/sandbox-standards.js +27 -0
  11. package/dist/sandbox/thread-env.d.ts +18 -12
  12. package/dist/sandbox/thread-env.js +36 -25
  13. package/dist/tools/bio/chembl.js +4 -3
  14. package/dist/tools/bio/drug-gene-interactions.d.ts +2 -14
  15. package/dist/tools/bio/drug-gene-interactions.js +10 -18
  16. package/dist/tools/bio/gene-disease-evidence.d.ts +3 -1
  17. package/dist/tools/bio/gene-disease-evidence.js +12 -9
  18. package/dist/tools/bio/keys.js +1 -0
  19. package/dist/tools/bio/lookup-annotation.d.ts +43 -0
  20. package/dist/tools/bio/lookup-annotation.js +19 -4
  21. package/dist/tools/bio/pubchem.js +5 -3
  22. package/dist/tools/bio/search-clinical-trials.js +5 -4
  23. package/dist/tools/bio/search-geo-datasets.d.ts +39 -9
  24. package/dist/tools/bio/search-geo-datasets.js +38 -20
  25. package/dist/tools/lib/api-utils.d.ts +27 -2
  26. package/dist/tools/lib/api-utils.js +43 -3
  27. package/dist/tools/lib/bgee-client.d.ts +16 -0
  28. package/dist/tools/lib/bgee-client.js +16 -5
  29. package/dist/tools/lib/cbioportal-client.d.ts +20 -0
  30. package/dist/tools/lib/cbioportal-client.js +16 -8
  31. package/dist/tools/lib/chembl-client.d.ts +105 -3
  32. package/dist/tools/lib/chembl-client.js +196 -84
  33. package/dist/tools/lib/clinical-benchmarks-client.d.ts +5 -0
  34. package/dist/tools/lib/clinical-benchmarks-client.js +5 -0
  35. package/dist/tools/lib/clinical-trials-client.d.ts +131 -2
  36. package/dist/tools/lib/clinical-trials-client.js +32 -6
  37. package/dist/tools/lib/clinvar-client.d.ts +35 -0
  38. package/dist/tools/lib/clinvar-client.js +34 -28
  39. package/dist/tools/lib/ctx-ops.d.ts +106 -35
  40. package/dist/tools/lib/ctx-ops.js +135 -69
  41. package/dist/tools/lib/dgidb-client.d.ts +73 -0
  42. package/dist/tools/lib/dgidb-client.js +25 -13
  43. package/dist/tools/lib/disgenet-client.d.ts +117 -24
  44. package/dist/tools/lib/disgenet-client.js +127 -34
  45. package/dist/tools/lib/disgenet-config.d.ts +1 -1
  46. package/dist/tools/lib/disgenet-config.js +5 -3
  47. package/dist/tools/lib/drugbank-client.d.ts +57 -58
  48. package/dist/tools/lib/drugbank-client.js +69 -64
  49. package/dist/tools/lib/drugbank-config.d.ts +6 -1
  50. package/dist/tools/lib/drugbank-config.js +6 -1
  51. package/dist/tools/lib/ema-client.d.ts +53 -0
  52. package/dist/tools/lib/ema-client.js +19 -7
  53. package/dist/tools/lib/ensembl-client.d.ts +4 -0
  54. package/dist/tools/lib/ensembl-client.js +4 -0
  55. package/dist/tools/lib/gwas-catalog-client.d.ts +64 -1
  56. package/dist/tools/lib/gwas-catalog-client.js +21 -6
  57. package/dist/tools/lib/identifier-resolver.d.ts +17 -1
  58. package/dist/tools/lib/identifier-resolver.js +13 -4
  59. package/dist/tools/lib/impc-client.d.ts +4 -0
  60. package/dist/tools/lib/impc-client.js +4 -0
  61. package/dist/tools/lib/iuphar-client.d.ts +10 -5
  62. package/dist/tools/lib/iuphar-client.js +49 -13
  63. package/dist/tools/lib/monarch-client.d.ts +4 -0
  64. package/dist/tools/lib/monarch-client.js +4 -0
  65. package/dist/tools/lib/openfda-client.d.ts +34 -0
  66. package/dist/tools/lib/openfda-client.js +22 -8
  67. package/dist/tools/lib/opentargets-client.d.ts +99 -4
  68. package/dist/tools/lib/opentargets-client.js +97 -37
  69. package/dist/tools/lib/pathway-client.d.ts +45 -0
  70. package/dist/tools/lib/pathway-client.js +88 -8
  71. package/dist/tools/lib/pharmgkb-client.d.ts +35 -1
  72. package/dist/tools/lib/pharmgkb-client.js +22 -6
  73. package/dist/tools/lib/pharmgkb-config.d.ts +8 -1
  74. package/dist/tools/lib/pharmgkb-config.js +8 -1
  75. package/dist/tools/lib/pubchem-client.d.ts +22 -0
  76. package/dist/tools/lib/pubchem-client.js +36 -33
  77. package/dist/tools/lib/pubchem-ops.d.ts +85 -5
  78. package/dist/tools/lib/pubchem-ops.js +96 -68
  79. package/dist/tools/lib/pubmed-client.d.ts +4 -0
  80. package/dist/tools/lib/pubmed-client.js +4 -0
  81. package/dist/tools/lib/string-client.d.ts +52 -0
  82. package/dist/tools/lib/string-client.js +12 -7
  83. package/dist/tools/lib/uniprot-client.d.ts +4 -0
  84. package/dist/tools/lib/uniprot-client.js +4 -0
  85. package/dist/tools/research/context7-docs.d.ts +23 -0
  86. package/dist/tools/research/context7-docs.js +49 -9
  87. package/dist/tools/research/search-github-repos.d.ts +4 -0
  88. package/dist/tools/research/search-github-repos.js +4 -0
  89. package/dist/workflows/execute-target-assessment.js +4 -4
  90. package/dist/workflows/target-assessment/assemblers/orchestrator.d.ts +2 -1
  91. package/dist/workflows/target-assessment/assemblers/orchestrator.js +3 -3
  92. package/dist/workflows/target-assessment/collectors/index.d.ts +8 -2
  93. package/dist/workflows/target-assessment/collectors/index.js +37 -10
  94. package/dist/workflows/target-assessment/fanout/index.d.ts +2 -1
  95. package/dist/workflows/target-assessment/fanout/index.js +2 -2
  96. package/dist/workflows/target-assessment/lib/safety-corroboration.js +2 -2
  97. package/dist/workflows/target-assessment/lib/target-identity-filter.d.ts +3 -2
  98. package/dist/workflows/target-assessment/lib/target-identity-filter.js +16 -5
  99. package/dist/workflows/target-assessment/phase4-assemble.d.ts +61 -60
  100. package/dist/workflows/target-assessment/phase4-assemble.js +2 -2
  101. package/dist/workflows/target-assessment/schemas.d.ts +2 -8
  102. package/dist/workflows/target-assessment/schemas.js +8 -2
  103. package/dist/workflows/target-assessment/steps/phase2-aggregate.d.ts +1 -4
  104. package/dist/workflows/target-assessment/steps/phase3-aggregate.d.ts +1 -4
  105. package/package.json +1 -1
  106. package/dist/agents/sandbox/__fixtures__/deps.d.ts +0 -23
  107. package/dist/agents/sandbox/__fixtures__/deps.js +0 -102
  108. package/dist/citations/__fixtures__/resolver.d.ts +0 -3
  109. package/dist/citations/__fixtures__/resolver.js +0 -9
  110. package/dist/loop/__fixtures__/scripted-provider.d.ts +0 -31
  111. package/dist/loop/__fixtures__/scripted-provider.js +0 -81
  112. package/dist/providers/__fixtures__/session.d.ts +0 -17
  113. package/dist/providers/__fixtures__/session.js +0 -20
  114. package/dist/tools/__fixtures__/tool-context.d.ts +0 -13
  115. package/dist/tools/__fixtures__/tool-context.js +0 -22
@@ -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 APIs (429/503), request
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
- const RETRYABLE_STATUSES = new Set([429, 503]);
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
- async function resolveOrtholog(symbol, targetSpecies) {
106
- const url = `${ENSEMBL_BASE}/homology/symbol/homo_sapiens/${encodeURIComponent(symbol)}` + `?type=orthologues;target_species=${targetSpecies};format=condensed`;
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(geneSymbol, sp);
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
- const RawMutationCountSchema = z.object({
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
- cancerType: z.object({ name: z.string().optional(), cancerTypeId: z.string().optional() }).optional(),
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 fetchMutationCountsForGene(entrezGeneId, profileIds) {
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(RawMutationCountSchema), {
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 fetchMutationCountsForGene(entrezGeneId, profileIds);
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?.cancerTypeId ?? study?.cancerTypeId ?? "unknown";
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