@vauban-org/agent-sdk 0.17.4 → 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 (506) 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 +327 -30
  39. package/dist/events/catalogue.d.ts.map +1 -1
  40. package/dist/events/catalogue.js +18 -0
  41. package/dist/events/catalogue.js.map +1 -1
  42. package/dist/events/index.d.ts +9 -0
  43. package/dist/events/index.d.ts.map +1 -1
  44. package/dist/events/index.js +9 -0
  45. package/dist/events/index.js.map +1 -1
  46. package/dist/events/schemas/agent.completed.v1.d.ts +4 -4
  47. package/dist/events/schemas/agent.failed.v1.d.ts +2 -2
  48. package/dist/events/schemas/agent.hitl_resolved.v1.d.ts +2 -2
  49. package/dist/events/schemas/agent.started.v1.d.ts +2 -2
  50. package/dist/events/schemas/brain.skill.extracted.v1.d.ts +4 -4
  51. package/dist/events/schemas/cc.cost.anomaly_detected.v1.d.ts +2 -2
  52. package/dist/events/schemas/cc.cost.recorded.v1.d.ts +4 -4
  53. package/dist/events/schemas/citadel.sprint.analyzed.v1.d.ts +55 -0
  54. package/dist/events/schemas/citadel.sprint.analyzed.v1.d.ts.map +1 -0
  55. package/dist/events/schemas/citadel.sprint.analyzed.v1.js +22 -0
  56. package/dist/events/schemas/citadel.sprint.analyzed.v1.js.map +1 -0
  57. package/dist/events/schemas/citadel.sprint.closed.v1.d.ts +2 -2
  58. package/dist/events/schemas/forge.inbox.reply_classified.v1.d.ts +33 -0
  59. package/dist/events/schemas/forge.inbox.reply_classified.v1.d.ts.map +1 -0
  60. package/dist/events/schemas/forge.inbox.reply_classified.v1.js +15 -0
  61. package/dist/events/schemas/forge.inbox.reply_classified.v1.js.map +1 -0
  62. package/dist/events/schemas/forge.lead.qualified.v1.d.ts +2 -2
  63. package/dist/events/schemas/forge.outreach.sent.v1.d.ts +4 -4
  64. package/dist/events/schemas/incident.detected.v1.d.ts +2 -2
  65. package/dist/events/schemas/vauban-finance.forecast.generated.v1.d.ts +21 -0
  66. package/dist/events/schemas/vauban-finance.forecast.generated.v1.d.ts.map +1 -0
  67. package/dist/events/schemas/vauban-finance.forecast.generated.v1.js +11 -0
  68. package/dist/events/schemas/vauban-finance.forecast.generated.v1.js.map +1 -0
  69. package/dist/events/schemas/vauban-finance.trade.executed.v1.d.ts +24 -0
  70. package/dist/events/schemas/vauban-finance.trade.executed.v1.d.ts.map +1 -0
  71. package/dist/events/schemas/vauban-finance.trade.executed.v1.js +12 -0
  72. package/dist/events/schemas/vauban-finance.trade.executed.v1.js.map +1 -0
  73. package/dist/events/schemas/vauban.goal.checked.v1.d.ts +21 -0
  74. package/dist/events/schemas/vauban.goal.checked.v1.d.ts.map +1 -0
  75. package/dist/events/schemas/vauban.goal.checked.v1.js +11 -0
  76. package/dist/events/schemas/vauban.goal.checked.v1.js.map +1 -0
  77. package/dist/events/schemas/vauban.rebalancing.checked.v1.d.ts +21 -0
  78. package/dist/events/schemas/vauban.rebalancing.checked.v1.d.ts.map +1 -0
  79. package/dist/events/schemas/vauban.rebalancing.checked.v1.js +11 -0
  80. package/dist/events/schemas/vauban.rebalancing.checked.v1.js.map +1 -0
  81. package/dist/events/schemas/vauban.tax.checked.v1.d.ts +21 -0
  82. package/dist/events/schemas/vauban.tax.checked.v1.d.ts.map +1 -0
  83. package/dist/events/schemas/vauban.tax.checked.v1.js +11 -0
  84. package/dist/events/schemas/vauban.tax.checked.v1.js.map +1 -0
  85. package/dist/events/schemas/vauban.vault.analyzed.v1.d.ts +59 -0
  86. package/dist/events/schemas/vauban.vault.analyzed.v1.d.ts.map +1 -0
  87. package/dist/events/schemas/vauban.vault.analyzed.v1.js +19 -0
  88. package/dist/events/schemas/vauban.vault.analyzed.v1.js.map +1 -0
  89. package/dist/events/schemas/vauban.vault.compounded.v1.d.ts +24 -0
  90. package/dist/events/schemas/vauban.vault.compounded.v1.d.ts.map +1 -0
  91. package/dist/events/schemas/vauban.vault.compounded.v1.js +12 -0
  92. package/dist/events/schemas/vauban.vault.compounded.v1.js.map +1 -0
  93. package/dist/identity/agent-persona.d.ts +73 -0
  94. package/dist/identity/agent-persona.d.ts.map +1 -0
  95. package/dist/identity/agent-persona.js +165 -0
  96. package/dist/identity/agent-persona.js.map +1 -0
  97. package/dist/identity/persona-prompt.d.ts +25 -0
  98. package/dist/identity/persona-prompt.d.ts.map +1 -0
  99. package/dist/identity/persona-prompt.js +71 -0
  100. package/dist/identity/persona-prompt.js.map +1 -0
  101. package/dist/identity/persona-schema.d.ts +120 -0
  102. package/dist/identity/persona-schema.d.ts.map +1 -0
  103. package/dist/identity/persona-schema.js +103 -0
  104. package/dist/identity/persona-schema.js.map +1 -0
  105. package/dist/index.d.ts +37 -2
  106. package/dist/index.d.ts.map +1 -1
  107. package/dist/index.js +29 -1
  108. package/dist/index.js.map +1 -1
  109. package/dist/loop/index.d.ts +1 -1
  110. package/dist/loop/index.d.ts.map +1 -1
  111. package/dist/loop/index.js.map +1 -1
  112. package/dist/loop/minimal-loop.js +293 -287
  113. package/dist/loop/sdk-loop.d.ts +1 -3
  114. package/dist/loop/sdk-loop.d.ts.map +1 -1
  115. package/dist/loop/sdk-loop.js +1 -1
  116. package/dist/loop/sdk-loop.js.map +1 -1
  117. package/dist/memory/episodic-rrf.d.ts +114 -0
  118. package/dist/memory/episodic-rrf.d.ts.map +1 -0
  119. package/dist/memory/episodic-rrf.js +148 -0
  120. package/dist/memory/episodic-rrf.js.map +1 -0
  121. package/dist/mesh/attenuation.d.ts +78 -0
  122. package/dist/mesh/attenuation.d.ts.map +1 -0
  123. package/dist/mesh/attenuation.js +141 -0
  124. package/dist/mesh/attenuation.js.map +1 -0
  125. package/dist/mesh/delegate.d.ts +96 -0
  126. package/dist/mesh/delegate.d.ts.map +1 -0
  127. package/dist/mesh/delegate.js +172 -0
  128. package/dist/mesh/delegate.js.map +1 -0
  129. package/dist/mesh/dispatcher.d.ts +119 -0
  130. package/dist/mesh/dispatcher.d.ts.map +1 -0
  131. package/dist/mesh/dispatcher.js +207 -0
  132. package/dist/mesh/dispatcher.js.map +1 -0
  133. package/dist/mesh/index.d.ts +12 -0
  134. package/dist/mesh/index.d.ts.map +1 -0
  135. package/dist/mesh/index.js +11 -0
  136. package/dist/mesh/index.js.map +1 -0
  137. package/dist/mesh/types.d.ts +30 -0
  138. package/dist/mesh/types.d.ts.map +1 -0
  139. package/dist/mesh/types.js +11 -0
  140. package/dist/mesh/types.js.map +1 -0
  141. package/dist/orchestration/ooda/skills.d.ts +104 -0
  142. package/dist/orchestration/ooda/skills.d.ts.map +1 -1
  143. package/dist/orchestration/ooda/skills.js +106 -0
  144. package/dist/orchestration/ooda/skills.js.map +1 -1
  145. package/dist/orchestration/ooda/types.d.ts +3 -8
  146. package/dist/orchestration/ooda/types.d.ts.map +1 -1
  147. package/dist/ports/bastion-action.contract.test.d.ts +11 -0
  148. package/dist/ports/bastion-action.contract.test.d.ts.map +1 -0
  149. package/dist/ports/bastion-action.contract.test.js +238 -0
  150. package/dist/ports/bastion-action.contract.test.js.map +1 -0
  151. package/dist/ports/bastion-action.d.ts +133 -0
  152. package/dist/ports/bastion-action.d.ts.map +1 -0
  153. package/dist/ports/bastion-action.js +73 -0
  154. package/dist/ports/bastion-action.js.map +1 -0
  155. package/dist/ports/brain.d.ts +31 -0
  156. package/dist/ports/brain.d.ts.map +1 -1
  157. package/dist/ports/brain.js +115 -1
  158. package/dist/ports/brain.js.map +1 -1
  159. package/dist/ports/citadel-action.contract.test.d.ts +11 -0
  160. package/dist/ports/citadel-action.contract.test.d.ts.map +1 -0
  161. package/dist/ports/citadel-action.contract.test.js +317 -0
  162. package/dist/ports/citadel-action.contract.test.js.map +1 -0
  163. package/dist/ports/citadel-action.d.ts +111 -0
  164. package/dist/ports/citadel-action.d.ts.map +1 -0
  165. package/dist/ports/citadel-action.js +62 -0
  166. package/dist/ports/citadel-action.js.map +1 -0
  167. package/dist/ports/compliance-contract.d.ts +123 -0
  168. package/dist/ports/compliance-contract.d.ts.map +1 -0
  169. package/dist/ports/compliance-contract.js +35 -0
  170. package/dist/ports/compliance-contract.js.map +1 -0
  171. package/dist/ports/db.d.ts +38 -0
  172. package/dist/ports/db.d.ts.map +1 -1
  173. package/dist/ports/db.js +88 -1
  174. package/dist/ports/db.js.map +1 -1
  175. package/dist/ports/delegation.contract.test.d.ts +9 -0
  176. package/dist/ports/delegation.contract.test.d.ts.map +1 -0
  177. package/dist/ports/delegation.contract.test.js +337 -0
  178. package/dist/ports/delegation.contract.test.js.map +1 -0
  179. package/dist/ports/delegation.d.ts +134 -0
  180. package/dist/ports/delegation.d.ts.map +1 -0
  181. package/dist/ports/delegation.js +105 -0
  182. package/dist/ports/delegation.js.map +1 -0
  183. package/dist/ports/event-bus.d.ts +29 -13
  184. package/dist/ports/event-bus.d.ts.map +1 -1
  185. package/dist/ports/event-bus.js +106 -1
  186. package/dist/ports/event-bus.js.map +1 -1
  187. package/dist/ports/federation.contract.test.d.ts +9 -0
  188. package/dist/ports/federation.contract.test.d.ts.map +1 -0
  189. package/dist/ports/federation.contract.test.js +279 -0
  190. package/dist/ports/federation.contract.test.js.map +1 -0
  191. package/dist/ports/federation.d.ts +140 -0
  192. package/dist/ports/federation.d.ts.map +1 -0
  193. package/dist/ports/federation.js +57 -0
  194. package/dist/ports/federation.js.map +1 -0
  195. package/dist/ports/index.d.ts +28 -2
  196. package/dist/ports/index.d.ts.map +1 -1
  197. package/dist/ports/index.js +17 -2
  198. package/dist/ports/index.js.map +1 -1
  199. package/dist/ports/llm-provider.d.ts +37 -0
  200. package/dist/ports/llm-provider.d.ts.map +1 -1
  201. package/dist/ports/llm-provider.js +99 -1
  202. package/dist/ports/llm-provider.js.map +1 -1
  203. package/dist/ports/logger.d.ts +27 -0
  204. package/dist/ports/logger.d.ts.map +1 -1
  205. package/dist/ports/logger.js +87 -0
  206. package/dist/ports/logger.js.map +1 -1
  207. package/dist/ports/manifest-registry.contract.test.d.ts +9 -0
  208. package/dist/ports/manifest-registry.contract.test.d.ts.map +1 -0
  209. package/dist/ports/manifest-registry.contract.test.js +246 -0
  210. package/dist/ports/manifest-registry.contract.test.js.map +1 -0
  211. package/dist/ports/manifest-registry.d.ts +116 -0
  212. package/dist/ports/manifest-registry.d.ts.map +1 -0
  213. package/dist/ports/manifest-registry.js +79 -0
  214. package/dist/ports/manifest-registry.js.map +1 -0
  215. package/dist/ports/observability.contract.test.d.ts +12 -0
  216. package/dist/ports/observability.contract.test.d.ts.map +1 -0
  217. package/dist/ports/observability.contract.test.js +260 -0
  218. package/dist/ports/observability.contract.test.js.map +1 -0
  219. package/dist/ports/observability.d.ts +98 -0
  220. package/dist/ports/observability.d.ts.map +1 -0
  221. package/dist/ports/observability.js +59 -0
  222. package/dist/ports/observability.js.map +1 -0
  223. package/dist/ports/outcome.d.ts +26 -0
  224. package/dist/ports/outcome.d.ts.map +1 -1
  225. package/dist/ports/outcome.js +62 -1
  226. package/dist/ports/outcome.js.map +1 -1
  227. package/dist/ports/privacy.contract.test.d.ts +12 -0
  228. package/dist/ports/privacy.contract.test.d.ts.map +1 -0
  229. package/dist/ports/privacy.contract.test.js +325 -0
  230. package/dist/ports/privacy.contract.test.js.map +1 -0
  231. package/dist/ports/privacy.d.ts +132 -0
  232. package/dist/ports/privacy.d.ts.map +1 -0
  233. package/dist/ports/privacy.js +83 -0
  234. package/dist/ports/privacy.js.map +1 -0
  235. package/dist/ports/tenant-context.contract.test.d.ts +14 -0
  236. package/dist/ports/tenant-context.contract.test.d.ts.map +1 -0
  237. package/dist/ports/tenant-context.contract.test.js +352 -0
  238. package/dist/ports/tenant-context.contract.test.js.map +1 -0
  239. package/dist/ports/tenant-context.d.ts +103 -0
  240. package/dist/ports/tenant-context.d.ts.map +1 -0
  241. package/dist/ports/tenant-context.js +48 -0
  242. package/dist/ports/tenant-context.js.map +1 -0
  243. package/dist/ports/vauban-finance-action.contract.test.d.ts +11 -0
  244. package/dist/ports/vauban-finance-action.contract.test.d.ts.map +1 -0
  245. package/dist/ports/vauban-finance-action.contract.test.js +260 -0
  246. package/dist/ports/vauban-finance-action.contract.test.js.map +1 -0
  247. package/dist/ports/vauban-finance-action.d.ts +106 -0
  248. package/dist/ports/vauban-finance-action.d.ts.map +1 -0
  249. package/dist/ports/vauban-finance-action.js +60 -0
  250. package/dist/ports/vauban-finance-action.js.map +1 -0
  251. package/dist/ports/workflow-runtime.d.ts +204 -0
  252. package/dist/ports/workflow-runtime.d.ts.map +1 -0
  253. package/dist/ports/workflow-runtime.js +72 -0
  254. package/dist/ports/workflow-runtime.js.map +1 -0
  255. package/dist/proof/cert-verify.d.ts +80 -0
  256. package/dist/proof/cert-verify.d.ts.map +1 -0
  257. package/dist/proof/cert-verify.js +178 -0
  258. package/dist/proof/cert-verify.js.map +1 -0
  259. package/dist/replay/replay.d.ts.map +1 -1
  260. package/dist/replay/replay.js +5 -1
  261. package/dist/replay/replay.js.map +1 -1
  262. package/dist/retry/index.d.ts +129 -0
  263. package/dist/retry/index.d.ts.map +1 -0
  264. package/dist/retry/index.js +156 -0
  265. package/dist/retry/index.js.map +1 -0
  266. package/dist/retry/presets.d.ts +39 -0
  267. package/dist/retry/presets.d.ts.map +1 -0
  268. package/dist/retry/presets.js +69 -0
  269. package/dist/retry/presets.js.map +1 -0
  270. package/dist/skill-loop/ab-runner.d.ts +67 -0
  271. package/dist/skill-loop/ab-runner.d.ts.map +1 -0
  272. package/dist/skill-loop/ab-runner.js +160 -0
  273. package/dist/skill-loop/ab-runner.js.map +1 -0
  274. package/dist/skill-loop/adoption.d.ts +67 -0
  275. package/dist/skill-loop/adoption.d.ts.map +1 -0
  276. package/dist/skill-loop/adoption.js +126 -0
  277. package/dist/skill-loop/adoption.js.map +1 -0
  278. package/dist/skill-loop/candidate.d.ts +45 -0
  279. package/dist/skill-loop/candidate.d.ts.map +1 -0
  280. package/dist/skill-loop/candidate.js +43 -0
  281. package/dist/skill-loop/candidate.js.map +1 -0
  282. package/dist/skill-loop/evaluator.d.ts +42 -0
  283. package/dist/skill-loop/evaluator.d.ts.map +1 -0
  284. package/dist/skill-loop/evaluator.js +184 -0
  285. package/dist/skill-loop/evaluator.js.map +1 -0
  286. package/dist/skill-loop/index.d.ts +27 -0
  287. package/dist/skill-loop/index.d.ts.map +1 -0
  288. package/dist/skill-loop/index.js +27 -0
  289. package/dist/skill-loop/index.js.map +1 -0
  290. package/dist/skill-loop/reflexion-replay.d.ts +87 -0
  291. package/dist/skill-loop/reflexion-replay.d.ts.map +1 -0
  292. package/dist/skill-loop/reflexion-replay.js +110 -0
  293. package/dist/skill-loop/reflexion-replay.js.map +1 -0
  294. package/dist/skill-loop/sign-off.d.ts +88 -0
  295. package/dist/skill-loop/sign-off.d.ts.map +1 -0
  296. package/dist/skill-loop/sign-off.js +146 -0
  297. package/dist/skill-loop/sign-off.js.map +1 -0
  298. package/dist/skill-loop/value-metric.d.ts +55 -0
  299. package/dist/skill-loop/value-metric.d.ts.map +1 -0
  300. package/dist/skill-loop/value-metric.js +69 -0
  301. package/dist/skill-loop/value-metric.js.map +1 -0
  302. package/dist/skill-loop/versioning.d.ts +36 -0
  303. package/dist/skill-loop/versioning.d.ts.map +1 -0
  304. package/dist/skill-loop/versioning.js +47 -0
  305. package/dist/skill-loop/versioning.js.map +1 -0
  306. package/dist/skill-manifest/anchor.d.ts +91 -0
  307. package/dist/skill-manifest/anchor.d.ts.map +1 -0
  308. package/dist/skill-manifest/anchor.js +331 -0
  309. package/dist/skill-manifest/anchor.js.map +1 -0
  310. package/dist/skill-manifest/builder.d.ts +47 -0
  311. package/dist/skill-manifest/builder.d.ts.map +1 -0
  312. package/dist/skill-manifest/builder.js +93 -0
  313. package/dist/skill-manifest/builder.js.map +1 -0
  314. package/dist/skill-manifest/index.d.ts +13 -0
  315. package/dist/skill-manifest/index.d.ts.map +1 -0
  316. package/dist/skill-manifest/index.js +9 -0
  317. package/dist/skill-manifest/index.js.map +1 -0
  318. package/dist/skill-manifest/types.d.ts +67 -0
  319. package/dist/skill-manifest/types.d.ts.map +1 -0
  320. package/dist/skill-manifest/types.js +16 -0
  321. package/dist/skill-manifest/types.js.map +1 -0
  322. package/dist/skill-manifest/verifier.d.ts +42 -0
  323. package/dist/skill-manifest/verifier.d.ts.map +1 -0
  324. package/dist/skill-manifest/verifier.js +136 -0
  325. package/dist/skill-manifest/verifier.js.map +1 -0
  326. package/dist/skills/brain-query.d.ts +4 -4
  327. package/dist/skills/brain-store.d.ts +6 -6
  328. package/dist/skills/errors.d.ts +15 -0
  329. package/dist/skills/errors.d.ts.map +1 -1
  330. package/dist/skills/errors.js +21 -0
  331. package/dist/skills/errors.js.map +1 -1
  332. package/dist/skills/hitl-request.d.ts +2 -2
  333. package/dist/skills/index.d.ts +3 -1
  334. package/dist/skills/index.d.ts.map +1 -1
  335. package/dist/skills/index.js +4 -1
  336. package/dist/skills/index.js.map +1 -1
  337. package/dist/skills/markdown/loader.d.ts +52 -0
  338. package/dist/skills/markdown/loader.d.ts.map +1 -0
  339. package/dist/skills/markdown/loader.js +93 -0
  340. package/dist/skills/markdown/loader.js.map +1 -0
  341. package/dist/skills/markdown/schema.d.ts +432 -0
  342. package/dist/skills/markdown/schema.d.ts.map +1 -0
  343. package/dist/skills/markdown/schema.js +121 -0
  344. package/dist/skills/markdown/schema.js.map +1 -0
  345. package/dist/skills/poc-md-loader/markdown-loader.d.ts +77 -0
  346. package/dist/skills/poc-md-loader/markdown-loader.d.ts.map +1 -0
  347. package/dist/skills/poc-md-loader/markdown-loader.js +125 -0
  348. package/dist/skills/poc-md-loader/markdown-loader.js.map +1 -0
  349. package/dist/skills/poc-md-loader/runner.d.ts +24 -0
  350. package/dist/skills/poc-md-loader/runner.d.ts.map +1 -0
  351. package/dist/skills/poc-md-loader/runner.js +57 -0
  352. package/dist/skills/poc-md-loader/runner.js.map +1 -0
  353. package/dist/skills/poc-md-loader/vitest.poc.config.d.ts +3 -0
  354. package/dist/skills/poc-md-loader/vitest.poc.config.d.ts.map +1 -0
  355. package/dist/skills/poc-md-loader/vitest.poc.config.js +13 -0
  356. package/dist/skills/poc-md-loader/vitest.poc.config.js.map +1 -0
  357. package/dist/skills/poc-md-loader/web-search/script.d.ts +33 -0
  358. package/dist/skills/poc-md-loader/web-search/script.d.ts.map +1 -0
  359. package/dist/skills/poc-md-loader/web-search/script.js +75 -0
  360. package/dist/skills/poc-md-loader/web-search/script.js.map +1 -0
  361. package/dist/skills/record-outcome.d.ts +4 -4
  362. package/dist/skills/send-email.d.ts.map +1 -1
  363. package/dist/skills/send-email.js +15 -3
  364. package/dist/skills/send-email.js.map +1 -1
  365. package/dist/skills/slack-notify.d.ts +4 -4
  366. package/dist/skills/starknet-balance.d.ts +1 -1
  367. package/dist/skills/telegram-notify.d.ts +4 -4
  368. package/dist/skills/web-search.d.ts +1 -1
  369. package/dist/testing/contracts/event-bus.contract.d.ts.map +1 -1
  370. package/dist/testing/contracts/event-bus.contract.js +14 -12
  371. package/dist/testing/contracts/event-bus.contract.js.map +1 -1
  372. package/dist/testing/index.d.ts +3 -0
  373. package/dist/testing/test-brain-port.d.ts +4 -0
  374. package/dist/testing/test-brain-port.d.ts.map +1 -1
  375. package/dist/testing/test-brain-port.js +75 -20
  376. package/dist/testing/test-brain-port.js.map +1 -1
  377. package/dist/testing/test-event-bus.d.ts.map +1 -1
  378. package/dist/testing/test-event-bus.js +89 -36
  379. package/dist/testing/test-event-bus.js.map +1 -1
  380. package/dist/trace/schema.d.ts +1 -1
  381. package/dist/trace/schema.d.ts.map +1 -1
  382. package/dist/trace/schema.js +1 -1
  383. package/dist/trace/schema.js.map +1 -1
  384. package/dist/verify/formal/index.d.ts +44 -0
  385. package/dist/verify/formal/index.d.ts.map +1 -0
  386. package/dist/verify/formal/index.js +98 -0
  387. package/dist/verify/formal/index.js.map +1 -0
  388. package/dist/verify/formal/policy.d.ts +105 -0
  389. package/dist/verify/formal/policy.d.ts.map +1 -0
  390. package/dist/verify/formal/policy.js +159 -0
  391. package/dist/verify/formal/policy.js.map +1 -0
  392. package/dist/verify/formal/result.d.ts +50 -0
  393. package/dist/verify/formal/result.d.ts.map +1 -0
  394. package/dist/verify/formal/result.js +21 -0
  395. package/dist/verify/formal/result.js.map +1 -0
  396. package/dist/verify/formal/solver.d.ts +67 -0
  397. package/dist/verify/formal/solver.d.ts.map +1 -0
  398. package/dist/verify/formal/solver.js +184 -0
  399. package/dist/verify/formal/solver.js.map +1 -0
  400. package/dist/verify/formal/spec-language.d.ts +80 -0
  401. package/dist/verify/formal/spec-language.d.ts.map +1 -0
  402. package/dist/verify/formal/spec-language.js +219 -0
  403. package/dist/verify/formal/spec-language.js.map +1 -0
  404. package/docs/attestation.md +199 -0
  405. package/docs/identity.md +193 -0
  406. package/package.json +22 -1
  407. package/src/adapters/llm/anthropic-direct.ts +51 -0
  408. package/src/adapters/llm/cascade.ts +64 -19
  409. package/src/adapters/llm/litellm.ts +49 -0
  410. package/src/compute/difficulty-estimator.ts +111 -0
  411. package/src/compute/strategies/mixture-of-agents.ts +150 -0
  412. package/src/compute/strategies/tree-of-thoughts.ts +293 -0
  413. package/src/compute/strategies/two-phase-orient.ts +147 -0
  414. package/src/container/protocol.ts +243 -0
  415. package/src/container/runtime.ts +424 -0
  416. package/src/db/migrations/026_formal_verify_results.sql +30 -0
  417. package/src/events/catalogue.ts +54 -0
  418. package/src/events/index.ts +9 -0
  419. package/src/events/schemas/citadel.sprint.analyzed.v1.ts +23 -0
  420. package/src/events/schemas/forge.inbox.reply_classified.v1.ts +15 -0
  421. package/src/events/schemas/vauban-finance.forecast.generated.v1.ts +11 -0
  422. package/src/events/schemas/vauban-finance.trade.executed.v1.ts +12 -0
  423. package/src/events/schemas/vauban.goal.checked.v1.ts +11 -0
  424. package/src/events/schemas/vauban.rebalancing.checked.v1.ts +11 -0
  425. package/src/events/schemas/vauban.tax.checked.v1.ts +11 -0
  426. package/src/events/schemas/vauban.vault.analyzed.v1.ts +21 -0
  427. package/src/events/schemas/vauban.vault.compounded.v1.ts +12 -0
  428. package/src/identity/agent-persona.ts +203 -0
  429. package/src/identity/persona-prompt.ts +84 -0
  430. package/src/identity/persona-schema.ts +127 -0
  431. package/src/index.ts +338 -1
  432. package/src/loop/index.ts +0 -1
  433. package/src/loop/sdk-loop.ts +5 -8
  434. package/src/memory/episodic-rrf.ts +224 -0
  435. package/src/mesh/attenuation.ts +190 -0
  436. package/src/mesh/delegate.ts +254 -0
  437. package/src/mesh/dispatcher.ts +301 -0
  438. package/src/mesh/index.ts +39 -0
  439. package/src/mesh/types.ts +31 -0
  440. package/src/orchestration/ooda/skills.ts +177 -0
  441. package/src/orchestration/ooda/types.ts +3 -9
  442. package/src/ports/bastion-action.contract.test.ts +355 -0
  443. package/src/ports/bastion-action.ts +198 -0
  444. package/src/ports/brain.ts +177 -15
  445. package/src/ports/citadel-action.contract.test.ts +430 -0
  446. package/src/ports/citadel-action.ts +174 -0
  447. package/src/ports/compliance-contract.ts +191 -0
  448. package/src/ports/db.ts +98 -0
  449. package/src/ports/delegation.contract.test.ts +428 -0
  450. package/src/ports/delegation.ts +211 -0
  451. package/src/ports/event-bus.ts +133 -18
  452. package/src/ports/federation.contract.test.ts +355 -0
  453. package/src/ports/federation.ts +190 -0
  454. package/src/ports/index.ts +186 -1
  455. package/src/ports/llm-provider.ts +123 -0
  456. package/src/ports/logger.ts +104 -0
  457. package/src/ports/manifest-registry.contract.test.ts +324 -0
  458. package/src/ports/manifest-registry.ts +188 -0
  459. package/src/ports/observability.contract.test.ts +315 -0
  460. package/src/ports/observability.ts +150 -0
  461. package/src/ports/outcome.ts +69 -0
  462. package/src/ports/privacy.contract.test.ts +413 -0
  463. package/src/ports/privacy.ts +207 -0
  464. package/src/ports/tenant-context.contract.test.ts +454 -0
  465. package/src/ports/tenant-context.ts +150 -0
  466. package/src/ports/vauban-finance-action.contract.test.ts +335 -0
  467. package/src/ports/vauban-finance-action.ts +166 -0
  468. package/src/ports/workflow-runtime.ts +327 -0
  469. package/src/proof/cert-verify.ts +249 -0
  470. package/src/replay/replay.ts +11 -8
  471. package/src/retry/index.ts +227 -0
  472. package/src/retry/presets.ts +75 -0
  473. package/src/skill-loop/ab-runner.ts +196 -0
  474. package/src/skill-loop/adoption.ts +188 -0
  475. package/src/skill-loop/candidate.ts +75 -0
  476. package/src/skill-loop/evaluator.ts +238 -0
  477. package/src/skill-loop/index.ts +51 -0
  478. package/src/skill-loop/reflexion-replay.ts +173 -0
  479. package/src/skill-loop/sign-off.ts +247 -0
  480. package/src/skill-loop/value-metric.ts +120 -0
  481. package/src/skill-loop/versioning.ts +75 -0
  482. package/src/skill-manifest/anchor.ts +401 -0
  483. package/src/skill-manifest/builder.ts +129 -0
  484. package/src/skill-manifest/index.ts +18 -0
  485. package/src/skill-manifest/types.ts +72 -0
  486. package/src/skill-manifest/verifier.ts +198 -0
  487. package/src/skills/errors.ts +30 -2
  488. package/src/skills/index.ts +19 -0
  489. package/src/skills/markdown/loader.ts +129 -0
  490. package/src/skills/markdown/schema.ts +144 -0
  491. package/src/skills/poc-md-loader/e2e-parity.test.ts +237 -0
  492. package/src/skills/poc-md-loader/markdown-loader.ts +161 -0
  493. package/src/skills/poc-md-loader/runner.ts +82 -0
  494. package/src/skills/poc-md-loader/vitest.poc.config.ts +13 -0
  495. package/src/skills/poc-md-loader/web-search/SKILL.md +42 -0
  496. package/src/skills/poc-md-loader/web-search/script.ts +109 -0
  497. package/src/skills/send-email.ts +15 -3
  498. package/src/testing/contracts/event-bus.contract.ts +16 -14
  499. package/src/testing/test-brain-port.ts +98 -24
  500. package/src/testing/test-event-bus.ts +104 -43
  501. package/src/trace/schema.ts +1 -1
  502. package/src/verify/formal/index.ts +154 -0
  503. package/src/verify/formal/policy.ts +253 -0
  504. package/src/verify/formal/result.ts +52 -0
  505. package/src/verify/formal/solver.ts +235 -0
  506. package/src/verify/formal/spec-language.ts +274 -0
