@vauban-org/agent-sdk 1.0.0 → 1.2.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 (442) hide show
  1. package/CONTRACT.md +6401 -813
  2. package/dist/adapters/llm/anthropic-direct.d.ts +1 -0
  3. package/dist/adapters/llm/anthropic-direct.d.ts.map +1 -1
  4. package/dist/adapters/llm/anthropic-direct.js +43 -0
  5. package/dist/adapters/llm/anthropic-direct.js.map +1 -1
  6. package/dist/adapters/llm/cascade.d.ts.map +1 -1
  7. package/dist/adapters/llm/cascade.js +57 -14
  8. package/dist/adapters/llm/cascade.js.map +1 -1
  9. package/dist/adapters/llm/litellm.d.ts +2 -0
  10. package/dist/adapters/llm/litellm.d.ts.map +1 -1
  11. package/dist/adapters/llm/litellm.js +44 -0
  12. package/dist/adapters/llm/litellm.js.map +1 -1
  13. package/dist/compute/difficulty-estimator.d.ts +53 -0
  14. package/dist/compute/difficulty-estimator.d.ts.map +1 -0
  15. package/dist/compute/difficulty-estimator.js +82 -0
  16. package/dist/compute/difficulty-estimator.js.map +1 -0
  17. package/dist/compute/strategies/mixture-of-agents.d.ts +40 -0
  18. package/dist/compute/strategies/mixture-of-agents.d.ts.map +1 -0
  19. package/dist/compute/strategies/mixture-of-agents.js +110 -0
  20. package/dist/compute/strategies/mixture-of-agents.js.map +1 -0
  21. package/dist/compute/strategies/tree-of-thoughts.d.ts +48 -0
  22. package/dist/compute/strategies/tree-of-thoughts.d.ts.map +1 -0
  23. package/dist/compute/strategies/tree-of-thoughts.js +242 -0
  24. package/dist/compute/strategies/tree-of-thoughts.js.map +1 -0
  25. package/dist/compute/strategies/two-phase-orient.d.ts +72 -0
  26. package/dist/compute/strategies/two-phase-orient.d.ts.map +1 -0
  27. package/dist/compute/strategies/two-phase-orient.js +85 -0
  28. package/dist/compute/strategies/two-phase-orient.js.map +1 -0
  29. package/dist/constitution/types.d.ts +10 -10
  30. package/dist/container/protocol.d.ts +134 -0
  31. package/dist/container/protocol.d.ts.map +1 -0
  32. package/dist/container/protocol.js +157 -0
  33. package/dist/container/protocol.js.map +1 -0
  34. package/dist/container/runtime.d.ts +140 -0
  35. package/dist/container/runtime.d.ts.map +1 -0
  36. package/dist/container/runtime.js +256 -0
  37. package/dist/container/runtime.js.map +1 -0
  38. package/dist/events/catalogue.d.ts +46 -46
  39. package/dist/events/schemas/agent.completed.v1.d.ts +4 -4
  40. package/dist/events/schemas/agent.failed.v1.d.ts +2 -2
  41. package/dist/events/schemas/agent.hitl_resolved.v1.d.ts +2 -2
  42. package/dist/events/schemas/agent.started.v1.d.ts +2 -2
  43. package/dist/events/schemas/brain.skill.extracted.v1.d.ts +4 -4
  44. package/dist/events/schemas/cc.cost.anomaly_detected.v1.d.ts +2 -2
  45. package/dist/events/schemas/cc.cost.recorded.v1.d.ts +4 -4
  46. package/dist/events/schemas/citadel.sprint.analyzed.v1.d.ts +6 -6
  47. package/dist/events/schemas/citadel.sprint.closed.v1.d.ts +2 -2
  48. package/dist/events/schemas/forge.inbox.reply_classified.v1.d.ts +6 -6
  49. package/dist/events/schemas/forge.lead.qualified.v1.d.ts +2 -2
  50. package/dist/events/schemas/forge.outreach.sent.v1.d.ts +4 -4
  51. package/dist/events/schemas/incident.detected.v1.d.ts +2 -2
  52. package/dist/events/schemas/vauban.goal.checked.v1.d.ts +2 -2
  53. package/dist/events/schemas/vauban.rebalancing.checked.v1.d.ts +2 -2
  54. package/dist/events/schemas/vauban.tax.checked.v1.d.ts +2 -2
  55. package/dist/events/schemas/vauban.vault.analyzed.v1.d.ts +6 -6
  56. package/dist/identity/agent-persona.d.ts +73 -0
  57. package/dist/identity/agent-persona.d.ts.map +1 -0
  58. package/dist/identity/agent-persona.js +165 -0
  59. package/dist/identity/agent-persona.js.map +1 -0
  60. package/dist/identity/persona-prompt.d.ts +25 -0
  61. package/dist/identity/persona-prompt.d.ts.map +1 -0
  62. package/dist/identity/persona-prompt.js +71 -0
  63. package/dist/identity/persona-prompt.js.map +1 -0
  64. package/dist/identity/persona-schema.d.ts +120 -0
  65. package/dist/identity/persona-schema.d.ts.map +1 -0
  66. package/dist/identity/persona-schema.js +103 -0
  67. package/dist/identity/persona-schema.js.map +1 -0
  68. package/dist/index.d.ts +37 -2
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +29 -1
  71. package/dist/index.js.map +1 -1
  72. package/dist/loop/minimal-loop.js +293 -287
  73. package/dist/memory/episodic-rrf.d.ts +114 -0
  74. package/dist/memory/episodic-rrf.d.ts.map +1 -0
  75. package/dist/memory/episodic-rrf.js +148 -0
  76. package/dist/memory/episodic-rrf.js.map +1 -0
  77. package/dist/mesh/attenuation.d.ts +78 -0
  78. package/dist/mesh/attenuation.d.ts.map +1 -0
  79. package/dist/mesh/attenuation.js +141 -0
  80. package/dist/mesh/attenuation.js.map +1 -0
  81. package/dist/mesh/delegate.d.ts +96 -0
  82. package/dist/mesh/delegate.d.ts.map +1 -0
  83. package/dist/mesh/delegate.js +172 -0
  84. package/dist/mesh/delegate.js.map +1 -0
  85. package/dist/mesh/dispatcher.d.ts +119 -0
  86. package/dist/mesh/dispatcher.d.ts.map +1 -0
  87. package/dist/mesh/dispatcher.js +207 -0
  88. package/dist/mesh/dispatcher.js.map +1 -0
  89. package/dist/mesh/index.d.ts +12 -0
  90. package/dist/mesh/index.d.ts.map +1 -0
  91. package/dist/mesh/index.js +11 -0
  92. package/dist/mesh/index.js.map +1 -0
  93. package/dist/mesh/types.d.ts +30 -0
  94. package/dist/mesh/types.d.ts.map +1 -0
  95. package/dist/mesh/types.js +11 -0
  96. package/dist/mesh/types.js.map +1 -0
  97. package/dist/orchestration/ooda/skills.d.ts +104 -0
  98. package/dist/orchestration/ooda/skills.d.ts.map +1 -1
  99. package/dist/orchestration/ooda/skills.js +106 -0
  100. package/dist/orchestration/ooda/skills.js.map +1 -1
  101. package/dist/ports/bastion-action.contract.test.d.ts +11 -0
  102. package/dist/ports/bastion-action.contract.test.d.ts.map +1 -0
  103. package/dist/ports/bastion-action.contract.test.js +238 -0
  104. package/dist/ports/bastion-action.contract.test.js.map +1 -0
  105. package/dist/ports/bastion-action.d.ts +133 -0
  106. package/dist/ports/bastion-action.d.ts.map +1 -0
  107. package/dist/ports/bastion-action.js +73 -0
  108. package/dist/ports/bastion-action.js.map +1 -0
  109. package/dist/ports/brain.d.ts +31 -0
  110. package/dist/ports/brain.d.ts.map +1 -1
  111. package/dist/ports/brain.js +115 -1
  112. package/dist/ports/brain.js.map +1 -1
  113. package/dist/ports/citadel-action.contract.test.d.ts +11 -0
  114. package/dist/ports/citadel-action.contract.test.d.ts.map +1 -0
  115. package/dist/ports/citadel-action.contract.test.js +317 -0
  116. package/dist/ports/citadel-action.contract.test.js.map +1 -0
  117. package/dist/ports/citadel-action.d.ts +111 -0
  118. package/dist/ports/citadel-action.d.ts.map +1 -0
  119. package/dist/ports/citadel-action.js +62 -0
  120. package/dist/ports/citadel-action.js.map +1 -0
  121. package/dist/ports/compliance-contract.d.ts +123 -0
  122. package/dist/ports/compliance-contract.d.ts.map +1 -0
  123. package/dist/ports/compliance-contract.js +35 -0
  124. package/dist/ports/compliance-contract.js.map +1 -0
  125. package/dist/ports/db.d.ts +38 -0
  126. package/dist/ports/db.d.ts.map +1 -1
  127. package/dist/ports/db.js +88 -1
  128. package/dist/ports/db.js.map +1 -1
  129. package/dist/ports/delegation.contract.test.d.ts +9 -0
  130. package/dist/ports/delegation.contract.test.d.ts.map +1 -0
  131. package/dist/ports/delegation.contract.test.js +337 -0
  132. package/dist/ports/delegation.contract.test.js.map +1 -0
  133. package/dist/ports/delegation.d.ts +134 -0
  134. package/dist/ports/delegation.d.ts.map +1 -0
  135. package/dist/ports/delegation.js +105 -0
  136. package/dist/ports/delegation.js.map +1 -0
  137. package/dist/ports/event-bus.d.ts +29 -0
  138. package/dist/ports/event-bus.d.ts.map +1 -1
  139. package/dist/ports/event-bus.js +106 -1
  140. package/dist/ports/event-bus.js.map +1 -1
  141. package/dist/ports/federation.contract.test.d.ts +9 -0
  142. package/dist/ports/federation.contract.test.d.ts.map +1 -0
  143. package/dist/ports/federation.contract.test.js +279 -0
  144. package/dist/ports/federation.contract.test.js.map +1 -0
  145. package/dist/ports/federation.d.ts +140 -0
  146. package/dist/ports/federation.d.ts.map +1 -0
  147. package/dist/ports/federation.js +57 -0
  148. package/dist/ports/federation.js.map +1 -0
  149. package/dist/ports/index.d.ts +28 -2
  150. package/dist/ports/index.d.ts.map +1 -1
  151. package/dist/ports/index.js +17 -2
  152. package/dist/ports/index.js.map +1 -1
  153. package/dist/ports/llm-provider.d.ts +37 -0
  154. package/dist/ports/llm-provider.d.ts.map +1 -1
  155. package/dist/ports/llm-provider.js +99 -1
  156. package/dist/ports/llm-provider.js.map +1 -1
  157. package/dist/ports/logger.d.ts +27 -0
  158. package/dist/ports/logger.d.ts.map +1 -1
  159. package/dist/ports/logger.js +87 -0
  160. package/dist/ports/logger.js.map +1 -1
  161. package/dist/ports/manifest-registry.contract.test.d.ts +9 -0
  162. package/dist/ports/manifest-registry.contract.test.d.ts.map +1 -0
  163. package/dist/ports/manifest-registry.contract.test.js +246 -0
  164. package/dist/ports/manifest-registry.contract.test.js.map +1 -0
  165. package/dist/ports/manifest-registry.d.ts +116 -0
  166. package/dist/ports/manifest-registry.d.ts.map +1 -0
  167. package/dist/ports/manifest-registry.js +79 -0
  168. package/dist/ports/manifest-registry.js.map +1 -0
  169. package/dist/ports/observability.contract.test.d.ts +12 -0
  170. package/dist/ports/observability.contract.test.d.ts.map +1 -0
  171. package/dist/ports/observability.contract.test.js +260 -0
  172. package/dist/ports/observability.contract.test.js.map +1 -0
  173. package/dist/ports/observability.d.ts +98 -0
  174. package/dist/ports/observability.d.ts.map +1 -0
  175. package/dist/ports/observability.js +59 -0
  176. package/dist/ports/observability.js.map +1 -0
  177. package/dist/ports/outcome.d.ts +26 -0
  178. package/dist/ports/outcome.d.ts.map +1 -1
  179. package/dist/ports/outcome.js +62 -1
  180. package/dist/ports/outcome.js.map +1 -1
  181. package/dist/ports/privacy.contract.test.d.ts +12 -0
  182. package/dist/ports/privacy.contract.test.d.ts.map +1 -0
  183. package/dist/ports/privacy.contract.test.js +325 -0
  184. package/dist/ports/privacy.contract.test.js.map +1 -0
  185. package/dist/ports/privacy.d.ts +132 -0
  186. package/dist/ports/privacy.d.ts.map +1 -0
  187. package/dist/ports/privacy.js +83 -0
  188. package/dist/ports/privacy.js.map +1 -0
  189. package/dist/ports/tenant-context.contract.test.d.ts +14 -0
  190. package/dist/ports/tenant-context.contract.test.d.ts.map +1 -0
  191. package/dist/ports/tenant-context.contract.test.js +352 -0
  192. package/dist/ports/tenant-context.contract.test.js.map +1 -0
  193. package/dist/ports/tenant-context.d.ts +103 -0
  194. package/dist/ports/tenant-context.d.ts.map +1 -0
  195. package/dist/ports/tenant-context.js +48 -0
  196. package/dist/ports/tenant-context.js.map +1 -0
  197. package/dist/ports/vauban-finance-action.contract.test.d.ts +11 -0
  198. package/dist/ports/vauban-finance-action.contract.test.d.ts.map +1 -0
  199. package/dist/ports/vauban-finance-action.contract.test.js +260 -0
  200. package/dist/ports/vauban-finance-action.contract.test.js.map +1 -0
  201. package/dist/ports/vauban-finance-action.d.ts +106 -0
  202. package/dist/ports/vauban-finance-action.d.ts.map +1 -0
  203. package/dist/ports/vauban-finance-action.js +60 -0
  204. package/dist/ports/vauban-finance-action.js.map +1 -0
  205. package/dist/ports/workflow-runtime.d.ts +204 -0
  206. package/dist/ports/workflow-runtime.d.ts.map +1 -0
  207. package/dist/ports/workflow-runtime.js +72 -0
  208. package/dist/ports/workflow-runtime.js.map +1 -0
  209. package/dist/proof/cert-verify.d.ts +80 -0
  210. package/dist/proof/cert-verify.d.ts.map +1 -0
  211. package/dist/proof/cert-verify.js +178 -0
  212. package/dist/proof/cert-verify.js.map +1 -0
  213. package/dist/replay/replay.d.ts.map +1 -1
  214. package/dist/replay/replay.js +5 -1
  215. package/dist/replay/replay.js.map +1 -1
  216. package/dist/retry/index.d.ts +129 -0
  217. package/dist/retry/index.d.ts.map +1 -0
  218. package/dist/retry/index.js +156 -0
  219. package/dist/retry/index.js.map +1 -0
  220. package/dist/retry/presets.d.ts +39 -0
  221. package/dist/retry/presets.d.ts.map +1 -0
  222. package/dist/retry/presets.js +69 -0
  223. package/dist/retry/presets.js.map +1 -0
  224. package/dist/skill-loop/ab-runner.d.ts +67 -0
  225. package/dist/skill-loop/ab-runner.d.ts.map +1 -0
  226. package/dist/skill-loop/ab-runner.js +160 -0
  227. package/dist/skill-loop/ab-runner.js.map +1 -0
  228. package/dist/skill-loop/adoption.d.ts +67 -0
  229. package/dist/skill-loop/adoption.d.ts.map +1 -0
  230. package/dist/skill-loop/adoption.js +126 -0
  231. package/dist/skill-loop/adoption.js.map +1 -0
  232. package/dist/skill-loop/candidate.d.ts +45 -0
  233. package/dist/skill-loop/candidate.d.ts.map +1 -0
  234. package/dist/skill-loop/candidate.js +43 -0
  235. package/dist/skill-loop/candidate.js.map +1 -0
  236. package/dist/skill-loop/evaluator.d.ts +42 -0
  237. package/dist/skill-loop/evaluator.d.ts.map +1 -0
  238. package/dist/skill-loop/evaluator.js +184 -0
  239. package/dist/skill-loop/evaluator.js.map +1 -0
  240. package/dist/skill-loop/index.d.ts +27 -0
  241. package/dist/skill-loop/index.d.ts.map +1 -0
  242. package/dist/skill-loop/index.js +27 -0
  243. package/dist/skill-loop/index.js.map +1 -0
  244. package/dist/skill-loop/reflexion-replay.d.ts +87 -0
  245. package/dist/skill-loop/reflexion-replay.d.ts.map +1 -0
  246. package/dist/skill-loop/reflexion-replay.js +110 -0
  247. package/dist/skill-loop/reflexion-replay.js.map +1 -0
  248. package/dist/skill-loop/sign-off.d.ts +88 -0
  249. package/dist/skill-loop/sign-off.d.ts.map +1 -0
  250. package/dist/skill-loop/sign-off.js +146 -0
  251. package/dist/skill-loop/sign-off.js.map +1 -0
  252. package/dist/skill-loop/value-metric.d.ts +55 -0
  253. package/dist/skill-loop/value-metric.d.ts.map +1 -0
  254. package/dist/skill-loop/value-metric.js +69 -0
  255. package/dist/skill-loop/value-metric.js.map +1 -0
  256. package/dist/skill-loop/versioning.d.ts +36 -0
  257. package/dist/skill-loop/versioning.d.ts.map +1 -0
  258. package/dist/skill-loop/versioning.js +47 -0
  259. package/dist/skill-loop/versioning.js.map +1 -0
  260. package/dist/skill-manifest/anchor.d.ts +91 -0
  261. package/dist/skill-manifest/anchor.d.ts.map +1 -0
  262. package/dist/skill-manifest/anchor.js +331 -0
  263. package/dist/skill-manifest/anchor.js.map +1 -0
  264. package/dist/skill-manifest/builder.d.ts +47 -0
  265. package/dist/skill-manifest/builder.d.ts.map +1 -0
  266. package/dist/skill-manifest/builder.js +93 -0
  267. package/dist/skill-manifest/builder.js.map +1 -0
  268. package/dist/skill-manifest/index.d.ts +13 -0
  269. package/dist/skill-manifest/index.d.ts.map +1 -0
  270. package/dist/skill-manifest/index.js +9 -0
  271. package/dist/skill-manifest/index.js.map +1 -0
  272. package/dist/skill-manifest/types.d.ts +67 -0
  273. package/dist/skill-manifest/types.d.ts.map +1 -0
  274. package/dist/skill-manifest/types.js +16 -0
  275. package/dist/skill-manifest/types.js.map +1 -0
  276. package/dist/skill-manifest/verifier.d.ts +42 -0
  277. package/dist/skill-manifest/verifier.d.ts.map +1 -0
  278. package/dist/skill-manifest/verifier.js +136 -0
  279. package/dist/skill-manifest/verifier.js.map +1 -0
  280. package/dist/skills/brain-query.d.ts +4 -4
  281. package/dist/skills/brain-store.d.ts +6 -6
  282. package/dist/skills/errors.d.ts +15 -0
  283. package/dist/skills/errors.d.ts.map +1 -1
  284. package/dist/skills/errors.js +21 -0
  285. package/dist/skills/errors.js.map +1 -1
  286. package/dist/skills/hitl-request.d.ts +2 -2
  287. package/dist/skills/index.d.ts +3 -1
  288. package/dist/skills/index.d.ts.map +1 -1
  289. package/dist/skills/index.js +4 -1
  290. package/dist/skills/index.js.map +1 -1
  291. package/dist/skills/markdown/loader.d.ts +52 -0
  292. package/dist/skills/markdown/loader.d.ts.map +1 -0
  293. package/dist/skills/markdown/loader.js +93 -0
  294. package/dist/skills/markdown/loader.js.map +1 -0
  295. package/dist/skills/markdown/schema.d.ts +432 -0
  296. package/dist/skills/markdown/schema.d.ts.map +1 -0
  297. package/dist/skills/markdown/schema.js +121 -0
  298. package/dist/skills/markdown/schema.js.map +1 -0
  299. package/dist/skills/poc-md-loader/markdown-loader.d.ts +77 -0
  300. package/dist/skills/poc-md-loader/markdown-loader.d.ts.map +1 -0
  301. package/dist/skills/poc-md-loader/markdown-loader.js +125 -0
  302. package/dist/skills/poc-md-loader/markdown-loader.js.map +1 -0
  303. package/dist/skills/poc-md-loader/runner.d.ts +24 -0
  304. package/dist/skills/poc-md-loader/runner.d.ts.map +1 -0
  305. package/dist/skills/poc-md-loader/runner.js +57 -0
  306. package/dist/skills/poc-md-loader/runner.js.map +1 -0
  307. package/dist/skills/poc-md-loader/vitest.poc.config.d.ts +3 -0
  308. package/dist/skills/poc-md-loader/vitest.poc.config.d.ts.map +1 -0
  309. package/dist/skills/poc-md-loader/vitest.poc.config.js +13 -0
  310. package/dist/skills/poc-md-loader/vitest.poc.config.js.map +1 -0
  311. package/dist/skills/poc-md-loader/web-search/script.d.ts +33 -0
  312. package/dist/skills/poc-md-loader/web-search/script.d.ts.map +1 -0
  313. package/dist/skills/poc-md-loader/web-search/script.js +75 -0
  314. package/dist/skills/poc-md-loader/web-search/script.js.map +1 -0
  315. package/dist/skills/record-outcome.d.ts +4 -4
  316. package/dist/skills/send-email.d.ts.map +1 -1
  317. package/dist/skills/send-email.js +15 -3
  318. package/dist/skills/send-email.js.map +1 -1
  319. package/dist/skills/slack-notify.d.ts +4 -4
  320. package/dist/skills/starknet-balance.d.ts +1 -1
  321. package/dist/skills/telegram-notify.d.ts +4 -4
  322. package/dist/skills/web-search.d.ts +1 -1
  323. package/dist/testing/index.d.ts +3 -0
  324. package/dist/testing/test-brain-port.d.ts +4 -0
  325. package/dist/testing/test-brain-port.d.ts.map +1 -1
  326. package/dist/testing/test-brain-port.js +75 -20
  327. package/dist/testing/test-brain-port.js.map +1 -1
  328. package/dist/testing/test-event-bus.d.ts.map +1 -1
  329. package/dist/testing/test-event-bus.js +89 -36
  330. package/dist/testing/test-event-bus.js.map +1 -1
  331. package/dist/trace/schema.d.ts +1 -1
  332. package/dist/trace/schema.d.ts.map +1 -1
  333. package/dist/trace/schema.js +1 -1
  334. package/dist/trace/schema.js.map +1 -1
  335. package/dist/verify/formal/index.d.ts +44 -0
  336. package/dist/verify/formal/index.d.ts.map +1 -0
  337. package/dist/verify/formal/index.js +98 -0
  338. package/dist/verify/formal/index.js.map +1 -0
  339. package/dist/verify/formal/policy.d.ts +105 -0
  340. package/dist/verify/formal/policy.d.ts.map +1 -0
  341. package/dist/verify/formal/policy.js +159 -0
  342. package/dist/verify/formal/policy.js.map +1 -0
  343. package/dist/verify/formal/result.d.ts +50 -0
  344. package/dist/verify/formal/result.d.ts.map +1 -0
  345. package/dist/verify/formal/result.js +21 -0
  346. package/dist/verify/formal/result.js.map +1 -0
  347. package/dist/verify/formal/solver.d.ts +67 -0
  348. package/dist/verify/formal/solver.d.ts.map +1 -0
  349. package/dist/verify/formal/solver.js +184 -0
  350. package/dist/verify/formal/solver.js.map +1 -0
  351. package/dist/verify/formal/spec-language.d.ts +80 -0
  352. package/dist/verify/formal/spec-language.d.ts.map +1 -0
  353. package/dist/verify/formal/spec-language.js +219 -0
  354. package/dist/verify/formal/spec-language.js.map +1 -0
  355. package/docs/attestation.md +199 -0
  356. package/docs/identity.md +193 -0
  357. package/package.json +34 -17
  358. package/src/adapters/llm/anthropic-direct.ts +51 -0
  359. package/src/adapters/llm/cascade.ts +64 -19
  360. package/src/adapters/llm/litellm.ts +49 -0
  361. package/src/compute/difficulty-estimator.ts +111 -0
  362. package/src/compute/strategies/mixture-of-agents.ts +150 -0
  363. package/src/compute/strategies/tree-of-thoughts.ts +293 -0
  364. package/src/compute/strategies/two-phase-orient.ts +147 -0
  365. package/src/container/protocol.ts +243 -0
  366. package/src/container/runtime.ts +424 -0
  367. package/src/db/migrations/026_formal_verify_results.sql +30 -0
  368. package/src/identity/agent-persona.ts +203 -0
  369. package/src/identity/persona-prompt.ts +84 -0
  370. package/src/identity/persona-schema.ts +127 -0
  371. package/src/index.ts +338 -1
  372. package/src/memory/episodic-rrf.ts +224 -0
  373. package/src/mesh/attenuation.ts +190 -0
  374. package/src/mesh/delegate.ts +254 -0
  375. package/src/mesh/dispatcher.ts +301 -0
  376. package/src/mesh/index.ts +39 -0
  377. package/src/mesh/types.ts +31 -0
  378. package/src/orchestration/ooda/skills.ts +177 -0
  379. package/src/ports/bastion-action.contract.test.ts +355 -0
  380. package/src/ports/bastion-action.ts +198 -0
  381. package/src/ports/brain.ts +177 -15
  382. package/src/ports/citadel-action.contract.test.ts +430 -0
  383. package/src/ports/citadel-action.ts +174 -0
  384. package/src/ports/compliance-contract.ts +191 -0
  385. package/src/ports/db.ts +98 -0
  386. package/src/ports/delegation.contract.test.ts +428 -0
  387. package/src/ports/delegation.ts +211 -0
  388. package/src/ports/event-bus.ts +133 -0
  389. package/src/ports/federation.contract.test.ts +355 -0
  390. package/src/ports/federation.ts +190 -0
  391. package/src/ports/index.ts +186 -1
  392. package/src/ports/llm-provider.ts +123 -0
  393. package/src/ports/logger.ts +104 -0
  394. package/src/ports/manifest-registry.contract.test.ts +324 -0
  395. package/src/ports/manifest-registry.ts +188 -0
  396. package/src/ports/observability.contract.test.ts +315 -0
  397. package/src/ports/observability.ts +150 -0
  398. package/src/ports/outcome.ts +69 -0
  399. package/src/ports/privacy.contract.test.ts +413 -0
  400. package/src/ports/privacy.ts +207 -0
  401. package/src/ports/tenant-context.contract.test.ts +454 -0
  402. package/src/ports/tenant-context.ts +150 -0
  403. package/src/ports/vauban-finance-action.contract.test.ts +335 -0
  404. package/src/ports/vauban-finance-action.ts +166 -0
  405. package/src/ports/workflow-runtime.ts +327 -0
  406. package/src/proof/cert-verify.ts +249 -0
  407. package/src/replay/replay.ts +11 -8
  408. package/src/retry/index.ts +227 -0
  409. package/src/retry/presets.ts +75 -0
  410. package/src/skill-loop/ab-runner.ts +196 -0
  411. package/src/skill-loop/adoption.ts +188 -0
  412. package/src/skill-loop/candidate.ts +75 -0
  413. package/src/skill-loop/evaluator.ts +238 -0
  414. package/src/skill-loop/index.ts +51 -0
  415. package/src/skill-loop/reflexion-replay.ts +173 -0
  416. package/src/skill-loop/sign-off.ts +247 -0
  417. package/src/skill-loop/value-metric.ts +120 -0
  418. package/src/skill-loop/versioning.ts +75 -0
  419. package/src/skill-manifest/anchor.ts +401 -0
  420. package/src/skill-manifest/builder.ts +129 -0
  421. package/src/skill-manifest/index.ts +18 -0
  422. package/src/skill-manifest/types.ts +72 -0
  423. package/src/skill-manifest/verifier.ts +198 -0
  424. package/src/skills/errors.ts +30 -2
  425. package/src/skills/index.ts +19 -0
  426. package/src/skills/markdown/loader.ts +129 -0
  427. package/src/skills/markdown/schema.ts +144 -0
  428. package/src/skills/poc-md-loader/e2e-parity.test.ts +237 -0
  429. package/src/skills/poc-md-loader/markdown-loader.ts +161 -0
  430. package/src/skills/poc-md-loader/runner.ts +82 -0
  431. package/src/skills/poc-md-loader/vitest.poc.config.ts +13 -0
  432. package/src/skills/poc-md-loader/web-search/SKILL.md +42 -0
  433. package/src/skills/poc-md-loader/web-search/script.ts +109 -0
  434. package/src/skills/send-email.ts +15 -3
  435. package/src/testing/test-brain-port.ts +98 -24
  436. package/src/testing/test-event-bus.ts +104 -43
  437. package/src/trace/schema.ts +1 -1
  438. package/src/verify/formal/index.ts +154 -0
  439. package/src/verify/formal/policy.ts +253 -0
  440. package/src/verify/formal/result.ts +52 -0
  441. package/src/verify/formal/solver.ts +235 -0
  442. package/src/verify/formal/spec-language.ts +274 -0
