@inflexa-ai/harness 0.1.1 → 0.3.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.
Files changed (330) hide show
  1. package/README.md +48 -0
  2. package/dist/agents/conversation-agent.d.ts +15 -11
  3. package/dist/agents/conversation-agent.js +31 -34
  4. package/dist/agents/report-builder.js +2 -1
  5. package/dist/agents/sandbox/bulk-transcriptomics-agent.js +1 -1
  6. package/dist/agents/sandbox/cheminformatics-agent.js +1 -19
  7. package/dist/agents/sandbox/chromatin-agent.js +1 -10
  8. package/dist/agents/sandbox/dna-methylation-agent.js +1 -10
  9. package/dist/agents/sandbox/drug-repurposing-agent.js +4 -14
  10. package/dist/agents/sandbox/enrichment-agent.js +1 -10
  11. package/dist/agents/sandbox/ephemeral-executor.js +1 -10
  12. package/dist/agents/sandbox/genomic-variant-agent.js +1 -3
  13. package/dist/agents/sandbox/immune-profiling-agent.js +1 -13
  14. package/dist/agents/sandbox/metabolomics-agent.js +1 -1
  15. package/dist/agents/sandbox/microbiome-agent.js +1 -1
  16. package/dist/agents/sandbox/multi-omics-integration-agent.js +1 -12
  17. package/dist/agents/sandbox/multimodal-sc-agent.js +1 -1
  18. package/dist/agents/sandbox/network-agent.js +1 -10
  19. package/dist/agents/sandbox/pkpd-clinical-response-agent.js +2 -8
  20. package/dist/agents/sandbox/proteomics-agent.js +1 -1
  21. package/dist/agents/sandbox/scientific-executor.js +1 -10
  22. package/dist/agents/sandbox/shared.d.ts +20 -6
  23. package/dist/agents/sandbox/shared.js +50 -39
  24. package/dist/agents/sandbox/single-cell-agent.js +1 -1
  25. package/dist/agents/sandbox/spatial-omics-agent.js +1 -1
  26. package/dist/agents/sandbox/statistical-modeling-agent.js +1 -1
  27. package/dist/agents/sandbox/translational-safety-agent.js +3 -9
  28. package/dist/agents/sandbox/types.d.ts +1 -1
  29. package/dist/agents/system-prompt.d.ts +37 -11
  30. package/dist/agents/system-prompt.js +35 -12
  31. package/dist/app/chat-turn.d.ts +3 -0
  32. package/dist/app/chat-turn.js +3 -1
  33. package/dist/app/data-profile-orientation.d.ts +34 -0
  34. package/dist/app/data-profile-orientation.js +117 -0
  35. package/dist/app/synthesize-run.d.ts +3 -0
  36. package/dist/app/synthesize-run.js +3 -1
  37. package/dist/contracts/schemas/chat-parts.d.ts +9 -9
  38. package/dist/execution/artifact-metadata.d.ts +3 -0
  39. package/dist/execution/artifact-metadata.js +10 -3
  40. package/dist/execution/artifact-registration.d.ts +2 -1
  41. package/dist/execution/artifact-registration.js +8 -2
  42. package/dist/execution/ephemeral-runner.d.ts +16 -0
  43. package/dist/execution/ephemeral-runner.js +31 -5
  44. package/dist/execution/post-step-pipeline.d.ts +3 -0
  45. package/dist/execution/post-step-pipeline.js +24 -4
  46. package/dist/execution/reconcile-manifest.d.ts +7 -0
  47. package/dist/execution/reconcile-manifest.js +19 -5
  48. package/dist/execution/report-runner.d.ts +3 -0
  49. package/dist/execution/report-runner.js +4 -4
  50. package/dist/execution/run-synthesis.js +20 -19
  51. package/dist/execution/step-summary.d.ts +3 -0
  52. package/dist/execution/step-summary.js +6 -3
  53. package/dist/index.d.ts +9 -2
  54. package/dist/index.js +24 -5
  55. package/dist/lib/chrome.d.ts +4 -1
  56. package/dist/lib/chrome.js +10 -7
  57. package/dist/lib/console-logger.d.ts +19 -0
  58. package/dist/lib/console-logger.js +62 -0
  59. package/dist/lib/logger.d.ts +88 -0
  60. package/dist/lib/logger.js +37 -0
  61. package/dist/lib/otel.d.ts +2 -1
  62. package/dist/lib/otel.js +8 -3
  63. package/dist/loop/__fixtures__/scripted-provider.d.ts +2 -2
  64. package/dist/loop/__fixtures__/scripted-provider.js +2 -1
  65. package/dist/loop/metrics.d.ts +33 -1
  66. package/dist/loop/metrics.js +56 -2
  67. package/dist/loop/run-agent.d.ts +13 -1
  68. package/dist/loop/run-agent.js +19 -4
  69. package/dist/memory/card-builders.d.ts +8 -1
  70. package/dist/memory/card-builders.js +20 -3
  71. package/dist/memory/reconstruct-cards.js +4 -3
  72. package/dist/memory/thread-history.d.ts +27 -2
  73. package/dist/memory/thread-history.js +45 -5
  74. package/dist/memory/working-memory.d.ts +93 -10
  75. package/dist/memory/working-memory.js +220 -84
  76. package/dist/prompts/SOUL.d.ts +22 -9
  77. package/dist/prompts/SOUL.js +56 -37
  78. package/dist/prompts/analogical-reasoner.d.ts +1 -1
  79. package/dist/prompts/analogical-reasoner.js +2 -2
  80. package/dist/prompts/briefing.d.ts +100 -0
  81. package/dist/prompts/briefing.js +166 -0
  82. package/dist/prompts/conversation.d.ts +1 -1
  83. package/dist/prompts/conversation.js +94 -440
  84. package/dist/prompts/literature-reviewer.d.ts +1 -1
  85. package/dist/prompts/literature-reviewer.js +10 -10
  86. package/dist/prompts/planner.js +28 -59
  87. package/dist/prompts/report-builder.d.ts +1 -1
  88. package/dist/prompts/report-builder.js +71 -24
  89. package/dist/prompts/sandbox/bulk-transcriptomics-agent.d.ts +1 -1
  90. package/dist/prompts/sandbox/bulk-transcriptomics-agent.js +2 -7
  91. package/dist/prompts/sandbox/cheminformatics-agent.d.ts +1 -1
  92. package/dist/prompts/sandbox/cheminformatics-agent.js +11 -15
  93. package/dist/prompts/sandbox/chromatin-agent.d.ts +1 -1
  94. package/dist/prompts/sandbox/chromatin-agent.js +3 -7
  95. package/dist/prompts/sandbox/data-profiler.d.ts +1 -1
  96. package/dist/prompts/sandbox/data-profiler.js +13 -8
  97. package/dist/prompts/sandbox/dna-methylation-agent.d.ts +1 -1
  98. package/dist/prompts/sandbox/dna-methylation-agent.js +2 -7
  99. package/dist/prompts/sandbox/drug-repurposing-agent.d.ts +1 -1
  100. package/dist/prompts/sandbox/drug-repurposing-agent.js +15 -16
  101. package/dist/prompts/sandbox/enrichment-agent.d.ts +1 -1
  102. package/dist/prompts/sandbox/enrichment-agent.js +2 -9
  103. package/dist/prompts/sandbox/genomic-variant-agent.d.ts +1 -1
  104. package/dist/prompts/sandbox/genomic-variant-agent.js +2 -6
  105. package/dist/prompts/sandbox/immune-profiling-agent.d.ts +1 -1
  106. package/dist/prompts/sandbox/immune-profiling-agent.js +3 -8
  107. package/dist/prompts/sandbox/metabolomics-agent.d.ts +1 -1
  108. package/dist/prompts/sandbox/metabolomics-agent.js +1 -7
  109. package/dist/prompts/sandbox/microbiome-agent.d.ts +1 -1
  110. package/dist/prompts/sandbox/microbiome-agent.js +2 -7
  111. package/dist/prompts/sandbox/multi-omics-integration-agent.d.ts +1 -1
  112. package/dist/prompts/sandbox/multi-omics-integration-agent.js +2 -8
  113. package/dist/prompts/sandbox/multimodal-sc-agent.d.ts +1 -1
  114. package/dist/prompts/sandbox/multimodal-sc-agent.js +2 -7
  115. package/dist/prompts/sandbox/network-agent.d.ts +1 -1
  116. package/dist/prompts/sandbox/network-agent.js +2 -7
  117. package/dist/prompts/sandbox/proteomics-agent.d.ts +1 -1
  118. package/dist/prompts/sandbox/proteomics-agent.js +2 -9
  119. package/dist/prompts/sandbox/single-cell-agent.d.ts +1 -1
  120. package/dist/prompts/sandbox/single-cell-agent.js +2 -9
  121. package/dist/prompts/sandbox/spatial-omics-agent.d.ts +1 -1
  122. package/dist/prompts/sandbox/spatial-omics-agent.js +3 -6
  123. package/dist/prompts/sandbox/statistical-modeling-agent.d.ts +1 -1
  124. package/dist/prompts/sandbox/statistical-modeling-agent.js +2 -7
  125. package/dist/prompts/sandbox/translational-safety-agent.d.ts +1 -1
  126. package/dist/prompts/sandbox/translational-safety-agent.js +13 -14
  127. package/dist/prompts/sandbox-standards.d.ts +22 -14
  128. package/dist/prompts/sandbox-standards.js +91 -71
  129. package/dist/prompts/synthesis-agent.d.ts +1 -1
  130. package/dist/prompts/synthesis-agent.js +33 -131
  131. package/dist/provenance/collector.js +1 -1
  132. package/dist/providers/ai-sdk.js +31 -4
  133. package/dist/providers/prompt-cache.d.ts +74 -0
  134. package/dist/providers/prompt-cache.js +77 -0
  135. package/dist/providers/types.d.ts +33 -0
  136. package/dist/reference-data/catalog.d.ts +131 -0
  137. package/dist/reference-data/catalog.js +348 -0
  138. package/dist/reference-data/receipt.d.ts +41 -0
  139. package/dist/reference-data/receipt.js +40 -0
  140. package/dist/runtime/boot.d.ts +2 -2
  141. package/dist/runtime/boot.js +1 -1
  142. package/dist/runtime/connection-budget.d.ts +2 -2
  143. package/dist/runtime/connection-budget.js +5 -3
  144. package/dist/runtime/dbos.d.ts +7 -7
  145. package/dist/runtime/dbos.js +14 -11
  146. package/dist/runtime/shutdown.d.ts +2 -2
  147. package/dist/runtime/shutdown.js +4 -3
  148. package/dist/sandbox/create-sandbox.d.ts +2 -2
  149. package/dist/sandbox/docker-client.d.ts +2 -2
  150. package/dist/sandbox/docker-client.js +4 -1
  151. package/dist/sandbox/k8s-client.d.ts +3 -0
  152. package/dist/sandbox/k8s-client.js +5 -4
  153. package/dist/sandbox/notification-sweep.d.ts +3 -3
  154. package/dist/sandbox/notification-sweep.js +4 -2
  155. package/dist/sandbox/reaper.d.ts +3 -3
  156. package/dist/sandbox/reaper.js +7 -4
  157. package/dist/sandbox/watchdog.d.ts +3 -3
  158. package/dist/sandbox/watchdog.js +8 -2
  159. package/dist/schemas/data-profile-schemas.js +5 -3
  160. package/dist/schemas/plan-schemas.d.ts +21 -21
  161. package/dist/schemas/plan-schemas.js +9 -3
  162. package/dist/schemas/run-synthesis.d.ts +8 -4
  163. package/dist/schemas/run-synthesis.js +92 -56
  164. package/dist/schemas/validate-plan.js +1 -1
  165. package/dist/schemas/workflow-state.d.ts +7 -1
  166. package/dist/schemas/workflow-state.js +33 -19
  167. package/dist/state/artifacts.d.ts +13 -0
  168. package/dist/state/artifacts.js +27 -0
  169. package/dist/state/data-profile.d.ts +64 -5
  170. package/dist/state/index.d.ts +3 -3
  171. package/dist/state/index.js +1 -1
  172. package/dist/state/init.d.ts +2 -1
  173. package/dist/state/init.js +5 -6
  174. package/dist/tasks/data-profile.d.ts +25 -2
  175. package/dist/tasks/data-profile.js +95 -39
  176. package/dist/tools/bio/chembl.d.ts +38 -0
  177. package/dist/tools/bio/chembl.js +138 -0
  178. package/dist/tools/bio/comptox.d.ts +50 -0
  179. package/dist/tools/bio/comptox.js +149 -0
  180. package/dist/tools/bio/get-impc-ko-profile.js +9 -6
  181. package/dist/tools/bio/index.d.ts +5 -17
  182. package/dist/tools/bio/index.js +5 -17
  183. package/dist/tools/bio/keys.d.ts +14 -9
  184. package/dist/tools/bio/keys.js +16 -16
  185. package/dist/tools/bio/opentargets.d.ts +38 -0
  186. package/dist/tools/bio/opentargets.js +89 -0
  187. package/dist/tools/bio/pubchem.d.ts +29 -0
  188. package/dist/tools/bio/pubchem.js +92 -0
  189. package/dist/tools/bio/pubmed.d.ts +51 -0
  190. package/dist/tools/bio/pubmed.js +100 -0
  191. package/dist/tools/bio/search-bgee-expression.js +12 -6
  192. package/dist/tools/bio/search-clinical-trials.js +16 -5
  193. package/dist/tools/bio/search-dgidb.d.ts +11 -1
  194. package/dist/tools/bio/search-dgidb.js +92 -78
  195. package/dist/tools/bio/search-faers.js +8 -4
  196. package/dist/tools/bio/search-geo-datasets.js +20 -6
  197. package/dist/tools/bio/search-gwas-catalog.d.ts +1 -1
  198. package/dist/tools/bio/search-pharmgkb.js +10 -4
  199. package/dist/tools/display/index.d.ts +1 -0
  200. package/dist/tools/display/index.js +1 -0
  201. package/dist/tools/display/normalize-echart-spec.d.ts +61 -0
  202. package/dist/tools/display/normalize-echart-spec.js +211 -0
  203. package/dist/tools/display/show-user.d.ts +6 -1
  204. package/dist/tools/display/show-user.js +25 -12
  205. package/dist/tools/execute-plan.js +5 -2
  206. package/dist/tools/iterate-report.d.ts +171 -118
  207. package/dist/tools/iterate-report.js +336 -96
  208. package/dist/tools/lib/chembl-client.d.ts +12 -0
  209. package/dist/tools/lib/chembl-client.js +127 -0
  210. package/dist/tools/lib/ctx-ops.d.ts +224 -0
  211. package/dist/tools/lib/ctx-ops.js +450 -0
  212. package/dist/tools/lib/iuphar-client.js +10 -1
  213. package/dist/tools/lib/openfda-client.js +11 -3
  214. package/dist/tools/lib/pathway-client.js +10 -4
  215. package/dist/tools/lib/pubchem-ops.d.ts +74 -0
  216. package/dist/tools/lib/pubchem-ops.js +224 -0
  217. package/dist/tools/memory/update-working-memory.d.ts +45 -7
  218. package/dist/tools/memory/update-working-memory.js +111 -41
  219. package/dist/tools/report/index.d.ts +3 -2
  220. package/dist/tools/report/index.js +3 -2
  221. package/dist/tools/research/generate-analogy-report.js +25 -12
  222. package/dist/tools/research/generate-plan.d.ts +12 -5
  223. package/dist/tools/research/generate-plan.js +168 -37
  224. package/dist/tools/research/index.d.ts +1 -0
  225. package/dist/tools/research/index.js +1 -0
  226. package/dist/tools/research/inspect-data-profile.d.ts +85 -0
  227. package/dist/tools/research/inspect-data-profile.js +161 -0
  228. package/dist/tools/research/literature-reviewer.d.ts +3 -0
  229. package/dist/tools/research/literature-reviewer.js +5 -6
  230. package/dist/tools/sandbox/list-available-packages.d.ts +79 -5
  231. package/dist/tools/sandbox/list-available-packages.js +152 -10
  232. package/dist/tools/sandbox/list-available-refs.d.ts +141 -5
  233. package/dist/tools/sandbox/list-available-refs.js +647 -134
  234. package/dist/tools/sandbox/report-blocker.d.ts +39 -9
  235. package/dist/tools/sandbox/report-blocker.js +43 -20
  236. package/dist/tools/workspace/execute-command.d.ts +3 -0
  237. package/dist/tools/workspace/execute-command.js +3 -1
  238. package/dist/tools/workspace/read-file.js +4 -5
  239. package/dist/tools/workspace/run-exec.d.ts +4 -4
  240. package/dist/tools/workspace/run-exec.js +4 -4
  241. package/dist/tools/workspace/show-file.js +10 -6
  242. package/dist/tools/workspace/show-plan.js +12 -6
  243. package/dist/tools/workspace/workspace-search.d.ts +1 -1
  244. package/dist/tools/workspace/workspace-search.js +11 -5
  245. package/dist/workflows/execute-analysis.d.ts +46 -4
  246. package/dist/workflows/execute-analysis.js +118 -13
  247. package/dist/workflows/execute-target-assessment.d.ts +3 -0
  248. package/dist/workflows/execute-target-assessment.js +19 -15
  249. package/dist/workflows/sandbox-step.d.ts +9 -0
  250. package/dist/workflows/sandbox-step.js +39 -17
  251. package/dist/workflows/target-assessment/lib/citation-validator.js +2 -2
  252. package/dist/workflows/target-assessment/lib/clinical-consequence-annotator.js +2 -1
  253. package/dist/workflows/target-assessment/lib/llm-step.d.ts +3 -0
  254. package/dist/workflows/target-assessment/lib/llm-step.js +3 -1
  255. package/dist/workflows/target-assessment/lib/structured-llm.d.ts +3 -0
  256. package/dist/workflows/target-assessment/lib/structured-llm.js +1 -0
  257. package/dist/workflows/target-assessment/phase5-persist.d.ts +3 -0
  258. package/dist/workflows/target-assessment/phase5-persist.js +8 -3
  259. package/dist/workflows/target-assessment/progress.d.ts +2 -1
  260. package/dist/workflows/target-assessment/progress.js +4 -3
  261. package/dist/workspace/filesystem.js +163 -74
  262. package/dist/workspace/paths.d.ts +2 -2
  263. package/dist/workspace/paths.js +2 -2
  264. package/package.json +95 -96
  265. package/dist/execution/filesystem-artifact-registry.d.ts +0 -57
  266. package/dist/execution/filesystem-artifact-registry.js +0 -92
  267. package/dist/lib/identifiers.d.ts +0 -8
  268. package/dist/lib/identifiers.js +0 -10
  269. package/dist/lib/mime-detect.d.ts +0 -17
  270. package/dist/lib/mime-detect.js +0 -29
  271. package/dist/lib/streamed-download.d.ts +0 -28
  272. package/dist/lib/streamed-download.js +0 -111
  273. package/dist/lib/trace-context.d.ts +0 -11
  274. package/dist/lib/trace-context.js +0 -49
  275. package/dist/providers/llm-capabilities.d.ts +0 -33
  276. package/dist/providers/llm-capabilities.js +0 -58
  277. package/dist/schemas/render-step-prompt.d.ts +0 -32
  278. package/dist/schemas/render-step-prompt.js +0 -76
  279. package/dist/tools/bio/find-approval-precedent.d.ts +0 -32
  280. package/dist/tools/bio/find-approval-precedent.js +0 -72
  281. package/dist/tools/bio/get-article-details.d.ts +0 -11
  282. package/dist/tools/bio/get-article-details.js +0 -20
  283. package/dist/tools/bio/get-article-full-text.d.ts +0 -19
  284. package/dist/tools/bio/get-article-full-text.js +0 -32
  285. package/dist/tools/bio/get-bioactivity.d.ts +0 -11
  286. package/dist/tools/bio/get-bioactivity.js +0 -23
  287. package/dist/tools/bio/get-drug-info.d.ts +0 -9
  288. package/dist/tools/bio/get-drug-info.js +0 -22
  289. package/dist/tools/bio/get-mechanism.d.ts +0 -8
  290. package/dist/tools/bio/get-mechanism.js +0 -18
  291. package/dist/tools/bio/get-pubchem-assays.d.ts +0 -22
  292. package/dist/tools/bio/get-pubchem-assays.js +0 -107
  293. package/dist/tools/bio/get-pubchem-cross-refs.d.ts +0 -15
  294. package/dist/tools/bio/get-pubchem-cross-refs.js +0 -68
  295. package/dist/tools/bio/get-target-safety.d.ts +0 -18
  296. package/dist/tools/bio/get-target-safety.js +0 -26
  297. package/dist/tools/bio/search-compounds.d.ts +0 -22
  298. package/dist/tools/bio/search-compounds.js +0 -160
  299. package/dist/tools/bio/search-ctx-chemical.d.ts +0 -50
  300. package/dist/tools/bio/search-ctx-chemical.js +0 -130
  301. package/dist/tools/bio/search-ctx-exposure.d.ts +0 -55
  302. package/dist/tools/bio/search-ctx-exposure.js +0 -176
  303. package/dist/tools/bio/search-ctx-hazard.d.ts +0 -111
  304. package/dist/tools/bio/search-ctx-hazard.js +0 -178
  305. package/dist/tools/bio/search-opentargets.d.ts +0 -11
  306. package/dist/tools/bio/search-opentargets.js +0 -25
  307. package/dist/tools/bio/search-pubchem-compound.d.ts +0 -26
  308. package/dist/tools/bio/search-pubchem-compound.js +0 -110
  309. package/dist/tools/bio/search-pubmed.d.ts +0 -17
  310. package/dist/tools/bio/search-pubmed.js +0 -31
  311. package/dist/tools/bio/search-targets.d.ts +0 -9
  312. package/dist/tools/bio/search-targets.js +0 -20
  313. package/dist/tools/bio/search-toxcast.d.ts +0 -36
  314. package/dist/tools/bio/search-toxcast.js +0 -141
  315. package/dist/workflows/register-workflows.d.ts +0 -51
  316. package/dist/workflows/register-workflows.js +0 -48
  317. package/dist/workflows/resume-execute-analysis.d.ts +0 -70
  318. package/dist/workflows/resume-execute-analysis.js +0 -80
  319. package/dist/workflows/target-assessment/correction-loop.d.ts +0 -45
  320. package/dist/workflows/target-assessment/correction-loop.js +0 -62
  321. package/dist/workflows/target-assessment/steps/phase0-resolve.d.ts +0 -71
  322. package/dist/workflows/target-assessment/steps/phase0-resolve.js +0 -21
  323. package/dist/workflows/target-assessment/steps/phase1-aggregate.d.ts +0 -1018
  324. package/dist/workflows/target-assessment/steps/phase1-aggregate.js +0 -25
  325. package/dist/workspace/mount-strategy.d.ts +0 -50
  326. package/dist/workspace/mount-strategy.js +0 -67
  327. package/dist/workspace/provenance-collector.d.ts +0 -34
  328. package/dist/workspace/provenance-collector.js +0 -16
  329. package/dist/workspace/workspace-paths.d.ts +0 -26
  330. package/dist/workspace/workspace-paths.js +0 -31