@@ -0,0 +1,193 @@
1
+ # Agent Identity & Persona
2
+
3
+ **Module:** `@vauban-org/agent-sdk` · **Since:** CC v3.1 sprint-562 (Livrable E, 2026-05-14)
4
+
5
+ An `AgentPersona` is a structured description of how an agent communicates — tone, formality, domain expertise, and response-shape preferences. The persona travels from Brain Tier 3 (semantic storage) through the CC server as a system-prompt prefix, and can be overridden locally via `~/.preste/persona.yaml`.
6
+
7
+ ## Quick start
8
+
9
+ ```typescript
10
+ import {
11
+ buildPersonaPromptBlock,
12
+ mergePersona,
13
+ DEFAULT_PERSONA,
14
+ validatePersona,
15
+ } from "@vauban-org/agent-sdk";
16
+ import type { AgentPersona } from "@vauban-org/agent-sdk";
17
+
18
+ const persona: AgentPersona = {
19
+ identity: {
20
+ name: "ARCHITECT",
21
+ role: "Senior Cairo/TypeScript engineer",
22
+ tone: "concise",
23
+ formality: "technical",
24
+ language: "en",
25
+ },
26
+ domain_expertise: ["Starknet", "TypeScript", "ZK proofs"],
27
+ communication: {
28
+ acknowledgment_style: "minimal",
29
+ explain_reasoning: "on_error",
30
+ },
31
+ };
32
+
33
+ const systemPrompt =
34
+ "You are an agent in the Vauban ecosystem." +
35
+ buildPersonaPromptBlock(persona);
36
+ ```
37
+
38
+ The `buildPersonaPromptBlock` call appends the block only when actionable fields are present — it is safe to concatenate unconditionally.
39
+
40
+ ---
41
+
42
+ ## `AgentPersona` schema
43
+
44
+ All fields are optional. Zod validation enforces the limits below; `PersonaSchema.parse(input)` throws on violation.
45
+
46
+ ```typescript
47
+ interface AgentPersona {
48
+ identity?: {
49
+ name?: string; // max 64 chars
50
+ role?: string; // max 256 chars
51
+ tone?: "concise" | "detailed" | "pedagogical";
52
+ formality?: "casual" | "formal" | "technical";
53
+ language?: string; // BCP 47, e.g. "en", "fr-FR"
54
+ };
55
+ traits?: string[]; // max 16 items, max 64 chars each
56
+ domain_expertise?: string[]; // max 32 items, max 128 chars each
57
+ communication?: {
58
+ max_response_length?: number;
59
+ use_analogies?: boolean;
60
+ explain_reasoning?: "always" | "on_error" | "never";
61
+ acknowledgment_style?: "minimal" | "detailed" | "none";
62
+ };
63
+ }
64
+ ```
65
+
66
+ `DEFAULT_PERSONA` is applied before any user-defined value:
67
+
68
+ ```typescript
69
+ const DEFAULT_PERSONA: AgentPersona = {
70
+ identity: { tone: "concise", formality: "technical", language: "en" },
71
+ traits: [],
72
+ domain_expertise: [],
73
+ communication: { explain_reasoning: "on_error", acknowledgment_style: "minimal" },
74
+ };
75
+ ```
76
+
77
+ ---
78
+
79
+ ## `buildPersonaPromptBlock(persona)`
80
+
81
+ Converts an `AgentPersona` to a compact system-prompt block bounded by `--- persona ---` / `--- end persona ---` markers.
82
+
83
+ ```typescript
84
+ import { buildPersonaPromptBlock } from "@vauban-org/agent-sdk";
85
+
86
+ const block = buildPersonaPromptBlock({
87
+ identity: { name: "SCRIBE", tone: "pedagogical", formality: "formal" },
88
+ domain_expertise: ["technical writing", "API documentation"],
89
+ communication: { explain_reasoning: "always" },
90
+ });
91
+
92
+ // block ===
93
+ // \n--- persona ---
94
+ // You are SCRIBE.
95
+ // Communication style: pedagogical, formal.
96
+ // Domain expertise: technical writing, API documentation.
97
+ // Always explain your reasoning step by step.
98
+ // --- end persona ---
99
+ ```
100
+
101
+ **Properties:**
102
+
103
+ - Returns `""` when the persona has no actionable fields — safe for unconditional concatenation.
104
+ - `language` field only emits an instruction when it differs from `"en"`.
105
+ - Empty `traits` / `domain_expertise` arrays produce no output.
106
+ - The leading `\n` ensures correct spacing when appended to an existing system prompt.
107
+
108
+ ---
109
+
110
+ ## Merge semantics
111
+
112
+ `mergePersona(base, local)` applies `local` on top of `base` field-by-field. Brain Tier 3 is the base; `~/.preste/persona.yaml` is the local override.
113
+
114
+ ```typescript
115
+ import { mergePersona, DEFAULT_PERSONA } from "@vauban-org/agent-sdk";
116
+
117
+ const brainPersona: AgentPersona = {
118
+ identity: { name: "BUILDER", tone: "concise" },
119
+ domain_expertise: ["Cairo", "TypeScript"],
120
+ };
121
+
122
+ const localOverride: AgentPersona = {
123
+ identity: { tone: "detailed" }, // overrides tone only
124
+ domain_expertise: ["Rust"], // REPLACES the array entirely
125
+ };
126
+
127
+ const resolved = mergePersona(
128
+ mergePersona(DEFAULT_PERSONA, brainPersona),
129
+ localOverride,
130
+ );
131
+ // resolved.identity.name === "BUILDER" (from brainPersona)
132
+ // resolved.identity.tone === "detailed" (from localOverride)
133
+ // resolved.domain_expertise === ["Rust"] (array replaced, not extended)
134
+ ```
135
+
136
+ !!! warning "Array replacement semantics"
137
+ `traits` and `domain_expertise` are **replaced**, not extended. If you want to extend the Brain-stored array, concatenate before calling `mergePersona`:
138
+ ```typescript
139
+ const extended = mergePersona(base, {
140
+ ...local,
141
+ domain_expertise: [...(base.domain_expertise ?? []), ...(local.domain_expertise ?? [])],
142
+ });
143
+ ```
144
+
145
+ ---
146
+
147
+ ## System-level injection (CC server)
148
+
149
+ Set `CC_AGENT_PERSONA_JSON` on the CC server to inject the persona as a system message prefix for every agent call, without modifying agent code.
150
+
151
+ **Generate the env value:**
152
+
153
+ ```bash
154
+ echo '{"identity":{"name":"ARCHITECT","role":"Senior Cairo/TypeScript engineer","tone":"concise","formality":"technical"},"domain_expertise":["Starknet","TypeScript","ZK proofs"],"communication":{"acknowledgment_style":"minimal","explain_reasoning":"on_error"}}' | base64 -w0
155
+ ```
156
+
157
+ ```bash
158
+ export CC_AGENT_PERSONA_JSON="<base64 output>"
159
+ ```
160
+
161
+ The CC server decodes, validates via `PersonaSchema.parse`, and calls `buildPersonaPromptBlock` before prepending to each agent system message.
162
+
163
+ ---
164
+
165
+ ## CLI persona management
166
+
167
+ The `preste persona` sub-command manages the local `~/.preste/persona.yaml` override file.
168
+
169
+ ```bash
170
+ preste persona show # display resolved persona (Brain + local merge)
171
+ preste persona set --name ARCHITECT --role "..." --tone concise --formality technical
172
+ preste persona export persona.yaml # write to YAML file
173
+ preste persona import persona.yaml # load from YAML file (validates schema)
174
+ preste persona reset # delete ~/.preste/persona.yaml (revert to Brain-only)
175
+ ```
176
+
177
+ `preste persona show` prints the fully-resolved persona (Brain base + local override + defaults) and the rendered `buildPersonaPromptBlock` output so you can inspect what the model will receive.
178
+
179
+ ---
180
+
181
+ ## Validation
182
+
183
+ ```typescript
184
+ import { validatePersona } from "@vauban-org/agent-sdk";
185
+
186
+ try {
187
+ const persona = validatePersona(untrustedInput);
188
+ } catch (err) {
189
+ // ZodError — inspect err.issues for field-level messages
190
+ }
191
+ ```
192
+
193
+ `validatePersona` wraps `PersonaSchema.parse` and throws `ZodError` on invalid input. Call it at ingestion boundaries (e.g., when loading `~/.preste/persona.yaml` or deserializing from Brain).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vauban-org/agent-sdk",
3
- "version": "0.17.4",
3
+ "version": "1.2.0",
4
4
  "description": "Vauban agent primitives: loop, budget, routing, HITL, permissions, tracking, durable execution",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -21,6 +21,11 @@