@@ -5,314 +5,320 @@
5
5
  * additional helpers MUST remain unexported.
6
6
  */
7
7
  import { SpanStatusCode } from "@opentelemetry/api";
8
- import { agentSpan, getTracer, llmSpan, recordLlmUsage, recordToolResult, toolSpan, } from "../tracking/gen-ai.js";
9
- import { compactToolLog, createCoherenceDetector, emergencyContextSummary, } from "../budget/budget-state.js";
8
+ import {
9
+ agentSpan,
10
+ getTracer,
11
+ llmSpan,
12
+ recordLlmUsage,
13
+ recordToolResult,
14
+ toolSpan,
15
+ } from "../tracking/gen-ai.js";
16
+ import {
17
+ compactToolLog,
18
+ createCoherenceDetector,
19
+ emergencyContextSummary,
20
+ } from "../budget/budget-state.js";
10
21
  class AgentLoopImpl {
11
- config;
12
- tracer;
13
- constructor(config) {
14
- this.config = config;
15
- this.tracer = config.tracer ?? getTracer("vauban-agent-sdk");
16
- }
17
- async run(userMessage) {
18
- const runId = cryptoRandomId();
19
- const rootSpan = agentSpan(this.tracer, {
20
- agentId: this.config.agentId,
21
- agentVersion: this.config.agentVersion,
22
- runId,
23
- });
24
- const traceId = rootSpan.spanContext().traceId;
25
- const log = [
26
- { role: "system", content: this.config.systemPrompt },
27
- { role: "user", content: userMessage },
28
- ];
29
- const coherence = createCoherenceDetector();
30
- const recentCalls = [];
31
- let stepsWithoutTool = 0;
32
- let stopReason = "complete";
33
- let finalMessage = "";
34
- /** Cumulative tool-call cost across the loop (USD), for the gate. */
35
- let budgetUsedUsd = 0;
36
- try {
37
- while (true) {
38
- if (this.config.budget.stepCount >= this.config.budget.maxSteps) {
39
- stopReason = "budget_exhausted";
40
- break;
41
- }
42
- // Auto-renewal: best-effort, debounced inside the manager. A
43
- // failed renewal is non-fatal — the existing token may still be
44
- // valid; the gate will deny on the next call if it expired.
45
- if (this.config.renewalManager) {
46
- try {
47
- await this.config.renewalManager.maybeRenew();
48
- }
49
- catch {
50
- /* swallow — verifier will surface expiry on next call */
51
- }
52
- }
53
- // Compaction trigger.
54
- if (this.config.budget.stepCount > 0 &&
55
- this.config.budget.stepCount === this.config.budget.compactionTrigger) {
56
- const before = this.config.budget.contextWindow.currentTokens;
57
- const compacted = compactToolLog(log);
58
- log.splice(0, log.length, ...compacted);
59
- rootSpan.addEvent("gen_ai.agent.compacted", {
60
- before_tokens: before,
61
- after_tokens: this.config.budget.contextWindow.currentTokens,
62
- });
63
- }
64
- // Emergency summary if context > 90% of max.
65
- const { contextWindow } = this.config.budget;
66
- if (contextWindow.maxTokens > 0 &&
67
- contextWindow.currentTokens >
68
- Math.floor(contextWindow.maxTokens * 0.9)) {
69
- try {
70
- const summary = await emergencyContextSummary(log, async (prompt) => {
71
- const res = await this.config.provider.complete({
72
- messages: [{ role: "user", content: prompt }],
73
- maxTokens: 1024,
74
- });
75
- return res.content;
76
- }, { recursion: false });
77
- log.splice(0, log.length, {
78
- role: "system",
79
- content: `[context recap] ${summary}`,
80
- });
81
- contextWindow.currentTokens = estimateTokens(summary);
82
- rootSpan.addEvent("gen_ai.agent.emergency_summary", {
83
- tokens_after: contextWindow.currentTokens,
84
- });
85
- }
86
- catch (err) {
87
- rootSpan.addEvent("gen_ai.agent.emergency_summary_failed", {
88
- error: err?.message ?? String(err),
89
- });
90
- }
91
- }
92
- // ─── LLM round-trip ─────────────────────────────────────────────
93
- const lSpan = llmSpan(this.tracer, {
94
- provider: "router",
95
- model: "auto",
96
- maxTokens: this.config.budget.tokensBudget.output,
97
- messageCount: log.length,
98
- });
99
- let response;
100
- try {
101
- response = await this.config.provider.complete({
102
- messages: log.map((m) => ({ role: m.role, content: m.content })),
103
- maxTokens: this.config.budget.tokensBudget.output,
104
- });
105
- recordLlmUsage(lSpan, {
106
- inputTokens: response.usage.inputTokens,
107
- outputTokens: response.usage.outputTokens,
108
- latencyMs: response.latencyMs,
109
- finishReason: response.toolCalls.length > 0 ? "tool_use" : "stop",
110
- });
111
- lSpan.setAttribute("gen_ai.system", response.provider);
112
- lSpan.setStatus({ code: SpanStatusCode.OK });
113
- }
114
- catch (err) {
115
- lSpan.setStatus({
116
- code: SpanStatusCode.ERROR,
117
- message: err?.message,
118
- });
119
- lSpan.recordException(err);
120
- lSpan.end();
121
- throw err;
122
- }
123
- finally {
124
- if (lSpan.isRecording())
125
- lSpan.end();
126
- }
127
- // Counters.
128
- this.config.budget.stepCount += 1;
129
- this.config.budget.tokensBudget.usedInput += response.usage.inputTokens;
130
- this.config.budget.tokensBudget.usedOutput +=
131
- response.usage.outputTokens;
132
- this.config.budget.contextWindow.currentTokens +=
133
- response.usage.inputTokens + response.usage.outputTokens;
134
- await this.config.tracker?.recordStep({
135
- inputTokens: response.usage.inputTokens,
136
- outputTokens: response.usage.outputTokens,
137
- toolCalls: response.toolCalls.length,
138
- costUsd: 0,
139
- });
140
- // ─── No tool call → assistant finalises. ────────────────────────
141
- if (response.toolCalls.length === 0) {
142
- log.push({ role: "assistant", content: response.content });
143
- finalMessage = response.content;
144
- stopReason = "complete";
145
- break;
146
- }
147
- log.push({ role: "assistant", content: response.content });
148
- stepsWithoutTool = 0;
149
- // ─── Execute each tool call sequentially. ───────────────────────
150
- let userCancelled = false;
151
- for (const tc of response.toolCalls) {
152
- recentCalls.push({ name: tc.name, args: tc.args });
153
- const tool = this.config.tools.get(tc.name);
154
- const isDangerous = tool?.dangerous === true;
155
- // ─── Capability gate (Biscuit) — pre-dispatch. ────────────────
156
- if (this.config.capabilityGate) {
157
- let verdict;
158
- try {
159
- verdict = await this.config.capabilityGate.verify({
160
- toolName: tc.name,
161
- budgetUsed: budgetUsedUsd,
162
- mcpScopes: tool?.mcpScopes,
163
- });
164
- }
165
- catch {
166
- verdict = { allowed: false, reason: "gate_error" };
167
- }
168
- if (!verdict.allowed) {
169
- try {
170
- this.config.onToolDenied?.({
171
- toolName: tc.name,
172
- reason: verdict.reason,
173
- budgetUsed: budgetUsedUsd,
174
- });
175
- }
176
- catch {
177
- /* best-effort */
178
- }
179
- rootSpan.addEvent("gen_ai.tool.denied", {
180
- tool_name: tc.name,
181
- reason: verdict.reason,
182
- });
183
- log.push({
184
- role: "tool",
185
- content: `ERROR: capability_denied:${verdict.reason}`,
186
- toolName: tc.name,
187
- });
188
- continue; // Token expiry / scope deny is graceful — try next call.
189
- }
190
- // Account this call against the per-loop budget for the
191
- // verifier on subsequent calls.
192
- budgetUsedUsd += this.config.costPerToolCallUsd ?? 0;
193
- }
194
- if (isDangerous) {
195
- if (!this.config.approvalChannel) {
196
- stopReason = "user_cancelled";
197
- userCancelled = true;
198
- break;
199
- }
200
- const approved = await this.awaitApproval(tc);
201
- if (!approved) {
202
- stopReason = "user_cancelled";
203
- userCancelled = true;
204
- break;
205
- }
206
- }
207
- const tSpan = toolSpan(this.tracer, tc.name, tc.args);
208
- const result = await this.config.tools.execute(tc.name, tc.args);
209
- recordToolResult(tSpan, {
210
- success: result.ok,
211
- errorMessage: result.ok ? undefined : result.error.message,
212
- });
213
- tSpan.end();
214
- const toolContent = summariseToolResult(result);
215
- log.push({ role: "tool", content: toolContent, toolName: tc.name });
216
- }
217
- if (userCancelled)
218
- break;
219
- // ─── Coherence check on tool loop / stall. ──────────────────────
220
- const verdict = coherence.check(recentCalls, stepsWithoutTool);
221
- this.config.budget.coherenceScore = verdict.score;
222
- if (verdict.isLoop || verdict.isStall) {
223
- stopReason = "incoherent";
224
- rootSpan.addEvent("gen_ai.agent.incoherent", {
225
- is_loop: verdict.isLoop,
226
- is_stall: verdict.isStall,
227
- });
228
- break;
229
- }
230
- }
231
- rootSpan.setAttribute("gen_ai.agent.stop_reason", stopReason);
232
- rootSpan.setStatus({ code: SpanStatusCode.OK });
233
- return {
234
- finalMessage,
235
- stopReason,
236
- budgetFinal: this.config.budget,
237
- traceId,
238
- };
22
+ config;
23
+ tracer;
24
+ constructor(config) {
25
+ this.config = config;
26
+ this.tracer = config.tracer ?? getTracer("vauban-agent-sdk");
27
+ }
28
+ async run(userMessage) {
29
+ const runId = cryptoRandomId();
30
+ const rootSpan = agentSpan(this.tracer, {
31
+ agentId: this.config.agentId,
32
+ agentVersion: this.config.agentVersion,
33
+ runId,
34
+ });
35
+ const traceId = rootSpan.spanContext().traceId;
36
+ const log = [
37
+ { role: "system", content: this.config.systemPrompt },
38
+ { role: "user", content: userMessage },
39
+ ];
40
+ const coherence = createCoherenceDetector();
41
+ const recentCalls = [];
42
+ let stepsWithoutTool = 0;
43
+ let stopReason = "complete";
44
+ let finalMessage = "";
45
+ /** Cumulative tool-call cost across the loop (USD), for the gate. */
46
+ let budgetUsedUsd = 0;
47
+ try {
48
+ while (true) {
49
+ if (this.config.budget.stepCount >= this.config.budget.maxSteps) {
50
+ stopReason = "budget_exhausted";
51
+ break;
52
+ }
53
+ // Auto-renewal: best-effort, debounced inside the manager. A
54
+ // failed renewal is non-fatal — the existing token may still be
55
+ // valid; the gate will deny on the next call if it expired.
56
+ if (this.config.renewalManager) {
57
+ try {
58
+ await this.config.renewalManager.maybeRenew();
59
+ } catch {
60
+ /* swallow — verifier will surface expiry on next call */
61
+ }
239
62
  }
240
- catch (err) {
241
- rootSpan.recordException(err);
242
- rootSpan.setStatus({
243
- code: SpanStatusCode.ERROR,
244
- message: err?.message,
63
+ // Compaction trigger.
64
+ if (
65
+ this.config.budget.stepCount > 0 &&
66
+ this.config.budget.stepCount === this.config.budget.compactionTrigger
67
+ ) {
68
+ const before = this.config.budget.contextWindow.currentTokens;
69
+ const compacted = compactToolLog(log);
70
+ log.splice(0, log.length, ...compacted);
71
+ rootSpan.addEvent("gen_ai.agent.compacted", {
72
+ before_tokens: before,
73
+ after_tokens: this.config.budget.contextWindow.currentTokens,
74
+ });
75
+ }
76
+ // Emergency summary if context > 90% of max.
77
+ const { contextWindow } = this.config.budget;
78
+ if (
79
+ contextWindow.maxTokens > 0 &&
80
+ contextWindow.currentTokens >
81
+ Math.floor(contextWindow.maxTokens * 0.9)
82
+ ) {
83
+ try {
84
+ const summary = await emergencyContextSummary(
85
+ log,
86
+ async (prompt) => {
87
+ const res = await this.config.provider.complete({
88
+ messages: [{ role: "user", content: prompt }],
89
+ maxTokens: 1024,
90
+ });
91
+ return res.content;
92
+ },
93
+ { recursion: false }
94
+ );
95
+ log.splice(0, log.length, {
96
+ role: "system",
97
+ content: `[context recap] ${summary}`,
98
+ });
99
+ contextWindow.currentTokens = estimateTokens(summary);
100
+ rootSpan.addEvent("gen_ai.agent.emergency_summary", {
101
+ tokens_after: contextWindow.currentTokens,
102
+ });
103
+ } catch (err) {
104
+ rootSpan.addEvent("gen_ai.agent.emergency_summary_failed", {
105
+ error: err?.message ?? String(err),
245
106
  });
246
- return {
247
- finalMessage: "",
248
- stopReason: "error",
249
- budgetFinal: this.config.budget,
250
- traceId,
251
- };
107
+ }
252
108
  }
253
- finally {
254
- rootSpan.end();
109
+ // ─── LLM round-trip ─────────────────────────────────────────────
110
+ const lSpan = llmSpan(this.tracer, {
111
+ provider: "router",
112
+ model: "auto",
113
+ maxTokens: this.config.budget.tokensBudget.output,
114
+ messageCount: log.length,
115
+ });
116
+ let response;
117
+ try {
118
+ response = await this.config.provider.complete({
119
+ messages: log.map((m) => ({ role: m.role, content: m.content })),
120
+ maxTokens: this.config.budget.tokensBudget.output,
121
+ });
122
+ recordLlmUsage(lSpan, {
123
+ inputTokens: response.usage.inputTokens,
124
+ outputTokens: response.usage.outputTokens,
125
+ latencyMs: response.latencyMs,
126
+ finishReason: response.toolCalls.length > 0 ? "tool_use" : "stop",
127
+ });
128
+ lSpan.setAttribute("gen_ai.system", response.provider);
129
+ lSpan.setStatus({ code: SpanStatusCode.OK });
130
+ } catch (err) {
131
+ lSpan.setStatus({
132
+ code: SpanStatusCode.ERROR,
133
+ message: err?.message,
134
+ });
135
+ lSpan.recordException(err);
136
+ lSpan.end();
137
+ throw err;
138
+ } finally {
139
+ if (lSpan.isRecording()) lSpan.end();
255
140
  }
256
- }
257
- async awaitApproval(tc) {
258
- const channel = this.config.approvalChannel;
259
- if (!channel)
260
- return false;
261
- const timeoutMs = this.config.approvalTimeoutMs ?? 60_000;
262
- const pollMs = this.config.approvalPollIntervalMs ?? 500;
263
- const requestId = await channel.send({
264
- agentId: this.config.agentId,
265
- action: tc.name,
266
- context: safeStringify(tc.args),
267
- timeoutMs,
141
+ // Counters.
142
+ this.config.budget.stepCount += 1;
143
+ this.config.budget.tokensBudget.usedInput += response.usage.inputTokens;
144
+ this.config.budget.tokensBudget.usedOutput +=
145
+ response.usage.outputTokens;
146
+ this.config.budget.contextWindow.currentTokens +=
147
+ response.usage.inputTokens + response.usage.outputTokens;
148
+ await this.config.tracker?.recordStep({
149
+ inputTokens: response.usage.inputTokens,
150
+ outputTokens: response.usage.outputTokens,
151
+ toolCalls: response.toolCalls.length,
152
+ costUsd: 0,
268
153
  });
269
- const deadline = Date.now() + timeoutMs;
270
- while (Date.now() < deadline) {
271
- const verdict = await channel.poll(requestId);
272
- if (verdict !== null) {
273
- return verdict.approved === true;
154
+ // ─── No tool call → assistant finalises. ────────────────────────
155
+ if (response.toolCalls.length === 0) {
156
+ log.push({ role: "assistant", content: response.content });
157
+ finalMessage = response.content;
158
+ stopReason = "complete";
159
+ break;
160
+ }
161
+ log.push({ role: "assistant", content: response.content });
162
+ stepsWithoutTool = 0;
163
+ // ─── Execute each tool call sequentially. ───────────────────────
164
+ let userCancelled = false;
165
+ for (const tc of response.toolCalls) {
166
+ recentCalls.push({ name: tc.name, args: tc.args });
167
+ const tool = this.config.tools.get(tc.name);
168
+ const isDangerous = tool?.dangerous === true;
169
+ // ─── Capability gate (Biscuit) — pre-dispatch. ────────────────
170
+ if (this.config.capabilityGate) {
171
+ let verdict;
172
+ try {
173
+ verdict = await this.config.capabilityGate.verify({
174
+ toolName: tc.name,
175
+ budgetUsed: budgetUsedUsd,
176
+ mcpScopes: tool?.mcpScopes,
177
+ });
178
+ } catch {
179
+ verdict = { allowed: false, reason: "gate_error" };
180
+ }
181
+ if (!verdict.allowed) {
182
+ try {
183
+ this.config.onToolDenied?.({
184
+ toolName: tc.name,
185
+ reason: verdict.reason,
186
+ budgetUsed: budgetUsedUsd,
187
+ });
188
+ } catch {
189
+ /* best-effort */
190
+ }
191
+ rootSpan.addEvent("gen_ai.tool.denied", {
192
+ tool_name: tc.name,
193
+ reason: verdict.reason,
194
+ });
195
+ log.push({
196
+ role: "tool",
197
+ content: `ERROR: capability_denied:${verdict.reason}`,
198
+ toolName: tc.name,
199
+ });
200
+ continue; // Token expiry / scope deny is graceful — try next call.
201
+ }
202
+ // Account this call against the per-loop budget for the
203
+ // verifier on subsequent calls.
204
+ budgetUsedUsd += this.config.costPerToolCallUsd ?? 0;
205
+ }
206
+ if (isDangerous) {
207
+ if (!this.config.approvalChannel) {
208
+ stopReason = "user_cancelled";
209
+ userCancelled = true;
210
+ break;
274
211
  }
275
- await sleep(pollMs);
212
+ const approved = await this.awaitApproval(tc);
213
+ if (!approved) {
214
+ stopReason = "user_cancelled";
215
+ userCancelled = true;
216
+ break;
217
+ }
218
+ }
219
+ const tSpan = toolSpan(this.tracer, tc.name, tc.args);
220
+ const result = await this.config.tools.execute(tc.name, tc.args);
221
+ recordToolResult(tSpan, {
222
+ success: result.ok,
223
+ errorMessage: result.ok ? undefined : result.error.message,
224
+ });
225
+ tSpan.end();
226
+ const toolContent = summariseToolResult(result);
227
+ log.push({ role: "tool", content: toolContent, toolName: tc.name });
276
228
  }
277
- await channel.cancel(requestId).catch(() => {
278
- /* best-effort */
279
- });
280
- return false;
229
+ if (userCancelled) break;
230
+ // ─── Coherence check on tool loop / stall. ──────────────────────
231
+ const verdict = coherence.check(recentCalls, stepsWithoutTool);
232
+ this.config.budget.coherenceScore = verdict.score;
233
+ if (verdict.isLoop || verdict.isStall) {
234
+ stopReason = "incoherent";
235
+ rootSpan.addEvent("gen_ai.agent.incoherent", {
236
+ is_loop: verdict.isLoop,
237
+ is_stall: verdict.isStall,
238
+ });
239
+ break;
240
+ }
241
+ }
242
+ rootSpan.setAttribute("gen_ai.agent.stop_reason", stopReason);
243
+ rootSpan.setStatus({ code: SpanStatusCode.OK });
244
+ return {
245
+ finalMessage,
246
+ stopReason,
247
+ budgetFinal: this.config.budget,
248
+ traceId,
249
+ };
250
+ } catch (err) {
251
+ rootSpan.recordException(err);
252
+ rootSpan.setStatus({
253
+ code: SpanStatusCode.ERROR,
254
+ message: err?.message,
255
+ });
256
+ return {
257
+ finalMessage: "",
258
+ stopReason: "error",
259
+ budgetFinal: this.config.budget,
260
+ traceId,
261
+ };
262
+ } finally {
263
+ rootSpan.end();
281
264
  }
265
+ }
266
+ async awaitApproval(tc) {
267
+ const channel = this.config.approvalChannel;
268
+ if (!channel) return false;
269
+ const timeoutMs = this.config.approvalTimeoutMs ?? 60_000;
270
+ const pollMs = this.config.approvalPollIntervalMs ?? 500;
271
+ const requestId = await channel.send({
272
+ agentId: this.config.agentId,
273
+ action: tc.name,
274
+ context: safeStringify(tc.args),
275
+ timeoutMs,
276
+ });
277
+ const deadline = Date.now() + timeoutMs;
278
+ while (Date.now() < deadline) {
279
+ const verdict = await channel.poll(requestId);
280
+ if (verdict !== null) {
281
+ return verdict.approved === true;
282
+ }
283
+ await sleep(pollMs);
284
+ }
285
+ await channel.cancel(requestId).catch(() => {
286
+ /* best-effort */
287
+ });
288
+ return false;
289
+ }
282
290
  }
283
291
  // ─── Helpers (unexported) ─────────────────────────────────────────────────
284
292
  function cryptoRandomId() {
285
- const bytes = new Uint8Array(8);
286
- if (typeof globalThis.crypto?.getRandomValues === "function") {
287
- globalThis.crypto.getRandomValues(bytes);
288
- }
289
- else {
290
- for (let i = 0; i < bytes.length; i++) {
291
- bytes[i] = Math.floor(Math.random() * 256);
292
- }
293
+ const bytes = new Uint8Array(8);
294
+ if (typeof globalThis.crypto?.getRandomValues === "function") {
295
+ globalThis.crypto.getRandomValues(bytes);
296
+ } else {
297
+ for (let i = 0; i < bytes.length; i++) {
298
+ bytes[i] = Math.floor(Math.random() * 256);
293
299
  }
294
- return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
300
+ }
301
+ return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
295
302
  }
296
303
  function safeStringify(v) {
297
- try {
298
- return typeof v === "string" ? v : (JSON.stringify(v) ?? "null");
299
- }
300
- catch {
301
- return "[unserialisable]";
302
- }
304
+ try {
305
+ return typeof v === "string" ? v : JSON.stringify(v) ?? "null";
306
+ } catch {
307
+ return "[unserialisable]";
308
+ }
303
309
  }
304
310
  function summariseToolResult(r) {
305
- if (r.ok) {
306
- return safeStringify(r.data).slice(0, 2000);
307
- }
308
- return `ERROR: ${r.error.message}`;
311
+ if (r.ok) {
312
+ return safeStringify(r.data).slice(0, 2000);
313
+ }
314
+ return `ERROR: ${r.error.message}`;
309
315
  }
310
316
  function sleep(ms) {
311
- return new Promise((resolve) => setTimeout(resolve, ms));
317
+ return new Promise((resolve) => setTimeout(resolve, ms));
312
318
  }
313
319
  function estimateTokens(s) {
314
- return Math.ceil(s.length / 4);
320
+ return Math.ceil(s.length / 4);
315
321
  }
316
322
  // ─── PUBLIC SURFACE ───────────────────────────────────────────────────────
317
323
  export { AgentLoopImpl as AgentLoop };
318
- //# sourceMappingURL=minimal-loop.js.map
324
+ //# sourceMappingURL=minimal-loop.js.map