@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,226 @@
1
+ /**
2
+ * Storage and infrastructure ports — `docs/02-core-and-persistence.md`.
3
+ *
4
+ * Small interfaces rather than one database adapter. Every read and write receives
5
+ * `tenantId` explicitly: `findById(id)` is forbidden, `findById({ tenantId, id })` is
6
+ * the shape. Ports never import adapters.
7
+ *
8
+ * Method bodies are intentionally sparse at this stage — each port is filled in as its
9
+ * phase in `docs/08-migration-plan.md` lands, against the shared conformance suite.
10
+ */
11
+ /**
12
+ * The ceiling on session state, defined here rather than in an adapter (#97). It is a domain limit —
13
+ * session state is bounded working memory, not a document store — and every adapter must enforce the
14
+ * same one. It previously lived in `adapters/memory/sessions.ts`, which made two adapters agreeing on
15
+ * it a coincidence rather than a property.
16
+ */
17
+ export const DEFAULT_SESSION_STATE_MAX_BYTES = 64 * 1024;
18
+ /**
19
+ * Rollup granularities (#139).
20
+ *
21
+ * Hour, day, week and month, and nothing finer than an hour. A minute bucket multiplies the row count
22
+ * sixty-fold to answer a question nobody asks.
23
+ *
24
+ * Week and month were added by #175, because they are the periods a *person's* allowance is actually expressed
25
+ * in — "500k tokens a month" is a plan, "500k tokens a day" is not. They cannot be derived by summing days
26
+ * either: a month is 28 to 31 days and a week crosses month boundaries, so a caller summing day buckets has to
27
+ * reimplement calendar arithmetic, and two callers doing it differently is two answers to what a month cost.
28
+ *
29
+ * A week starts **Monday**, in UTC, following ISO 8601 — chosen rather than defaulted, because a Sunday start
30
+ * would split a working week across two buckets and every weekly figure would describe half of one week and half
31
+ * of another.
32
+ */
33
+ export const ROLLUP_PERIODS = ["hour", "day", "week", "month"];
34
+ /**
35
+ * Admin-configured spend limits — #175.
36
+ *
37
+ * `principalId` absent is the **tenant default**; present overrides it for one person. One store rather than
38
+ * two, because "the default" and "an override" are the same kind of fact and resolution is then a single query
39
+ * ordered by specificity rather than two queries and a merge.
40
+ *
41
+ * Every limit is optional and an omitted one is **unbounded**, not zero — matching `QuotaLimits`, and for the
42
+ * reason stated there: a misconfigured quota that blocks everything is an outage, and one that blocks nothing is
43
+ * a bill that the rollups make visible.
44
+ */
45
+ /**
46
+ * A window as one storable string, and back — #181.
47
+ *
48
+ * `usage_limits` keys its unique indexes on this single column, so the two kinds of window have to share one
49
+ * value space. A calendar window is its own period; a rolling one is `rolling:<minutes>`. Both spellings are
50
+ * pinned by the table's CHECK constraint, so a value that would not round-trip cannot be stored in the first
51
+ * place.
52
+ *
53
+ * The codec lives here, beside the type, rather than in each adapter: two adapters spelling a key differently is
54
+ * two stores that cannot read each other's rows, and conformance would pass because each is self-consistent.
55
+ */
56
+ export const windowKey = (window) => window.kind === "calendar" ? window.period : `rolling:${window.minutes}`;
57
+ /**
58
+ * `null` for anything this does not recognise — a row written by a newer version, or by hand.
59
+ *
60
+ * Null rather than a thrown error or a calendar fallback. A fallback would silently enforce the wrong window,
61
+ * which for a spend limit means either refusing people wrongly or charging them wrongly; null makes the caller
62
+ * decide, and every caller here treats it as "no limit I can honour", which fails towards *not* pretending.
63
+ */
64
+ export const parseWindowKey = (key) => {
65
+ if (ROLLUP_PERIODS.includes(key))
66
+ return { kind: "calendar", period: key };
67
+ const match = /^rolling:([1-9][0-9]{0,5})$/.exec(key);
68
+ if (match === null)
69
+ return null;
70
+ return { kind: "rolling", minutes: Number(match[1]) };
71
+ };
72
+ // ---------------------------------------------------------------------------
73
+ // Artifacts (#133) — REQ-028. Substantial assistant output as a named, versioned thing rather than
74
+ // text buried in a thread.
75
+ // ---------------------------------------------------------------------------
76
+ /**
77
+ * What an artifact is.
78
+ *
79
+ * Markdown and structured content first, per `docs/05` → Document writing. Rendered formats — PDF, DOCX — are
80
+ * *exports* of an artifact rather than kinds of one, which is why they are absent here: an artifact exported
81
+ * twice is one artifact, and making PDF a kind would make it two things that drift.
82
+ */
83
+ export const ARTIFACT_KINDS = ["markdown", "html", "json", "csv", "code", "diagram"];
84
+ /**
85
+ * A rendered export of one artifact version (#134).
86
+ *
87
+ * **Not an artifact version.** #133's versions are versions of the *content*; a PDF is a rendering of one.
88
+ * Making a render a new version would bump `latestVersion` for a reason unrelated to the content, and
89
+ * "the newest version" would stop meaning "the newest thing the assistant wrote". The issue's wording said
90
+ * artifact version; this is the deviation, and the reason.
91
+ *
92
+ * Keyed on `(artifactId, version, format)`, which is what makes "re-downloaded without re-rendering" a
93
+ * constraint rather than a cache someone remembers to check.
94
+ */
95
+ export const EXPORT_FORMATS = ["pdf", "markdown"];
96
+ export const EXPORT_STATES = ["pending", "rendering", "rendered", "failed"];
97
+ // ---------------------------------------------------------------------------
98
+ // Files (`docs/05-knowledge-and-documents.md`, REQ-026). Two ports, not one.
99
+ //
100
+ // `BlobStore` below is `put(value) -> ref` / `get(ref) -> value` — JSON, for spilled tool output. It has
101
+ // no content type, no size and no stream, so it cannot hold a file: bytes through a `jsonb` column means
102
+ // base64, which is the "inject rather than reference" failure the platform forbids everywhere else. #102
103
+ // recorded this in the `0011` migration when it declined to make `blobs` a pointer table.
104
+ //
105
+ // So metadata and bytes are separate ports. They also have genuinely different lifecycles: metadata is
106
+ // transactional and soft-deleted, bytes are eventually deleted by a sweep, and the gap between the two is
107
+ // where orphans live.
108
+ // ---------------------------------------------------------------------------
109
+ /**
110
+ * Where a file is in its lifecycle.
111
+ *
112
+ * `pending` exists because an upload is two writes — metadata, then bytes — and the window between them is
113
+ * real. A file stuck in `pending` is metadata with no bytes, which is one of the two orphan directions
114
+ * reconciliation looks for.
115
+ *
116
+ * `deleting` is the same window in reverse: the metadata is gone from the user's view and the bytes are
117
+ * not yet gone from storage. Deleting them in one transaction is not available — object storage does not
118
+ * join a database transaction — so the intermediate state is named rather than pretended away.
119
+ */
120
+ export const FILE_STATES = ["pending", "stored", "deleting", "deleted"];
121
+ /**
122
+ * What a file records about its derived text (#131).
123
+ *
124
+ * Declared here rather than imported from `documents/`: a store port that depended on the extraction pipeline
125
+ * would make the pipeline a prerequisite for storing a file, and `persistence` is the layer nothing above it
126
+ * gets to reach into.
127
+ *
128
+ * Separate from the file's own `state` on purpose. A file is perfectly `stored` while its extraction has
129
+ * `failed`, and conflating the two would make an unreadable document look like a lost upload.
130
+ */
131
+ /**
132
+ * Below this, a recognised extraction is flagged rather than presented as certain (#132).
133
+ *
134
+ * Here rather than in `documents/` because two layers interpret the same field and neither may import the
135
+ * other: `documents/vision.ts` sets the flag, and `files/context.ts` marks the reference line so a model
136
+ * choosing between attachments knows before it reads any of them. A copy in each is a copy that drifts, and
137
+ * the port that declares `confidence` is the right place for the number that gives it meaning.
138
+ *
139
+ * 0.7 because that is roughly where OCR stops being "a few wrong characters" and becomes "wrong words" — and
140
+ * a wrong word is worse than a gap, because the sentence still reads.
141
+ */
142
+ export const LOW_CONFIDENCE_THRESHOLD = 0.7;
143
+ /**
144
+ * Knowledge chunks and the vector index — REQ-029 (#135).
145
+ *
146
+ * Two ports rather than one, because they answer different questions and can be backed by different systems:
147
+ * `KnowledgeStore` owns the *rows* (content, provenance, which embedding produced them) and `VectorIndex` owns
148
+ * the *similarity search*. A deployment on pgvector satisfies both with one table; a deployment on a dedicated
149
+ * vector database satisfies them with two systems, and nothing above this layer changes.
150
+ *
151
+ * **The authorisation subject is on the chunk row.** That is the single most important decision here. The SPEC
152
+ * says filtering happens *inside* the query, and the reason is precise: filtering after retrieval leaks through
153
+ * result counts. Ask for ten chunks, get three back, and you have learned that seven exist that you may not
154
+ * see — and with a few queries, roughly what they are about. So `authSubject` travels with the chunk and every
155
+ * search takes it as a required filter.
156
+ */
157
+ /**
158
+ * The embedding width every adapter stores.
159
+ *
160
+ * On the port, not in an adapter, for the reason `DEFAULT_SESSION_STATE_MAX_BYTES` is (#97): a vector column has
161
+ * one width and a vector index cannot span widths, so "every adapter agrees on the size" must be a property
162
+ * rather than a coincidence. The reference adapter accepted 768 while pgvector refused it, which is exactly the
163
+ * laxness that turns a production write failure into a passing test.
164
+ *
165
+ * 1536 is OpenAI's `text-embedding-3-small` and `-large` at its default reduction, and Cohere's v3 — the sizes
166
+ * a deployment is most likely to have. Changing it is a **migration**, not a re-index, which is why
167
+ * `EmbeddingModelRef` carries `dimensions` and a mismatch is refused rather than queued for re-embedding.
168
+ */
169
+ export const EMBEDDING_DIMENSIONS = 1536;
170
+ export const KNOWLEDGE_SOURCE_TYPES = ["file", "artifact", "message", "external"];
171
+ /**
172
+ * The floor above which a vector hit is worth having (#136).
173
+ *
174
+ * 0.5 is orthogonal — see `VectorSearchHit.score` — so anything at or below it shares nothing with the query.
175
+ * 0.55 is comfortably above that and still admits a weak-but-real match. Without a floor, retrieval always
176
+ * returns *something*, and a model handed the least-bad chunk cites it: this constant is what makes an honest
177
+ * empty result possible at all.
178
+ *
179
+ * Deliberately absolute, unlike the fusion floor which is relative to the best hit. They answer different
180
+ * questions — "is this hit any good" and "is this hit much worse than the best" — and one instrument cannot do
181
+ * both: a relative floor can never reject a result set that is uniformly poor, because something is always the
182
+ * best of it.
183
+ */
184
+ export const SEMANTIC_RELEVANCE_FLOOR = 0.55;
185
+ /**
186
+ * Words a keyword query drops (#136).
187
+ *
188
+ * On the port, like `EMBEDDING_DIMENSIONS`, because both adapters need the same list and a copy in each is a
189
+ * copy that drifts.
190
+ *
191
+ * **Why the query and not the index.** Postgres's `simple` text configuration is chosen deliberately over
192
+ * `english`: `english` stems, and stemming is exactly what destroys `ERR-4021` and `Q3-2026` — the terms
193
+ * keyword retrieval exists to find. But `simple` also keeps stopwords, so `was the site down` matches whichever
194
+ * document says `the` most often. Found by measuring hybrid against semantic-only, where a decoy sharing only
195
+ * `was` and `the` outranked the document that actually answered the question.
196
+ *
197
+ * Stripping them from the *query* keeps identifiers intact in the index while removing the terms that carry no
198
+ * retrieval signal. Small and English-only, which is honest: a deployment in another language needs its own
199
+ * list, and pretending otherwise would be worse than the list being visibly incomplete.
200
+ */
201
+ export const KEYWORD_STOPWORDS = new Set([
202
+ "a", "about", "all", "also", "an", "and", "any", "are", "as", "at", "be", "been", "but", "by", "can",
203
+ "did", "do", "does", "for", "from", "had", "has", "have", "how", "i", "if", "in", "into", "is", "it",
204
+ "its", "just", "me", "my", "no", "not", "of", "on", "or", "our", "out", "over", "so", "some", "than",
205
+ "that", "the", "their", "them", "then", "there", "these", "they", "this", "to", "up", "us", "was",
206
+ "we", "were", "what", "when", "where", "which", "who", "why", "will", "with", "would", "you", "your",
207
+ ]);
208
+ /**
209
+ * A keyword query with its stopwords removed.
210
+ *
211
+ * Returns the empty string when nothing survives, which callers treat as "no query" — a search for `the` is a
212
+ * search for nothing, and returning every document would be the worst possible answer.
213
+ */
214
+ export const stripStopwords = (query) => (query.toLowerCase().match(/[a-z0-9]+(?:-[a-z0-9]+)*/g) ?? [])
215
+ .filter((term) => !KEYWORD_STOPWORDS.has(term))
216
+ .join(" ");
217
+ export const ADAPTER_CAPABILITIES = [
218
+ "transactions",
219
+ "row-level-security",
220
+ "full-text-search",
221
+ "vector-search",
222
+ "realtime",
223
+ "distributed-locking",
224
+ "durable-jobs",
225
+ ];
226
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,106 @@
1
+ /**
2
+ * User-level (principal) memory — `docs/15` (referenced by REQ-006).
3
+ *
4
+ * Durable working memory scoped to a principal within a tenant: it persists across that principal's
5
+ * conversations, and is never visible to another principal or tenant. Memories are *extracted* from
6
+ * model output through a deterministic, validated, deduplicated step — raw model output is never
7
+ * stored directly. A budgeted context provider retrieves only the relevant entries and tags each
8
+ * with its provenance, so the context inspector can attribute which memories influenced a turn, and
9
+ * so it can never crowd out recent turns or session state (it draws from the user-context bucket).
10
+ */
11
+ import { AgentPlatformError } from "../core/errors.js";
12
+ import type { ExecutionContext, Page, PageRequest, TenantScope } from "../core/context.js";
13
+ import type { PrincipalId } from "../core/ids.js";
14
+ import type { ContextProvider } from "../context/index.js";
15
+ export type PrincipalMemoryEntry = {
16
+ readonly id: string;
17
+ readonly tenantId: string;
18
+ readonly principalId: string;
19
+ readonly text: string;
20
+ readonly tags: readonly string[];
21
+ /** Higher wins when retrieval is budget-limited. */
22
+ readonly salience: number;
23
+ readonly version: number;
24
+ readonly createdAt: string;
25
+ readonly updatedAt: string;
26
+ /** Set when the user disables the entry; disabled entries are never retrieved for prompts. */
27
+ readonly disabledAt?: string;
28
+ };
29
+ export type MemoryPatch = {
30
+ readonly text?: string;
31
+ readonly tags?: readonly string[];
32
+ readonly salience?: number;
33
+ /** true disables, false re-enables. */
34
+ readonly disabled?: boolean;
35
+ };
36
+ /**
37
+ * Principal-scoped memory. Every method takes `{ tenantId, principalId }` explicitly, so a query can
38
+ * never reach another principal's or tenant's memory. `delete` is a hard delete — a deleted entry
39
+ * cannot resurface in a later prompt.
40
+ */
41
+ export interface PrincipalMemoryStore {
42
+ put(input: TenantScope & {
43
+ principalId: PrincipalId;
44
+ id?: string;
45
+ text: string;
46
+ tags?: readonly string[];
47
+ salience?: number;
48
+ }): Promise<PrincipalMemoryEntry>;
49
+ get(input: TenantScope & {
50
+ principalId: PrincipalId;
51
+ id: string;
52
+ }): Promise<PrincipalMemoryEntry | null>;
53
+ list(input: TenantScope & {
54
+ principalId: PrincipalId;
55
+ } & PageRequest): Promise<Page<PrincipalMemoryEntry>>;
56
+ update(input: TenantScope & {
57
+ principalId: PrincipalId;
58
+ id: string;
59
+ expectedVersion: number;
60
+ patch: MemoryPatch;
61
+ }): Promise<PrincipalMemoryEntry>;
62
+ delete(input: TenantScope & {
63
+ principalId: PrincipalId;
64
+ id: string;
65
+ }): Promise<void>;
66
+ /** Active (not disabled) entries relevant to `query`, most salient first, capped at `limit`. */
67
+ retrieve(input: TenantScope & {
68
+ principalId: PrincipalId;
69
+ query?: string;
70
+ limit: number;
71
+ }): Promise<readonly PrincipalMemoryEntry[]>;
72
+ }
73
+ export declare const MEMORY_LIMITS: {
74
+ readonly textMaxLength: 1000;
75
+ readonly maxTagsPerEntry: 8;
76
+ };
77
+ export type MemoryCandidate = {
78
+ readonly text: string;
79
+ readonly tags?: readonly string[];
80
+ readonly salience?: number;
81
+ };
82
+ /**
83
+ * The deterministic gate between model output and durable memory: trims, enforces bounds, and dedupes
84
+ * candidates against each other and existing entries by normalized text. Returns the accepted
85
+ * candidates to commit — so raw model output is never stored, only validated, unique memories.
86
+ */
87
+ export declare const validateAndDedupe: (candidates: readonly MemoryCandidate[], existing: readonly PrincipalMemoryEntry[]) => readonly MemoryCandidate[];
88
+ /** Commit extracted candidates, skipping duplicates. Returns the entries actually stored. */
89
+ export declare const commitExtractedMemories: (store: PrincipalMemoryStore, input: TenantScope & {
90
+ principalId: PrincipalId;
91
+ candidates: readonly MemoryCandidate[];
92
+ }) => Promise<readonly PrincipalMemoryEntry[]>;
93
+ /**
94
+ * A budgeted context provider over principal memory. Retrieves only relevant, active entries under
95
+ * `maxEntries`, and emits them as `user-context` sections — so they never crowd out recent turns
96
+ * (history bucket) or session state. Each section's provenance carries the entry id for attribution.
97
+ */
98
+ export declare const createPrincipalMemoryProvider: (config: {
99
+ readonly store: PrincipalMemoryStore;
100
+ readonly maxEntries?: number;
101
+ readonly estimateTokens?: (text: string) => number;
102
+ /** Optional query derived from the turn (e.g. the latest user message) to focus retrieval. */
103
+ readonly queryOf?: (context: ExecutionContext) => string | undefined;
104
+ }) => ContextProvider;
105
+ export declare const memoryConflict: (message: string) => AgentPlatformError;
106
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,89 @@
1
+ /**
2
+ * User-level (principal) memory — `docs/15` (referenced by REQ-006).
3
+ *
4
+ * Durable working memory scoped to a principal within a tenant: it persists across that principal's
5
+ * conversations, and is never visible to another principal or tenant. Memories are *extracted* from
6
+ * model output through a deterministic, validated, deduplicated step — raw model output is never
7
+ * stored directly. A budgeted context provider retrieves only the relevant entries and tags each
8
+ * with its provenance, so the context inspector can attribute which memories influenced a turn, and
9
+ * so it can never crowd out recent turns or session state (it draws from the user-context bucket).
10
+ */
11
+ import { AgentPlatformError } from "../core/errors.js";
12
+ import { estimateTokens } from "../core/tokens.js";
13
+ export const MEMORY_LIMITS = { textMaxLength: 1_000, maxTagsPerEntry: 8 };
14
+ const normalize = (text) => text.trim().toLowerCase().replace(/\s+/g, " ");
15
+ /**
16
+ * The deterministic gate between model output and durable memory: trims, enforces bounds, and dedupes
17
+ * candidates against each other and existing entries by normalized text. Returns the accepted
18
+ * candidates to commit — so raw model output is never stored, only validated, unique memories.
19
+ */
20
+ export const validateAndDedupe = (candidates, existing) => {
21
+ const seen = new Set(existing.map((e) => normalize(e.text)));
22
+ const accepted = [];
23
+ for (const candidate of candidates) {
24
+ const text = candidate.text.trim();
25
+ if (text.length === 0 || text.length > MEMORY_LIMITS.textMaxLength)
26
+ continue;
27
+ const key = normalize(text);
28
+ if (seen.has(key))
29
+ continue; // duplicate of an existing or already-accepted memory
30
+ seen.add(key);
31
+ const tags = (candidate.tags ?? []).slice(0, MEMORY_LIMITS.maxTagsPerEntry);
32
+ accepted.push({ text, tags, ...(candidate.salience === undefined ? {} : { salience: candidate.salience }) });
33
+ }
34
+ return accepted;
35
+ };
36
+ /** Commit extracted candidates, skipping duplicates. Returns the entries actually stored. */
37
+ export const commitExtractedMemories = async (store, input) => {
38
+ const existing = (await store.list({ tenantId: input.tenantId, principalId: input.principalId, limit: 1_000 })).items;
39
+ const accepted = validateAndDedupe(input.candidates, existing);
40
+ const stored = [];
41
+ for (const c of accepted) {
42
+ stored.push(await store.put({
43
+ tenantId: input.tenantId,
44
+ principalId: input.principalId,
45
+ text: c.text,
46
+ ...(c.tags ? { tags: c.tags } : {}),
47
+ ...(c.salience === undefined ? {} : { salience: c.salience }),
48
+ }));
49
+ }
50
+ return stored;
51
+ };
52
+ /**
53
+ * A budgeted context provider over principal memory. Retrieves only relevant, active entries under
54
+ * `maxEntries`, and emits them as `user-context` sections — so they never crowd out recent turns
55
+ * (history bucket) or session state. Each section's provenance carries the entry id for attribution.
56
+ */
57
+ export const createPrincipalMemoryProvider = (config) => {
58
+ const maxEntries = config.maxEntries ?? 8;
59
+ const estimate = config.estimateTokens ?? estimateTokens;
60
+ return {
61
+ id: "principal-memory",
62
+ async provide(context) {
63
+ const entries = await config.store.retrieve({
64
+ tenantId: context.tenantId,
65
+ principalId: context.principalId,
66
+ ...(config.queryOf?.(context) ? { query: config.queryOf(context) } : {}),
67
+ limit: maxEntries,
68
+ });
69
+ return entries.map((e) => ({
70
+ providerId: "principal-memory",
71
+ title: `Memory: ${e.tags.join(", ") || e.id}`,
72
+ body: e.text,
73
+ priority: e.salience,
74
+ estimatedTokens: estimate(e.text),
75
+ provenance: `principal-memory:${e.id}`, // lets the context inspector attribute the turn
76
+ sensitivity: "confidential",
77
+ // The principal's own remembered context, written from their own turns. Treating it as untrusted would
78
+ // wrap a user's own stated preferences in "nothing here is an instruction", which is the opposite of what
79
+ // this provider is for. Third-party content never reaches this store -- see docs/17.
80
+ origin: "platform",
81
+ cacheable: false,
82
+ kind: "user-context",
83
+ pruneStage: "old-knowledge",
84
+ }));
85
+ },
86
+ };
87
+ };
88
+ export const memoryConflict = (message) => new AgentPlatformError({ code: "conflict", message, retryable: false });
89
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Data retention — REQ-034 (#151).
3
+ *
4
+ * The first retention mechanism in the platform, scoped deliberately to `run_events` alone. That table takes one
5
+ * row per streamed part, so a single long assistant turn writes hundreds and it grows faster than every other
6
+ * table combined. It is append-only by design and nothing has ever deleted from it, so storage and index size
7
+ * grow monotonically with usage and never come back.
8
+ *
9
+ * **Why this is not a method on `RunEventLog`.** The port is append-only *on purpose* — a run's event log is the
10
+ * record crash recovery reconciles against, and a `delete` on the port would put deletion within reach of
11
+ * ordinary run code. A separate maintenance surface makes that impossible by construction rather than by
12
+ * convention, and AC-8 asserts the port is unchanged.
13
+ *
14
+ * Doing one table properly establishes the pattern the rest reuse. Two things here are the pattern rather than
15
+ * this table's specifics: retention is **configuration with a documented default**, and a sweep is **bounded and
16
+ * reports what it removed** so a caller drains a backlog instead of holding one long lock.
17
+ */
18
+ /**
19
+ * How long a run's events are kept.
20
+ *
21
+ * **Provisional, and marked as such.** #151 asks the product owner which it should be — 30 days, 90 days, or
22
+ * indefinite-until-configured — and that is a compliance answer, not a technical one. 90 days is the level the
23
+ * table's own purpose implies: long enough that a customer investigating last quarter's run still has its log,
24
+ * short enough that the largest table in the schema does not grow without bound. Nobody has agreed to it.
25
+ *
26
+ * A deployment overrides it. The default exists so an unconfigured deployment prunes *something* rather than
27
+ * nothing — the failure direction being "an old log was removed" rather than "the disk filled".
28
+ */
29
+ export declare const DEFAULT_RUN_EVENT_RETENTION_DAYS = 90;
30
+ /**
31
+ * The statuses whose events may be pruned.
32
+ *
33
+ * Terminal only, and this is the safety property AC-2 names. A `running`, `queued`, `waiting-for-*` or
34
+ * `retry-pending` run can still be reconciled against its log — that is precisely what #93/#94 exist to provide
35
+ * — so deleting its events breaks crash recovery for a run that is still alive. Age is irrelevant to that: a
36
+ * run waiting on a human approval for four months is old *and* still needs its log.
37
+ *
38
+ * Written here rather than inlined in SQL so the list has one home, and so a new non-terminal status cannot
39
+ * silently become prunable by not being mentioned.
40
+ */
41
+ export declare const PRUNABLE_RUN_STATUSES: readonly string[];
42
+ export type PruneRequest = {
43
+ /** Delete events created strictly before this instant. ISO-8601. */
44
+ readonly olderThan: string;
45
+ /**
46
+ * Rows per call. Bounded, because an unbounded `DELETE` over this table takes a long-lived lock and blocks the
47
+ * live appends that are the reason the table exists.
48
+ */
49
+ readonly limit: number;
50
+ };
51
+ export type PruneResult = {
52
+ /**
53
+ * Rows actually removed.
54
+ *
55
+ * The caller's loop condition. Returning it rather than a boolean is what lets `drain` know whether a full
56
+ * batch means "more to do" — and it is the number an operator needs to see that retention is running at all.
57
+ */
58
+ readonly deleted: number;
59
+ };
60
+ /**
61
+ * The maintenance surface. Narrow on purpose: one operation, and nothing that reads or writes a run.
62
+ */
63
+ export interface RunEventPruner {
64
+ prune(input: PruneRequest): Promise<PruneResult>;
65
+ }
66
+ /** The cutoff for a retention period, from a clock. Exported so a caller does not recompute the arithmetic. */
67
+ export declare const cutoffFor: (input: {
68
+ readonly now: number;
69
+ readonly retentionDays: number;
70
+ }) => string;
71
+ /**
72
+ * Drain a backlog by calling `prune` until it stops removing rows.
73
+ *
74
+ * A helper rather than a loop inside `prune`, because the two have different failure modes: one long call that
75
+ * dies halfway leaves an operator with no idea how far it got, whereas a loop over bounded calls has made
76
+ * durable progress after every iteration.
77
+ *
78
+ * `maxBatches` is a required ceiling, not an optional one. A loop whose termination depends on the database
79
+ * eventually returning zero is a loop that runs forever the day a bug makes `prune` return a positive count
80
+ * without deleting anything — and it would run forever *inside a maintenance job*, where nobody is watching.
81
+ */
82
+ export declare const drain: (pruner: RunEventPruner, input: PruneRequest & {
83
+ readonly maxBatches: number;
84
+ }) => Promise<{
85
+ readonly deleted: number;
86
+ readonly batches: number;
87
+ readonly drained: boolean;
88
+ }>;
89
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Data retention — REQ-034 (#151).
3
+ *
4
+ * The first retention mechanism in the platform, scoped deliberately to `run_events` alone. That table takes one
5
+ * row per streamed part, so a single long assistant turn writes hundreds and it grows faster than every other
6
+ * table combined. It is append-only by design and nothing has ever deleted from it, so storage and index size
7
+ * grow monotonically with usage and never come back.
8
+ *
9
+ * **Why this is not a method on `RunEventLog`.** The port is append-only *on purpose* — a run's event log is the
10
+ * record crash recovery reconciles against, and a `delete` on the port would put deletion within reach of
11
+ * ordinary run code. A separate maintenance surface makes that impossible by construction rather than by
12
+ * convention, and AC-8 asserts the port is unchanged.
13
+ *
14
+ * Doing one table properly establishes the pattern the rest reuse. Two things here are the pattern rather than
15
+ * this table's specifics: retention is **configuration with a documented default**, and a sweep is **bounded and
16
+ * reports what it removed** so a caller drains a backlog instead of holding one long lock.
17
+ */
18
+ /**
19
+ * How long a run's events are kept.
20
+ *
21
+ * **Provisional, and marked as such.** #151 asks the product owner which it should be — 30 days, 90 days, or
22
+ * indefinite-until-configured — and that is a compliance answer, not a technical one. 90 days is the level the
23
+ * table's own purpose implies: long enough that a customer investigating last quarter's run still has its log,
24
+ * short enough that the largest table in the schema does not grow without bound. Nobody has agreed to it.
25
+ *
26
+ * A deployment overrides it. The default exists so an unconfigured deployment prunes *something* rather than
27
+ * nothing — the failure direction being "an old log was removed" rather than "the disk filled".
28
+ */
29
+ export const DEFAULT_RUN_EVENT_RETENTION_DAYS = 90;
30
+ /**
31
+ * The statuses whose events may be pruned.
32
+ *
33
+ * Terminal only, and this is the safety property AC-2 names. A `running`, `queued`, `waiting-for-*` or
34
+ * `retry-pending` run can still be reconciled against its log — that is precisely what #93/#94 exist to provide
35
+ * — so deleting its events breaks crash recovery for a run that is still alive. Age is irrelevant to that: a
36
+ * run waiting on a human approval for four months is old *and* still needs its log.
37
+ *
38
+ * Written here rather than inlined in SQL so the list has one home, and so a new non-terminal status cannot
39
+ * silently become prunable by not being mentioned.
40
+ */
41
+ export const PRUNABLE_RUN_STATUSES = ["completed", "failed", "cancelled"];
42
+ /** The cutoff for a retention period, from a clock. Exported so a caller does not recompute the arithmetic. */
43
+ export const cutoffFor = (input) => new Date(input.now - input.retentionDays * 86_400_000).toISOString();
44
+ /**
45
+ * Drain a backlog by calling `prune` until it stops removing rows.
46
+ *
47
+ * A helper rather than a loop inside `prune`, because the two have different failure modes: one long call that
48
+ * dies halfway leaves an operator with no idea how far it got, whereas a loop over bounded calls has made
49
+ * durable progress after every iteration.
50
+ *
51
+ * `maxBatches` is a required ceiling, not an optional one. A loop whose termination depends on the database
52
+ * eventually returning zero is a loop that runs forever the day a bug makes `prune` return a positive count
53
+ * without deleting anything — and it would run forever *inside a maintenance job*, where nobody is watching.
54
+ */
55
+ export const drain = async (pruner, input) => {
56
+ let deleted = 0;
57
+ let batches = 0;
58
+ for (; batches < input.maxBatches; batches += 1) {
59
+ const result = await pruner.prune({ olderThan: input.olderThan, limit: input.limit });
60
+ deleted += result.deleted;
61
+ // A short batch means the backlog is exhausted. Checking the count rather than issuing one more empty call
62
+ // saves a full index scan per drain, which on this table is not free.
63
+ if (result.deleted < input.limit)
64
+ return { deleted, batches: batches + 1, drained: true };
65
+ }
66
+ // `drained: false` says the ceiling was hit, so a caller can log that there is more to do rather than assuming
67
+ // the table is clean. Silence here would look identical to a finished sweep.
68
+ return { deleted, batches, drained: false };
69
+ };
70
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Run checkpoints — `docs/04-durable-runtime-and-hitl.md` → Durable execution.
3
+ *
4
+ * A checkpoint is the durable snapshot the worker writes as a run streams. It is what lets a page
5
+ * refresh lose no output and a crashed worker recover: a new claim reloads the latest checkpoint,
6
+ * finalizes any tool calls that were mid-flight, and continues from there.
7
+ */
8
+ import type { MessagePart } from "../core/content-parts.js";
9
+ import type { RunId, ToolCallId } from "../core/ids.js";
10
+ /** A tool call the runtime started but has not yet seen complete — reconciled on recovery. */
11
+ export type PendingToolCall = {
12
+ readonly toolCallId: ToolCallId;
13
+ readonly toolName: string;
14
+ readonly startedAt: string;
15
+ };
16
+ /** Running token/cost totals, checkpointed so a recovered run keeps accounting continuity. */
17
+ export type RunUsageTotals = {
18
+ readonly inputTokens: number;
19
+ readonly outputTokens: number;
20
+ readonly costMinorUnits: number;
21
+ };
22
+ export declare const EMPTY_USAGE_TOTALS: RunUsageTotals;
23
+ export type RunCheckpoint = {
24
+ readonly runId: RunId;
25
+ /** Highest event sequence durably persisted. A reconnecting client resumes with `after: sequence`. */
26
+ readonly sequence: number;
27
+ /** Accumulated parts of the assistant message being produced, in order. */
28
+ readonly parts: readonly MessagePart[];
29
+ /** Step index reached in the agent loop, bounded by `ExecutionLimits.maxSteps`. */
30
+ readonly step: number;
31
+ /** Tool calls started but not yet completed. Non-empty after a crash → finalized on recovery. */
32
+ readonly pendingToolCalls: readonly PendingToolCall[];
33
+ readonly usage: RunUsageTotals;
34
+ readonly updatedAt: string;
35
+ };
36
+ export declare const emptyCheckpoint: (runId: RunId, updatedAt: string) => RunCheckpoint;
37
+ //# sourceMappingURL=checkpoint.d.ts.map
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Run checkpoints — `docs/04-durable-runtime-and-hitl.md` → Durable execution.
3
+ *
4
+ * A checkpoint is the durable snapshot the worker writes as a run streams. It is what lets a page
5
+ * refresh lose no output and a crashed worker recover: a new claim reloads the latest checkpoint,
6
+ * finalizes any tool calls that were mid-flight, and continues from there.
7
+ */
8
+ export const EMPTY_USAGE_TOTALS = {
9
+ inputTokens: 0,
10
+ outputTokens: 0,
11
+ costMinorUnits: 0,
12
+ };
13
+ export const emptyCheckpoint = (runId, updatedAt) => ({
14
+ runId,
15
+ sequence: 0,
16
+ parts: [],
17
+ step: 0,
18
+ pendingToolCalls: [],
19
+ usage: EMPTY_USAGE_TOTALS,
20
+ updatedAt,
21
+ });
22
+ //# sourceMappingURL=checkpoint.js.map