21
21
  "import": "./dist/proof/index.js",
22
22
  "default": "./dist/proof/index.js"
23
23
  },
24
+ "./proof/cert-verify": {
25
+ "types": "./dist/proof/cert-verify.d.ts",
26
+ "import": "./dist/proof/cert-verify.js",
27
+ "default": "./dist/proof/cert-verify.js"
28
+ },
24
29
  "./outcomes": {
25
30
  "types": "./dist/outcomes/index.d.ts",
26
31
  "import": "./dist/outcomes/index.js",
@@ -75,6 +80,21 @@
75
80
  "types": "./dist/hitl/callback-handlers.d.ts",
76
81
  "import": "./dist/hitl/callback-handlers.js",
77
82
  "default": "./dist/hitl/callback-handlers.js"
83
+ },
84
+ "./economy": {
85
+ "types": "./dist/economy/index.d.ts",
86
+ "import": "./dist/economy/index.js",
87
+ "default": "./dist/economy/index.js"
88
+ },
89
+ "./skill-manifest": {
90
+ "types": "./dist/skill-manifest/index.d.ts",
91
+ "import": "./dist/skill-manifest/index.js",
92
+ "default": "./dist/skill-manifest/index.js"
93
+ },
94
+ "./skill-loop": {
95
+ "types": "./dist/skill-loop/index.d.ts",
96
+ "import": "./dist/skill-loop/index.js",
97
+ "default": "./dist/skill-loop/index.js"
78
98
  }
