@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,143 @@
1
+ /**
2
+ * Telemetry that does nothing, and the in-memory telemetry the tests assert on.
3
+ *
4
+ * `NOOP_TELEMETRY` is why no call site has an `if (telemetry)`. Optional-and-checked would be checked in
5
+ * nineteen places and forgotten in the twentieth, and the forgotten one is a crash rather than a missing span.
6
+ *
7
+ * `createRecordingTelemetry` is the same port over arrays. It is what makes AC-1, AC-2 and AC-5 assertable
8
+ * without a collector: the redaction test needs to see the *actual bytes* a sink would write, and a mock that
9
+ * captured the call arguments would prove the caller's intent rather than the output.
10
+ */
11
+ import { boundMetricAttributes } from "./metrics.js";
12
+ import { formatLogLine, redactFields } from "./redaction.js";
13
+ import { formatTraceparent, parseTraceparent, TRACE_FLAG_SAMPLED } from "./trace-context.js";
14
+ const NOOP_RECORDER = { record: () => { } };
15
+ const NOOP_SPAN = {
16
+ context: { traceId: "0".repeat(32), spanId: "0".repeat(16), traceFlags: 0 },
17
+ setAttributes: () => { },
18
+ recordError: () => { },
19
+ setStatus: () => { },
20
+ end: () => { },
21
+ };
22
+ const NOOP_LOGGER = { log: () => { }, child: () => NOOP_LOGGER };
23
+ export const NOOP_TELEMETRY = {
24
+ tracer: { startSpan: () => NOOP_SPAN },
25
+ meter: { counter: () => NOOP_RECORDER, histogram: () => NOOP_RECORDER, gauge: () => NOOP_RECORDER },
26
+ logger: NOOP_LOGGER,
27
+ };
28
+ /**
29
+ * Deterministic ids.
30
+ *
31
+ * A counter, not randomness. The property worth asserting is "the worker's span carries the API host's trace
32
+ * id", and that is untestable against a random source — you can only check the two happen to be equal, which is
33
+ * also true of two random values one time in 2^128 and, more usefully, is what a bug producing a *constant* id
34
+ * would also satisfy.
35
+ */
36
+ const sequentialIds = () => {
37
+ let trace = 0;
38
+ let span = 0;
39
+ return {
40
+ traceId: () => (++trace).toString(16).padStart(32, "0"),
41
+ spanId: () => (++span).toString(16).padStart(16, "0"),
42
+ };
43
+ };
44
+ export const createRecordingTelemetry = (base = { tenantId: "t1" }, now = () => "2026-08-23T12:00:00.000Z") => {
45
+ const spans = [];
46
+ const metrics = [];
47
+ const logs = [];
48
+ const lines = [];
49
+ const ids = sequentialIds();
50
+ const tracer = {
51
+ startSpan(name, options = {}) {
52
+ const parent = parseTraceparent(options.parent);
53
+ // The parent's trace id, or a new one. This single line is AC-1: the worker passes the job's traceparent
54
+ // and lands in the API host's trace rather than starting its own.
55
+ const traceId = parent?.traceId ?? ids.traceId();
56
+ const spanId = ids.spanId();
57
+ const record = {
58
+ name,
59
+ kind: options.kind ?? "internal",
60
+ traceId,
61
+ spanId,
62
+ parentSpanId: parent?.spanId ?? null,
63
+ attributes: { ...(options.attributes ?? {}) },
64
+ status: "unset",
65
+ errorCode: null,
66
+ ended: false,
67
+ };
68
+ spans.push(record);
69
+ return {
70
+ context: { traceId, spanId, traceFlags: parent?.traceFlags ?? TRACE_FLAG_SAMPLED },
71
+ setAttributes(attributes) {
72
+ Object.assign(record.attributes, attributes);
73
+ },
74
+ recordError({ code }) {
75
+ record.errorCode = code;
76
+ },
77
+ setStatus(status) {
78
+ record.status = status;
79
+ },
80
+ end() {
81
+ record.ended = true;
82
+ },
83
+ };
84
+ },
85
+ };
86
+ const recorder = (instrument) => ({
87
+ record(value, attributes) {
88
+ // Bounded here, in the *implementation*, so a call site that passes a run id cannot create a series. The
89
+ // test that proves this passes an unbounded attribute deliberately.
90
+ metrics.push({ instrument, value, attributes: boundMetricAttributes(attributes) });
91
+ },
92
+ });
93
+ const meter = {
94
+ counter: (name) => recorder(name),
95
+ histogram: (name) => recorder(name),
96
+ gauge: (name) => recorder(name),
97
+ };
98
+ const makeLogger = (context) => ({
99
+ log(level, event, raw) {
100
+ const { fields, dropped } = redactFields(raw);
101
+ const record = { level, event, context, fields, at: now() };
102
+ logs.push(record);
103
+ lines.push(formatLogLine({ ...record, context: context }));
104
+ if (dropped.length > 0) {
105
+ // The *names* of what was dropped, never the values, and as its own line rather than a field on this
106
+ // one: a redaction that quietly removed a field would look to whoever needs it like the field was never
107
+ // set, and they would go looking in the wrong place.
108
+ const notice = {
109
+ level: "debug",
110
+ event: "telemetry.fields-dropped",
111
+ context,
112
+ fields: { count: dropped.length, reason: dropped.slice(0, 8).join(",").slice(0, 120) },
113
+ at: now(),
114
+ };
115
+ logs.push(notice);
116
+ lines.push(formatLogLine({ ...notice, context: context }));
117
+ }
118
+ },
119
+ child(extra) {
120
+ return makeLogger({ ...context, ...extra });
121
+ },
122
+ });
123
+ return {
124
+ tracer,
125
+ meter,
126
+ logger: makeLogger(base),
127
+ get spans() {
128
+ return spans;
129
+ },
130
+ get metrics() {
131
+ return metrics;
132
+ },
133
+ get logs() {
134
+ return logs;
135
+ },
136
+ get lines() {
137
+ return lines;
138
+ },
139
+ };
140
+ };
141
+ /** The traceparent for a span, for putting into a job payload or an outbound header. */
142
+ export const traceparentOf = (span) => formatTraceparent(span.context);
143
+ //# sourceMappingURL=noop.js.map
@@ -0,0 +1,64 @@
1
+ /**
2
+ * The redaction boundary — AC-5.
3
+ *
4
+ * "No prompt content, message content or credential ever appears in logs" is the failure mode discovered too
5
+ * late: it is found by someone reading a log aggregator, months after the line was added, and by then the data
6
+ * is in a third-party index and a backup.
7
+ *
8
+ * **An allowlist, not a denylist.** This is the whole design. A denylist has to name every field that must not
9
+ * be logged, forever, including the one a colleague adds next month. An allowlist names the fields that may be,
10
+ * and anything else is dropped without being asked about. The failure direction is "an incident is missing a
11
+ * field", not "a prompt is in Datadog".
12
+ *
13
+ * Three properties beyond the list:
14
+ *
15
+ * **Primitives only.** A nested object is where content hides — `{ input: {...} }` on a tool log line is one
16
+ * keystroke from being the whole tool input. An object value is dropped even if its key is allowlisted.
17
+ *
18
+ * **Strings are bounded.** An allowlisted key can still be *handed* content: nothing stops a caller passing
19
+ * prose as `toolName`. A short cap means the leak is a truncated fragment rather than a document, and a value
20
+ * that hits the cap is visibly truncated, which is how someone notices the bug.
21
+ *
22
+ * **A dropped field is reported, not silent.** `redactFields` returns what it removed so the logger can emit
23
+ * `telemetry.fields-dropped`. Silent dropping turns redaction into invisible data loss, and the person
24
+ * debugging finds an empty field rather than an explanation.
25
+ */
26
+ import type { AttributeValue } from "./index.js";
27
+ /**
28
+ * The fields any log line or span may carry.
29
+ *
30
+ * Ids, names from closed sets, counts, durations, and classified codes. Nothing whose value is authored by a
31
+ * user or a model. Read the list as the answer to "what can this platform tell you about a failure?" — if it is
32
+ * not here, the answer is a metric or a trace, not a log field.
33
+ */
34
+ export declare const LOG_FIELD_ALLOWLIST: readonly string[];
35
+ /**
36
+ * The cap on a string field.
37
+ *
38
+ * 120 characters: comfortably longer than every id, model name and error code in the list, and far shorter than
39
+ * a prompt, a message or a signed URL. Deliberately not generous — the cap is a *bound on a leak*, and a
40
+ * generous bound is a leak.
41
+ */
42
+ export declare const MAX_FIELD_LENGTH = 120;
43
+ export declare const TRUNCATION_MARKER = "\u2026[truncated]";
44
+ export type Redacted = {
45
+ readonly fields: Readonly<Record<string, AttributeValue>>;
46
+ /** The keys that were removed, so the caller can say so. Names only — never the values. */
47
+ readonly dropped: readonly string[];
48
+ };
49
+ export declare const redactFields: (input: Readonly<Record<string, unknown>> | undefined) => Redacted;
50
+ /**
51
+ * A log record as a single line of JSON.
52
+ *
53
+ * Serialized here rather than by the sink, so every sink emits the same shape and the redaction cannot be
54
+ * bypassed by a sink that formats the record itself. The context is spread at the top level, because a query
55
+ * for `runId:...` in a log aggregator should not need to know it is nested.
56
+ */
57
+ export declare const formatLogLine: (record: {
58
+ readonly level: string;
59
+ readonly event: string;
60
+ readonly at: string;
61
+ readonly context: Readonly<Record<string, string | undefined>>;
62
+ readonly fields: Readonly<Record<string, AttributeValue>>;
63
+ }) => string;
64
+ //# sourceMappingURL=redaction.d.ts.map
@@ -0,0 +1,153 @@
1
+ /**
2
+ * The redaction boundary — AC-5.
3
+ *
4
+ * "No prompt content, message content or credential ever appears in logs" is the failure mode discovered too
5
+ * late: it is found by someone reading a log aggregator, months after the line was added, and by then the data
6
+ * is in a third-party index and a backup.
7
+ *
8
+ * **An allowlist, not a denylist.** This is the whole design. A denylist has to name every field that must not
9
+ * be logged, forever, including the one a colleague adds next month. An allowlist names the fields that may be,
10
+ * and anything else is dropped without being asked about. The failure direction is "an incident is missing a
11
+ * field", not "a prompt is in Datadog".
12
+ *
13
+ * Three properties beyond the list:
14
+ *
15
+ * **Primitives only.** A nested object is where content hides — `{ input: {...} }` on a tool log line is one
16
+ * keystroke from being the whole tool input. An object value is dropped even if its key is allowlisted.
17
+ *
18
+ * **Strings are bounded.** An allowlisted key can still be *handed* content: nothing stops a caller passing
19
+ * prose as `toolName`. A short cap means the leak is a truncated fragment rather than a document, and a value
20
+ * that hits the cap is visibly truncated, which is how someone notices the bug.
21
+ *
22
+ * **A dropped field is reported, not silent.** `redactFields` returns what it removed so the logger can emit
23
+ * `telemetry.fields-dropped`. Silent dropping turns redaction into invisible data loss, and the person
24
+ * debugging finds an empty field rather than an explanation.
25
+ */
26
+ /**
27
+ * The fields any log line or span may carry.
28
+ *
29
+ * Ids, names from closed sets, counts, durations, and classified codes. Nothing whose value is authored by a
30
+ * user or a model. Read the list as the answer to "what can this platform tell you about a failure?" — if it is
31
+ * not here, the answer is a metric or a trace, not a log field.
32
+ */
33
+ export const LOG_FIELD_ALLOWLIST = [
34
+ // Correlation. Also present on the record's `context`; allowed here so a line about a *different* run than
35
+ // the bound one can name it.
36
+ "tenantId",
37
+ "conversationId",
38
+ "runId",
39
+ "principalId",
40
+ "requestId",
41
+ "traceId",
42
+ "spanId",
43
+ "interactionId",
44
+ "jobId",
45
+ "workerId",
46
+ // What happened, from closed sets
47
+ "status",
48
+ "outcome",
49
+ "decision",
50
+ "reason",
51
+ "eventType",
52
+ "partType",
53
+ "riskCategory",
54
+ "toolName",
55
+ "modelId",
56
+ "providerId",
57
+ "agentId",
58
+ "skillId",
59
+ "graderId",
60
+ "sourceType",
61
+ "period",
62
+ // Classified failures. A *code*, never a message.
63
+ "errorCode",
64
+ "retryable",
65
+ "attempt",
66
+ "maxAttempts",
67
+ // Numbers
68
+ "durationMs",
69
+ "waitMs",
70
+ "latencyMs",
71
+ "queueDepth",
72
+ "count",
73
+ "sequence",
74
+ "stepCount",
75
+ "toolCallCount",
76
+ "inputTokens",
77
+ "outputTokens",
78
+ "cachedInputTokens",
79
+ "reasoningTokens",
80
+ "costMinorUnits",
81
+ "currency",
82
+ "byteSize",
83
+ "version",
84
+ "expectedVersion",
85
+ "limit",
86
+ "chunkCount",
87
+ "resultCount",
88
+ "score",
89
+ ];
90
+ const ALLOWED = new Set(LOG_FIELD_ALLOWLIST);
91
+ /**
92
+ * The cap on a string field.
93
+ *
94
+ * 120 characters: comfortably longer than every id, model name and error code in the list, and far shorter than
95
+ * a prompt, a message or a signed URL. Deliberately not generous — the cap is a *bound on a leak*, and a
96
+ * generous bound is a leak.
97
+ */
98
+ export const MAX_FIELD_LENGTH = 120;
99
+ export const TRUNCATION_MARKER = "…[truncated]";
100
+ export const redactFields = (input) => {
101
+ if (input === undefined)
102
+ return { fields: {}, dropped: [] };
103
+ const fields = {};
104
+ const dropped = [];
105
+ for (const [key, value] of Object.entries(input)) {
106
+ if (!ALLOWED.has(key)) {
107
+ dropped.push(key);
108
+ continue;
109
+ }
110
+ if (typeof value === "number") {
111
+ // NaN and Infinity serialize as `null` in JSON, which reads as "no value" rather than "a bad value".
112
+ if (!Number.isFinite(value)) {
113
+ dropped.push(key);
114
+ continue;
115
+ }
116
+ fields[key] = value;
117
+ continue;
118
+ }
119
+ if (typeof value === "boolean") {
120
+ fields[key] = value;
121
+ continue;
122
+ }
123
+ if (typeof value === "string") {
124
+ fields[key] =
125
+ value.length > MAX_FIELD_LENGTH ? `${value.slice(0, MAX_FIELD_LENGTH)}${TRUNCATION_MARKER}` : value;
126
+ continue;
127
+ }
128
+ // Everything else — objects, arrays, functions, null, undefined, symbols, bigint. An object is dropped even
129
+ // under an allowlisted key, because the key says nothing about what a nested value contains.
130
+ dropped.push(key);
131
+ }
132
+ return { fields, dropped };
133
+ };
134
+ /**
135
+ * A log record as a single line of JSON.
136
+ *
137
+ * Serialized here rather than by the sink, so every sink emits the same shape and the redaction cannot be
138
+ * bypassed by a sink that formats the record itself. The context is spread at the top level, because a query
139
+ * for `runId:...` in a log aggregator should not need to know it is nested.
140
+ */
141
+ export const formatLogLine = (record) => {
142
+ const flat = { at: record.at, level: record.level, event: record.event };
143
+ for (const [key, value] of Object.entries(record.context))
144
+ if (value !== undefined)
145
+ flat[key] = value;
146
+ // Fields last, but they cannot overwrite `event` or `level`: a field named `event` would make a line claim to
147
+ // be a different event than the one that was logged, which is the one lie a log must not be able to tell.
148
+ for (const [key, value] of Object.entries(record.fields))
149
+ if (key !== "at" && key !== "level" && key !== "event")
150
+ flat[key] = value;
151
+ return JSON.stringify(flat);
152
+ };
153
+ //# sourceMappingURL=redaction.js.map
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Span names — AC-2: "spans align with the existing run event types, so traces and event history correspond".
3
+ *
4
+ * The alignment is a **total map keyed by `RunEventType`**, so adding an event type without deciding on its span
5
+ * is a compile error. A `Record<string, string>` here would let a new event type land with no span and the
6
+ * mismatch would only be found by someone comparing a trace against an event log during an incident — which is
7
+ * exactly when they can least afford to.
8
+ *
9
+ * Names follow the event names, which is not laziness: an operator holding a trace and an event history is
10
+ * matching them by eye, and a span called `agent.inference` next to a `model.called` event costs a lookup every
11
+ * time. The same word means the same thing in both places.
12
+ */
13
+ import { type RunEventType } from "../core/events.js";
14
+ /**
15
+ * Every run event's span name.
16
+ *
17
+ * Several events map to the *same* span deliberately — `part.added` and `part.updated` are both activity within
18
+ * a run, not boundaries worth their own span, and a span per streamed part would produce thousands per run and
19
+ * bury the ones that matter. They still get a span *name* rather than being excluded, because "this event has
20
+ * no span" is a decision that must be visible, and an omission looks identical to an oversight.
21
+ */
22
+ export declare const SPAN_FOR_RUN_EVENT: Readonly<Record<RunEventType, string>>;
23
+ /**
24
+ * The spans that are *not* run events.
25
+ *
26
+ * The request and the claim have no event type — a run event exists once there is a run, and these happen
27
+ * before or around that. Listed here so the full set of span names has one home; a name invented at a call site
28
+ * is a name nothing can check.
29
+ */
30
+ export declare const BOUNDARY_SPANS: {
31
+ /** The inbound GraphQL operation. `server` kind — the root of the trace. */
32
+ readonly request: "http.request";
33
+ /** Quota and authorization, before anything is claimed or enqueued. */
34
+ readonly admission: "run.admit";
35
+ /** The producer side of the queue. Where the `traceparent` is written into the job. */
36
+ readonly enqueue: "run.enqueue";
37
+ /** The consumer side. Where the `traceparent` is read back and the trace continues. */
38
+ readonly claim: "run.claim";
39
+ /** One model call. */
40
+ readonly model: "model.call";
41
+ /** One tool call. */
42
+ readonly tool: "tool.call";
43
+ /** Waiting for a human. Often the longest span in a trace, and the one an operator most wants to see. */
44
+ readonly approvalWait: "hitl.approval";
45
+ };
46
+ export type BoundarySpan = (typeof BOUNDARY_SPANS)[keyof typeof BOUNDARY_SPANS];
47
+ /** Every span name the platform emits. Used by the test that asserts the two sets agree. */
48
+ export declare const ALL_SPAN_NAMES: readonly string[];
49
+ /**
50
+ * The span a run event belongs to.
51
+ *
52
+ * A function rather than direct map access, so a caller holding a `RunEventType` from a store — where the type
53
+ * is a string at runtime — cannot index into `undefined` and produce a span named "undefined".
54
+ */
55
+ export declare const spanForRunEvent: (type: string) => string | null;
56
+ //# sourceMappingURL=spans.d.ts.map
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Span names — AC-2: "spans align with the existing run event types, so traces and event history correspond".
3
+ *
4
+ * The alignment is a **total map keyed by `RunEventType`**, so adding an event type without deciding on its span
5
+ * is a compile error. A `Record<string, string>` here would let a new event type land with no span and the
6
+ * mismatch would only be found by someone comparing a trace against an event log during an incident — which is
7
+ * exactly when they can least afford to.
8
+ *
9
+ * Names follow the event names, which is not laziness: an operator holding a trace and an event history is
10
+ * matching them by eye, and a span called `agent.inference` next to a `model.called` event costs a lookup every
11
+ * time. The same word means the same thing in both places.
12
+ */
13
+ import { RUN_EVENT_TYPES } from "../core/events.js";
14
+ /**
15
+ * Every run event's span name.
16
+ *
17
+ * Several events map to the *same* span deliberately — `part.added` and `part.updated` are both activity within
18
+ * a run, not boundaries worth their own span, and a span per streamed part would produce thousands per run and
19
+ * bury the ones that matter. They still get a span *name* rather than being excluded, because "this event has
20
+ * no span" is a decision that must be visible, and an omission looks identical to an oversight.
21
+ */
22
+ export const SPAN_FOR_RUN_EVENT = {
23
+ "run.queued": "run.enqueue",
24
+ "run.started": "run.execute",
25
+ "run.checkpointed": "run.checkpoint",
26
+ "run.completed": "run.execute",
27
+ "run.failed": "run.execute",
28
+ "run.cancelled": "run.execute",
29
+ "run.retry-pending": "run.retry",
30
+ "part.added": "run.step",
31
+ "part.updated": "run.step",
32
+ "tool.started": "tool.call",
33
+ "tool.completed": "tool.call",
34
+ "tool.failed": "tool.call",
35
+ "question.requested": "hitl.question",
36
+ "question.answered": "hitl.question",
37
+ "approval.requested": "hitl.approval",
38
+ "approval.decided": "hitl.approval",
39
+ "usage.updated": "run.step",
40
+ "context.compacted": "context.compact",
41
+ };
42
+ /**
43
+ * The spans that are *not* run events.
44
+ *
45
+ * The request and the claim have no event type — a run event exists once there is a run, and these happen
46
+ * before or around that. Listed here so the full set of span names has one home; a name invented at a call site
47
+ * is a name nothing can check.
48
+ */
49
+ export const BOUNDARY_SPANS = {
50
+ /** The inbound GraphQL operation. `server` kind — the root of the trace. */
51
+ request: "http.request",
52
+ /** Quota and authorization, before anything is claimed or enqueued. */
53
+ admission: "run.admit",
54
+ /** The producer side of the queue. Where the `traceparent` is written into the job. */
55
+ enqueue: "run.enqueue",
56
+ /** The consumer side. Where the `traceparent` is read back and the trace continues. */
57
+ claim: "run.claim",
58
+ /** One model call. */
59
+ model: "model.call",
60
+ /** One tool call. */
61
+ tool: "tool.call",
62
+ /** Waiting for a human. Often the longest span in a trace, and the one an operator most wants to see. */
63
+ approvalWait: "hitl.approval",
64
+ };
65
+ /** Every span name the platform emits. Used by the test that asserts the two sets agree. */
66
+ export const ALL_SPAN_NAMES = [
67
+ ...new Set([...Object.values(SPAN_FOR_RUN_EVENT), ...Object.values(BOUNDARY_SPANS)]),
68
+ ];
69
+ /**
70
+ * The span a run event belongs to.
71
+ *
72
+ * A function rather than direct map access, so a caller holding a `RunEventType` from a store — where the type
73
+ * is a string at runtime — cannot index into `undefined` and produce a span named "undefined".
74
+ */
75
+ export const spanForRunEvent = (type) => RUN_EVENT_TYPES.includes(type)
76
+ ? SPAN_FOR_RUN_EVENT[type]
77
+ : null;
78
+ //# sourceMappingURL=spans.js.map
@@ -0,0 +1,55 @@
1
+ /**
2
+ * W3C trace context — the wire format that makes AC-1 possible.
3
+ *
4
+ * A run is enqueued by the API host and executed by a worker in a different process, possibly minutes later.
5
+ * The only thing that can join them into one trace is a `traceparent` travelling in the job payload, so this is
6
+ * the parsing and formatting of that string and nothing else.
7
+ *
8
+ * Chosen over a bespoke correlation id because the format is what every collector already understands. A
9
+ * home-grown id would work exactly as well right up to the point a customer pointed their own tooling at it,
10
+ * which is AC-6.
11
+ */
12
+ /** Only version 00 exists. A future version must be *ignored*, not guessed at — see `parseTraceparent`. */
13
+ export declare const TRACEPARENT_VERSION = "00";
14
+ export declare const TRACE_ID_LENGTH = 32;
15
+ export declare const SPAN_ID_LENGTH = 16;
16
+ /**
17
+ * The sampled bit, as W3C defines it.
18
+ *
19
+ * A number rather than a boolean because the field is a bitfield and only bit 0 is assigned; keeping it numeric
20
+ * means an unrecognised flag survives a round trip instead of being flattened to false by us.
21
+ */
22
+ export type TraceFlags = number;
23
+ export declare const TRACE_FLAG_SAMPLED = 1;
24
+ export type TraceparentParts = {
25
+ readonly traceId: string;
26
+ readonly spanId: string;
27
+ readonly traceFlags: TraceFlags;
28
+ };
29
+ export declare const formatTraceparent: (parts: TraceparentParts) => string;
30
+ /**
31
+ * Parse a `traceparent`, or return `null`.
32
+ *
33
+ * `null` rather than a throw, and this is the important decision: a malformed or absent header means *start a
34
+ * new trace*, never fail the request. Telemetry that can break a run is worse than no telemetry, and this
35
+ * function sits on the hot path of every request and every job.
36
+ *
37
+ * Strict about what it accepts, though. An all-zero trace id or span id is invalid per the spec, and accepting
38
+ * one produces a trace that silently merges unrelated requests — every caller that failed to propagate lands in
39
+ * the same "trace 000…0", which looks like a working trace and is worse than a missing one.
40
+ */
41
+ export declare const parseTraceparent: (value: string | undefined | null) => TraceparentParts | null;
42
+ export declare const isSampled: (flags: TraceFlags) => boolean;
43
+ /**
44
+ * Fresh ids.
45
+ *
46
+ * `randomHex` is injected rather than reaching for `crypto` here, so a test can pin ids and assert that a
47
+ * child span really carries its parent's trace id — which is the one property of propagation that matters and
48
+ * the one that is untestable against a random source.
49
+ */
50
+ export type IdGenerator = {
51
+ readonly traceId: () => string;
52
+ readonly spanId: () => string;
53
+ };
54
+ export declare const createIdGenerator: (randomHex: (bytes: number) => string) => IdGenerator;
55
+ //# sourceMappingURL=trace-context.d.ts.map
@@ -0,0 +1,60 @@
1
+ /**
2
+ * W3C trace context — the wire format that makes AC-1 possible.
3
+ *
4
+ * A run is enqueued by the API host and executed by a worker in a different process, possibly minutes later.
5
+ * The only thing that can join them into one trace is a `traceparent` travelling in the job payload, so this is
6
+ * the parsing and formatting of that string and nothing else.
7
+ *
8
+ * Chosen over a bespoke correlation id because the format is what every collector already understands. A
9
+ * home-grown id would work exactly as well right up to the point a customer pointed their own tooling at it,
10
+ * which is AC-6.
11
+ */
12
+ /** Only version 00 exists. A future version must be *ignored*, not guessed at — see `parseTraceparent`. */
13
+ export const TRACEPARENT_VERSION = "00";
14
+ export const TRACE_ID_LENGTH = 32;
15
+ export const SPAN_ID_LENGTH = 16;
16
+ export const TRACE_FLAG_SAMPLED = 0x01;
17
+ const INVALID_TRACE_ID = "0".repeat(TRACE_ID_LENGTH);
18
+ const INVALID_SPAN_ID = "0".repeat(SPAN_ID_LENGTH);
19
+ const isLowerHex = (value, length) => value.length === length && /^[0-9a-f]+$/.test(value);
20
+ export const formatTraceparent = (parts) => `${TRACEPARENT_VERSION}-${parts.traceId}-${parts.spanId}-${(parts.traceFlags & 0xff).toString(16).padStart(2, "0")}`;
21
+ /**
22
+ * Parse a `traceparent`, or return `null`.
23
+ *
24
+ * `null` rather than a throw, and this is the important decision: a malformed or absent header means *start a
25
+ * new trace*, never fail the request. Telemetry that can break a run is worse than no telemetry, and this
26
+ * function sits on the hot path of every request and every job.
27
+ *
28
+ * Strict about what it accepts, though. An all-zero trace id or span id is invalid per the spec, and accepting
29
+ * one produces a trace that silently merges unrelated requests — every caller that failed to propagate lands in
30
+ * the same "trace 000…0", which looks like a working trace and is worse than a missing one.
31
+ */
32
+ export const parseTraceparent = (value) => {
33
+ if (typeof value !== "string")
34
+ return null;
35
+ const parts = value.trim().split("-");
36
+ // A version above 00 may carry *extra* fields, which the spec says to tolerate; fewer than four is malformed
37
+ // whatever the version.
38
+ if (parts.length < 4)
39
+ return null;
40
+ const [version, traceId, spanId, flags] = parts;
41
+ if (version === undefined || traceId === undefined || spanId === undefined || flags === undefined)
42
+ return null;
43
+ // Version ff is explicitly forbidden. Any other unknown version is *forward* compatible: the first four
44
+ // fields keep their meaning, so a newer producer's context still joins our trace rather than being dropped.
45
+ if (!isLowerHex(version, 2) || version === "ff")
46
+ return null;
47
+ if (!isLowerHex(traceId, TRACE_ID_LENGTH) || traceId === INVALID_TRACE_ID)
48
+ return null;
49
+ if (!isLowerHex(spanId, SPAN_ID_LENGTH) || spanId === INVALID_SPAN_ID)
50
+ return null;
51
+ if (!isLowerHex(flags, 2))
52
+ return null;
53
+ return { traceId, spanId, traceFlags: Number.parseInt(flags, 16) };
54
+ };
55
+ export const isSampled = (flags) => (flags & TRACE_FLAG_SAMPLED) !== 0;
56
+ export const createIdGenerator = (randomHex) => ({
57
+ traceId: () => randomHex(TRACE_ID_LENGTH / 2),
58
+ spanId: () => randomHex(SPAN_ID_LENGTH / 2),
59
+ });
60
+ //# sourceMappingURL=trace-context.js.map
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Time and arithmetic — REQ-039 (#188).
3
+ *
4
+ * The two things a model is reliably bad at and a two-line function is reliably good at. Both are pure, so both
5
+ * are here as functions and the tool envelopes over them are trivial.
6
+ */
7
+ /**
8
+ * Evaluate an arithmetic expression, without `eval`.
9
+ *
10
+ * `eval` on a string a model produced is remote code execution with extra steps, and `new Function` is the same
11
+ * thing wearing a hat. So this is a small recursive-descent parser over a closed grammar: numbers, `+ - * / % ^`,
12
+ * parentheses, unary minus, and a fixed set of named functions and constants. Anything else is a syntax error
13
+ * rather than a silent success.
14
+ *
15
+ * Precision is IEEE-754 double, like every other number in this runtime. It is not a decimal library, and
16
+ * `0.1 + 0.2` is documented rather than hidden, because a tool that quietly rounds is a tool that disagrees with
17
+ * the spreadsheet the person is comparing it against.
18
+ */
19
+ export type CalculationResult = {
20
+ readonly ok: true;
21
+ readonly expression: string;
22
+ readonly value: number;
23
+ } | {
24
+ readonly ok: false;
25
+ readonly expression: string;
26
+ readonly reason: string;
27
+ };
28
+ export declare const MAX_EXPRESSION_CHARS = 500;
29
+ export declare const calculate: (expression: string) => CalculationResult;
30
+ export type TimeResult = {
31
+ readonly ok: true;
32
+ readonly iso: string;
33
+ readonly formatted: string;
34
+ readonly timeZone: string;
35
+ readonly epochMs: number;
36
+ } | {
37
+ readonly ok: false;
38
+ readonly reason: string;
39
+ };
40
+ /**
41
+ * The current time, in a named zone.
42
+ *
43
+ * A model has no clock -- it has a training cutoff, and it will answer "what is today's date" with something
44
+ * plausible and wrong. The zone is a parameter because "today" is a different day depending on where the person
45
+ * asking is, and the caller is often not in UTC.
46
+ *
47
+ * The clock is injected so a test can pin it, which is the convention everywhere else in this runtime.
48
+ */
49
+ export declare const currentTime: (input?: {
50
+ readonly timeZone?: string;
51
+ readonly now?: () => Date;
52
+ }) => TimeResult;
53
+ //# sourceMappingURL=compute.d.ts.map