@retinue/agentkit 0.1.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 (405) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +310 -0
  3. package/dist/adapters/bullmq/consumer.d.ts +33 -0
  4. package/dist/adapters/bullmq/consumer.js +41 -0
  5. package/dist/adapters/bullmq/dispatcher.d.ts +74 -0
  6. package/dist/adapters/bullmq/dispatcher.js +160 -0
  7. package/dist/adapters/bullmq/export.d.ts +31 -0
  8. package/dist/adapters/bullmq/export.js +53 -0
  9. package/dist/adapters/bullmq/extraction.d.ts +42 -0
  10. package/dist/adapters/bullmq/extraction.js +63 -0
  11. package/dist/adapters/bullmq/index.d.ts +13 -0
  12. package/dist/adapters/bullmq/index.js +13 -0
  13. package/dist/adapters/bullmq/lock.d.ts +77 -0
  14. package/dist/adapters/bullmq/lock.js +126 -0
  15. package/dist/adapters/bullmq/queue.d.ts +50 -0
  16. package/dist/adapters/bullmq/queue.js +81 -0
  17. package/dist/adapters/memory/artifact-exports.d.ts +11 -0
  18. package/dist/adapters/memory/artifact-exports.js +102 -0
  19. package/dist/adapters/memory/artifacts.d.ts +15 -0
  20. package/dist/adapters/memory/artifacts.js +134 -0
  21. package/dist/adapters/memory/blobs.d.ts +7 -0
  22. package/dist/adapters/memory/blobs.js +27 -0
  23. package/dist/adapters/memory/evaluation.d.ts +18 -0
  24. package/dist/adapters/memory/evaluation.js +148 -0
  25. package/dist/adapters/memory/files.d.ts +27 -0
  26. package/dist/adapters/memory/files.js +0 -0
  27. package/dist/adapters/memory/flows.d.ts +16 -0
  28. package/dist/adapters/memory/flows.js +117 -0
  29. package/dist/adapters/memory/hitl.d.ts +9 -0
  30. package/dist/adapters/memory/hitl.js +130 -0
  31. package/dist/adapters/memory/idempotency.d.ts +13 -0
  32. package/dist/adapters/memory/idempotency.js +32 -0
  33. package/dist/adapters/memory/index.d.ts +39 -0
  34. package/dist/adapters/memory/index.js +107 -0
  35. package/dist/adapters/memory/knowledge.d.ts +43 -0
  36. package/dist/adapters/memory/knowledge.js +248 -0
  37. package/dist/adapters/memory/mcp.d.ts +9 -0
  38. package/dist/adapters/memory/mcp.js +37 -0
  39. package/dist/adapters/memory/message-store.d.ts +17 -0
  40. package/dist/adapters/memory/message-store.js +70 -0
  41. package/dist/adapters/memory/principal-memory.d.ts +7 -0
  42. package/dist/adapters/memory/principal-memory.js +83 -0
  43. package/dist/adapters/memory/runtime.d.ts +29 -0
  44. package/dist/adapters/memory/runtime.js +0 -0
  45. package/dist/adapters/memory/sessions.d.ts +29 -0
  46. package/dist/adapters/memory/sessions.js +0 -0
  47. package/dist/adapters/memory/skills.d.ts +10 -0
  48. package/dist/adapters/memory/skills.js +41 -0
  49. package/dist/adapters/memory/thread-summary.d.ts +7 -0
  50. package/dist/adapters/memory/thread-summary.js +29 -0
  51. package/dist/adapters/memory/usage-limits.d.ts +13 -0
  52. package/dist/adapters/memory/usage-limits.js +72 -0
  53. package/dist/adapters/memory/usage.d.ts +16 -0
  54. package/dist/adapters/memory/usage.js +279 -0
  55. package/dist/adapters/otel/index.d.ts +111 -0
  56. package/dist/adapters/otel/index.js +133 -0
  57. package/dist/adapters/postgres/artifact-exports.d.ts +12 -0
  58. package/dist/adapters/postgres/artifact-exports.js +117 -0
  59. package/dist/adapters/postgres/artifacts.d.ts +16 -0
  60. package/dist/adapters/postgres/artifacts.js +172 -0
  61. package/dist/adapters/postgres/checkpoint-store.d.ts +16 -0
  62. package/dist/adapters/postgres/checkpoint-store.js +34 -0
  63. package/dist/adapters/postgres/config.d.ts +15 -0
  64. package/dist/adapters/postgres/config.js +187 -0
  65. package/dist/adapters/postgres/conversation-store.d.ts +4 -0
  66. package/dist/adapters/postgres/conversation-store.js +82 -0
  67. package/dist/adapters/postgres/evaluation.d.ts +17 -0
  68. package/dist/adapters/postgres/evaluation.js +193 -0
  69. package/dist/adapters/postgres/file-content.d.ts +30 -0
  70. package/dist/adapters/postgres/file-content.js +111 -0
  71. package/dist/adapters/postgres/files.d.ts +19 -0
  72. package/dist/adapters/postgres/files.js +209 -0
  73. package/dist/adapters/postgres/flows.d.ts +20 -0
  74. package/dist/adapters/postgres/flows.js +206 -0
  75. package/dist/adapters/postgres/hitl.d.ts +5 -0
  76. package/dist/adapters/postgres/hitl.js +247 -0
  77. package/dist/adapters/postgres/index.d.ts +35 -0
  78. package/dist/adapters/postgres/index.js +35 -0
  79. package/dist/adapters/postgres/knowledge.d.ts +48 -0
  80. package/dist/adapters/postgres/knowledge.js +255 -0
  81. package/dist/adapters/postgres/memory.d.ts +14 -0
  82. package/dist/adapters/postgres/memory.js +194 -0
  83. package/dist/adapters/postgres/message-store.d.ts +11 -0
  84. package/dist/adapters/postgres/message-store.js +145 -0
  85. package/dist/adapters/postgres/migrations.d.ts +69 -0
  86. package/dist/adapters/postgres/migrations.js +1594 -0
  87. package/dist/adapters/postgres/pg-executor.d.ts +19 -0
  88. package/dist/adapters/postgres/pg-executor.js +32 -0
  89. package/dist/adapters/postgres/retention.d.ts +26 -0
  90. package/dist/adapters/postgres/retention.js +59 -0
  91. package/dist/adapters/postgres/rollups.d.ts +17 -0
  92. package/dist/adapters/postgres/rollups.js +267 -0
  93. package/dist/adapters/postgres/run-coordinator.d.ts +5 -0
  94. package/dist/adapters/postgres/run-coordinator.js +98 -0
  95. package/dist/adapters/postgres/run-event-log.d.ts +26 -0
  96. package/dist/adapters/postgres/run-event-log.js +30 -0
  97. package/dist/adapters/postgres/run-store.d.ts +4 -0
  98. package/dist/adapters/postgres/run-store.js +199 -0
  99. package/dist/adapters/postgres/schema.d.ts +39 -0
  100. package/dist/adapters/postgres/schema.js +70 -0
  101. package/dist/adapters/postgres/session-state.d.ts +7 -0
  102. package/dist/adapters/postgres/session-state.js +99 -0
  103. package/dist/adapters/postgres/sql.d.ts +8 -0
  104. package/dist/adapters/postgres/sql.js +2 -0
  105. package/dist/adapters/postgres/transaction.d.ts +37 -0
  106. package/dist/adapters/postgres/transaction.js +93 -0
  107. package/dist/adapters/postgres/unit-of-work.d.ts +18 -0
  108. package/dist/adapters/postgres/unit-of-work.js +8 -0
  109. package/dist/adapters/postgres/usage-limits.d.ts +15 -0
  110. package/dist/adapters/postgres/usage-limits.js +136 -0
  111. package/dist/adapters/postgres/usage.d.ts +15 -0
  112. package/dist/adapters/postgres/usage.js +226 -0
  113. package/dist/adapters/redis/index.d.ts +9 -0
  114. package/dist/adapters/redis/index.js +9 -0
  115. package/dist/adapters/redis/realtime.d.ts +74 -0
  116. package/dist/adapters/redis/realtime.js +112 -0
  117. package/dist/adapters/supabase/index.d.ts +88 -0
  118. package/dist/adapters/supabase/index.js +84 -0
  119. package/dist/adapters/supabase/realtime.d.ts +30 -0
  120. package/dist/adapters/supabase/realtime.js +53 -0
  121. package/dist/adapters/supabase/rls.d.ts +99 -0
  122. package/dist/adapters/supabase/rls.js +216 -0
  123. package/dist/adapters/supabase/storage.d.ts +50 -0
  124. package/dist/adapters/supabase/storage.js +207 -0
  125. package/dist/agents/agent.d.ts +66 -0
  126. package/dist/agents/agent.js +209 -0
  127. package/dist/agents/define.d.ts +21 -0
  128. package/dist/agents/define.js +63 -0
  129. package/dist/agents/engine.d.ts +98 -0
  130. package/dist/agents/engine.js +462 -0
  131. package/dist/agents/index.d.ts +50 -0
  132. package/dist/agents/index.js +17 -0
  133. package/dist/artifacts/index.d.ts +114 -0
  134. package/dist/artifacts/index.js +219 -0
  135. package/dist/authorization/index.d.ts +76 -0
  136. package/dist/authorization/index.js +76 -0
  137. package/dist/capabilities/index.d.ts +120 -0
  138. package/dist/capabilities/index.js +167 -0
  139. package/dist/capabilities/runtime.d.ts +89 -0
  140. package/dist/capabilities/runtime.js +84 -0
  141. package/dist/citations/index.d.ts +161 -0
  142. package/dist/citations/index.js +182 -0
  143. package/dist/context/assembler.d.ts +82 -0
  144. package/dist/context/assembler.js +129 -0
  145. package/dist/context/compaction.d.ts +45 -0
  146. package/dist/context/compaction.js +55 -0
  147. package/dist/context/index.d.ts +75 -0
  148. package/dist/context/index.js +17 -0
  149. package/dist/core/content-parts.d.ts +194 -0
  150. package/dist/core/content-parts.js +23 -0
  151. package/dist/core/context.d.ts +51 -0
  152. package/dist/core/context.js +9 -0
  153. package/dist/core/env.d.ts +25 -0
  154. package/dist/core/env.js +41 -0
  155. package/dist/core/errors.d.ts +30 -0
  156. package/dist/core/errors.js +65 -0
  157. package/dist/core/events.d.ts +139 -0
  158. package/dist/core/events.js +99 -0
  159. package/dist/core/ids.d.ts +52 -0
  160. package/dist/core/ids.js +13 -0
  161. package/dist/core/index.d.ts +9 -0
  162. package/dist/core/index.js +9 -0
  163. package/dist/core/tokens.d.ts +22 -0
  164. package/dist/core/tokens.js +22 -0
  165. package/dist/core/validation.d.ts +34 -0
  166. package/dist/core/validation.js +176 -0
  167. package/dist/documents/extraction.d.ts +121 -0
  168. package/dist/documents/extraction.js +293 -0
  169. package/dist/documents/index.d.ts +199 -0
  170. package/dist/documents/index.js +65 -0
  171. package/dist/documents/parsers/pdf.d.ts +47 -0
  172. package/dist/documents/parsers/pdf.js +508 -0
  173. package/dist/documents/parsers/text.d.ts +59 -0
  174. package/dist/documents/parsers/text.js +325 -0
  175. package/dist/documents/read-tool.d.ts +52 -0
  176. package/dist/documents/read-tool.js +109 -0
  177. package/dist/documents/render.d.ts +29 -0
  178. package/dist/documents/render.js +59 -0
  179. package/dist/documents/vision.d.ts +159 -0
  180. package/dist/documents/vision.js +214 -0
  181. package/dist/entries/adapters-bullmq.d.ts +8 -0
  182. package/dist/entries/adapters-bullmq.js +8 -0
  183. package/dist/entries/adapters-otel.d.ts +13 -0
  184. package/dist/entries/adapters-otel.js +13 -0
  185. package/dist/entries/adapters-postgres.d.ts +10 -0
  186. package/dist/entries/adapters-postgres.js +10 -0
  187. package/dist/entries/adapters-redis.d.ts +3 -0
  188. package/dist/entries/adapters-redis.js +3 -0
  189. package/dist/entries/context.d.ts +20 -0
  190. package/dist/entries/context.js +20 -0
  191. package/dist/entries/flows.d.ts +15 -0
  192. package/dist/entries/flows.js +15 -0
  193. package/dist/entries/hitl.d.ts +10 -0
  194. package/dist/entries/hitl.js +10 -0
  195. package/dist/entries/knowledge.d.ts +18 -0
  196. package/dist/entries/knowledge.js +19 -0
  197. package/dist/entries/mcp.d.ts +10 -0
  198. package/dist/entries/mcp.js +10 -0
  199. package/dist/entries/observability.d.ts +14 -0
  200. package/dist/entries/observability.js +16 -0
  201. package/dist/entries/persistence.d.ts +11 -0
  202. package/dist/entries/persistence.js +11 -0
  203. package/dist/entries/providers.d.ts +14 -0
  204. package/dist/entries/providers.js +14 -0
  205. package/dist/entries/runtime.d.ts +13 -0
  206. package/dist/entries/runtime.js +13 -0
  207. package/dist/entries/server.d.ts +24 -0
  208. package/dist/entries/server.js +24 -0
  209. package/dist/entries/tools.d.ts +21 -0
  210. package/dist/entries/tools.js +21 -0
  211. package/dist/entries/usage.d.ts +10 -0
  212. package/dist/entries/usage.js +10 -0
  213. package/dist/evaluation/gate.d.ts +168 -0
  214. package/dist/evaluation/gate.js +180 -0
  215. package/dist/evaluation/graders.d.ts +125 -0
  216. package/dist/evaluation/graders.js +203 -0
  217. package/dist/evaluation/index.d.ts +120 -0
  218. package/dist/evaluation/index.js +183 -0
  219. package/dist/evaluation/judge.d.ts +75 -0
  220. package/dist/evaluation/judge.js +111 -0
  221. package/dist/export/index.d.ts +162 -0
  222. package/dist/export/index.js +363 -0
  223. package/dist/export/markdown.d.ts +19 -0
  224. package/dist/export/markdown.js +29 -0
  225. package/dist/export/pdf.d.ts +73 -0
  226. package/dist/export/pdf.js +407 -0
  227. package/dist/files/context.d.ts +97 -0
  228. package/dist/files/context.js +185 -0
  229. package/dist/files/index.d.ts +210 -0
  230. package/dist/files/index.js +338 -0
  231. package/dist/files/read-tool.d.ts +81 -0
  232. package/dist/files/read-tool.js +163 -0
  233. package/dist/files/turn-parts.d.ts +96 -0
  234. package/dist/files/turn-parts.js +171 -0
  235. package/dist/flows/index.d.ts +270 -0
  236. package/dist/flows/index.js +62 -0
  237. package/dist/flows/interpreter.d.ts +146 -0
  238. package/dist/flows/interpreter.js +426 -0
  239. package/dist/flows/runner.d.ts +145 -0
  240. package/dist/flows/runner.js +270 -0
  241. package/dist/graphql/index.d.ts +8 -0
  242. package/dist/graphql/index.js +8 -0
  243. package/dist/graphql/resolvers.d.ts +237 -0
  244. package/dist/graphql/resolvers.js +253 -0
  245. package/dist/graphql/schema.d.ts +11 -0
  246. package/dist/graphql/schema.js +258 -0
  247. package/dist/graphql/sse.d.ts +77 -0
  248. package/dist/graphql/sse.js +100 -0
  249. package/dist/hitl/approved-execution.d.ts +127 -0
  250. package/dist/hitl/approved-execution.js +177 -0
  251. package/dist/hitl/index.d.ts +79 -0
  252. package/dist/hitl/index.js +12 -0
  253. package/dist/hitl/service.d.ts +221 -0
  254. package/dist/hitl/service.js +268 -0
  255. package/dist/idempotency/index.d.ts +70 -0
  256. package/dist/idempotency/index.js +59 -0
  257. package/dist/index.d.ts +103 -0
  258. package/dist/index.js +60 -0
  259. package/dist/knowledge/chunking.d.ts +57 -0
  260. package/dist/knowledge/chunking.js +158 -0
  261. package/dist/knowledge/index.d.ts +119 -0
  262. package/dist/knowledge/index.js +166 -0
  263. package/dist/knowledge/retrieval.d.ts +146 -0
  264. package/dist/knowledge/retrieval.js +170 -0
  265. package/dist/loadtest/harness.d.ts +168 -0
  266. package/dist/loadtest/harness.js +507 -0
  267. package/dist/loadtest/index.d.ts +13 -0
  268. package/dist/loadtest/index.js +13 -0
  269. package/dist/loadtest/injection.d.ts +89 -0
  270. package/dist/loadtest/injection.js +147 -0
  271. package/dist/loadtest/metrics.d.ts +197 -0
  272. package/dist/loadtest/metrics.js +160 -0
  273. package/dist/loadtest/runbooks.d.ts +28 -0
  274. package/dist/loadtest/runbooks.js +159 -0
  275. package/dist/loadtest/scenario.d.ts +104 -0
  276. package/dist/loadtest/scenario.js +208 -0
  277. package/dist/mcp/egress.d.ts +53 -0
  278. package/dist/mcp/egress.js +115 -0
  279. package/dist/mcp/index.d.ts +93 -0
  280. package/dist/mcp/index.js +33 -0
  281. package/dist/mcp/provider.d.ts +62 -0
  282. package/dist/mcp/provider.js +0 -0
  283. package/dist/models/index.d.ts +98 -0
  284. package/dist/models/index.js +74 -0
  285. package/dist/models/pricing.d.ts +24 -0
  286. package/dist/models/pricing.js +37 -0
  287. package/dist/models/provider-factory.d.ts +31 -0
  288. package/dist/models/provider-factory.js +67 -0
  289. package/dist/models/streaming.d.ts +145 -0
  290. package/dist/models/streaming.js +272 -0
  291. package/dist/models/vision.d.ts +38 -0
  292. package/dist/models/vision.js +62 -0
  293. package/dist/persistence/index.d.ts +1654 -0
  294. package/dist/persistence/index.js +226 -0
  295. package/dist/principal-memory/index.d.ts +106 -0
  296. package/dist/principal-memory/index.js +89 -0
  297. package/dist/retention/index.d.ts +89 -0
  298. package/dist/retention/index.js +70 -0
  299. package/dist/runtime/checkpoint.d.ts +37 -0
  300. package/dist/runtime/checkpoint.js +22 -0
  301. package/dist/runtime/index.d.ts +118 -0
  302. package/dist/runtime/index.js +69 -0
  303. package/dist/runtime/retry.d.ts +95 -0
  304. package/dist/runtime/retry.js +126 -0
  305. package/dist/runtime/serialization.d.ts +85 -0
  306. package/dist/runtime/serialization.js +95 -0
  307. package/dist/runtime/streaming.d.ts +54 -0
  308. package/dist/runtime/streaming.js +115 -0
  309. package/dist/runtime/worker.d.ts +130 -0
  310. package/dist/runtime/worker.js +405 -0
  311. package/dist/security/checklist.d.ts +53 -0
  312. package/dist/security/checklist.js +204 -0
  313. package/dist/security/findings.d.ts +56 -0
  314. package/dist/security/findings.js +168 -0
  315. package/dist/security/index.d.ts +14 -0
  316. package/dist/security/index.js +14 -0
  317. package/dist/security/prompt-safety.d.ts +100 -0
  318. package/dist/security/prompt-safety.js +133 -0
  319. package/dist/server/boot.d.ts +32 -0
  320. package/dist/server/boot.js +36 -0
  321. package/dist/server/cli-worker.d.ts +37 -0
  322. package/dist/server/cli-worker.js +151 -0
  323. package/dist/server/cli.d.ts +27 -0
  324. package/dist/server/cli.js +74 -0
  325. package/dist/server/config.d.ts +42 -0
  326. package/dist/server/config.js +127 -0
  327. package/dist/server/health.d.ts +59 -0
  328. package/dist/server/health.js +90 -0
  329. package/dist/server/host.d.ts +39 -0
  330. package/dist/server/host.js +124 -0
  331. package/dist/server/index.d.ts +15 -0
  332. package/dist/server/index.js +15 -0
  333. package/dist/server/main.d.ts +16 -0
  334. package/dist/server/main.js +31 -0
  335. package/dist/server/sse-route.d.ts +21 -0
  336. package/dist/server/sse-route.js +282 -0
  337. package/dist/skills/index.d.ts +67 -0
  338. package/dist/skills/index.js +31 -0
  339. package/dist/skills/resolver.d.ts +54 -0
  340. package/dist/skills/resolver.js +121 -0
  341. package/dist/teams/index.d.ts +93 -0
  342. package/dist/teams/index.js +207 -0
  343. package/dist/telemetry/index.d.ts +157 -0
  344. package/dist/telemetry/index.js +71 -0
  345. package/dist/telemetry/instrument.d.ts +108 -0
  346. package/dist/telemetry/instrument.js +232 -0
  347. package/dist/telemetry/log-events.d.ts +17 -0
  348. package/dist/telemetry/log-events.js +58 -0
  349. package/dist/telemetry/metrics.d.ts +123 -0
  350. package/dist/telemetry/metrics.js +135 -0
  351. package/dist/telemetry/noop.d.ts +39 -0
  352. package/dist/telemetry/noop.js +143 -0
  353. package/dist/telemetry/redaction.d.ts +64 -0
  354. package/dist/telemetry/redaction.js +153 -0
  355. package/dist/telemetry/spans.d.ts +56 -0
  356. package/dist/telemetry/spans.js +78 -0
  357. package/dist/telemetry/trace-context.d.ts +55 -0
  358. package/dist/telemetry/trace-context.js +60 -0
  359. package/dist/toolkit/compute.d.ts +53 -0
  360. package/dist/toolkit/compute.js +152 -0
  361. package/dist/toolkit/data.d.ts +98 -0
  362. package/dist/toolkit/data.js +235 -0
  363. package/dist/toolkit/http.d.ts +113 -0
  364. package/dist/toolkit/http.js +205 -0
  365. package/dist/toolkit/index.d.ts +21 -0
  366. package/dist/toolkit/index.js +17 -0
  367. package/dist/toolkit/web.d.ts +107 -0
  368. package/dist/toolkit/web.js +147 -0
  369. package/dist/tools/define.d.ts +25 -0
  370. package/dist/tools/define.js +45 -0
  371. package/dist/tools/delegating.d.ts +132 -0
  372. package/dist/tools/delegating.js +211 -0
  373. package/dist/tools/index.d.ts +129 -0
  374. package/dist/tools/index.js +33 -0
  375. package/dist/tools/library/compute.d.ts +11 -0
  376. package/dist/tools/library/compute.js +46 -0
  377. package/dist/tools/library/data.d.ts +16 -0
  378. package/dist/tools/library/data.js +92 -0
  379. package/dist/tools/library/http.d.ts +28 -0
  380. package/dist/tools/library/http.js +71 -0
  381. package/dist/tools/library/index.d.ts +97 -0
  382. package/dist/tools/library/index.js +134 -0
  383. package/dist/tools/library/knowledge.d.ts +39 -0
  384. package/dist/tools/library/knowledge.js +58 -0
  385. package/dist/tools/library/web.d.ts +19 -0
  386. package/dist/tools/library/web.js +65 -0
  387. package/dist/tools/meta-tools.d.ts +19 -0
  388. package/dist/tools/meta-tools.js +36 -0
  389. package/dist/tools/registry.d.ts +146 -0
  390. package/dist/tools/registry.js +291 -0
  391. package/dist/usage/index.d.ts +105 -0
  392. package/dist/usage/index.js +20 -0
  393. package/dist/usage/quota.d.ts +258 -0
  394. package/dist/usage/quota.js +510 -0
  395. package/dist/usage/recorder.d.ts +29 -0
  396. package/dist/usage/recorder.js +96 -0
  397. package/dist/usage/rollups.d.ts +121 -0
  398. package/dist/usage/rollups.js +157 -0
  399. package/dist/worker/export.d.ts +57 -0
  400. package/dist/worker/export.js +81 -0
  401. package/dist/worker/extraction.d.ts +57 -0
  402. package/dist/worker/extraction.js +84 -0
  403. package/dist/worker/main.d.ts +103 -0
  404. package/dist/worker/main.js +159 -0
  405. package/package.json +187 -0