79
99
  },
80
100
  "files": [
@@ -107,6 +127,7 @@
107
127
  "api:extract": "api-extractor run --local --verbose",
108
128
  "api:check": "api-extractor run",
109
129
  "depcruise": "depcruise src",
130
+ "docs": "typedoc",
110
131
  "prepublishOnly": "pnpm build && pnpm test"
111
132
  },
112
133
  "dependencies": {
@@ -8,6 +8,8 @@
8
8
  */
9
9
 
10
10
  import Anthropic from "@anthropic-ai/sdk";
11
+ import type { Span } from "@opentelemetry/api";
12
+ import { SpanStatusCode, trace } from "@opentelemetry/api";
11
13
  import type {
12
14
  ChatRequest,
13
15
  ChatResponse,
@@ -16,6 +18,11 @@ import type {
16
18
  StreamDelta,
17
19
  } from "../../ports/llm-provider.js";
18
20
 
21
+ const ADAPTER_TRACER = trace.getTracer(
22
+ "vauban-agent-sdk.llm.anthropic",
23
+ "0.1.0"
24
+ );
25
+
19
26
  export interface AnthropicDirectAdapterConfig {
20
27
  apiKey: string;
21
28
  /** Default model to use when ChatRequest.model is not specified. */
@@ -70,6 +77,50 @@ export class AnthropicDirectAdapter implements LLMProviderPort {
70
77
  }
71
78
 
72
79
  async complete(req: ChatRequest): Promise<ChatResponse> {
80
+ return ADAPTER_TRACER.startActiveSpan(
81
+ "llm-provider.complete",
82
+ {
83
+ attributes: {
84
+ "gen_ai.system": "anthropic",
85
+ "gen_ai.request.model": req.model ?? this.defaultModel,
86
+ "gen_ai.request.message_count": req.messages.length,
87
+ "vauban.port.name": "llm-provider",
88
+ "vauban.port.impl": "AnthropicDirectAdapter",
89
+ },
90
+ },
91
+ async (span: Span): Promise<ChatResponse> => {
92
+ try {
93
+ const response: ChatResponse = await this._doComplete(req);
94
+ span.setAttributes({
95
+ "gen_ai.usage.input_tokens": response.usage.inputTokens,
96
+ "gen_ai.usage.output_tokens": response.usage.outputTokens,
97
+ "gen_ai.response.model": response.model,
98
+ "gen_ai.response.finish_reasons": [response.finishReason],
99
+ });
100
+ if (response.usage.costUsd !== undefined) {
101
+ span.setAttribute("gen_ai.usage.cost_usd", response.usage.costUsd);
102
+ }
103
+ span.setStatus({ code: SpanStatusCode.OK });
104
+ return response;
105
+ } catch (_err) {
106
+ span.setStatus({
107
+ code: SpanStatusCode.ERROR,
108
+ message: "span wrapper caught exception",
109
+ });
110
+ return {
111
+ content: "",
112
+ usage: { inputTokens: 0, outputTokens: 0 },
113
+ model: req.model ?? this.defaultModel,
114
+ finishReason: "error" as const,
115
+ };
116
+ } finally {
117
+ span.end();
118
+ }
119
+ }
120
+ );
121
+ }
122
+
123
+ private async _doComplete(req: ChatRequest): Promise<ChatResponse> {
73
124
  const model = req.model ?? this.defaultModel;
74
125
 
75
126
  // Extract system message (Anthropic API separates system from messages)
@@ -12,6 +12,8 @@
12
12
  * BYOM: no default model hardcoded.
13
13
  */
14
14
 
15
+ import type { Span } from "@opentelemetry/api";
16
+ import { SpanStatusCode, trace } from "@opentelemetry/api";
15
17
  import type {
16
18
  ChatRequest,
17
19
  ChatResponse,
@@ -19,6 +21,8 @@ import type {
19
21
  StreamDelta,
20
22
  } from "../../ports/llm-provider.js";
21
23
 
24
+ const ADAPTER_TRACER = trace.getTracer("vauban-agent-sdk.llm.cascade", "0.1.0");
25
+
22
26
  const ALL_FAIL_RESPONSE: ChatResponse = {
23
27
  content: "",
24
28
  usage: { inputTokens: 0, outputTokens: 0 },
@@ -51,26 +55,67 @@ export class CascadeAdapter implements LLMProviderPort {
51
55
  }
52
56
 
53
57
  async complete(req: ChatRequest): Promise<ChatResponse> {
54
- for (const provider of this.providers) {
55
- if (req.abortSignal?.aborted) {
56
- return { ...ALL_FAIL_RESPONSE };
57
- }
58
-
59
- let response: ChatResponse;
60
- try {
61
- response = await provider.complete(req);
62
- } catch {
63
- // Unexpected throw — treat as failure, try next
64
- continue;
65
- }
66
-
67
- if (response.finishReason !== "error") {
68
- return response;
58
+ return ADAPTER_TRACER.startActiveSpan(
59
+ "llm-provider.complete",
60
+ {
61
+ attributes: {
62
+ "gen_ai.system": "cascade",
63
+ "gen_ai.request.model": req.model ?? "cascade",
64
+ "gen_ai.request.message_count": req.messages.length,
65
+ "vauban.port.name": "llm-provider",
66
+ "vauban.port.impl": "CascadeAdapter",
67
+ "vauban.cascade.provider_count": this.providers.length,
68
+ },
69
+ },
70
+ async (span: Span) => {
71
+ try {
72
+ let attemptCount = 0;
73
+ for (const provider of this.providers) {
74
+ attemptCount++;
75
+ if (req.abortSignal?.aborted) {
76
+ span.setAttribute("vauban.cascade.attempts", attemptCount);
77
+ span.setStatus({ code: SpanStatusCode.OK });
78
+ return { ...ALL_FAIL_RESPONSE };
79
+ }
80
+
81
+ let response: ChatResponse;
82
+ try {
83
+ response = await provider.complete(req);
84
+ } catch {
85
+ // Unexpected throw — treat as failure, try next
86
+ continue;
87
+ }
88
+
89
+ if (response.finishReason !== "error") {
90
+ span.setAttribute("vauban.cascade.attempts", attemptCount);
91
+ span.setAttributes({
92
+ "gen_ai.usage.input_tokens": response.usage.inputTokens,
93
+ "gen_ai.usage.output_tokens": response.usage.outputTokens,
94
+ "gen_ai.response.model": response.model,
95
+ "gen_ai.response.finish_reasons": [response.finishReason],
96
+ });
97
+ span.setStatus({ code: SpanStatusCode.OK });
98
+ return response;
99
+ }
100
+ // finishReason === "error" → try next provider
101
+ }
102
+ span.setAttribute("vauban.cascade.attempts", attemptCount);
103
+ span.setAttribute("vauban.cascade.all_failed", true);
104
+ span.setStatus({
105
+ code: SpanStatusCode.ERROR,
106
+ message: "all providers failed",
107
+ });
108
+ return { ...ALL_FAIL_RESPONSE };
109
+ } catch (err) {
110
+ const message = err instanceof Error ? err.message : String(err);
111
+ span.setStatus({ code: SpanStatusCode.ERROR, message });
112
+ if (err instanceof Error) span.recordException(err);
113
+ return { ...ALL_FAIL_RESPONSE };
114
+ } finally {
115
+ span.end();
116
+ }
69
117
  }
70
- // finishReason === "error" → try next provider
71
- }
72
-
73
- return { ...ALL_FAIL_RESPONSE };
118
+ );
74
119
  }
75
120
 
76
121
  async *stream(req: ChatRequest): AsyncIterable<StreamDelta> {
@@ -9,6 +9,8 @@
9
9
  * No model string is hardcoded at module scope.
10
10
  */
11
11
 
12
+ import type { Span } from "@opentelemetry/api";
13
+ import { SpanStatusCode, trace } from "@opentelemetry/api";
12
14
  import type {
13
15
  ChatRequest,
14
16
  ChatResponse,
@@ -17,6 +19,8 @@ import type {
17
19
  StreamDelta,
18
20
  } from "../../ports/llm-provider.js";
19
21
 
22
+ const ADAPTER_TRACER = trace.getTracer("vauban-agent-sdk.llm.litellm", "0.1.0");
23
+
20
24
  export interface LiteLLMAdapterConfig {
21
25
  baseUrl: string;
22
26
  apiKey?: string;
@@ -103,6 +107,51 @@ export class LiteLLMAdapter implements LLMProviderPort {
103
107
  }
104
108
 
105
109
  async complete(req: ChatRequest): Promise<ChatResponse> {
110
+ return ADAPTER_TRACER.startActiveSpan(
111
+ "llm-provider.complete",
112
+ {
113
+ attributes: {
114
+ "gen_ai.system": "litellm",
115
+ "gen_ai.request.model": req.model ?? this.defaultModel,
116
+ "gen_ai.request.message_count": req.messages.length,
117
+ "vauban.port.name": "llm-provider",
118
+ "vauban.port.impl": "LiteLLMAdapter",
119
+ },
120
+ },
121
+ async (span: Span): Promise<ChatResponse> => {
122
+ try {
123
+ const response: ChatResponse = await this._doComplete(req);
124
+ span.setAttributes({
125
+ "gen_ai.usage.input_tokens": response.usage.inputTokens,
126
+ "gen_ai.usage.output_tokens": response.usage.outputTokens,
127
+ "gen_ai.response.model": response.model,
128
+ "gen_ai.response.finish_reasons": [response.finishReason],
129
+ });
130
+ if (response.usage.costUsd !== undefined) {
131
+ span.setAttribute("gen_ai.usage.cost_usd", response.usage.costUsd);
132
+ }
133
+ span.setStatus({ code: SpanStatusCode.OK });
134
+ return response;
135
+ } catch (_err) {
136
+ span.setStatus({
137
+ code: SpanStatusCode.ERROR,
138
+ message: "span wrapper caught exception",
139
+ });
140
+ return {
141
+ content: "",
142
+ usage: { inputTokens: 0, outputTokens: 0 },
143
+ model: req.model ?? this.defaultModel,
144
+ finishReason: "error" as const,
145
+ };
146
+ } finally {
147
+ span.end();
148
+ }
149
+ }
150
+ );
151
+ }
152
+
153
+ /** Internal completion logic — extracted from complete() for span instrumentation. */
154
+ private async _doComplete(req: ChatRequest): Promise<ChatResponse> {
106
155
  const model = req.model ?? this.defaultModel;
107
156
  const body = {
108
157
  model,
@@ -0,0 +1,111 @@
1
+ /**
2
+ * src/compute/difficulty-estimator.ts
3
+ *
4
+ * Deterministic task-difficulty classifier + strategy recommender.
5
+ *
6
+ * NOT an LLM call — pure feature extraction + rule-based classification.
7
+ * Routes input difficulty → recommended compute strategy.
8
+ *
9
+ * @experimental Public-experimental API per `contract-stability.md` (sprint-582).
10
+ */
11
+
12
+ // ─── Public types ────────────────────────────────────────────────────────────
13
+
14
+ export type DifficultyClass = "simple" | "standard" | "complex" | "reasoning";
15
+
16
+ export interface TaskFeatures {
17
+ /** Character count of input. */
18
+ inputLength: number;
19
+ /** Input contains "step", "then", or "first…then" pattern. */
20
+ hasMultipleSteps: boolean;
21
+ /** Input contains "why", "explain", "reason", "prove", "deduce". */
22
+ requiresReasoning: boolean;
23
+ /** Input contains "create", "generate", "design", "imagine". */
24
+ requiresCreativity: boolean;
25
+ /** Input contains digits or math operators. */
26
+ hasNumerics: boolean;
27
+ /** Input references multiple entities ("A and B", "compare"). */
28
+ hasCrossReference: boolean;
29
+ /** Length of optional context/system prompt. */
30
+ contextLength: number;
31
+ }
32
+
33
+ // ─── Regex patterns (case-insensitive, word-bounded where useful) ───────────
34
+
35
+ const RE_STEPS = /\b(step|steps|then|first|next|finally)\b/i;
36
+ const RE_REASONING =
37
+ /\b(why|explain|explains|reason|reasons|prove|proves|deduce|deduces|infer|justify)\b/i;
38
+ const RE_CREATIVITY = /\b(create|generate|design|imagine|invent|compose)\b/i;
39
+ const RE_NUMERICS = /[0-9]|[+\-*/^=]/;
40
+ const RE_CROSS_REF = /\b(compare|and|versus|vs\.?|both)\b/i;
41
+
42
+ // ─── Feature extraction ──────────────────────────────────────────────────────
43
+
44
+ /**
45
+ * Extract task features from input + optional context.
46
+ * Deterministic, side-effect free.
47
+ */
48
+ export function extractFeatures(input: string, context?: string): TaskFeatures {
49
+ const inputLength = input.length;
50
+ const contextLength = context?.length ?? 0;
51
+
52
+ return {
53
+ inputLength,
54
+ hasMultipleSteps: RE_STEPS.test(input),
55
+ requiresReasoning: RE_REASONING.test(input),
56
+ requiresCreativity: RE_CREATIVITY.test(input),
57
+ hasNumerics: RE_NUMERICS.test(input),
58
+ hasCrossReference: RE_CROSS_REF.test(input),
59
+ contextLength,
60
+ };
61
+ }
62
+
63
+ // ─── Difficulty classification ───────────────────────────────────────────────
64
+
65
+ /**
66
+ * Classify difficulty from task features.
67
+ *
68
+ * Decision tree (most specific first):
69
+ * - requiresReasoning → "reasoning"
70
+ * - inputLength > 500 OR hasMultipleSteps OR requiresCreativity → "complex"
71
+ * - inputLength in [100, 500] OR hasNumerics → "standard"
72
+ * - else → "simple"
73
+ */
74
+ export function estimateDifficulty(features: TaskFeatures): DifficultyClass {
75
+ if (features.requiresReasoning) return "reasoning";
76
+ if (features.inputLength > 500 || features.hasMultipleSteps || features.requiresCreativity) {
77
+ return "complex";
78
+ }
79
+ if (features.inputLength >= 100 || features.hasNumerics) {
80
+ return "standard";
81
+ }
82
+ return "simple";
83
+ }
84
+
85
+ // ─── Strategy recommendation ─────────────────────────────────────────────────
86
+
87
+ /**
88
+ * Recommend a compute strategy for a given difficulty class.
89
+ *
90
+ * Map (per Sprint A bench results + Sprint-582 spec):
91
+ * simple → single-shot
92
+ * standard → bon-mav
93
+ * complex → tree-of-thoughts
94
+ * reasoning → mixture-of-agents
95
+ */
96
+ export function recommendStrategy(difficulty: DifficultyClass): string {
97
+ switch (difficulty) {
98
+ case "simple":
99
+ return "single-shot";
100
+ case "standard":
101
+ return "bon-mav";
102
+ case "complex":
103
+ return "tree-of-thoughts";
104
+ case "reasoning":
105
+ return "mixture-of-agents";
106
+ default: {
107
+ const _exhaustive: never = difficulty;
108
+ throw new Error(`recommendStrategy: unknown difficulty "${String(_exhaustive)}"`);
109
+ }
110
+ }
111
+ }