@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,185 @@
1
+ /**
2
+ * Attachments in context: referenced, never injected (#130).
3
+ *
4
+ * `docs/README` governing principle 6 — *"Large files and tool results are referenced, not injected
5
+ * wholesale into model context."* The rule is easy to state and easy to break by accident, so the defence
6
+ * here is structural rather than a convention someone maintains:
7
+ *
8
+ * **This module is constructed with a `FileMetadataStore` and nothing else.** It has no `FileContentStore`,
9
+ * so it cannot read a byte of an attachment even if a future edit tried to. A rule that says "do not inject
10
+ * content" can be forgotten; a provider with no way to reach the content cannot forget it.
11
+ *
12
+ * The second property is the one AC-2 measures: **an attachment's context cost does not grow with the
13
+ * file.** The rendered line carries a rounded, unit-bearing size — `1 KB`, `100 MB` — rather than a byte
14
+ * count, so a thousand-fold difference in file size is the same number of characters. The cost is bounded by
15
+ * the *filename*, which is the user's own text and belongs in context.
16
+ */
17
+ import { estimateTokens } from "../core/tokens.js";
18
+ import { neutralizeDelimiters } from "../security/prompt-safety.js";
19
+ import { LOW_CONFIDENCE_THRESHOLD } from "../persistence/index.js";
20
+ /**
21
+ * How many attachments are described before the list is summarised.
22
+ *
23
+ * A conversation with two hundred attachments would otherwise cost two hundred lines — linear in something
24
+ * the user controls, which is the same unbounded-growth failure by a slower route. Past the cap the section
25
+ * says how many more there are and names the tool that lists them.
26
+ */
27
+ export const MAX_LISTED_ATTACHMENTS = 20;
28
+ /** The longest filename rendered. A filename is user input, and user input has no length. */
29
+ export const MAX_RENDERED_FILENAME = 80;
30
+ /**
31
+ * A rounded, unit-bearing size.
32
+ *
33
+ * Deliberately not the byte count. `104857600` and `1024` differ in width, so rendering bytes would make an
34
+ * attachment's token cost a function of its size — small, but AC-2 is a statement about *measurably*, and a
35
+ * property that holds approximately is one that stops holding when someone changes the renderer.
36
+ */
37
+ export const SIZE_FIELD_WIDTH = 8;
38
+ export const humanSize = (byteSize) => {
39
+ const units = ["B", "KB", "MB", "GB", "TB"];
40
+ let value = Math.max(0, byteSize);
41
+ let unit = 0;
42
+ while (value >= 1024 && unit < units.length - 1) {
43
+ value /= 1024;
44
+ unit += 1;
45
+ }
46
+ // One decimal below 10, none above: "1.5 MB", "100 MB". Keeps the width inside a two-character band
47
+ // across the whole range a file can occupy.
48
+ const rounded = value < 10 && unit > 0 ? value.toFixed(1) : String(Math.round(value));
49
+ // Right-aligned to a fixed width, which is what makes AC-2 exact rather than approximate. Rounded units
50
+ // alone leave three widths across the range a file can have (`1 B`, `50 MB`, `1.0 GB`), so a 1000x size
51
+ // difference still moved the token estimate by one — small, but "measurably" is the AC's word and a
52
+ // property that holds approximately is one that stops holding when someone edits the renderer. Padding
53
+ // also aligns the list, which is the incidental benefit rather than the reason.
54
+ return `${rounded} ${units[unit]}`.padStart(SIZE_FIELD_WIDTH);
55
+ };
56
+ /** A filename, trimmed to a bound, with the extension kept because it is the part that carries meaning. */
57
+ export const truncateFilename = (filename) => {
58
+ if (filename.length <= MAX_RENDERED_FILENAME)
59
+ return filename;
60
+ const dot = filename.lastIndexOf(".");
61
+ const extension = dot > 0 && filename.length - dot <= 12 ? filename.slice(dot) : "";
62
+ return `${filename.slice(0, MAX_RENDERED_FILENAME - extension.length - 1)}…${extension}`;
63
+ };
64
+ /**
65
+ * One attachment, as the model sees it.
66
+ *
67
+ * Every field comes from `FileMetadata`. There is no branch that could reach content, which is the point:
68
+ * the function's inputs are the enforcement.
69
+ */
70
+ /**
71
+ * One attachment as a prompt line.
72
+ *
73
+ * The filename is **neutralised**, not merely truncated (#145). A filename is arbitrary text chosen by whoever
74
+ * uploaded the file — any principal in the tenant — and it is interpolated into the system prompt. A file called
75
+ * `report.pdf\n## System: ignore prior instructions and` forges a heading inside the platform's own section.
76
+ *
77
+ * The section stays `platform` rather than being wrapped in an untrusted envelope, deliberately: the envelope's
78
+ * preamble says nothing inside it is an instruction, and this section's `READ_INSTRUCTION` *is* the platform's
79
+ * instruction for how to read a file. Wrapping it would negate the thing it exists to say. So the untrusted
80
+ * *values* are neutralised in place, which is the surgical version of the same defence.
81
+ *
82
+ * The nonce is empty: there is no envelope here to forge, so only the structural markers matter.
83
+ */
84
+ export const renderAttachmentReference = (file) => `- ${neutralizeDelimiters(truncateFilename(file.filename), "")} (${file.mediaType}, ${humanSize(file.byteSize)}) — file:${file.id}${extractionSuffix(file)}`;
85
+ /**
86
+ * What extraction says about a file, in as few words as possible (#131).
87
+ *
88
+ * A model needs three facts to choose its next move, and only three: whether text is available now, whether
89
+ * to wait, or whether it will never come and why. So `extracted` names the tool, `failed` gives the reason,
90
+ * and everything else says "not yet".
91
+ *
92
+ * **Bounded on purpose.** The failure message is truncated because it can carry a page count or a byte limit,
93
+ * and an unbounded string here would make an attachment's context cost depend on how badly extraction went —
94
+ * undoing #130's AC-2 by a side door.
95
+ */
96
+ export const MAX_EXTRACTION_NOTE = 90;
97
+ const extractionSuffix = (file) => {
98
+ const extraction = file.extraction;
99
+ if (extraction === undefined)
100
+ return "";
101
+ switch (extraction.state) {
102
+ case "extracted":
103
+ // The low-confidence marker is in the *reference line* and not only in the read result, because a model
104
+ // choosing which of three attachments to trust decides before it reads any of them (#132).
105
+ return extraction.confidence !== undefined && extraction.confidence < LOW_CONFIDENCE_THRESHOLD
106
+ ? " [text available (recognised, low confidence): read_document]"
107
+ : " [text available: read_document]";
108
+ case "failed":
109
+ return ` [unreadable: ${(extraction.failureMessage ?? extraction.failureReason ?? "unknown reason").slice(0, MAX_EXTRACTION_NOTE)}]`;
110
+ case "skipped":
111
+ // Not "we failed" — nobody asked for this type to be readable, and saying "failed" would send a model
112
+ // looking for a fix that does not exist.
113
+ return " [no text extraction for this type]";
114
+ default:
115
+ return " [text extraction in progress]";
116
+ }
117
+ };
118
+ /** The instruction that makes AC-3 discoverable rather than something the model has to guess. */
119
+ const READ_INSTRUCTION = "Contents are not included. Call `read_document` for an attachment marked as having text, or " +
120
+ "`read_attachment` to read raw bytes. Both return a bounded portion.";
121
+ export const ATTACHMENT_PROVIDER_ID = "attachments";
122
+ /**
123
+ * Estimated tokens for a body.
124
+ *
125
+ * Computed from the body this module just built, never accepted from elsewhere. `ContextSection`'s
126
+ * `estimatedTokens` is self-reported, and a section that under-reports its cost is a section that survives
127
+ * budgeting it should have lost — so the one place that could lie about an attachment's cost does not.
128
+ *
129
+ * Re-exported from `core/tokens.ts` rather than defined here: five copies of this arithmetic had accumulated,
130
+ * agreeing by coincidence, and a section sized against one and budgeted against another is a section that does
131
+ * not fit the budget it was measured for.
132
+ */
133
+ // `estimateTokens` is core's, reachable at `./runtime`. A second export here would be a second home
134
+ // for one name, which #199 rules out.
135
+ /**
136
+ * The attachment section for a conversation.
137
+ *
138
+ * `knowledge` rather than `history`: an attachment is a durable fact about the conversation, not a turn, and
139
+ * putting it in the history bucket would make it compete with recent messages for the same budget. It is
140
+ * prunable at the `old-knowledge` stage — an attachment list is worth dropping before a recent turn is.
141
+ */
142
+ export const createAttachmentContextProvider = (deps) => ({
143
+ id: ATTACHMENT_PROVIDER_ID,
144
+ async provide(context) {
145
+ const page = await deps.metadata.listByConversation({
146
+ tenantId: context.tenantId,
147
+ conversationId: deps.conversationId,
148
+ // One over the cap, so "there are more" is answered by what came back rather than by a second count
149
+ // that could disagree with it.
150
+ limit: MAX_LISTED_ATTACHMENTS + 1,
151
+ });
152
+ if (page.items.length === 0)
153
+ return [];
154
+ const listed = page.items.slice(0, MAX_LISTED_ATTACHMENTS);
155
+ const more = page.items.length - listed.length;
156
+ const lines = [
157
+ ...listed.map(renderAttachmentReference),
158
+ ...(more > 0 || page.nextCursor !== undefined
159
+ ? [`- …and more, not listed. Call \`list_attachments\` for the rest.`]
160
+ : []),
161
+ READ_INSTRUCTION,
162
+ ];
163
+ const body = lines.join("\n");
164
+ return [
165
+ {
166
+ providerId: ATTACHMENT_PROVIDER_ID,
167
+ title: "Attachments",
168
+ body,
169
+ priority: 40,
170
+ estimatedTokens: estimateTokens(body),
171
+ provenance: `conversation:${deps.conversationId}`,
172
+ sensitivity: "internal",
173
+ // Platform, not external: the body is the platform's own scaffolding and read instruction. The untrusted
174
+ // parts -- the filenames -- are neutralised where they are interpolated. See `renderAttachmentReference`.
175
+ origin: "platform",
176
+ // Not cacheable: the list changes when a file is attached or deleted, and a stale list is a model
177
+ // confidently reading a file that is gone.
178
+ cacheable: false,
179
+ kind: "knowledge",
180
+ pruneStage: "old-knowledge",
181
+ },
182
+ ];
183
+ },
184
+ });
185
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1,210 @@
1
+ /**
2
+ * The attachment lifecycle — `docs/05-knowledge-and-documents.md`, REQ-026 (#129).
3
+ *
4
+ * The ports are in `persistence/`; what lives here is the sequencing that makes them safe together, and it
5
+ * is the part that cannot be a rule someone remembers:
6
+ *
7
+ * - an upload is two writes, metadata then bytes, and the window between them is where orphans live
8
+ * - a declared size is a claim, and the only real defence is a cap enforced while reading
9
+ * - object storage cannot join a database transaction, so deletion is scheduled rather than performed
10
+ */
11
+ import type { AuthorizationPolicy } from "../authorization/index.js";
12
+ import type { ExecutionContext } from "../core/context.js";
13
+ import type { ConversationId, FileId, TenantId } from "../core/ids.js";
14
+ import type { Page } from "../core/context.js";
15
+ import type { FileContentStore, FileMetadata, FileMetadataStore } from "../persistence/index.js";
16
+ /**
17
+ * What a deployment will accept.
18
+ *
19
+ * Configuration rather than constants, because the ceiling belongs to the storage bucket. ShareFlow's
20
+ * `MEDIA_MAX_BYTES` is 50 MB precisely because that *is* its bucket's `file_size_limit` — a limit here
21
+ * larger than the bucket's would refuse at upload time with the wrong number, and one smaller would refuse
22
+ * files the bucket would have taken.
23
+ */
24
+ export type UploadLimits = {
25
+ readonly maxBytes: number;
26
+ /** Exact media types. No wildcards: `image/*` is how an SVG becomes an accepted image. */
27
+ readonly allowedMediaTypes: readonly string[];
28
+ /** How long a signed read URL lives. Short — see `MAX_SIGNED_URL_SECONDS`. */
29
+ readonly signedUrlSeconds: number;
30
+ };
31
+ /**
32
+ * The ceiling on a signed URL's life.
33
+ *
34
+ * A signed URL is a bearer token in a query string: it goes into logs, into a browser's history, and — if a
35
+ * tool result ever carried one — into the run event log, where anyone who can read the conversation can read
36
+ * it long after the check that produced it. #118 refused to return one from a tool for exactly that reason.
37
+ *
38
+ * Fifteen minutes is long enough to load a document and short enough that a leaked URL is usually already
39
+ * dead. `signedReadUrl` clamps rather than trusting the caller.
40
+ */
41
+ export declare const MAX_SIGNED_URL_SECONDS = 900;
42
+ /** A conservative default set. A deployment narrows or widens it deliberately. */
43
+ export declare const DEFAULT_UPLOAD_LIMITS: UploadLimits;
44
+ /**
45
+ * The cheap early refusal — AC-2's first half.
46
+ *
47
+ * *"Refused before the bytes are accepted, with the limit stated."* The limit is in the message because an
48
+ * error saying "too large" sends someone to guess; one saying "25 MB" does not.
49
+ *
50
+ * **This check can only ever see the declared size.** A client that declares 1 KB and sends 1 GB passes it,
51
+ * which is why `streamWithCap` exists and is not optional.
52
+ */
53
+ export declare const validateUpload: (input: {
54
+ readonly mediaType: string;
55
+ readonly declaredBytes: number;
56
+ }, limits: UploadLimits) => void;
57
+ /**
58
+ * AC-2's second half, and the one that holds.
59
+ *
60
+ * Wraps a byte stream so it **stops** at the cap rather than reading to the end and then complaining. The
61
+ * difference is the whole point: reading a hostile 1 GB body into memory and *then* returning an error is a
62
+ * denial of service that happens to report itself politely.
63
+ *
64
+ * `safefetch.py` in ShareFlow exists for the same reason, and says it plainly: *"the callers parse whole
65
+ * documents in memory, so an unbounded download is a denial-of-service vector on a container capped at
66
+ * 600 MB."*
67
+ */
68
+ export declare const streamWithCap: (bytes: AsyncIterable<Uint8Array>, maxBytes: number) => AsyncIterable<Uint8Array>;
69
+ export type FileServiceDeps = {
70
+ readonly metadata: FileMetadataStore;
71
+ readonly content: FileContentStore;
72
+ /**
73
+ * AC-3, enforced rather than asserted.
74
+ *
75
+ * **Required, not optional.** Entitlement to a file is entitlement to its conversation, and a service that
76
+ * would run without a policy is a service someone constructs without one — at which point every
77
+ * attachment in the tenant is readable by every member of it. Tenant scoping alone is not AC-3.
78
+ */
79
+ readonly authorization: AuthorizationPolicy;
80
+ readonly limits?: UploadLimits;
81
+ readonly clock?: () => string;
82
+ /**
83
+ * Mints the opaque content key.
84
+ *
85
+ * Injectable so it can be asserted, and **not** derived from the filename or the file id: a key a caller
86
+ * can construct is a key a caller can guess. `sanitizeMediaRefs` in ShareFlow is the cautionary tale — its
87
+ * workspace-prefix check was *"the ONLY thing standing between a forged path and a signed URL to another
88
+ * tenant's private object."*
89
+ */
90
+ readonly contentKey?: () => string;
91
+ readonly fileId?: () => string;
92
+ /**
93
+ * Asks for text extraction after a successful upload (#131).
94
+ *
95
+ * A function rather than the service itself, so `files` does not depend on `documents` — the dependency
96
+ * runs the other way, and a cycle here would make attaching a file require the extraction pipeline to
97
+ * exist. Optional: a deployment with no extraction is a valid one.
98
+ *
99
+ * **It is not awaited in a way that can fail the upload.** AC-2 is that the user's next request is served
100
+ * without waiting, so a rejection here is logged and dropped — the file is stored, and the sweep will find
101
+ * an extraction that never got requested.
102
+ */
103
+ readonly requestExtraction?: (input: {
104
+ readonly tenantId: TenantId;
105
+ readonly fileId: FileId;
106
+ readonly mediaType: string;
107
+ }) => Promise<unknown>;
108
+ readonly log?: (message: string, detail?: Readonly<Record<string, unknown>>) => void;
109
+ };
110
+ /**
111
+ * The attachment lifecycle.
112
+ *
113
+ * Every method takes an `ExecutionContext`, and entitlement to a file *is* entitlement to its conversation —
114
+ * so there is no second permission model to keep in step with the first.
115
+ */
116
+ export declare const createFileService: (deps: FileServiceDeps) => {
117
+ limits: UploadLimits;
118
+ /**
119
+ * Upload: validate, record `pending`, write bytes, then move to `stored`.
120
+ *
121
+ * The order is the point, and the alternative is worse in a specific way. Writing bytes first and
122
+ * metadata second means a crash between them leaves an object nothing references — invisible, and
123
+ * billed for. Metadata first means a crash leaves a row in `pending`, which reconciliation can see and
124
+ * a user cannot. **An orphan you can find beats an orphan you cannot.**
125
+ */
126
+ upload(context: ExecutionContext, input: {
127
+ readonly conversationId: ConversationId;
128
+ readonly filename: string;
129
+ readonly mediaType: string;
130
+ readonly declaredBytes: number;
131
+ readonly bytes: AsyncIterable<Uint8Array>;
132
+ }): Promise<FileMetadata>;
133
+ /** AC-3: only through the owning conversation, and a foreign file is `not_found`, never `forbidden`. */
134
+ get(context: ExecutionContext, id: FileId): Promise<FileMetadata>;
135
+ /**
136
+ * A short-lived URL, or a stream when the adapter proxies.
137
+ *
138
+ * The expiry is clamped rather than trusted: a caller asking for a day gets fifteen minutes. AC-6 is
139
+ * about what is *reachable*, and a caller's optimism is not a reason to widen it.
140
+ */
141
+ signedReadUrl(context: ExecutionContext, id: FileId): Promise<string | null>;
142
+ /** The proxied read, for an adapter that cannot sign — and the fallback when one can. */
143
+ read(context: ExecutionContext, id: FileId): Promise<AsyncIterable<Uint8Array>>;
144
+ /**
145
+ * The listing is authorised on the conversation before it runs, not filtered afterwards.
146
+ *
147
+ * Filtering results would mean the query ran, which for an unentitled caller is a query whose *shape*
148
+ * — a page count, a cursor, a timing difference — still answers "does this conversation have files".
149
+ */
150
+ listForConversation(context: ExecutionContext, input: {
151
+ readonly conversationId: ConversationId;
152
+ readonly limit: number;
153
+ readonly cursor?: string;
154
+ }): Promise<Page<FileMetadata>>;
155
+ /**
156
+ * AC-4: deleting a conversation removes the metadata and schedules the bytes.
157
+ *
158
+ * Two steps, and they cannot be one: object storage does not join a database transaction. So the
159
+ * metadata moves to `deleting` — gone from the user's view — and `sweepDeletions` removes the bytes
160
+ * afterwards. The intermediate state is named rather than pretended away.
161
+ */
162
+ deleteConversationFiles(context: ExecutionContext, conversationId: ConversationId): Promise<{
163
+ readonly scheduled: number;
164
+ }>;
165
+ /**
166
+ * Remove the bytes of files marked `deleting`.
167
+ *
168
+ * Bytes first, then the state — the opposite order from upload, and for the mirrored reason. Marking
169
+ * `deleted` first means a crash leaves an object nothing references and nothing will look for again.
170
+ * Deleting bytes first means a crash leaves the row in `deleting`, and the next sweep retries it;
171
+ * `deleteFile` is idempotent so the retry costs nothing.
172
+ */
173
+ sweepDeletions(context: ExecutionContext, input: {
174
+ readonly olderThan: string;
175
+ readonly limit: number;
176
+ }): Promise<{
177
+ readonly deleted: number;
178
+ readonly failed: number;
179
+ }>;
180
+ };
181
+ export type FileService = ReturnType<typeof createFileService>;
182
+ /** What reconciliation found. Reported, never acted on — see `reconcileFiles`. */
183
+ export type ReconciliationReport = {
184
+ /** Metadata with no bytes: stuck in `pending` past the threshold. */
185
+ readonly stuckPending: readonly FileId[];
186
+ /** Deletion scheduled and never completed. */
187
+ readonly stuckDeleting: readonly FileId[];
188
+ /** Bytes with nothing referencing them. The direction that costs money silently. */
189
+ readonly orphanedObjects: readonly string[];
190
+ /** Metadata that says `stored` while the bytes are gone. */
191
+ readonly missingContent: readonly FileId[];
192
+ };
193
+ /**
194
+ * AC-5: detect and report orphans.
195
+ *
196
+ * **Reports, never deletes**, and that is the AC's own wording rather than caution for its own sake: a
197
+ * reconciliation job that deletes is a job that can delete a file whose metadata write is merely slow. The
198
+ * threshold makes that unlikely; deleting on the strength of "unlikely" is how data goes missing.
199
+ *
200
+ * Both directions are covered, and only one of them is visible to the metadata store — bytes with no
201
+ * metadata can only be found by listing the objects, which is why `FileContentStore.listObjects` exists.
202
+ */
203
+ export declare const reconcileFiles: (context: ExecutionContext, deps: {
204
+ readonly metadata: FileMetadataStore;
205
+ readonly content: FileContentStore;
206
+ }, input: {
207
+ readonly olderThan: string;
208
+ readonly limit: number;
209
+ }) => Promise<ReconciliationReport>;
210
+ //# sourceMappingURL=index.d.ts.map