@@ -0,0 +1,205 @@
1
+ /**
2
+ * The one HTTP client the first-party tools use — REQ-039 (#188).
3
+ *
4
+ * Every outbound tool in the library goes through here, and that is the point. The security properties of an
5
+ * outbound tool are not properties of the tool; they are properties of whatever makes the request. Spread across
6
+ * five tools they would hold in four of them.
7
+ *
8
+ * This lives in `toolkit/` rather than `tools/` because it performs I/O and boundary rule **R7** forbids that in
9
+ * the tools layer: an envelope that reached the network itself would be doing the work it exists to delegate.
10
+ * The tools in `tools/library/` are envelopes over these functions.
11
+ *
12
+ * ## What is refused, and why each one
13
+ *
14
+ * The egress policy is the platform's own (`validateHttpEgress`), applied to an argument a *model* produced —
15
+ * which is the difference from an MCP endpoint an operator configured once. It refuses:
16
+ *
17
+ * - **Private, loopback and link-local hosts.** `169.254.169.254` is cloud metadata: credentials in plain text
18
+ * to anything that can make an HTTP request from inside the network.
19
+ * - **Every IPv6 literal** unless explicitly allowed, because `::ffff:169.254.169.254` is that same address in a
20
+ * form any IPv4-only check waves through.
21
+ * - **Credentials in the URL** — refused rather than stripped, so the caller never believes it sent one.
22
+ * - **Anything but https** by default. `file://` reads the disk.
23
+ *
24
+ * And two decisions this module adds on top:
25
+ *
26
+ * - **Redirects are not followed.** `redirect: "manual"`, always. Following one lets a permitted host bounce the
27
+ * request to a forbidden one: the policy checked the URL the model asked for, and the request lands somewhere
28
+ * it never saw. That is the standard SSRF bypass, and it is the reason a per-URL allow-list is not sufficient
29
+ * on its own. The redirect target is reported so the model can ask for it explicitly and have it checked on
30
+ * its own merits.
31
+ * - **Credentials come from configuration, keyed by host.** `headersFor` is consulted with the *validated* host,
32
+ * so a model cannot name the credential it wants used, cannot send one to a host it was not issued for, and
33
+ * cannot read one back: a tool's own input schema has no field for it (see `tools/library/http.ts`).
34
+ */
35
+ import { AgentPlatformError } from "../core/errors.js";
36
+ import { validateHttpEgress } from "../mcp/egress.js";
37
+ import { encloseUntrusted, makeNonce } from "../security/prompt-safety.js";
38
+ /** https only, no private networks, no allow-list. A deployment narrows it; nothing widens it silently. */
39
+ export const DEFAULT_EGRESS_POLICY = {
40
+ allowedSchemes: ["https"],
41
+ allowPrivateNetworks: false,
42
+ };
43
+ /**
44
+ * Bytes are bounded, and the bound is enforced **while reading**.
45
+ *
46
+ * `await response.text()` on a multi-gigabyte response buffers all of it before any length check could run, so a
47
+ * limit applied afterwards protects nothing at all.
48
+ */
49
+ export const MAX_RESPONSE_BYTES = 200_000;
50
+ /** A model waiting on a hung server is a run holding a worker slot. */
51
+ export const REQUEST_TIMEOUT_MS = 10_000;
52
+ /**
53
+ * Headers a caller may not set, because they are decided here or by configuration.
54
+ *
55
+ * `authorization` and `cookie` are the ones that matter: a tool input that could set them would let a model
56
+ * choose which credential to spend and where to send it. `host` forges the request target past the policy check.
57
+ */
58
+ const RESERVED_HEADERS = new Set(["authorization", "cookie", "proxy-authorization", "host", "content-length"]);
59
+ export const createHttpClient = (config = {}) => {
60
+ const policy = config.policy ?? DEFAULT_EGRESS_POLICY;
61
+ const doFetch = config.fetchImpl ?? fetch;
62
+ const maxBytes = config.maxBytes ?? MAX_RESPONSE_BYTES;
63
+ const timeoutMs = config.timeoutMs ?? REQUEST_TIMEOUT_MS;
64
+ // A nonce factory is injectable so a test can pin it; the default needs randomness the caller supplies,
65
+ // because `node:crypto` is an import this layer does not get to make.
66
+ const nonce = config.nonce ??
67
+ (config.randomHex !== undefined
68
+ ? () => makeNonce(config.randomHex)
69
+ : () => makeNonce(weakHex));
70
+ return {
71
+ async request(input) {
72
+ const method = (input.method ?? "GET").toUpperCase();
73
+ // The policy first, before any network call. A refusal that still sends the packet is not a refusal.
74
+ let url;
75
+ try {
76
+ url = validateHttpEgress(policy, input.url);
77
+ }
78
+ catch (thrown) {
79
+ const error = thrown;
80
+ return {
81
+ ok: false,
82
+ url: input.url,
83
+ kind: "forbidden",
84
+ reason: error.message ?? "that URL is not permitted",
85
+ };
86
+ }
87
+ const supplied = Object.entries(input.headers ?? {}).filter(([name]) => !RESERVED_HEADERS.has(name.toLowerCase()));
88
+ const headers = {
89
+ accept: input.accept ?? "text/html, text/plain;q=0.9, application/json;q=0.9, */*;q=0.1",
90
+ ...Object.fromEntries(supplied),
91
+ // Configured headers last: they are the deployment's, and nothing a caller passes may shadow them.
92
+ ...(config.headersFor?.(url.hostname) ?? {}),
93
+ };
94
+ const controller = new AbortController();
95
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
96
+ try {
97
+ const response = await doFetch(url.toString(), {
98
+ method,
99
+ signal: controller.signal,
100
+ redirect: "manual",
101
+ headers,
102
+ ...(input.body === undefined ? {} : { body: input.body }),
103
+ });
104
+ if (response.status >= 300 && response.status < 400) {
105
+ const location = response.headers.get("location") ?? "";
106
+ return {
107
+ ok: false,
108
+ url: url.toString(),
109
+ kind: "redirected",
110
+ status: response.status,
111
+ reason: `That URL redirects to ${location || "somewhere unspecified"}. Redirects are not followed ` +
112
+ `automatically — ask for that URL directly if you want it, and it will be checked on its own merits.`,
113
+ };
114
+ }
115
+ const contentType = response.headers.get("content-type") ?? "";
116
+ const { text, truncated } = await readBounded(response, maxBytes);
117
+ // A 4xx/5xx is reported as a failure with its status, because "the page returned 404" is what the model
118
+ // needs to hear. The body still comes back where there is one: an API's error payload is often the only
119
+ // thing that says what was wrong with the request.
120
+ if (response.status >= 400) {
121
+ return {
122
+ ok: false,
123
+ url: url.toString(),
124
+ kind: "http-error",
125
+ status: response.status,
126
+ reason: `That URL returned ${response.status}${text.trim() === "" ? "" : `: ${text.slice(0, 500)}`}`,
127
+ };
128
+ }
129
+ const body = input.fence === false
130
+ ? text
131
+ : encloseUntrusted({
132
+ // Provenance is the URL actually read, after validation, so a model quoting this can say where it
133
+ // came from and a reader can check.
134
+ provenance: url.toString(),
135
+ title: `${method} ${url.hostname} (${response.status})`,
136
+ body: text,
137
+ nonce: nonce(),
138
+ });
139
+ return { ok: true, url: url.toString(), status: response.status, contentType, truncated, body };
140
+ }
141
+ catch (thrown) {
142
+ // A timeout and a DNS failure are both "could not read that", and neither is worth a stack trace in a
143
+ // model's context. Named enough to act on, not enough to be noise.
144
+ const aborted = thrown.name === "AbortError";
145
+ return aborted
146
+ ? {
147
+ ok: false,
148
+ url: url.toString(),
149
+ kind: "timeout",
150
+ reason: `That URL did not respond within ${timeoutMs / 1000} seconds.`,
151
+ }
152
+ : { ok: false, url: url.toString(), kind: "unreachable", reason: "Could not reach that URL." };
153
+ }
154
+ finally {
155
+ clearTimeout(timer);
156
+ }
157
+ },
158
+ };
159
+ };
160
+ /**
161
+ * A last-resort nonce source.
162
+ *
163
+ * Not cryptographic, and named so nobody mistakes it. The nonce's job is to stop *fetched text* from closing the
164
+ * fence around itself, so it has to be unguessable to the page, not to an attacker who can see this process. A
165
+ * deployment that cares passes `randomHex` and gets `node:crypto`; the alternative to this fallback is a fixed
166
+ * nonce, which a page could simply include.
167
+ */
168
+ const weakHex = (bytes) => {
169
+ let out = "";
170
+ for (let i = 0; i < bytes; i += 1)
171
+ out += Math.floor(Math.random() * 256).toString(16).padStart(2, "0");
172
+ return out;
173
+ };
174
+ /**
175
+ * Read at most `maxBytes`, stopping as they arrive, and abandon the rest.
176
+ *
177
+ * Without `reader.cancel()` the connection stays open pulling a body nobody wants.
178
+ */
179
+ export const readBounded = async (response, maxBytes) => {
180
+ const body = response.body;
181
+ // No stream — a mock, or a runtime without one. Falling back to `text()` and slicing is honest about being a
182
+ // weaker bound rather than pretending the ceiling held.
183
+ if (body === null || body === undefined) {
184
+ const whole = await response.text();
185
+ return { text: whole.slice(0, maxBytes), truncated: whole.length > maxBytes };
186
+ }
187
+ const reader = body.getReader();
188
+ const decoder = new TextDecoder();
189
+ let text = "";
190
+ let bytes = 0;
191
+ for (;;) {
192
+ const { value, done } = await reader.read();
193
+ if (done)
194
+ break;
195
+ bytes += value.byteLength;
196
+ if (bytes > maxBytes) {
197
+ text += decoder.decode(value.slice(0, Math.max(0, maxBytes - (bytes - value.byteLength))));
198
+ await reader.cancel();
199
+ return { text, truncated: true };
200
+ }
201
+ text += decoder.decode(value, { stream: true });
202
+ }
203
+ return { text, truncated: false };
204
+ };
205
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The deterministic functions the first-party tools delegate to — REQ-039 (#188).
3
+ *
4
+ * Why this is a layer of its own: boundary rule **R7** forbids the tools layer from performing I/O, because a
5
+ * tool is "a thin, agent-facing envelope over a deterministic function" and an envelope that reached the network
6
+ * itself would be doing the work it exists to delegate. So the network, the parsing and the arithmetic live here,
7
+ * and `tools/library/` holds envelopes that add authorisation, approval and idempotency and then call these.
8
+ *
9
+ * Everything here is directly callable and separately testable, which is the other half of the point: the
10
+ * interesting behaviour of an outbound tool — what it refuses, where it stops reading — should be provable
11
+ * without constructing a run.
12
+ */
13
+ export { DEFAULT_EGRESS_POLICY, MAX_RESPONSE_BYTES, REQUEST_TIMEOUT_MS, createHttpClient, readBounded, } from "./http.js";
14
+ export type { HttpClient, HttpClientConfig, HttpFailure, HttpOutcome, HttpRequest, HttpSuccess } from "./http.js";
15
+ export { DEFAULT_SEARCH_LIMIT, MAX_SNIPPET_CHARS, createFetchJson, createFetchPage, createWebSearch, htmlToText, } from "./web.js";
16
+ export type { JsonResult, PageResult, SearchHit, SearchOutcome, SearchProvider } from "./web.js";
17
+ export { MAX_CELL_CHARS, MAX_CSV_ROWS, MAX_SQL_ROWS, createSqlQuery, createSqlSchema, parseCsv, queryJson, } from "./data.js";
18
+ export type { CsvResult, JsonQueryResult, ReadOnlyQuery, SchemaResult, SqlResult } from "./data.js";
19
+ export { MAX_EXPRESSION_CHARS, calculate, currentTime } from "./compute.js";
20
+ export type { CalculationResult, TimeResult } from "./compute.js";
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The deterministic functions the first-party tools delegate to — REQ-039 (#188).
3
+ *
4
+ * Why this is a layer of its own: boundary rule **R7** forbids the tools layer from performing I/O, because a
5
+ * tool is "a thin, agent-facing envelope over a deterministic function" and an envelope that reached the network
6
+ * itself would be doing the work it exists to delegate. So the network, the parsing and the arithmetic live here,
7
+ * and `tools/library/` holds envelopes that add authorisation, approval and idempotency and then call these.
8
+ *
9
+ * Everything here is directly callable and separately testable, which is the other half of the point: the
10
+ * interesting behaviour of an outbound tool — what it refuses, where it stops reading — should be provable
11
+ * without constructing a run.
12
+ */
13
+ export { DEFAULT_EGRESS_POLICY, MAX_RESPONSE_BYTES, REQUEST_TIMEOUT_MS, createHttpClient, readBounded, } from "./http.js";
14
+ export { DEFAULT_SEARCH_LIMIT, MAX_SNIPPET_CHARS, createFetchJson, createFetchPage, createWebSearch, htmlToText, } from "./web.js";
15
+ export { MAX_CELL_CHARS, MAX_CSV_ROWS, MAX_SQL_ROWS, createSqlQuery, createSqlSchema, parseCsv, queryJson, } from "./data.js";
16
+ export { MAX_EXPRESSION_CHARS, calculate, currentTime } from "./compute.js";
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Reading the web — REQ-039 (#188).
3
+ *
4
+ * Two functions the library's `fetch_url`, `fetch_json` and `web_search` tools delegate to. Both go through
5
+ * `createHttpClient`, so the egress policy, the redirect refusal, the byte ceiling and the untrusted-content
6
+ * fence are decided in one place rather than three.
7
+ */
8
+ import type { HttpClient, HttpClientConfig, HttpOutcome } from "./http.js";
9
+ /**
10
+ * Strip HTML to something a model can read.
11
+ *
12
+ * Crude and openly so: `script` and `style` bodies removed, tags dropped, entities for the five characters that
13
+ * matter, whitespace collapsed. It is not a parser and does not need to be — the goal is *legible text*, and a
14
+ * DOM implementation is both a dependency and an attack surface for a tool whose output is prose either way.
15
+ *
16
+ * `script` and `style` go **with their contents**; otherwise a page's JavaScript arrives as sentences and the
17
+ * model reads minified code as content.
18
+ */
19
+ export declare const htmlToText: (html: string) => string;
20
+ export type PageResult = {
21
+ readonly ok: true;
22
+ readonly url: string;
23
+ readonly status: number;
24
+ readonly truncated: boolean;
25
+ readonly content: string;
26
+ } | {
27
+ readonly ok: false;
28
+ readonly url: string;
29
+ readonly reason: string;
30
+ };
31
+ /** Fetch a page and return readable text. HTML is flattened; anything else comes back as it arrived. */
32
+ export declare const createFetchPage: (config?: HttpClientConfig & {
33
+ readonly client?: HttpClient;
34
+ }) => (rawUrl: string) => Promise<PageResult>;
35
+ export type JsonResult = {
36
+ readonly ok: true;
37
+ readonly url: string;
38
+ readonly status: number;
39
+ readonly data: unknown;
40
+ } | {
41
+ readonly ok: false;
42
+ readonly url: string;
43
+ readonly reason: string;
44
+ };
45
+ /**
46
+ * Fetch and parse JSON.
47
+ *
48
+ * Requested unfenced, because the body is parsed here and reaches the model as *structured data*, not as prose.
49
+ * Fencing it would put delimiters inside string values. The safety argument is different in kind: a parsed object
50
+ * cannot forge a section boundary, and a caller rendering one back into a prompt is the caller that must fence.
51
+ */
52
+ export declare const createFetchJson: (config?: HttpClientConfig & {
53
+ readonly client?: HttpClient;
54
+ }) => (rawUrl: string) => Promise<JsonResult>;
55
+ export type SearchHit = {
56
+ readonly title: string;
57
+ readonly url: string;
58
+ readonly snippet: string;
59
+ };
60
+ /**
61
+ * What a search returned, or why it did not.
62
+ *
63
+ * `searched: false` is not an empty result list, and the distinction is the whole type. "I searched and found
64
+ * nothing" and "I could not search" lead a model to opposite next actions, and collapsing them into `[]` makes it
65
+ * confidently report that nothing exists.
66
+ */
67
+ export type SearchOutcome = {
68
+ readonly searched: true;
69
+ readonly query: string;
70
+ readonly hits: readonly SearchHit[];
71
+ } | {
72
+ readonly searched: false;
73
+ readonly query: string;
74
+ readonly reason: "not-configured" | "unavailable" | "timed-out";
75
+ readonly detail: string;
76
+ };
77
+ /**
78
+ * A search provider, as configuration.
79
+ *
80
+ * Deliberately not a hard-coded vendor. Every usable search API is a GET with a key and a JSON body of results,
81
+ * so the shape a deployment supplies is: where to send it, and how to read what comes back. `apiKey` is
82
+ * configuration and never appears in a tool's input schema — a model must not be able to name the credential it
83
+ * wants spent.
84
+ */
85
+ export type SearchProvider = {
86
+ readonly name: string;
87
+ /** Build the request URL for a query. The key belongs in `headers`, not here, wherever the provider allows it. */
88
+ readonly endpoint: (query: string, limit: number) => string;
89
+ readonly headers?: Readonly<Record<string, string>>;
90
+ /** Read the provider's JSON into hits. Returning `[]` means "searched, found nothing". */
91
+ readonly parse: (payload: unknown) => readonly SearchHit[];
92
+ };
93
+ export declare const DEFAULT_SEARCH_LIMIT = 5;
94
+ export declare const MAX_SNIPPET_CHARS = 400;
95
+ /**
96
+ * Web search over a configured provider.
97
+ *
98
+ * With no provider this returns `not-configured` rather than throwing or pretending. A stubbed search that
99
+ * returns plausible-looking results is worse than no search: it is a tool the model trusts and cannot verify.
100
+ */
101
+ export declare const createWebSearch: (config?: HttpClientConfig & {
102
+ readonly provider?: SearchProvider;
103
+ readonly client?: HttpClient;
104
+ readonly limit?: number;
105
+ }) => (query: string, limit?: number) => Promise<SearchOutcome>;
106
+ export type { HttpOutcome };
107
+ //# sourceMappingURL=web.d.ts.map
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Reading the web — REQ-039 (#188).
3
+ *
4
+ * Two functions the library's `fetch_url`, `fetch_json` and `web_search` tools delegate to. Both go through
5
+ * `createHttpClient`, so the egress policy, the redirect refusal, the byte ceiling and the untrusted-content
6
+ * fence are decided in one place rather than three.
7
+ */
8
+ import { createHttpClient } from "./http.js";
9
+ /**
10
+ * Strip HTML to something a model can read.
11
+ *
12
+ * Crude and openly so: `script` and `style` bodies removed, tags dropped, entities for the five characters that
13
+ * matter, whitespace collapsed. It is not a parser and does not need to be — the goal is *legible text*, and a
14
+ * DOM implementation is both a dependency and an attack surface for a tool whose output is prose either way.
15
+ *
16
+ * `script` and `style` go **with their contents**; otherwise a page's JavaScript arrives as sentences and the
17
+ * model reads minified code as content.
18
+ */
19
+ export const htmlToText = (html) => html
20
+ .replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, " ")
21
+ .replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, " ")
22
+ .replace(/<!--[\s\S]*?-->/g, " ")
23
+ // Block-level ends become newlines first, so paragraphs do not run together into one wall of text.
24
+ .replace(/<\/(p|div|h[1-6]|li|tr|section|article|br)\s*>/gi, "\n")
25
+ .replace(/<[^>]+>/g, " ")
26
+ .replace(/&nbsp;/g, " ")
27
+ .replace(/&lt;/g, "<")
28
+ .replace(/&gt;/g, ">")
29
+ .replace(/&quot;/g, '"')
30
+ .replace(/&#39;/g, "'")
31
+ // Ampersand last: first would turn `&amp;lt;` into `<`, the classic double-decode.
32
+ .replace(/&amp;/g, "&")
33
+ .replace(/[ \t]+/g, " ")
34
+ .replace(/\n{3,}/g, "\n\n")
35
+ .trim();
36
+ /** Fetch a page and return readable text. HTML is flattened; anything else comes back as it arrived. */
37
+ export const createFetchPage = (config = {}) => {
38
+ const client = config.client ?? createHttpClient(config);
39
+ return async (rawUrl) => {
40
+ const outcome = await client.request({ url: rawUrl, accept: "text/html, text/plain;q=0.9, */*;q=0.1" });
41
+ if (!outcome.ok)
42
+ return { ok: false, url: outcome.url, reason: outcome.reason };
43
+ // Flattening happens after fencing, which is safe: `htmlToText` only removes markup, and the fence's
44
+ // delimiters are not markup. Doing it the other way would let a page's tags rewrite the fence.
45
+ const content = /html/i.test(outcome.contentType) ? htmlToText(outcome.body) : outcome.body;
46
+ return { ok: true, url: outcome.url, status: outcome.status, truncated: outcome.truncated, content };
47
+ };
48
+ };
49
+ /**
50
+ * Fetch and parse JSON.
51
+ *
52
+ * Requested unfenced, because the body is parsed here and reaches the model as *structured data*, not as prose.
53
+ * Fencing it would put delimiters inside string values. The safety argument is different in kind: a parsed object
54
+ * cannot forge a section boundary, and a caller rendering one back into a prompt is the caller that must fence.
55
+ */
56
+ export const createFetchJson = (config = {}) => {
57
+ const client = config.client ?? createHttpClient(config);
58
+ return async (rawUrl) => {
59
+ const outcome = await client.request({ url: rawUrl, accept: "application/json", fence: false });
60
+ if (!outcome.ok)
61
+ return { ok: false, url: outcome.url, reason: outcome.reason };
62
+ try {
63
+ return { ok: true, url: outcome.url, status: outcome.status, data: JSON.parse(outcome.body) };
64
+ }
65
+ catch {
66
+ return {
67
+ ok: false,
68
+ url: outcome.url,
69
+ // Named precisely, because "invalid JSON" plus a truncation flag is the difference between a broken
70
+ // endpoint and a response the ceiling cut in half.
71
+ reason: outcome.truncated
72
+ ? "The response was larger than the byte limit, so what arrived is not parseable JSON."
73
+ : "That URL did not return valid JSON.",
74
+ };
75
+ }
76
+ };
77
+ };
78
+ export const DEFAULT_SEARCH_LIMIT = 5;
79
+ export const MAX_SNIPPET_CHARS = 400;
80
+ /**
81
+ * Web search over a configured provider.
82
+ *
83
+ * With no provider this returns `not-configured` rather than throwing or pretending. A stubbed search that
84
+ * returns plausible-looking results is worse than no search: it is a tool the model trusts and cannot verify.
85
+ */
86
+ export const createWebSearch = (config = {}) => {
87
+ const provider = config.provider;
88
+ const client = config.client ?? createHttpClient(config);
89
+ const defaultLimit = config.limit ?? DEFAULT_SEARCH_LIMIT;
90
+ return async (query, limit = defaultLimit) => {
91
+ if (provider === undefined) {
92
+ return {
93
+ searched: false,
94
+ query,
95
+ reason: "not-configured",
96
+ detail: "No web-search provider is configured, so I cannot search. Configure one, or give me a URL to read " +
97
+ "directly.",
98
+ };
99
+ }
100
+ const outcome = await client.request({
101
+ url: provider.endpoint(query, limit),
102
+ headers: provider.headers,
103
+ accept: "application/json",
104
+ fence: false,
105
+ });
106
+ if (!outcome.ok) {
107
+ return {
108
+ searched: false,
109
+ query,
110
+ reason: outcome.kind === "timeout" ? "timed-out" : "unavailable",
111
+ detail: `${provider.name}: ${outcome.reason}`,
112
+ };
113
+ }
114
+ let payload;
115
+ try {
116
+ payload = JSON.parse(outcome.body);
117
+ }
118
+ catch {
119
+ return { searched: false, query, reason: "unavailable", detail: `${provider.name} returned a response that is not JSON.` };
120
+ }
121
+ let hits;
122
+ try {
123
+ hits = provider.parse(payload);
124
+ }
125
+ catch (error) {
126
+ // A provider that changed its response shape is an operational failure, not an empty search.
127
+ return {
128
+ searched: false,
129
+ query,
130
+ reason: "unavailable",
131
+ detail: `${provider.name} returned a shape this configuration cannot read: ${error.message}`,
132
+ };
133
+ }
134
+ return {
135
+ searched: true,
136
+ query,
137
+ hits: hits.slice(0, limit).map((hit) => ({
138
+ title: hit.title,
139
+ url: hit.url,
140
+ // Snippets are bounded here rather than trusting the provider: a "snippet" is whatever the remote decides
141
+ // it is, and five of them at 40KB each is a context window.
142
+ snippet: hit.snippet.length > MAX_SNIPPET_CHARS ? `${hit.snippet.slice(0, MAX_SNIPPET_CHARS)}…` : hit.snippet,
143
+ })),
144
+ };
145
+ };
146
+ };
147
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Tool authoring helpers — `docs/03` → Tool registry. Ergonomic ways to build a `Tool` and a
3
+ * `ToolProvider` from a plain spec: you write `execute(input, context) => data` and throw on error;
4
+ * the helper wraps the result in the shared success/error envelope and fills descriptor defaults
5
+ * (idempotency is required automatically for external/destructive effects).
6
+ */
7
+ import type { ExecutionContext } from "../core/context.js";
8
+ import type { ApprovalPolicy, Tool, ToolEffect, ToolProvider } from "./index.js";
9
+ export type ToolSpec<I = unknown, O = unknown> = {
10
+ readonly name: string;
11
+ readonly description: string;
12
+ readonly label?: string;
13
+ readonly category?: string;
14
+ readonly effect?: ToolEffect;
15
+ readonly approvalPolicy?: ApprovalPolicy;
16
+ readonly inputSchema?: unknown;
17
+ readonly outputSchema?: unknown;
18
+ readonly requiresIdempotencyKey?: boolean;
19
+ execute(input: I, context: ExecutionContext): Promise<O> | O;
20
+ };
21
+ /** Build a `Tool` from a plain spec: `execute` returns data (or throws); the envelope is handled here. */
22
+ export declare const defineTool: <I = unknown, O = unknown>(spec: ToolSpec<I, O>) => Tool<O>;
23
+ /** A `ToolProvider` serving a fixed set of tools. For dynamic per-tenant tools, implement the port. */
24
+ export declare const toolProvider: (id: string, tools: readonly Tool[]) => ToolProvider;
25
+ //# sourceMappingURL=define.d.ts.map
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Tool authoring helpers — `docs/03` → Tool registry. Ergonomic ways to build a `Tool` and a
3
+ * `ToolProvider` from a plain spec: you write `execute(input, context) => data` and throw on error;
4
+ * the helper wraps the result in the shared success/error envelope and fills descriptor defaults
5
+ * (idempotency is required automatically for external/destructive effects).
6
+ */
7
+ // One definition of the error envelope, not two. `runtime/retry.ts` already exported
8
+ // `toPlatformError`; this module had a private duplicate, and exporting that for #113's delegating
9
+ // envelope made the package barrel ambiguous about which one it meant — the same collision
10
+ // `DEFAULT_SESSION_STATE_MAX_BYTES` caused in #97. Importing the existing one instead.
11
+ import { toPlatformError } from "../runtime/retry.js";
12
+ /** Build a `Tool` from a plain spec: `execute` returns data (or throws); the envelope is handled here. */
13
+ export const defineTool = (spec) => {
14
+ const effect = spec.effect ?? "read";
15
+ const descriptor = {
16
+ name: spec.name,
17
+ label: spec.label ?? spec.name,
18
+ description: spec.description,
19
+ category: spec.category ?? "general",
20
+ inputSchema: spec.inputSchema ?? {},
21
+ outputSchema: spec.outputSchema ?? {},
22
+ effect,
23
+ approvalPolicy: spec.approvalPolicy ?? (effect === "external-write" || effect === "destructive" ? "always" : "never"),
24
+ requiresIdempotencyKey: spec.requiresIdempotencyKey ?? (effect === "external-write" || effect === "destructive"),
25
+ };
26
+ return {
27
+ descriptor,
28
+ async execute({ context, input }) {
29
+ try {
30
+ return { ok: true, data: await spec.execute(input, context) };
31
+ }
32
+ catch (error) {
33
+ return { ok: false, error: toPlatformError(error) };
34
+ }
35
+ },
36
+ };
37
+ };
38
+ /** A `ToolProvider` serving a fixed set of tools. For dynamic per-tenant tools, implement the port. */
39
+ export const toolProvider = (id, tools) => ({
40
+ id,
41
+ async listTools() {
42
+ return tools;
43
+ },
44
+ });
45
+ //# sourceMappingURL=define.js.map