@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
@@ -1,176 +0,0 @@
1
- /**
2
- * searchCtxExposure — look up chemical exposure data from EPA's CTX
3
- * Exposure APIs.
4
- */
5
- import { ok } from "neverthrow";
6
- import { z } from "zod";
7
- import { defineTool } from "../define-tool.js";
8
- import { apiFetchValidated, describeApiError } from "../lib/api-utils.js";
9
- import { EPA_CCTE_BASE, getEpaCcteHeaders } from "../lib/toxcast-config.js";
10
- // The chemical-search endpoint returns rows the code reads `[0].dtxsid` from
11
- // after a length guard, so `dtxsid` stays required — a row missing it is a
12
- // contract break surfaced as `invalid_response`, not a silent `undefined`.
13
- const CtxChemicalSearchRowSchema = z.object({
14
- dtxsid: z.string(),
15
- });
16
- // SEEM exposure-prediction wire shape (endpoint returns a single object or an
17
- // array). `probabilityPesticde` is the API's own misspelling, read as a
18
- // fallback before the corrected `probabilityPesticide`, so both stay modeled.
19
- const RawSeemPredictionSchema = z.object({
20
- dtxsid: z.string().optional(),
21
- productionVolume: z.number().nullable().optional(),
22
- units: z.string().nullable().optional(),
23
- probabilityDietary: z.number().nullable().optional(),
24
- probabilityResidential: z.number().nullable().optional(),
25
- probabilityPesticde: z.number().nullable().optional(),
26
- probabilityPesticide: z.number().nullable().optional(),
27
- probabilityIndustrial: z.number().nullable().optional(),
28
- });
29
- const RawHttkRowSchema = z.object({
30
- parameter: z.string().nullable().optional(),
31
- measured: z.number().nullable().optional(),
32
- predicted: z.number().nullable().optional(),
33
- units: z.string().nullable().optional(),
34
- model: z.string().nullable().optional(),
35
- species: z.string().nullable().optional(),
36
- reference: z.string().nullable().optional(),
37
- });
38
- const RawFunctionalUseRowSchema = z.object({
39
- functioncategory: z.string().nullable().optional(),
40
- reportedfunction: z.string().nullable().optional(),
41
- doctitle: z.string().nullable().optional(),
42
- });
43
- const RawProductDataRowSchema = z.object({
44
- productname: z.string().nullable().optional(),
45
- gencat: z.string().nullable().optional(),
46
- prodfam: z.string().nullable().optional(),
47
- prodtype: z.string().nullable().optional(),
48
- centralweightfraction: z.number().nullable().optional(),
49
- weightfractiontype: z.string().nullable().optional(),
50
- });
51
- export function createSearchCtxExposureTool(deps) {
52
- return defineTool({
53
- id: "search_ctx_exposure",
54
- description: "Look up chemical exposure data from EPA's CTX Exposure APIs. Returns: " +
55
- "SEEM general exposure predictions (estimated daily intake, exposure pathway probabilities), " +
56
- "HTTK toxicokinetic parameters (Css, clearance, volume of distribution, protein binding), " +
57
- "functional use categories, and product composition data. " +
58
- "Use for exposure-based safety margin calculations (comparing ToxCast bioactivity AC50 " +
59
- "against predicted human exposure), IVIVE context, and exposure pathway characterization. " +
60
- "Requires EPA_CCTE_API_KEY environment variable.",
61
- inputSchema: z.object({
62
- query: z.string().describe("Chemical identifier: DTXSID (e.g. DTXSID7020182), CASRN (e.g. 80-05-7), " + "or chemical name (e.g. bisphenol A)"),
63
- dataType: z
64
- .enum(["seem", "httk", "functional-use", "product-data", "all"])
65
- .default("all")
66
- .describe("'seem' for SEEM exposure predictions, " +
67
- "'httk' for toxicokinetic parameters, " +
68
- "'functional-use' for chemical use categories, " +
69
- "'product-data' for consumer product composition, " +
70
- "'all' for combined results"),
71
- limit: z.number().int().min(1).max(100).default(25).describe("Max results per category (for functional-use and product-data)"),
72
- }),
73
- execute: async ({ query, dataType = "all", limit = 25 }) => {
74
- const headers = getEpaCcteHeaders(deps.apiKey);
75
- const resolved = await resolveDtxsid(query, headers);
76
- // "No chemical found" is an expected outcome — a data variant, not an error.
77
- if (!resolved)
78
- return ok({ found: false, query });
79
- const { dtxsid } = resolved;
80
- const result = { found: true, dtxsid };
81
- const fetchers = [];
82
- if (dataType === "seem" || dataType === "all") {
83
- fetchers.push(fetchSeem(dtxsid, headers).then((v) => {
84
- result.seem = v;
85
- }));
86
- }
87
- if (dataType === "httk" || dataType === "all") {
88
- fetchers.push(fetchHttk(dtxsid, headers).then((v) => {
89
- result.httk = v;
90
- }));
91
- }
92
- if (dataType === "functional-use" || dataType === "all") {
93
- fetchers.push(fetchFunctionalUse(dtxsid, headers, limit).then((v) => {
94
- result.functionalUse = v;
95
- }));
96
- }
97
- if (dataType === "product-data" || dataType === "all") {
98
- fetchers.push(fetchProductData(dtxsid, headers, limit).then((v) => {
99
- result.productData = v;
100
- }));
101
- }
102
- await Promise.all(fetchers);
103
- return ok(result);
104
- },
105
- });
106
- }
107
- async function resolveDtxsid(query, headers) {
108
- if (query.startsWith("DTXSID")) {
109
- return { dtxsid: query };
110
- }
111
- const url = `${EPA_CCTE_BASE}/chemical/search/equal/${encodeURIComponent(query)}`;
112
- const res = await apiFetchValidated(url, z.array(CtxChemicalSearchRowSchema), { headers });
113
- if (res.isErr())
114
- throw new Error(describeApiError(res.error));
115
- if (!res.value?.length)
116
- return null;
117
- return { dtxsid: res.value[0].dtxsid };
118
- }
119
- async function fetchSeem(dtxsid, headers) {
120
- const url = `${EPA_CCTE_BASE}/exposure/seem/general/search/by-dtxsid/${dtxsid}`;
121
- const res = await apiFetchValidated(url, z.union([RawSeemPredictionSchema, z.array(RawSeemPredictionSchema)]), { headers });
122
- if (res.isErr() || !res.value)
123
- return undefined;
124
- const d = Array.isArray(res.value) ? res.value[0] : res.value;
125
- if (!d)
126
- return undefined;
127
- return {
128
- dtxsid: d.dtxsid ?? dtxsid,
129
- productionVolume: d.productionVolume ?? null,
130
- units: d.units ?? "",
131
- probabilityDietary: d.probabilityDietary ?? null,
132
- probabilityResidential: d.probabilityResidential ?? null,
133
- probabilityPesticide: d.probabilityPesticde ?? d.probabilityPesticide ?? null,
134
- probabilityIndustrial: d.probabilityIndustrial ?? null,
135
- };
136
- }
137
- async function fetchHttk(dtxsid, headers) {
138
- const url = `${EPA_CCTE_BASE}/exposure/httk/search/by-dtxsid/${dtxsid}`;
139
- const res = await apiFetchValidated(url, z.array(RawHttkRowSchema), { headers });
140
- if (res.isErr() || !Array.isArray(res.value))
141
- return [];
142
- return res.value.map((r) => ({
143
- parameter: r.parameter ?? "",
144
- measured: r.measured ?? null,
145
- predicted: r.predicted ?? null,
146
- units: r.units ?? "",
147
- model: r.model ?? "",
148
- species: r.species ?? "",
149
- reference: r.reference ?? "",
150
- }));
151
- }
152
- async function fetchFunctionalUse(dtxsid, headers, limit) {
153
- const url = `${EPA_CCTE_BASE}/exposure/functional-use/search/by-dtxsid/${dtxsid}`;
154
- const res = await apiFetchValidated(url, z.array(RawFunctionalUseRowSchema), { headers });
155
- if (res.isErr() || !Array.isArray(res.value))
156
- return [];
157
- return res.value.slice(0, limit).map((r) => ({
158
- functionCategory: r.functioncategory ?? "",
159
- reportedFunction: r.reportedfunction ?? "",
160
- docTitle: r.doctitle ?? "",
161
- }));
162
- }
163
- async function fetchProductData(dtxsid, headers, limit) {
164
- const url = `${EPA_CCTE_BASE}/exposure/product-data/search/by-dtxsid/${dtxsid}`;
165
- const res = await apiFetchValidated(url, z.array(RawProductDataRowSchema), { headers });
166
- if (res.isErr() || !Array.isArray(res.value))
167
- return [];
168
- return res.value.slice(0, limit).map((r) => ({
169
- productName: r.productname ?? "",
170
- generalCategory: r.gencat ?? "",
171
- productFamily: r.prodfam ?? "",
172
- productType: r.prodtype ?? "",
173
- centralWeightFraction: r.centralweightfraction ?? null,
174
- weightFractionType: r.weightfractiontype ?? "",
175
- }));
176
- }
@@ -1,111 +0,0 @@
1
- /**
2
- * searchCtxHazard — search EPA CTX Hazard APIs (ToxValDB, ToxRefDB) for
3
- * toxicological hazard data on a chemical.
4
- */
5
- import { z } from "zod";
6
- declare const ToxValSchema: z.ZodPipe<z.ZodObject<{
7
- source: z.ZodOptional<z.ZodNullable<z.ZodString>>;
8
- toxvalType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
9
- toxvalNumeric: z.ZodOptional<z.ZodUnknown>;
10
- toxvalUnits: z.ZodOptional<z.ZodNullable<z.ZodString>>;
11
- studyType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
12
- studyDurationClass: z.ZodOptional<z.ZodNullable<z.ZodString>>;
13
- speciesCommon: z.ZodOptional<z.ZodNullable<z.ZodString>>;
14
- exposureRoute: z.ZodOptional<z.ZodNullable<z.ZodString>>;
15
- toxicologicalEffect: z.ZodOptional<z.ZodNullable<z.ZodString>>;
16
- riskAssessmentClass: z.ZodOptional<z.ZodNullable<z.ZodString>>;
17
- humanEco: z.ZodOptional<z.ZodNullable<z.ZodString>>;
18
- year: z.ZodOptional<z.ZodUnknown>;
19
- quality: z.ZodOptional<z.ZodNullable<z.ZodString>>;
20
- }, z.core.$strip>, z.ZodTransform<{
21
- source: string;
22
- toxvalType: string;
23
- toxvalNumeric: number | null;
24
- toxvalUnits: string;
25
- studyType: string;
26
- studyDurationClass: string;
27
- species: string;
28
- exposureRoute: string;
29
- toxicologicalEffect: string;
30
- riskAssessmentClass: string;
31
- humanEco: string;
32
- year: number | null;
33
- quality: string;
34
- }, {
35
- source?: string | null | undefined;
36
- toxvalType?: string | null | undefined;
37
- toxvalNumeric?: unknown;
38
- toxvalUnits?: string | null | undefined;
39
- studyType?: string | null | undefined;
40
- studyDurationClass?: string | null | undefined;
41
- speciesCommon?: string | null | undefined;
42
- exposureRoute?: string | null | undefined;
43
- toxicologicalEffect?: string | null | undefined;
44
- riskAssessmentClass?: string | null | undefined;
45
- humanEco?: string | null | undefined;
46
- year?: unknown;
47
- quality?: string | null | undefined;
48
- }>>;
49
- type ToxValEntry = z.infer<typeof ToxValSchema>;
50
- declare const GenetoxSchema: z.ZodPipe<z.ZodObject<{
51
- source: z.ZodOptional<z.ZodNullable<z.ZodString>>;
52
- assayCategory: z.ZodOptional<z.ZodNullable<z.ZodString>>;
53
- assayType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
54
- metabolicActivation: z.ZodOptional<z.ZodNullable<z.ZodString>>;
55
- species: z.ZodOptional<z.ZodNullable<z.ZodString>>;
56
- overallResult: z.ZodOptional<z.ZodNullable<z.ZodString>>;
57
- year: z.ZodOptional<z.ZodUnknown>;
58
- }, z.core.$strip>, z.ZodTransform<{
59
- source: string;
60
- assayCategory: string;
61
- assayType: string;
62
- metabolicActivation: string;
63
- species: string;
64
- overallResult: string;
65
- year: number | null;
66
- }, {
67
- source?: string | null | undefined;
68
- assayCategory?: string | null | undefined;
69
- assayType?: string | null | undefined;
70
- metabolicActivation?: string | null | undefined;
71
- species?: string | null | undefined;
72
- overallResult?: string | null | undefined;
73
- year?: unknown;
74
- }>>;
75
- type GenetoxSummary = z.infer<typeof GenetoxSchema>;
76
- declare const CancerSchema: z.ZodPipe<z.ZodObject<{
77
- source: z.ZodOptional<z.ZodNullable<z.ZodString>>;
78
- classification: z.ZodOptional<z.ZodNullable<z.ZodString>>;
79
- cancerClassification: z.ZodOptional<z.ZodNullable<z.ZodString>>;
80
- url: z.ZodOptional<z.ZodNullable<z.ZodString>>;
81
- }, z.core.$strip>, z.ZodTransform<{
82
- source: string;
83
- classification: string;
84
- url: string;
85
- }, {
86
- source?: string | null | undefined;
87
- classification?: string | null | undefined;
88
- cancerClassification?: string | null | undefined;
89
- url?: string | null | undefined;
90
- }>>;
91
- type CancerSummary = z.infer<typeof CancerSchema>;
92
- interface CtxHazardOutput {
93
- found: true;
94
- dtxsid: string;
95
- preferredName: string;
96
- toxval?: ToxValEntry[];
97
- genetox?: GenetoxSummary[];
98
- cancer?: CancerSummary[];
99
- }
100
- type CtxHazardResult = {
101
- found: false;
102
- query: string;
103
- } | CtxHazardOutput;
104
- export declare function createSearchCtxHazardTool(deps: {
105
- apiKey: string;
106
- }): import("../define-tool.js").Tool<{
107
- query: string;
108
- dataType: "toxval" | "genetox" | "cancer" | "all";
109
- limit: number;
110
- }, CtxHazardResult>;
111
- export {};
@@ -1,178 +0,0 @@
1
- /**
2
- * searchCtxHazard — search EPA CTX Hazard APIs (ToxValDB, ToxRefDB) for
3
- * toxicological hazard data on a chemical.
4
- */
5
- import { ok } from "neverthrow";
6
- import { z } from "zod";
7
- import { defineTool } from "../define-tool.js";
8
- import { apiFetchValidated, describeApiError } from "../lib/api-utils.js";
9
- import { EPA_CCTE_BASE, getEpaCcteHeaders } from "../lib/toxcast-config.js";
10
- // Each schema below both validates one raw CTX hazard row and normalizes it
11
- // into the curated output shape via `.transform`; `z.infer` is that output
12
- // type. Every wire field is optional (the API omits absent values); the two
13
- // numeric fields the API sends as string-or-number stay `z.unknown()` so
14
- // `toNumberOrNull` can coerce them without the schema rejecting the row.
15
- const ToxValSchema = z
16
- .object({
17
- source: z.string().nullable().optional(),
18
- toxvalType: z.string().nullable().optional(),
19
- toxvalNumeric: z.unknown().optional(),
20
- toxvalUnits: z.string().nullable().optional(),
21
- studyType: z.string().nullable().optional(),
22
- studyDurationClass: z.string().nullable().optional(),
23
- speciesCommon: z.string().nullable().optional(),
24
- exposureRoute: z.string().nullable().optional(),
25
- toxicologicalEffect: z.string().nullable().optional(),
26
- riskAssessmentClass: z.string().nullable().optional(),
27
- humanEco: z.string().nullable().optional(),
28
- year: z.unknown().optional(),
29
- quality: z.string().nullable().optional(),
30
- })
31
- .transform((r) => ({
32
- source: r.source ?? "",
33
- toxvalType: r.toxvalType ?? "",
34
- toxvalNumeric: toNumberOrNull(r.toxvalNumeric),
35
- toxvalUnits: r.toxvalUnits ?? "",
36
- studyType: r.studyType ?? "",
37
- studyDurationClass: r.studyDurationClass ?? "",
38
- species: r.speciesCommon ?? "",
39
- exposureRoute: r.exposureRoute ?? "",
40
- toxicologicalEffect: r.toxicologicalEffect ?? "",
41
- riskAssessmentClass: r.riskAssessmentClass ?? "",
42
- humanEco: r.humanEco ?? "",
43
- year: toNumberOrNull(r.year),
44
- quality: r.quality ?? "",
45
- }));
46
- const GenetoxSchema = z
47
- .object({
48
- source: z.string().nullable().optional(),
49
- assayCategory: z.string().nullable().optional(),
50
- assayType: z.string().nullable().optional(),
51
- metabolicActivation: z.string().nullable().optional(),
52
- species: z.string().nullable().optional(),
53
- overallResult: z.string().nullable().optional(),
54
- year: z.unknown().optional(),
55
- })
56
- .transform((r) => ({
57
- source: r.source ?? "",
58
- assayCategory: r.assayCategory ?? "",
59
- assayType: r.assayType ?? "",
60
- metabolicActivation: r.metabolicActivation ?? "",
61
- species: r.species ?? "",
62
- overallResult: r.overallResult ?? "",
63
- year: toNumberOrNull(r.year),
64
- }));
65
- const CancerSchema = z
66
- .object({
67
- source: z.string().nullable().optional(),
68
- classification: z.string().nullable().optional(),
69
- cancerClassification: z.string().nullable().optional(),
70
- url: z.string().nullable().optional(),
71
- })
72
- .transform((r) => ({
73
- source: r.source ?? "",
74
- classification: r.classification ?? r.cancerClassification ?? "",
75
- url: r.url ?? "",
76
- }));
77
- // The chemical-search endpoint returns rows the code reads `dtxsid` from
78
- // unguarded, so `dtxsid` stays required — a row missing it is a contract break
79
- // surfaced as `invalid_response`, not a silent `undefined`.
80
- const CtxChemicalSearchRowSchema = z.object({
81
- dtxsid: z.string(),
82
- preferredName: z.string().nullable().optional(),
83
- });
84
- export function createSearchCtxHazardTool(deps) {
85
- return defineTool({
86
- id: "search_ctx_hazard",
87
- description: "Search EPA CTX Hazard APIs (ToxValDB, ToxRefDB) for toxicological hazard data on a chemical. " +
88
- "Returns in-vivo toxicity values (NOAELs, LOAELs, LD50s, BMDs), " +
89
- "genetox summaries, and cancer classifications. " +
90
- "Use to assess toxicological hazard profile for safety evaluation. " +
91
- "Requires EPA_CCTE_API_KEY environment variable.",
92
- inputSchema: z.object({
93
- query: z.string().describe("Chemical identifier: DTXSID (e.g. DTXSID7020182), CASRN (e.g. 80-05-7), " + "or chemical name (e.g. bisphenol A)"),
94
- dataType: z
95
- .enum(["toxval", "genetox", "cancer", "all"])
96
- .default("all")
97
- .describe("'toxval' for ToxValDB dose-response data (NOAELs, LOAELs, LD50s), " +
98
- "'genetox' for genotoxicity summaries, " +
99
- "'cancer' for cancer classifications, " +
100
- "'all' for combined results"),
101
- limit: z.number().int().min(1).max(100).default(30).describe("Max results per category"),
102
- }),
103
- execute: async ({ query, dataType = "all", limit = 30 }) => {
104
- const headers = getEpaCcteHeaders(deps.apiKey);
105
- const resolved = await resolveDtxsid(query, headers);
106
- // "No chemical found" is an expected outcome — a data variant, not an error.
107
- if (!resolved)
108
- return ok({ found: false, query });
109
- const { dtxsid, preferredName } = resolved;
110
- const result = {
111
- found: true,
112
- dtxsid,
113
- preferredName,
114
- };
115
- const fetchers = [];
116
- if (dataType === "toxval" || dataType === "all") {
117
- fetchers.push(fetchToxval(dtxsid, headers, limit).then((v) => {
118
- result.toxval = v;
119
- }));
120
- }
121
- if (dataType === "genetox" || dataType === "all") {
122
- fetchers.push(fetchGenetox(dtxsid, headers, limit).then((v) => {
123
- result.genetox = v;
124
- }));
125
- }
126
- if (dataType === "cancer" || dataType === "all") {
127
- fetchers.push(fetchCancer(dtxsid, headers).then((v) => {
128
- result.cancer = v;
129
- }));
130
- }
131
- await Promise.all(fetchers);
132
- return ok(result);
133
- },
134
- });
135
- }
136
- async function resolveDtxsid(query, headers) {
137
- if (query.startsWith("DTXSID")) {
138
- return { dtxsid: query, preferredName: query };
139
- }
140
- const url = `${EPA_CCTE_BASE}/chemical/search/equal/${encodeURIComponent(query)}`;
141
- const res = await apiFetchValidated(url, z.array(CtxChemicalSearchRowSchema), { headers });
142
- if (res.isErr())
143
- throw new Error(describeApiError(res.error));
144
- if (!res.value?.length)
145
- return null;
146
- const chem = res.value[0];
147
- return {
148
- dtxsid: chem.dtxsid,
149
- preferredName: chem.preferredName ?? query,
150
- };
151
- }
152
- async function fetchToxval(dtxsid, headers, limit) {
153
- const url = `${EPA_CCTE_BASE}/hazard/toxval/search/by-dtxsid/${dtxsid}`;
154
- const res = await apiFetchValidated(url, z.array(ToxValSchema), { headers });
155
- if (res.isErr() || !Array.isArray(res.value))
156
- return [];
157
- return res.value.slice(0, limit);
158
- }
159
- function toNumberOrNull(v) {
160
- if (v == null || v === "")
161
- return null;
162
- const n = typeof v === "number" ? v : Number(v);
163
- return Number.isFinite(n) ? n : null;
164
- }
165
- async function fetchGenetox(dtxsid, headers, limit) {
166
- const url = `${EPA_CCTE_BASE}/hazard/genetox/summary/search/by-dtxsid/${dtxsid}`;
167
- const res = await apiFetchValidated(url, z.array(GenetoxSchema), { headers });
168
- if (res.isErr() || !Array.isArray(res.value))
169
- return [];
170
- return res.value.slice(0, limit);
171
- }
172
- async function fetchCancer(dtxsid, headers) {
173
- const url = `${EPA_CCTE_BASE}/hazard/cancer-summary/search/by-dtxsid/${dtxsid}`;
174
- const res = await apiFetchValidated(url, z.array(CancerSchema), { headers });
175
- if (res.isErr() || !Array.isArray(res.value))
176
- return [];
177
- return res.value;
178
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * searchOpenTargets — query Open Targets Platform for target-disease
3
- * associations, genetic evidence, tractability, and known drug scores.
4
- */
5
- export declare const searchOpenTargetsTool: import("../define-tool.js").Tool<{
6
- query: string;
7
- searchType: "target" | "disease";
8
- limit: number;
9
- }, {
10
- associations: import("../lib/opentargets-client.js").Association[];
11
- }>;
@@ -1,25 +0,0 @@
1
- /**
2
- * searchOpenTargets — query Open Targets Platform for target-disease
3
- * associations, genetic evidence, tractability, and known drug scores.
4
- */
5
- import { ok } from "neverthrow";
6
- import { z } from "zod";
7
- import { defineTool } from "../define-tool.js";
8
- import { searchDiseaseAssociations, searchTargetAssociations } from "../lib/opentargets-client.js";
9
- export const searchOpenTargetsTool = defineTool({
10
- id: "search_opentargets",
11
- description: "Search Open Targets Platform for target-disease associations, genetic evidence, tractability, and known drug scores. Query by Ensembl gene ID (target mode) or EFO disease ID (disease mode).",
12
- inputSchema: z.object({
13
- query: z.string().describe("Ensembl gene ID (e.g. ENSG00000141510) or EFO disease ID (e.g. EFO_0000311)"),
14
- searchType: z.enum(["target", "disease"]).describe("'target' to find diseases for a gene, 'disease' to find targets for a disease"),
15
- limit: z.number().int().min(1).max(100).default(25).describe("Max results to return"),
16
- }),
17
- execute: async ({ query, searchType, limit = 25 }) => {
18
- if (searchType === "target") {
19
- const targetInfo = await searchTargetAssociations(query, limit);
20
- return ok({ targetInfo, associations: targetInfo?.associations ?? [] });
21
- }
22
- const associations = await searchDiseaseAssociations(query, limit);
23
- return ok({ associations });
24
- },
25
- });
@@ -1,26 +0,0 @@
1
- /**
2
- * searchPubchemCompound tool — resolve compounds against PubChem's 110M+ database.
3
- *
4
- * Supports search by name, SMILES, InChI, InChIKey, or CID.
5
- * Returns compound identity and computed molecular properties.
6
- */
7
- export declare const searchPubchemCompoundTool: import("../define-tool.js").Tool<{
8
- query: string;
9
- searchBy: "name" | "smiles" | "inchikey" | "cid" | "inchi";
10
- }, {
11
- results: {
12
- cid: number;
13
- canonicalSmiles: string | null;
14
- molecularFormula: string | null;
15
- molecularWeight: number | null;
16
- iupacName: string | null;
17
- inchi: string | null;
18
- inchiKey: string | null;
19
- xlogp: number | null;
20
- tpsa: number | null;
21
- hbondDonorCount: number | null;
22
- hbondAcceptorCount: number | null;
23
- rotatableBondCount: number | null;
24
- complexity: number | null;
25
- }[];
26
- }>;
@@ -1,110 +0,0 @@
1
- /**
2
- * searchPubchemCompound tool — resolve compounds against PubChem's 110M+ database.
3
- *
4
- * Supports search by name, SMILES, InChI, InChIKey, or CID.
5
- * Returns compound identity and computed molecular properties.
6
- */
7
- import { ok } from "neverthrow";
8
- import { z } from "zod";
9
- import { defineTool } from "../define-tool.js";
10
- import { apiFetchValidated, describeApiError } from "../lib/api-utils.js";
11
- import { PUBCHEM_HEADERS as HEADERS, PUBCHEM_BASE } from "../lib/pubchem-config.js";
12
- const PROPERTY_LIST = [
13
- "MolecularFormula",
14
- "MolecularWeight",
15
- "CanonicalSMILES",
16
- "InChI",
17
- "InChIKey",
18
- "IUPACName",
19
- "XLogP",
20
- "TPSA",
21
- "HBondDonorCount",
22
- "HBondAcceptorCount",
23
- "RotatableBondCount",
24
- "Complexity",
25
- ].join(",");
26
- // A single schema that both validates and normalizes one PUG-REST property row:
27
- // the `.object(...)` half is the wire shape (every field optional — PubChem
28
- // omits absent properties), the `.transform(...)` half maps it to the camelCase
29
- // `Compound` we return. Parsing IS the validation, and because the transform
30
- // rides on the schema, `z.infer` below is the OUTPUT type — no separate raw
31
- // interface or mapper.
32
- const PugPropertyRowSchema = z
33
- .object({
34
- CID: z.number().optional(),
35
- CanonicalSMILES: z.string().optional(),
36
- MolecularFormula: z.string().optional(),
37
- // PUG-REST serializes MolecularWeight as a string (e.g. "180.16") to
38
- // preserve significant figures; accept both and let the transform's
39
- // `Number(...)` normalize it.
40
- MolecularWeight: z.union([z.number(), z.string()]).optional(),
41
- IUPACName: z.string().optional(),
42
- InChI: z.string().optional(),
43
- InChIKey: z.string().optional(),
44
- XLogP: z.number().optional(),
45
- TPSA: z.number().optional(),
46
- HBondDonorCount: z.number().optional(),
47
- HBondAcceptorCount: z.number().optional(),
48
- RotatableBondCount: z.number().optional(),
49
- Complexity: z.number().optional(),
50
- })
51
- .transform((raw) => ({
52
- cid: raw.CID ?? 0,
53
- canonicalSmiles: raw.CanonicalSMILES ?? null,
54
- molecularFormula: raw.MolecularFormula ?? null,
55
- molecularWeight: raw.MolecularWeight != null ? Number(raw.MolecularWeight) : null,
56
- iupacName: raw.IUPACName ?? null,
57
- inchi: raw.InChI ?? null,
58
- inchiKey: raw.InChIKey ?? null,
59
- xlogp: raw.XLogP ?? null,
60
- tpsa: raw.TPSA ?? null,
61
- hbondDonorCount: raw.HBondDonorCount ?? null,
62
- hbondAcceptorCount: raw.HBondAcceptorCount ?? null,
63
- rotatableBondCount: raw.RotatableBondCount ?? null,
64
- complexity: raw.Complexity ?? null,
65
- }));
66
- const PubChemPropertyResponseSchema = z.object({
67
- PropertyTable: z.object({ Properties: z.array(PugPropertyRowSchema).optional() }).optional(),
68
- });
69
- /** Build the PUG-REST URL path segment for the given search type. */
70
- function buildNamespace(searchBy, query) {
71
- switch (searchBy) {
72
- case "name":
73
- return `compound/name/${encodeURIComponent(query)}`;
74
- case "smiles":
75
- return `compound/smiles/${encodeURIComponent(query)}`;
76
- case "inchi":
77
- return `compound/inchi/${encodeURIComponent(query)}`;
78
- case "inchikey":
79
- return `compound/inchikey/${encodeURIComponent(query)}`;
80
- case "cid":
81
- return `compound/cid/${encodeURIComponent(query)}`;
82
- default:
83
- return `compound/name/${encodeURIComponent(query)}`;
84
- }
85
- }
86
- export const searchPubchemCompoundTool = defineTool({
87
- id: "search_pubchem_compound",
88
- description: "Search PubChem for a compound by name, SMILES, InChI, InChIKey, or CID. " +
89
- "Returns compound identity (CID, SMILES, InChI, IUPAC name) and computed properties " +
90
- "(molecular weight, XLogP, TPSA, HBD, HBA, rotatable bonds, complexity). " +
91
- "PubChem covers 110M+ compounds — use when ChEMBL doesn't find the compound.",
92
- inputSchema: z.object({
93
- query: z.string().min(1).describe("Search term: compound name, SMILES, InChI, InChIKey, or CID"),
94
- searchBy: z.enum(["name", "smiles", "inchi", "inchikey", "cid"]).describe("Identifier type for the query"),
95
- }),
96
- execute: async ({ query, searchBy }) => {
97
- const namespace = buildNamespace(searchBy, query);
98
- const url = `${PUBCHEM_BASE}/${namespace}/property/${PROPERTY_LIST}/JSON`;
99
- const res = await apiFetchValidated(url, PubChemPropertyResponseSchema, { headers: HEADERS });
100
- if (res.isErr()) {
101
- // PubChem returns 404 when the query matches no compound — expected.
102
- if (res.error.type === "http_status" && res.error.status === 404)
103
- return ok({ results: [] });
104
- throw new Error(describeApiError(res.error));
105
- }
106
- // Already validated + normalized by PugPropertyRowSchema's transform.
107
- const rows = res.value.PropertyTable?.Properties ?? [];
108
- return ok({ results: rows });
109
- },
110
- });
@@ -1,17 +0,0 @@
1
- /**
2
- * searchPubMed — search PubMed via NCBI E-utilities.
3
- */
4
- export declare function createSearchPubMedTool(deps: {
5
- ncbiApiKey?: string;
6
- }): import("../define-tool.js").Tool<{
7
- query: string;
8
- maxResults: number;
9
- sort: "date" | "relevance";
10
- dateRange?: {
11
- from: string;
12
- to: string;
13
- } | undefined;
14
- }, {
15
- totalFound: number;
16
- results: import("../lib/ncbi-utils.js").PubMedSummary[];
17
- }>;