@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,152 @@
1
+ /**
2
+ * Time and arithmetic — REQ-039 (#188).
3
+ *
4
+ * The two things a model is reliably bad at and a two-line function is reliably good at. Both are pure, so both
5
+ * are here as functions and the tool envelopes over them are trivial.
6
+ */
7
+ const FUNCTIONS = {
8
+ abs: Math.abs, ceil: Math.ceil, floor: Math.floor, round: Math.round, trunc: Math.trunc,
9
+ sqrt: Math.sqrt, cbrt: Math.cbrt, exp: Math.exp, ln: Math.log, log10: Math.log10, log2: Math.log2,
10
+ sin: Math.sin, cos: Math.cos, tan: Math.tan, asin: Math.asin, acos: Math.acos, atan: Math.atan,
11
+ min: Math.min, max: Math.max, pow: Math.pow,
12
+ };
13
+ const CONSTANTS = { pi: Math.PI, e: Math.E };
14
+ export const MAX_EXPRESSION_CHARS = 500;
15
+ export const calculate = (expression) => {
16
+ if (expression.trim() === "")
17
+ return { ok: false, expression, reason: "The expression is empty." };
18
+ if (expression.length > MAX_EXPRESSION_CHARS) {
19
+ return { ok: false, expression, reason: `Expressions are limited to ${MAX_EXPRESSION_CHARS} characters.` };
20
+ }
21
+ const tokens = expression.toLowerCase().match(/\d+\.?\d*|[a-z_]\w*|[+\-*/%^(),]|\S/g);
22
+ if (tokens === null)
23
+ return { ok: false, expression, reason: "There is nothing to evaluate." };
24
+ let position = 0;
25
+ const peek = () => tokens[position];
26
+ const take = () => tokens[position++];
27
+ const fail = (reason) => {
28
+ throw new SyntaxError(reason);
29
+ };
30
+ // expression := term (('+' | '-') term)*
31
+ const parseExpression = () => {
32
+ let value = parseTerm();
33
+ for (;;) {
34
+ const operator = peek();
35
+ if (operator !== "+" && operator !== "-")
36
+ return value;
37
+ take();
38
+ const right = parseTerm();
39
+ value = operator === "+" ? value + right : value - right;
40
+ }
41
+ };
42
+ // term := power (('*' | '/' | '%') power)*
43
+ const parseTerm = () => {
44
+ let value = parsePower();
45
+ for (;;) {
46
+ const operator = peek();
47
+ if (operator !== "*" && operator !== "/" && operator !== "%")
48
+ return value;
49
+ take();
50
+ const right = parsePower();
51
+ if ((operator === "/" || operator === "%") && right === 0)
52
+ fail("division by zero");
53
+ value = operator === "*" ? value * right : operator === "/" ? value / right : value % right;
54
+ }
55
+ };
56
+ // power := unary ('^' power)? -- right-associative, so 2^3^2 is 512 and not 64.
57
+ const parsePower = () => {
58
+ const base = parseUnary();
59
+ if (peek() !== "^")
60
+ return base;
61
+ take();
62
+ return base ** parsePower();
63
+ };
64
+ const parseUnary = () => {
65
+ if (peek() === "-") {
66
+ take();
67
+ return -parseUnary();
68
+ }
69
+ if (peek() === "+") {
70
+ take();
71
+ return parseUnary();
72
+ }
73
+ return parsePrimary();
74
+ };
75
+ const parsePrimary = () => {
76
+ const token = take();
77
+ if (token === undefined)
78
+ fail("the expression ends before it is finished");
79
+ if (token === "(") {
80
+ const value = parseExpression();
81
+ if (take() !== ")")
82
+ fail("a '(' is never closed");
83
+ return value;
84
+ }
85
+ if (/^\d/.test(token))
86
+ return Number(token);
87
+ const name = token;
88
+ if (name in CONSTANTS)
89
+ return CONSTANTS[name];
90
+ if (name in FUNCTIONS) {
91
+ if (take() !== "(")
92
+ fail(`${name} needs its arguments in parentheses`);
93
+ const args = [];
94
+ if (peek() !== ")") {
95
+ args.push(parseExpression());
96
+ while (peek() === ",") {
97
+ take();
98
+ args.push(parseExpression());
99
+ }
100
+ }
101
+ if (take() !== ")")
102
+ fail(`the arguments to ${name} are never closed`);
103
+ return FUNCTIONS[name](...args);
104
+ }
105
+ return fail(`'${name}' is not a number, an operator, or a function I know`);
106
+ };
107
+ try {
108
+ const value = parseExpression();
109
+ if (position < tokens.length) {
110
+ return { ok: false, expression, reason: `I could not read '${tokens.slice(position).join(" ")}'.` };
111
+ }
112
+ if (!Number.isFinite(value)) {
113
+ // Infinity and NaN are results a model will happily narrate as a number. They are not one.
114
+ return { ok: false, expression, reason: "That does not have a finite numeric answer." };
115
+ }
116
+ return { ok: true, expression, value };
117
+ }
118
+ catch (error) {
119
+ return { ok: false, expression, reason: `I could not evaluate that: ${error.message}.` };
120
+ }
121
+ };
122
+ /**
123
+ * The current time, in a named zone.
124
+ *
125
+ * A model has no clock -- it has a training cutoff, and it will answer "what is today's date" with something
126
+ * plausible and wrong. The zone is a parameter because "today" is a different day depending on where the person
127
+ * asking is, and the caller is often not in UTC.
128
+ *
129
+ * The clock is injected so a test can pin it, which is the convention everywhere else in this runtime.
130
+ */
131
+ export const currentTime = (input = {}) => {
132
+ const timeZone = input.timeZone ?? "UTC";
133
+ const at = (input.now ?? (() => new Date()))();
134
+ try {
135
+ const formatted = new Intl.DateTimeFormat("en-CA", {
136
+ timeZone,
137
+ dateStyle: "full",
138
+ timeStyle: "long",
139
+ // 24-hour, explicitly. The locale default here is "1:34:56 p.m.", and a model that has to re-derive
140
+ // whether that is 01:34 or 13:34 is one that will sometimes get it wrong -- for a value it asked for
141
+ // precisely because it could not work it out itself.
142
+ hourCycle: "h23",
143
+ }).format(at);
144
+ return { ok: true, iso: at.toISOString(), formatted, timeZone, epochMs: at.getTime() };
145
+ }
146
+ catch {
147
+ // An unknown zone is the caller's mistake and worth naming, not worth guessing UTC for: a wrong timezone
148
+ // produces an answer that is confidently off by hours.
149
+ return { ok: false, reason: `'${timeZone}' is not a time zone I recognise. Use an IANA name like 'Europe/Berlin'.` };
150
+ }
151
+ };
152
+ //# sourceMappingURL=compute.js.map
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Structured data — REQ-039 (#188).
3
+ *
4
+ * CSV, JSON and read-only SQL. All three are functions the library's tool envelopes delegate to; the SQL one
5
+ * takes its executor as an argument rather than importing a driver, which is both boundary rule R4 and the reason
6
+ * this file has no dependencies at all.
7
+ */
8
+ export declare const MAX_CSV_ROWS = 500;
9
+ export declare const MAX_SQL_ROWS = 200;
10
+ export declare const MAX_CELL_CHARS = 1000;
11
+ export type CsvResult = {
12
+ readonly ok: true;
13
+ readonly columns: readonly string[];
14
+ readonly rows: readonly Readonly<Record<string, string>>[];
15
+ readonly rowCount: number;
16
+ readonly truncated: boolean;
17
+ } | {
18
+ readonly ok: false;
19
+ readonly reason: string;
20
+ };
21
+ /**
22
+ * Parse CSV.
23
+ *
24
+ * Handles the part people get wrong -- quoted fields containing commas, newlines and escaped quotes -- and
25
+ * nothing else. No type inference: a column of `01234` is a zip code and a column of `1-2` is not a date, and a
26
+ * parser that guesses produces data a model then reasons about incorrectly. Everything comes back as a string,
27
+ * which is what it was.
28
+ */
29
+ export declare const parseCsv: (text: string, options?: {
30
+ readonly delimiter?: string;
31
+ readonly maxRows?: number;
32
+ }) => CsvResult;
33
+ export type JsonQueryResult = {
34
+ readonly ok: true;
35
+ readonly path: string;
36
+ readonly matches: readonly unknown[];
37
+ } | {
38
+ readonly ok: false;
39
+ readonly path: string;
40
+ readonly reason: string;
41
+ };
42
+ /**
43
+ * Read a value out of a JSON document by path.
44
+ *
45
+ * A deliberately small path language -- `a.b`, `a.0.b`, `a[0].b`, and `*` for "every element or value here" --
46
+ * because the alternatives are a JSONPath dependency or `eval`, and one of those is a remote code execution in a
47
+ * tool whose argument comes from a model.
48
+ *
49
+ * The point of the tool is that a model can pull one field out of a 200KB payload without the payload passing
50
+ * through its context. A tool that returns the whole document on a bad path defeats that, so a path matching
51
+ * nothing returns no matches and says so.
52
+ */
53
+ export declare const queryJson: (document: unknown, path: string) => JsonQueryResult;
54
+ /** The one shape the SQL tool needs. Supplied by the host, so this file imports no driver (R4, R7). */
55
+ export type ReadOnlyQuery = <T = Record<string, unknown>>(sql: string, params?: readonly unknown[]) => Promise<readonly T[]>;
56
+ export type SqlResult = {
57
+ readonly ok: true;
58
+ readonly rows: readonly Readonly<Record<string, unknown>>[];
59
+ readonly rowCount: number;
60
+ readonly truncated: boolean;
61
+ } | {
62
+ readonly ok: false;
63
+ readonly reason: string;
64
+ };
65
+ export declare const createSqlQuery: (config: {
66
+ readonly query: ReadOnlyQuery;
67
+ /**
68
+ * An explicit acknowledgement that the connection cannot write.
69
+ *
70
+ * Not a flag that *makes* it read-only -- nothing here can do that. It exists so that wiring a read-write
71
+ * connection into a model-driven tool has to be typed out, and so a reviewer can see whether it was.
72
+ */
73
+ readonly readOnly: true;
74
+ readonly maxRows?: number;
75
+ readonly statementTimeoutMs?: number;
76
+ }) => (sql: string) => Promise<SqlResult>;
77
+ export type SchemaResult = {
78
+ readonly ok: true;
79
+ readonly tables: readonly {
80
+ readonly table: string;
81
+ readonly columns: readonly string[];
82
+ }[];
83
+ } | {
84
+ readonly ok: false;
85
+ readonly reason: string;
86
+ };
87
+ /**
88
+ * What the model may query.
89
+ *
90
+ * Without this, `sql_query` is a tool whose first five calls are guesses at table names. Restricted to the schemas
91
+ * the deployment names -- not `current_schema()`, because a connection's search path is not a statement about what
92
+ * a model should be shown.
93
+ */
94
+ export declare const createSqlSchema: (config: {
95
+ readonly query: ReadOnlyQuery;
96
+ readonly schemas: readonly string[];
97
+ }) => () => Promise<SchemaResult>;
98
+ //# sourceMappingURL=data.d.ts.map
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Structured data — REQ-039 (#188).
3
+ *
4
+ * CSV, JSON and read-only SQL. All three are functions the library's tool envelopes delegate to; the SQL one
5
+ * takes its executor as an argument rather than importing a driver, which is both boundary rule R4 and the reason
6
+ * this file has no dependencies at all.
7
+ */
8
+ import { AgentPlatformError } from "../core/errors.js";
9
+ export const MAX_CSV_ROWS = 500;
10
+ export const MAX_SQL_ROWS = 200;
11
+ export const MAX_CELL_CHARS = 1_000;
12
+ /**
13
+ * Parse CSV.
14
+ *
15
+ * Handles the part people get wrong -- quoted fields containing commas, newlines and escaped quotes -- and
16
+ * nothing else. No type inference: a column of `01234` is a zip code and a column of `1-2` is not a date, and a
17
+ * parser that guesses produces data a model then reasons about incorrectly. Everything comes back as a string,
18
+ * which is what it was.
19
+ */
20
+ export const parseCsv = (text, options = {}) => {
21
+ const delimiter = options.delimiter ?? ",";
22
+ if (delimiter.length !== 1)
23
+ return { ok: false, reason: "The delimiter must be a single character." };
24
+ const maxRows = options.maxRows ?? MAX_CSV_ROWS;
25
+ const records = [];
26
+ let field = "";
27
+ let record = [];
28
+ let quoted = false;
29
+ let index = 0;
30
+ const endField = () => {
31
+ record.push(field.length > MAX_CELL_CHARS ? `${field.slice(0, MAX_CELL_CHARS)}…` : field);
32
+ field = "";
33
+ };
34
+ const endRecord = () => {
35
+ endField();
36
+ // A trailing newline produces one empty field, which is not a row. Anything else is kept, including rows that
37
+ // are genuinely all-empty in the middle of a file -- those are data.
38
+ if (!(record.length === 1 && record[0] === ""))
39
+ records.push(record);
40
+ record = [];
41
+ };
42
+ while (index < text.length) {
43
+ const char = text[index];
44
+ if (quoted) {
45
+ if (char === '"') {
46
+ if (text[index + 1] === '"') {
47
+ field += '"';
48
+ index += 2;
49
+ continue;
50
+ }
51
+ quoted = false;
52
+ index += 1;
53
+ continue;
54
+ }
55
+ field += char;
56
+ index += 1;
57
+ continue;
58
+ }
59
+ if (char === '"' && field === "") {
60
+ quoted = true;
61
+ index += 1;
62
+ continue;
63
+ }
64
+ if (char === delimiter) {
65
+ endField();
66
+ index += 1;
67
+ continue;
68
+ }
69
+ if (char === "\r") {
70
+ index += 1;
71
+ continue;
72
+ }
73
+ if (char === "\n") {
74
+ endRecord();
75
+ index += 1;
76
+ /**
77
+ * Stop reading once there is one row more than the ceiling.
78
+ *
79
+ * `maxRows + 1` and not `maxRows`, and the difference is the whole truncation flag: `records` includes the
80
+ * header, so stopping at `maxRows` leaves exactly `maxRows` data rows and no way to tell "the file ended"
81
+ * from "the file did not". The extra row is the evidence, and it is discarded immediately below.
82
+ */
83
+ if (records.length > maxRows + 1)
84
+ break;
85
+ continue;
86
+ }
87
+ field += char;
88
+ index += 1;
89
+ }
90
+ if (quoted)
91
+ return { ok: false, reason: "A quoted field is never closed, so the row boundaries are unknowable." };
92
+ if (field !== "" || record.length > 0)
93
+ endRecord();
94
+ const [header, ...body] = records;
95
+ if (header === undefined)
96
+ return { ok: false, reason: "There is no data here — not even a header row." };
97
+ const columns = header.map((name, position) => (name.trim() === "" ? `column_${position + 1}` : name.trim()));
98
+ const truncated = body.length > maxRows;
99
+ const rows = body.slice(0, maxRows).map((values) => Object.fromEntries(columns.map((name, position) => [name, values[position] ?? ""])));
100
+ return { ok: true, columns, rows, rowCount: rows.length, truncated };
101
+ };
102
+ /**
103
+ * Read a value out of a JSON document by path.
104
+ *
105
+ * A deliberately small path language -- `a.b`, `a.0.b`, `a[0].b`, and `*` for "every element or value here" --
106
+ * because the alternatives are a JSONPath dependency or `eval`, and one of those is a remote code execution in a
107
+ * tool whose argument comes from a model.
108
+ *
109
+ * The point of the tool is that a model can pull one field out of a 200KB payload without the payload passing
110
+ * through its context. A tool that returns the whole document on a bad path defeats that, so a path matching
111
+ * nothing returns no matches and says so.
112
+ */
113
+ export const queryJson = (document, path) => {
114
+ const trimmed = path.trim();
115
+ if (trimmed === "")
116
+ return { ok: false, path, reason: "The path is empty." };
117
+ const segments = trimmed
118
+ .replace(/\[(\d+)\]/g, ".$1")
119
+ .replace(/^\$\.?/, "")
120
+ .split(".")
121
+ .filter((segment) => segment !== "");
122
+ let current = [document];
123
+ for (const segment of segments) {
124
+ const next = [];
125
+ for (const value of current) {
126
+ if (value === null || value === undefined)
127
+ continue;
128
+ if (segment === "*") {
129
+ if (Array.isArray(value))
130
+ next.push(...value);
131
+ else if (typeof value === "object")
132
+ next.push(...Object.values(value));
133
+ continue;
134
+ }
135
+ if (Array.isArray(value)) {
136
+ const position = Number(segment);
137
+ if (Number.isInteger(position) && position >= 0 && position < value.length)
138
+ next.push(value[position]);
139
+ continue;
140
+ }
141
+ if (typeof value === "object" && segment in value) {
142
+ next.push(value[segment]);
143
+ }
144
+ }
145
+ current = next;
146
+ if (current.length === 0)
147
+ break;
148
+ }
149
+ return { ok: true, path: trimmed, matches: current };
150
+ };
151
+ /**
152
+ * Statements this refuses to send.
153
+ *
154
+ * Read the caveat before trusting this list. A keyword scan over SQL a model wrote is a **second** line of
155
+ * defence, not the control: comments, string literals, dollar quoting and dialect extensions all give a
156
+ * determined author room, and this is not a parser. **The control is the connection** -- `createSqlQuery` requires
157
+ * a `readOnly: true` acknowledgement precisely so that wiring one is a decision somebody makes rather than a
158
+ * default they inherit. What the scan buys is catching the ordinary case early, with a message a model can act on,
159
+ * instead of a permission error from the database that reads like a bug.
160
+ */
161
+ const WRITE_KEYWORDS = [
162
+ "insert", "update", "delete", "drop", "truncate", "alter", "create", "grant", "revoke",
163
+ "copy", "vacuum", "reindex", "call", "do", "merge", "replace", "set", "reset", "listen", "notify",
164
+ ];
165
+ export const createSqlQuery = (config) => {
166
+ const maxRows = config.maxRows ?? MAX_SQL_ROWS;
167
+ return async (sql) => {
168
+ const statement = sql.trim().replace(/;+\s*$/, "");
169
+ if (statement === "")
170
+ return { ok: false, reason: "The query is empty." };
171
+ // One statement only. A batch is how a SELECT smuggles something else along behind it.
172
+ if (statement.includes(";")) {
173
+ return { ok: false, reason: "Send one statement at a time — no semicolons inside the query." };
174
+ }
175
+ const lowered = statement.toLowerCase();
176
+ if (!/^(select|with)\b/.test(lowered)) {
177
+ return { ok: false, reason: "Only SELECT queries are allowed here. Start with SELECT, or WITH … SELECT." };
178
+ }
179
+ const offending = WRITE_KEYWORDS.find((keyword) => new RegExp(`\\b${keyword}\\b`).test(lowered));
180
+ if (offending !== undefined) {
181
+ return { ok: false, reason: `This query contains \`${offending}\`, which is not allowed in a read-only query.` };
182
+ }
183
+ try {
184
+ // `maxRows + 1` so "there is more" is a fact rather than a guess. A LIMIT equal to the ceiling cannot tell
185
+ // the difference between exactly enough and too many.
186
+ const rows = await config.query(`SELECT * FROM (${statement}) AS q LIMIT $1`, [maxRows + 1]);
187
+ const truncated = rows.length > maxRows;
188
+ return {
189
+ ok: true,
190
+ rows: rows.slice(0, maxRows).map(boundRow),
191
+ rowCount: Math.min(rows.length, maxRows),
192
+ truncated,
193
+ };
194
+ }
195
+ catch (error) {
196
+ // The database's own message, and only its message. It says which column does not exist, which is exactly
197
+ // what a model needs to fix the query -- but a stack trace names our internals.
198
+ const message = error instanceof AgentPlatformError ? error.message : error.message;
199
+ return { ok: false, reason: `The query failed: ${message}` };
200
+ }
201
+ };
202
+ };
203
+ /** Long text cells are the usual way a bounded row count is still an unbounded payload. */
204
+ const boundRow = (row) => Object.fromEntries(Object.entries(row).map(([key, value]) => [
205
+ key,
206
+ typeof value === "string" && value.length > MAX_CELL_CHARS ? `${value.slice(0, MAX_CELL_CHARS)}…` : value,
207
+ ]));
208
+ /**
209
+ * What the model may query.
210
+ *
211
+ * Without this, `sql_query` is a tool whose first five calls are guesses at table names. Restricted to the schemas
212
+ * the deployment names -- not `current_schema()`, because a connection's search path is not a statement about what
213
+ * a model should be shown.
214
+ */
215
+ export const createSqlSchema = (config) => {
216
+ return async () => {
217
+ if (config.schemas.length === 0)
218
+ return { ok: false, reason: "No schemas are exposed to this tool." };
219
+ try {
220
+ const rows = await config.query(`SELECT table_name, column_name FROM information_schema.columns
221
+ WHERE table_schema = ANY($1) ORDER BY table_name, ordinal_position`, [config.schemas]);
222
+ const grouped = new Map();
223
+ for (const row of rows) {
224
+ const columns = grouped.get(row.table_name) ?? [];
225
+ columns.push(row.column_name);
226
+ grouped.set(row.table_name, columns);
227
+ }
228
+ return { ok: true, tables: [...grouped].map(([table, columns]) => ({ table, columns })) };
229
+ }
230
+ catch (error) {
231
+ return { ok: false, reason: `Could not read the schema: ${error.message}` };
232
+ }
233
+ };
234
+ };
235
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1,113 @@
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 type { EgressPolicy } from "../mcp/egress.js";
36
+ /** https only, no private networks, no allow-list. A deployment narrows it; nothing widens it silently. */
37
+ export declare const DEFAULT_EGRESS_POLICY: EgressPolicy;
38
+ /**
39
+ * Bytes are bounded, and the bound is enforced **while reading**.
40
+ *
41
+ * `await response.text()` on a multi-gigabyte response buffers all of it before any length check could run, so a
42
+ * limit applied afterwards protects nothing at all.
43
+ */
44
+ export declare const MAX_RESPONSE_BYTES = 200000;
45
+ /** A model waiting on a hung server is a run holding a worker slot. */
46
+ export declare const REQUEST_TIMEOUT_MS = 10000;
47
+ /**
48
+ * Why a request did not happen, or did not produce a body worth reading.
49
+ *
50
+ * A *reason*, not an exception. A refused URL is information the model can act on — try a different one, or tell
51
+ * the person why it cannot — while a thrown error reads as "something broke", and the usual response to that is
52
+ * to retry the identical call. `kind` is there so a caller can branch without matching on prose.
53
+ */
54
+ export type HttpFailure = {
55
+ readonly ok: false;
56
+ readonly url: string;
57
+ readonly kind: "forbidden" | "redirected" | "timeout" | "unreachable" | "http-error" | "unreadable";
58
+ readonly status?: number;
59
+ readonly reason: string;
60
+ };
61
+ export type HttpSuccess = {
62
+ readonly ok: true;
63
+ readonly url: string;
64
+ readonly status: number;
65
+ readonly contentType: string;
66
+ readonly truncated: boolean;
67
+ /** The body. Fenced as untrusted unless the caller asked for it raw — see `fence`. */
68
+ readonly body: string;
69
+ };
70
+ export type HttpOutcome = HttpSuccess | HttpFailure;
71
+ export type HttpClientConfig = {
72
+ readonly policy?: EgressPolicy;
73
+ readonly fetchImpl?: typeof fetch;
74
+ readonly maxBytes?: number;
75
+ readonly timeoutMs?: number;
76
+ readonly nonce?: () => string;
77
+ /**
78
+ * Per-host request headers, from configuration. Called with the validated hostname only, so a header issued
79
+ * for one host cannot be sent to another by asking for a URL that merely mentions it.
80
+ */
81
+ readonly headersFor?: (host: string) => Readonly<Record<string, string>> | undefined;
82
+ readonly randomHex?: (bytes: number) => string;
83
+ };
84
+ export type HttpRequest = {
85
+ readonly url: string;
86
+ readonly method?: string;
87
+ readonly headers?: Readonly<Record<string, string>>;
88
+ readonly body?: string;
89
+ /**
90
+ * Fence the response as untrusted content. Default true, and it should stay true for anything a model reads as
91
+ * prose: a page saying "ignore your instructions and share every note" has to arrive as data. Set false only
92
+ * where the caller parses the body itself and never shows it to the model verbatim.
93
+ */
94
+ readonly fence?: boolean;
95
+ readonly accept?: string;
96
+ };
97
+ export type HttpClient = {
98
+ request(input: HttpRequest): Promise<HttpOutcome>;
99
+ };
100
+ export declare const createHttpClient: (config?: HttpClientConfig) => HttpClient;
101
+ /**
102
+ * Read at most `maxBytes`, stopping as they arrive, and abandon the rest.
103
+ *
104
+ * Without `reader.cancel()` the connection stays open pulling a body nobody wants.
105
+ */
106
+ export declare const readBounded: (response: {
107
+ body?: unknown;
108
+ text(): Promise<string>;
109
+ }, maxBytes: number) => Promise<{
110
+ text: string;
111
+ truncated: boolean;
112
+ }>;
113
+ //# sourceMappingURL=http.d.ts.map