@@ -70,6 +70,47 @@ const MoleculeStructuresResponseSchema = z.object({
70
70
  const TargetComponentsResponseSchema = z.object({
71
71
  target_components: z.array(z.object({ accession: z.string().optional(), component_type: z.string().optional() })).optional(),
72
72
  });
73
+ // A single schema that both validates and normalizes one ChEMBL molecule
74
+ // record for the compound search: the `.object(...)` half is the snake_case wire
75
+ // shape (every field optional — ChEMBL omits absent values), the
76
+ // `.transform(...)` half maps it to the camelCase `ChemblCompound` we return.
77
+ // Parsing IS the validation, so there is no separate raw interface or mapper.
78
+ const CompoundRecordSchema = z
79
+ .object({
80
+ molecule_chembl_id: z.string().optional(),
81
+ // ChEMBL sends explicit `null` (not omission) for an unnamed compound, and
82
+ // `null` for the whole structures/properties blocks on biologics/antibodies
83
+ // — `.nullable()` so those rows parse instead of failing the `molecules` array.
84
+ pref_name: z.string().nullable().optional(),
85
+ molecule_structures: z
86
+ .object({
87
+ canonical_smiles: z.string().nullable().optional(),
88
+ })
89
+ .nullable()
90
+ .optional(),
91
+ molecule_properties: z
92
+ .object({
93
+ full_mwt: z.string().nullable().optional(),
94
+ alogp: z.string().nullable().optional(),
95
+ molecular_formula: z.string().nullable().optional(),
96
+ })
97
+ .nullable()
98
+ .optional(),
99
+ })
100
+ .transform((raw) => ({
101
+ chemblId: raw.molecule_chembl_id ?? "",
102
+ preferredCompoundName: raw.pref_name ?? null,
103
+ canonicalSmiles: raw.molecule_structures?.canonical_smiles ?? null,
104
+ molecularWeight: raw.molecule_properties?.full_mwt ? parseFloat(raw.molecule_properties.full_mwt) : null,
105
+ alogp: raw.molecule_properties?.alogp ? parseFloat(raw.molecule_properties.alogp) : null,
106
+ molecularFormula: raw.molecule_properties?.molecular_formula ?? null,
107
+ }));
108
+ const CompoundsResponseSchema = z.object({ molecules: z.array(CompoundRecordSchema).optional() });
109
+ // The two hops of the target-mode compound search read one id each, so they
110
+ // project the response down to that id rather than reusing the richer
111
+ // target/activity schemas above.
112
+ const CompoundTargetIdResponseSchema = z.object({ targets: z.array(z.object({ target_chembl_id: z.string().optional() })).optional() });
113
+ const CompoundActivityIdResponseSchema = z.object({ activities: z.array(z.object({ molecule_chembl_id: z.string().optional() })).optional() });
73
114
  function extractGeneNames(components) {
74
115
  if (!components?.length)
75
116
  return [];
@@ -104,6 +145,92 @@ function parseNumeric(val) {
104
145
  const n = typeof val === "number" ? val : parseFloat(val);
105
146
  return Number.isNaN(n) ? null : n;
106
147
  }
148
+ /**
149
+ * Compounds assayed against a target: resolve the query to a target ChEMBL ID,
150
+ * read that target's activity rows, then fetch the unique molecules behind them.
151
+ * `limit` caps the activity rows scanned, so the compound count is usually lower.
152
+ */
153
+ async function searchCompoundsByTarget(query, limit) {
154
+ const targetRes = await apiFetchValidated(`${CHEMBL_BASE}/target/search.json?q=${encodeURIComponent(query)}&limit=1`, CompoundTargetIdResponseSchema, {
155
+ headers: HEADERS,
156
+ });
157
+ if (targetRes.isErr()) {
158
+ if (targetRes.error.type === "http_status" && targetRes.error.status === 404)
159
+ return [];
160
+ throw new Error(describeApiError(targetRes.error));
161
+ }
162
+ if (!targetRes.value.targets?.length)
163
+ return [];
164
+ const targetChemblId = targetRes.value.targets[0].target_chembl_id;
165
+ if (!targetChemblId)
166
+ return [];
167
+ const activityRes = await apiFetchValidated(`${CHEMBL_BASE}/activity.json?target_chembl_id=${targetChemblId}&limit=${limit}`, CompoundActivityIdResponseSchema, {
168
+ headers: HEADERS,
169
+ });
170
+ if (activityRes.isErr()) {
171
+ if (activityRes.error.type === "http_status" && activityRes.error.status === 404)
172
+ return [];
173
+ throw new Error(describeApiError(activityRes.error));
174
+ }
175
+ if (!activityRes.value.activities?.length)
176
+ return [];
177
+ const uniqueIds = new Set();
178
+ for (const act of activityRes.value.activities) {
179
+ if (act.molecule_chembl_id)
180
+ uniqueIds.add(act.molecule_chembl_id);
181
+ }
182
+ const compounds = [];
183
+ const idArray = [...uniqueIds];
184
+ // Fetch in batches of 50 to avoid overly long URLs.
185
+ const batchSize = 50;
186
+ for (let i = 0; i < idArray.length; i += batchSize) {
187
+ const batch = idArray.slice(i, i + batchSize);
188
+ const idsParam = batch.join(";");
189
+ const molRes = await apiFetchValidated(`${CHEMBL_BASE}/molecule/set/${idsParam}.json`, CompoundsResponseSchema, { headers: HEADERS });
190
+ if (molRes.isErr()) {
191
+ if (!(molRes.error.type === "http_status" && molRes.error.status === 404)) {
192
+ throw new Error(describeApiError(molRes.error));
193
+ }
194
+ continue;
195
+ }
196
+ if (molRes.value.molecules) {
197
+ for (const mol of molRes.value.molecules) {
198
+ compounds.push(mol);
199
+ }
200
+ }
201
+ }
202
+ return compounds;
203
+ }
204
+ /** Free-text search over molecule names. */
205
+ async function searchCompoundsByName(query, limit) {
206
+ const res = await apiFetchValidated(`${CHEMBL_BASE}/molecule/search.json?q=${encodeURIComponent(query)}&limit=${limit}`, CompoundsResponseSchema, {
207
+ headers: HEADERS,
208
+ });
209
+ if (res.isErr()) {
210
+ if (res.error.type === "http_status" && res.error.status === 404)
211
+ return [];
212
+ throw new Error(describeApiError(res.error));
213
+ }
214
+ return res.value.molecules ?? [];
215
+ }
216
+ /** Flexible (flexmatch) structure search on canonical SMILES. */
217
+ async function searchCompoundsBySmiles(smiles, limit) {
218
+ const res = await apiFetchValidated(`${CHEMBL_BASE}/molecule.json?molecule_structures__canonical_smiles__flexmatch=${encodeURIComponent(smiles)}&limit=${limit}`, CompoundsResponseSchema, { headers: HEADERS });
219
+ if (res.isErr()) {
220
+ if (res.error.type === "http_status" && res.error.status === 404)
221
+ return [];
222
+ throw new Error(describeApiError(res.error));
223
+ }
224
+ return res.value.molecules ?? [];
225
+ }
226
+ /** Search ChEMBL for compounds by target, compound name, or SMILES. */
227
+ export async function searchCompounds(query, searchType, limit = 500) {
228
+ if (searchType === "target")
229
+ return searchCompoundsByTarget(query, limit);
230
+ if (searchType === "smiles")
231
+ return searchCompoundsBySmiles(query, limit);
232
+ return searchCompoundsByName(query, limit);
233
+ }
107
234
  export async function searchTargets(query, limit = 25) {
108
235
  const url = `${CHEMBL_BASE}/target/search.json?q=${encodeURIComponent(query)}&limit=${limit}`;
109
236
  const res = await apiFetchValidated(url, TargetSearchResponseSchema, { headers: HEADERS });
@@ -0,0 +1,224 @@
1
+ /**
2
+ * EPA CompTox (CTX) operations — the four datasets the CompTox tools expose:
3
+ * ToxCast/Tox21 bioactivity, hazard (ToxValDB/ToxRefDB), chemical identity +
4
+ * physicochemical properties, and exposure.
5
+ *
6
+ * Every dataset keys off a DTXSID, so `resolveDtxsid` is the single entry
7
+ * point they share: a DTXSID is used directly, anything else is resolved by
8
+ * exact match against the chemical-search endpoint. `null` means the query
9
+ * resolved to no chemical — an expected outcome, not an error.
10
+ */
11
+ import { z } from "zod";
12
+ export interface CtxResolved {
13
+ dtxsid: string;
14
+ preferredName: string;
15
+ casrn: string | null;
16
+ }
17
+ /** Resolve a DTXSID / CASRN / name to a chemical. `null` = no match (valid no-data). */
18
+ export declare function resolveDtxsid(query: string, headers: Record<string, string>): Promise<CtxResolved | null>;
19
+ export interface ToxcastAssayResult {
20
+ aeid: number;
21
+ assayEndpoint: string;
22
+ ac50: number | null;
23
+ hitCall: number;
24
+ maxMean: number | null;
25
+ model: string;
26
+ flags: string[];
27
+ }
28
+ export interface ToxcastBioactivity {
29
+ totalAssays: number;
30
+ activeAssays: number;
31
+ activeHitRate: number;
32
+ results: ToxcastAssayResult[];
33
+ }
34
+ /**
35
+ * ToxCast/Tox21 assay results for a chemical, sorted by AC50 ascending.
36
+ * `totalAssays` / `activeAssays` / `activeHitRate` always describe the full
37
+ * tested panel, never the returned slice.
38
+ */
39
+ export declare function fetchToxcastBioactivity(dtxsid: string, headers: Record<string, string>, opts: {
40
+ activeOnly: boolean;
41
+ limit: number;
42
+ }): Promise<ToxcastBioactivity>;
43
+ declare const ToxValSchema: z.ZodPipe<z.ZodObject<{
44
+ source: z.ZodOptional<z.ZodNullable<z.ZodString>>;
45
+ toxvalType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
46
+ toxvalNumeric: z.ZodOptional<z.ZodUnknown>;
47
+ toxvalUnits: z.ZodOptional<z.ZodNullable<z.ZodString>>;
48
+ studyType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
49
+ studyDurationClass: z.ZodOptional<z.ZodNullable<z.ZodString>>;
50
+ speciesCommon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
51
+ exposureRoute: z.ZodOptional<z.ZodNullable<z.ZodString>>;
52
+ toxicologicalEffect: z.ZodOptional<z.ZodNullable<z.ZodString>>;
53
+ riskAssessmentClass: z.ZodOptional<z.ZodNullable<z.ZodString>>;
54
+ humanEco: z.ZodOptional<z.ZodNullable<z.ZodString>>;
55
+ year: z.ZodOptional<z.ZodUnknown>;
56
+ quality: z.ZodOptional<z.ZodNullable<z.ZodString>>;
57
+ }, z.core.$strip>, z.ZodTransform<{
58
+ source: string;
59
+ toxvalType: string;
60
+ toxvalNumeric: number | null;
61
+ toxvalUnits: string;
62
+ studyType: string;
63
+ studyDurationClass: string;
64
+ species: string;
65
+ exposureRoute: string;
66
+ toxicologicalEffect: string;
67
+ riskAssessmentClass: string;
68
+ humanEco: string;
69
+ year: number | null;
70
+ quality: string;
71
+ }, {
72
+ source?: string | null | undefined;
73
+ toxvalType?: string | null | undefined;
74
+ toxvalNumeric?: unknown;
75
+ toxvalUnits?: string | null | undefined;
76
+ studyType?: string | null | undefined;
77
+ studyDurationClass?: string | null | undefined;
78
+ speciesCommon?: string | null | undefined;
79
+ exposureRoute?: string | null | undefined;
80
+ toxicologicalEffect?: string | null | undefined;
81
+ riskAssessmentClass?: string | null | undefined;
82
+ humanEco?: string | null | undefined;
83
+ year?: unknown;
84
+ quality?: string | null | undefined;
85
+ }>>;
86
+ export type ToxValEntry = z.infer<typeof ToxValSchema>;
87
+ declare const GenetoxSchema: z.ZodPipe<z.ZodObject<{
88
+ source: z.ZodOptional<z.ZodNullable<z.ZodString>>;
89
+ assayCategory: z.ZodOptional<z.ZodNullable<z.ZodString>>;
90
+ assayType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
91
+ metabolicActivation: z.ZodOptional<z.ZodNullable<z.ZodString>>;
92
+ species: z.ZodOptional<z.ZodNullable<z.ZodString>>;
93
+ overallResult: z.ZodOptional<z.ZodNullable<z.ZodString>>;
94
+ year: z.ZodOptional<z.ZodUnknown>;
95
+ }, z.core.$strip>, z.ZodTransform<{
96
+ source: string;
97
+ assayCategory: string;
98
+ assayType: string;
99
+ metabolicActivation: string;
100
+ species: string;
101
+ overallResult: string;
102
+ year: number | null;
103
+ }, {
104
+ source?: string | null | undefined;
105
+ assayCategory?: string | null | undefined;
106
+ assayType?: string | null | undefined;
107
+ metabolicActivation?: string | null | undefined;
108
+ species?: string | null | undefined;
109
+ overallResult?: string | null | undefined;
110
+ year?: unknown;
111
+ }>>;
112
+ export type GenetoxSummary = z.infer<typeof GenetoxSchema>;
113
+ declare const CancerSchema: z.ZodPipe<z.ZodObject<{
114
+ source: z.ZodOptional<z.ZodNullable<z.ZodString>>;
115
+ classification: z.ZodOptional<z.ZodNullable<z.ZodString>>;
116
+ cancerClassification: z.ZodOptional<z.ZodNullable<z.ZodString>>;
117
+ url: z.ZodOptional<z.ZodNullable<z.ZodString>>;
118
+ }, z.core.$strip>, z.ZodTransform<{
119
+ source: string;
120
+ classification: string;
121
+ url: string;
122
+ }, {
123
+ source?: string | null | undefined;
124
+ classification?: string | null | undefined;
125
+ cancerClassification?: string | null | undefined;
126
+ url?: string | null | undefined;
127
+ }>>;
128
+ export type CancerSummary = z.infer<typeof CancerSchema>;
129
+ export type CtxHazardDataType = "toxval" | "genetox" | "cancer" | "all";
130
+ export interface CtxHazardData {
131
+ toxval?: ToxValEntry[];
132
+ genetox?: GenetoxSummary[];
133
+ cancer?: CancerSummary[];
134
+ }
135
+ /**
136
+ * In-vivo hazard data for a chemical. `limit` caps toxval and genetox only —
137
+ * cancer classifications always come back whole.
138
+ */
139
+ export declare function fetchCtxHazardData(dtxsid: string, headers: Record<string, string>, opts: {
140
+ dataType: CtxHazardDataType;
141
+ limit: number;
142
+ }): Promise<CtxHazardData>;
143
+ export interface ChemicalDetail {
144
+ dtxsid: string;
145
+ dtxcid: string;
146
+ casrn: string | null;
147
+ preferredName: string;
148
+ iupacName: string;
149
+ molFormula: string;
150
+ smiles: string;
151
+ inchikey: string;
152
+ monoisotopicMass: number | null;
153
+ averageMass: number | null;
154
+ qcLevel: number | null;
155
+ totalAssays: number | null;
156
+ activeAssays: number | null;
157
+ percentAssays: number | null;
158
+ pubchemCid: number | null;
159
+ pubmedCount: number | null;
160
+ sourcesCount: number | null;
161
+ }
162
+ export interface PropertySummary {
163
+ propName: string;
164
+ unit: string;
165
+ experimentalCount: number | null;
166
+ experimentalMedian: number | null;
167
+ experimentalMin: number | null;
168
+ experimentalMax: number | null;
169
+ predictedCount: number | null;
170
+ predictedMedian: number | null;
171
+ predictedMin: number | null;
172
+ predictedMax: number | null;
173
+ }
174
+ /** Chemical identity, mass, and dashboard counts for a DTXSID. */
175
+ export declare function fetchCtxChemicalDetail(dtxsid: string, headers: Record<string, string>): Promise<ChemicalDetail>;
176
+ /** Experimental + predicted physicochemical property summaries. `undefined` = none served. */
177
+ export declare function fetchCtxChemicalProperties(dtxsid: string, headers: Record<string, string>): Promise<PropertySummary[] | undefined>;
178
+ export interface SeemPrediction {
179
+ dtxsid: string;
180
+ productionVolume: number | null;
181
+ units: string;
182
+ probabilityDietary: number | null;
183
+ probabilityResidential: number | null;
184
+ probabilityPesticide: number | null;
185
+ probabilityIndustrial: number | null;
186
+ }
187
+ export interface HttkParameter {
188
+ parameter: string;
189
+ measured: number | null;
190
+ predicted: number | null;
191
+ units: string;
192
+ model: string;
193
+ species: string;
194
+ reference: string;
195
+ }
196
+ export interface FunctionalUse {
197
+ functionCategory: string;
198
+ reportedFunction: string;
199
+ docTitle: string;
200
+ }
201
+ export interface ProductData {
202
+ productName: string;
203
+ generalCategory: string;
204
+ productFamily: string;
205
+ productType: string;
206
+ centralWeightFraction: number | null;
207
+ weightFractionType: string;
208
+ }
209
+ export type CtxExposureDataType = "seem" | "httk" | "functional-use" | "product-data" | "all";
210
+ export interface CtxExposureData {
211
+ seem?: SeemPrediction;
212
+ httk?: HttkParameter[];
213
+ functionalUse?: FunctionalUse[];
214
+ productData?: ProductData[];
215
+ }
216
+ /**
217
+ * Human-exposure data for a chemical. `limit` caps functional-use and
218
+ * product-data only — seem and httk always come back whole.
219
+ */
220
+ export declare function fetchCtxExposureData(dtxsid: string, headers: Record<string, string>, opts: {
221
+ dataType: CtxExposureDataType;
222
+ limit: number;
223
+ }): Promise<CtxExposureData>;
224
+ export {};