@esankhan3/anvil-agent-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (459) hide show
  1. package/README.md +142 -0
  2. package/dist/__tests__/adapter-enrichment.test.d.ts +12 -0
  3. package/dist/__tests__/adapter-enrichment.test.d.ts.map +1 -0
  4. package/dist/__tests__/adapter-enrichment.test.js +199 -0
  5. package/dist/__tests__/adapter-enrichment.test.js.map +1 -0
  6. package/dist/__tests__/adk-anthropic-llm.test.d.ts +18 -0
  7. package/dist/__tests__/adk-anthropic-llm.test.d.ts.map +1 -0
  8. package/dist/__tests__/adk-anthropic-llm.test.js +124 -0
  9. package/dist/__tests__/adk-anthropic-llm.test.js.map +1 -0
  10. package/dist/__tests__/cost-breakdown.test.d.ts +11 -0
  11. package/dist/__tests__/cost-breakdown.test.d.ts.map +1 -0
  12. package/dist/__tests__/cost-breakdown.test.js +163 -0
  13. package/dist/__tests__/cost-breakdown.test.js.map +1 -0
  14. package/dist/__tests__/mcp.test.d.ts +13 -0
  15. package/dist/__tests__/mcp.test.d.ts.map +1 -0
  16. package/dist/__tests__/mcp.test.js +413 -0
  17. package/dist/__tests__/mcp.test.js.map +1 -0
  18. package/dist/__tests__/ollama-adapter-agentic.test.d.ts +15 -0
  19. package/dist/__tests__/ollama-adapter-agentic.test.d.ts.map +1 -0
  20. package/dist/__tests__/ollama-adapter-agentic.test.js +268 -0
  21. package/dist/__tests__/ollama-adapter-agentic.test.js.map +1 -0
  22. package/dist/__tests__/ollama-adapter-executor.test.d.ts +10 -0
  23. package/dist/__tests__/ollama-adapter-executor.test.d.ts.map +1 -0
  24. package/dist/__tests__/ollama-adapter-executor.test.js +95 -0
  25. package/dist/__tests__/ollama-adapter-executor.test.js.map +1 -0
  26. package/dist/__tests__/openai-adapter-output.test.d.ts +17 -0
  27. package/dist/__tests__/openai-adapter-output.test.d.ts.map +1 -0
  28. package/dist/__tests__/openai-adapter-output.test.js +127 -0
  29. package/dist/__tests__/openai-adapter-output.test.js.map +1 -0
  30. package/dist/__tests__/opencode-adapter.test.d.ts +7 -0
  31. package/dist/__tests__/opencode-adapter.test.d.ts.map +1 -0
  32. package/dist/__tests__/opencode-adapter.test.js +141 -0
  33. package/dist/__tests__/opencode-adapter.test.js.map +1 -0
  34. package/dist/__tests__/openrouter-adapter-agentic.test.d.ts +11 -0
  35. package/dist/__tests__/openrouter-adapter-agentic.test.d.ts.map +1 -0
  36. package/dist/__tests__/openrouter-adapter-agentic.test.js +297 -0
  37. package/dist/__tests__/openrouter-adapter-agentic.test.js.map +1 -0
  38. package/dist/__tests__/router-circuit-breaker.test.d.ts +6 -0
  39. package/dist/__tests__/router-circuit-breaker.test.d.ts.map +1 -0
  40. package/dist/__tests__/router-circuit-breaker.test.js +253 -0
  41. package/dist/__tests__/router-circuit-breaker.test.js.map +1 -0
  42. package/dist/__tests__/router-config-loader.test.d.ts +8 -0
  43. package/dist/__tests__/router-config-loader.test.d.ts.map +1 -0
  44. package/dist/__tests__/router-config-loader.test.js +172 -0
  45. package/dist/__tests__/router-config-loader.test.js.map +1 -0
  46. package/dist/__tests__/router-discovery.test.d.ts +5 -0
  47. package/dist/__tests__/router-discovery.test.d.ts.map +1 -0
  48. package/dist/__tests__/router-discovery.test.js +129 -0
  49. package/dist/__tests__/router-discovery.test.js.map +1 -0
  50. package/dist/__tests__/router-fallback.test.d.ts +9 -0
  51. package/dist/__tests__/router-fallback.test.d.ts.map +1 -0
  52. package/dist/__tests__/router-fallback.test.js +283 -0
  53. package/dist/__tests__/router-fallback.test.js.map +1 -0
  54. package/dist/__tests__/router-local-executor.test.d.ts +6 -0
  55. package/dist/__tests__/router-local-executor.test.d.ts.map +1 -0
  56. package/dist/__tests__/router-local-executor.test.js +193 -0
  57. package/dist/__tests__/router-local-executor.test.js.map +1 -0
  58. package/dist/__tests__/router-model-registry.test.d.ts +8 -0
  59. package/dist/__tests__/router-model-registry.test.d.ts.map +1 -0
  60. package/dist/__tests__/router-model-registry.test.js +389 -0
  61. package/dist/__tests__/router-model-registry.test.js.map +1 -0
  62. package/dist/__tests__/router-rate-limiter.test.d.ts +8 -0
  63. package/dist/__tests__/router-rate-limiter.test.d.ts.map +1 -0
  64. package/dist/__tests__/router-rate-limiter.test.js +128 -0
  65. package/dist/__tests__/router-rate-limiter.test.js.map +1 -0
  66. package/dist/__tests__/router-resolver.test.d.ts +7 -0
  67. package/dist/__tests__/router-resolver.test.d.ts.map +1 -0
  68. package/dist/__tests__/router-resolver.test.js +110 -0
  69. package/dist/__tests__/router-resolver.test.js.map +1 -0
  70. package/dist/__tests__/router-retry.test.d.ts +7 -0
  71. package/dist/__tests__/router-retry.test.d.ts.map +1 -0
  72. package/dist/__tests__/router-retry.test.js +302 -0
  73. package/dist/__tests__/router-retry.test.js.map +1 -0
  74. package/dist/__tests__/router-scaffold.test.d.ts +11 -0
  75. package/dist/__tests__/router-scaffold.test.d.ts.map +1 -0
  76. package/dist/__tests__/router-scaffold.test.js +103 -0
  77. package/dist/__tests__/router-scaffold.test.js.map +1 -0
  78. package/dist/__tests__/router-spend-ledger.test.d.ts +8 -0
  79. package/dist/__tests__/router-spend-ledger.test.d.ts.map +1 -0
  80. package/dist/__tests__/router-spend-ledger.test.js +227 -0
  81. package/dist/__tests__/router-spend-ledger.test.js.map +1 -0
  82. package/dist/__tests__/router-telemetry.test.d.ts +11 -0
  83. package/dist/__tests__/router-telemetry.test.d.ts.map +1 -0
  84. package/dist/__tests__/router-telemetry.test.js +173 -0
  85. package/dist/__tests__/router-telemetry.test.js.map +1 -0
  86. package/dist/__tests__/single-shot.test.d.ts +12 -0
  87. package/dist/__tests__/single-shot.test.d.ts.map +1 -0
  88. package/dist/__tests__/single-shot.test.js +204 -0
  89. package/dist/__tests__/single-shot.test.js.map +1 -0
  90. package/dist/__tests__/skills-prompt.test.d.ts +11 -0
  91. package/dist/__tests__/skills-prompt.test.d.ts.map +1 -0
  92. package/dist/__tests__/skills-prompt.test.js +208 -0
  93. package/dist/__tests__/skills-prompt.test.js.map +1 -0
  94. package/dist/__tests__/skills.test.d.ts +11 -0
  95. package/dist/__tests__/skills.test.d.ts.map +1 -0
  96. package/dist/__tests__/skills.test.js +161 -0
  97. package/dist/__tests__/skills.test.js.map +1 -0
  98. package/dist/__tests__/telemetry-integration.test.d.ts +12 -0
  99. package/dist/__tests__/telemetry-integration.test.d.ts.map +1 -0
  100. package/dist/__tests__/telemetry-integration.test.js +153 -0
  101. package/dist/__tests__/telemetry-integration.test.js.map +1 -0
  102. package/dist/__tests__/telemetry.test.d.ts +13 -0
  103. package/dist/__tests__/telemetry.test.d.ts.map +1 -0
  104. package/dist/__tests__/telemetry.test.js +161 -0
  105. package/dist/__tests__/telemetry.test.js.map +1 -0
  106. package/dist/__tests__/upstream-error.test.d.ts +8 -0
  107. package/dist/__tests__/upstream-error.test.d.ts.map +1 -0
  108. package/dist/__tests__/upstream-error.test.js +186 -0
  109. package/dist/__tests__/upstream-error.test.js.map +1 -0
  110. package/dist/adk-adapter.d.ts +45 -0
  111. package/dist/adk-adapter.d.ts.map +1 -0
  112. package/dist/adk-adapter.js +403 -0
  113. package/dist/adk-adapter.js.map +1 -0
  114. package/dist/adk-anthropic-llm.d.ts +59 -0
  115. package/dist/adk-anthropic-llm.d.ts.map +1 -0
  116. package/dist/adk-anthropic-llm.js +397 -0
  117. package/dist/adk-anthropic-llm.js.map +1 -0
  118. package/dist/agent/index.d.ts +14 -0
  119. package/dist/agent/index.d.ts.map +1 -0
  120. package/dist/agent/index.js +14 -0
  121. package/dist/agent/index.js.map +1 -0
  122. package/dist/agent/session/__tests__/bridge-tool-executor.test.d.ts +10 -0
  123. package/dist/agent/session/__tests__/bridge-tool-executor.test.d.ts.map +1 -0
  124. package/dist/agent/session/__tests__/bridge-tool-executor.test.js +152 -0
  125. package/dist/agent/session/__tests__/bridge-tool-executor.test.js.map +1 -0
  126. package/dist/agent/session/__tests__/collect-trajectory.test.d.ts +18 -0
  127. package/dist/agent/session/__tests__/collect-trajectory.test.d.ts.map +1 -0
  128. package/dist/agent/session/__tests__/collect-trajectory.test.js +208 -0
  129. package/dist/agent/session/__tests__/collect-trajectory.test.js.map +1 -0
  130. package/dist/agent/session/__tests__/run-with-agent.test.d.ts +8 -0
  131. package/dist/agent/session/__tests__/run-with-agent.test.d.ts.map +1 -0
  132. package/dist/agent/session/__tests__/run-with-agent.test.js +98 -0
  133. package/dist/agent/session/__tests__/run-with-agent.test.js.map +1 -0
  134. package/dist/agent/session/__tests__/runtime.test.d.ts +7 -0
  135. package/dist/agent/session/__tests__/runtime.test.d.ts.map +1 -0
  136. package/dist/agent/session/__tests__/runtime.test.js +361 -0
  137. package/dist/agent/session/__tests__/runtime.test.js.map +1 -0
  138. package/dist/agent/session/__tests__/skills-mcp-spawn.test.d.ts +15 -0
  139. package/dist/agent/session/__tests__/skills-mcp-spawn.test.d.ts.map +1 -0
  140. package/dist/agent/session/__tests__/skills-mcp-spawn.test.js +160 -0
  141. package/dist/agent/session/__tests__/skills-mcp-spawn.test.js.map +1 -0
  142. package/dist/agent/session/__tests__/spawn-telemetry.test.d.ts +13 -0
  143. package/dist/agent/session/__tests__/spawn-telemetry.test.d.ts.map +1 -0
  144. package/dist/agent/session/__tests__/spawn-telemetry.test.js +135 -0
  145. package/dist/agent/session/__tests__/spawn-telemetry.test.js.map +1 -0
  146. package/dist/agent/session/__tests__/types.test.d.ts +9 -0
  147. package/dist/agent/session/__tests__/types.test.d.ts.map +1 -0
  148. package/dist/agent/session/__tests__/types.test.js +220 -0
  149. package/dist/agent/session/__tests__/types.test.js.map +1 -0
  150. package/dist/agent/session/adapter.d.ts +108 -0
  151. package/dist/agent/session/adapter.d.ts.map +1 -0
  152. package/dist/agent/session/adapter.js +39 -0
  153. package/dist/agent/session/adapter.js.map +1 -0
  154. package/dist/agent/session/collect-trajectory.d.ts +36 -0
  155. package/dist/agent/session/collect-trajectory.d.ts.map +1 -0
  156. package/dist/agent/session/collect-trajectory.js +193 -0
  157. package/dist/agent/session/collect-trajectory.js.map +1 -0
  158. package/dist/agent/session/default-adapter-factory.d.ts +48 -0
  159. package/dist/agent/session/default-adapter-factory.d.ts.map +1 -0
  160. package/dist/agent/session/default-adapter-factory.js +227 -0
  161. package/dist/agent/session/default-adapter-factory.js.map +1 -0
  162. package/dist/agent/session/headless-types.d.ts +85 -0
  163. package/dist/agent/session/headless-types.d.ts.map +1 -0
  164. package/dist/agent/session/headless-types.js +16 -0
  165. package/dist/agent/session/headless-types.js.map +1 -0
  166. package/dist/agent/session/index.d.ts +18 -0
  167. package/dist/agent/session/index.d.ts.map +1 -0
  168. package/dist/agent/session/index.js +20 -0
  169. package/dist/agent/session/index.js.map +1 -0
  170. package/dist/agent/session/language-model-bridge.d.ts +84 -0
  171. package/dist/agent/session/language-model-bridge.d.ts.map +1 -0
  172. package/dist/agent/session/language-model-bridge.js +454 -0
  173. package/dist/agent/session/language-model-bridge.js.map +1 -0
  174. package/dist/agent/session/legacy-adapter-types.d.ts +63 -0
  175. package/dist/agent/session/legacy-adapter-types.d.ts.map +1 -0
  176. package/dist/agent/session/legacy-adapter-types.js +11 -0
  177. package/dist/agent/session/legacy-adapter-types.js.map +1 -0
  178. package/dist/agent/session/run-with-agent.d.ts +36 -0
  179. package/dist/agent/session/run-with-agent.d.ts.map +1 -0
  180. package/dist/agent/session/run-with-agent.js +81 -0
  181. package/dist/agent/session/run-with-agent.js.map +1 -0
  182. package/dist/agent/session/session-registry.d.ts +71 -0
  183. package/dist/agent/session/session-registry.d.ts.map +1 -0
  184. package/dist/agent/session/session-registry.js +209 -0
  185. package/dist/agent/session/session-registry.js.map +1 -0
  186. package/dist/agent/session/session.d.ts +76 -0
  187. package/dist/agent/session/session.d.ts.map +1 -0
  188. package/dist/agent/session/session.js +327 -0
  189. package/dist/agent/session/session.js.map +1 -0
  190. package/dist/agent/session/types.d.ts +230 -0
  191. package/dist/agent/session/types.d.ts.map +1 -0
  192. package/dist/agent/session/types.js +44 -0
  193. package/dist/agent/session/types.js.map +1 -0
  194. package/dist/checkpoint/__tests__/blob-store.test.d.ts +5 -0
  195. package/dist/checkpoint/__tests__/blob-store.test.d.ts.map +1 -0
  196. package/dist/checkpoint/__tests__/blob-store.test.js +82 -0
  197. package/dist/checkpoint/__tests__/blob-store.test.js.map +1 -0
  198. package/dist/checkpoint/__tests__/key.test.d.ts +7 -0
  199. package/dist/checkpoint/__tests__/key.test.d.ts.map +1 -0
  200. package/dist/checkpoint/__tests__/key.test.js +130 -0
  201. package/dist/checkpoint/__tests__/key.test.js.map +1 -0
  202. package/dist/checkpoint/__tests__/runner.test.d.ts +12 -0
  203. package/dist/checkpoint/__tests__/runner.test.d.ts.map +1 -0
  204. package/dist/checkpoint/__tests__/runner.test.js +201 -0
  205. package/dist/checkpoint/__tests__/runner.test.js.map +1 -0
  206. package/dist/checkpoint/__tests__/store.test.d.ts +6 -0
  207. package/dist/checkpoint/__tests__/store.test.d.ts.map +1 -0
  208. package/dist/checkpoint/__tests__/store.test.js +150 -0
  209. package/dist/checkpoint/__tests__/store.test.js.map +1 -0
  210. package/dist/checkpoint/blob-store.d.ts +41 -0
  211. package/dist/checkpoint/blob-store.d.ts.map +1 -0
  212. package/dist/checkpoint/blob-store.js +119 -0
  213. package/dist/checkpoint/blob-store.js.map +1 -0
  214. package/dist/checkpoint/index.d.ts +15 -0
  215. package/dist/checkpoint/index.d.ts.map +1 -0
  216. package/dist/checkpoint/index.js +14 -0
  217. package/dist/checkpoint/index.js.map +1 -0
  218. package/dist/checkpoint/key.d.ts +39 -0
  219. package/dist/checkpoint/key.d.ts.map +1 -0
  220. package/dist/checkpoint/key.js +112 -0
  221. package/dist/checkpoint/key.js.map +1 -0
  222. package/dist/checkpoint/runner.d.ts +83 -0
  223. package/dist/checkpoint/runner.d.ts.map +1 -0
  224. package/dist/checkpoint/runner.js +146 -0
  225. package/dist/checkpoint/runner.js.map +1 -0
  226. package/dist/checkpoint/store.d.ts +91 -0
  227. package/dist/checkpoint/store.d.ts.map +1 -0
  228. package/dist/checkpoint/store.js +292 -0
  229. package/dist/checkpoint/store.js.map +1 -0
  230. package/dist/checkpoint/types.d.ts +74 -0
  231. package/dist/checkpoint/types.d.ts.map +1 -0
  232. package/dist/checkpoint/types.js +16 -0
  233. package/dist/checkpoint/types.js.map +1 -0
  234. package/dist/claude-adapter.d.ts +23 -0
  235. package/dist/claude-adapter.d.ts.map +1 -0
  236. package/dist/claude-adapter.js +233 -0
  237. package/dist/claude-adapter.js.map +1 -0
  238. package/dist/cost.d.ts +67 -0
  239. package/dist/cost.d.ts.map +1 -0
  240. package/dist/cost.js +148 -0
  241. package/dist/cost.js.map +1 -0
  242. package/dist/data/model-prices.json +39681 -0
  243. package/dist/fallback-adapter.d.ts +51 -0
  244. package/dist/fallback-adapter.d.ts.map +1 -0
  245. package/dist/fallback-adapter.js +116 -0
  246. package/dist/fallback-adapter.js.map +1 -0
  247. package/dist/gemini-adapter.d.ts +22 -0
  248. package/dist/gemini-adapter.d.ts.map +1 -0
  249. package/dist/gemini-adapter.js +185 -0
  250. package/dist/gemini-adapter.js.map +1 -0
  251. package/dist/gemini-cli-adapter.d.ts +24 -0
  252. package/dist/gemini-cli-adapter.d.ts.map +1 -0
  253. package/dist/gemini-cli-adapter.js +169 -0
  254. package/dist/gemini-cli-adapter.js.map +1 -0
  255. package/dist/index.d.ts +39 -0
  256. package/dist/index.d.ts.map +1 -0
  257. package/dist/index.js +39 -0
  258. package/dist/index.js.map +1 -0
  259. package/dist/mcp/client.d.ts +32 -0
  260. package/dist/mcp/client.d.ts.map +1 -0
  261. package/dist/mcp/client.js +92 -0
  262. package/dist/mcp/client.js.map +1 -0
  263. package/dist/mcp/config-loader.d.ts +36 -0
  264. package/dist/mcp/config-loader.d.ts.map +1 -0
  265. package/dist/mcp/config-loader.js +129 -0
  266. package/dist/mcp/config-loader.js.map +1 -0
  267. package/dist/mcp/index.d.ts +12 -0
  268. package/dist/mcp/index.d.ts.map +1 -0
  269. package/dist/mcp/index.js +11 -0
  270. package/dist/mcp/index.js.map +1 -0
  271. package/dist/mcp/tool-merger.d.ts +18 -0
  272. package/dist/mcp/tool-merger.d.ts.map +1 -0
  273. package/dist/mcp/tool-merger.js +34 -0
  274. package/dist/mcp/tool-merger.js.map +1 -0
  275. package/dist/mcp/types.d.ts +35 -0
  276. package/dist/mcp/types.d.ts.map +1 -0
  277. package/dist/mcp/types.js +10 -0
  278. package/dist/mcp/types.js.map +1 -0
  279. package/dist/ollama-adapter.d.ts +95 -0
  280. package/dist/ollama-adapter.d.ts.map +1 -0
  281. package/dist/ollama-adapter.js +404 -0
  282. package/dist/ollama-adapter.js.map +1 -0
  283. package/dist/openai-adapter.d.ts +40 -0
  284. package/dist/openai-adapter.d.ts.map +1 -0
  285. package/dist/openai-adapter.js +81 -0
  286. package/dist/openai-adapter.js.map +1 -0
  287. package/dist/opencode-adapter.d.ts +39 -0
  288. package/dist/opencode-adapter.d.ts.map +1 -0
  289. package/dist/opencode-adapter.js +105 -0
  290. package/dist/opencode-adapter.js.map +1 -0
  291. package/dist/openrouter-adapter.d.ts +69 -0
  292. package/dist/openrouter-adapter.d.ts.map +1 -0
  293. package/dist/openrouter-adapter.js +481 -0
  294. package/dist/openrouter-adapter.js.map +1 -0
  295. package/dist/registry.d.ts +55 -0
  296. package/dist/registry.d.ts.map +1 -0
  297. package/dist/registry.js +191 -0
  298. package/dist/registry.js.map +1 -0
  299. package/dist/router/circuit-breaker.d.ts +57 -0
  300. package/dist/router/circuit-breaker.d.ts.map +1 -0
  301. package/dist/router/circuit-breaker.js +110 -0
  302. package/dist/router/circuit-breaker.js.map +1 -0
  303. package/dist/router/config-loader.d.ts +43 -0
  304. package/dist/router/config-loader.d.ts.map +1 -0
  305. package/dist/router/config-loader.js +155 -0
  306. package/dist/router/config-loader.js.map +1 -0
  307. package/dist/router/discovery.d.ts +37 -0
  308. package/dist/router/discovery.d.ts.map +1 -0
  309. package/dist/router/discovery.js +54 -0
  310. package/dist/router/discovery.js.map +1 -0
  311. package/dist/router/errors.d.ts +39 -0
  312. package/dist/router/errors.d.ts.map +1 -0
  313. package/dist/router/errors.js +103 -0
  314. package/dist/router/errors.js.map +1 -0
  315. package/dist/router/index.d.ts +31 -0
  316. package/dist/router/index.d.ts.map +1 -0
  317. package/dist/router/index.js +20 -0
  318. package/dist/router/index.js.map +1 -0
  319. package/dist/router/local-executor.d.ts +62 -0
  320. package/dist/router/local-executor.d.ts.map +1 -0
  321. package/dist/router/local-executor.js +161 -0
  322. package/dist/router/local-executor.js.map +1 -0
  323. package/dist/router/model-registry.d.ts +90 -0
  324. package/dist/router/model-registry.d.ts.map +1 -0
  325. package/dist/router/model-registry.js +242 -0
  326. package/dist/router/model-registry.js.map +1 -0
  327. package/dist/router/rate-limiter.d.ts +63 -0
  328. package/dist/router/rate-limiter.d.ts.map +1 -0
  329. package/dist/router/rate-limiter.js +136 -0
  330. package/dist/router/rate-limiter.js.map +1 -0
  331. package/dist/router/resolver.d.ts +45 -0
  332. package/dist/router/resolver.d.ts.map +1 -0
  333. package/dist/router/resolver.js +71 -0
  334. package/dist/router/resolver.js.map +1 -0
  335. package/dist/router/retry.d.ts +58 -0
  336. package/dist/router/retry.d.ts.map +1 -0
  337. package/dist/router/retry.js +119 -0
  338. package/dist/router/retry.js.map +1 -0
  339. package/dist/router/router.d.ts +100 -0
  340. package/dist/router/router.d.ts.map +1 -0
  341. package/dist/router/router.js +306 -0
  342. package/dist/router/router.js.map +1 -0
  343. package/dist/router/spend-ledger.d.ts +69 -0
  344. package/dist/router/spend-ledger.d.ts.map +1 -0
  345. package/dist/router/spend-ledger.js +191 -0
  346. package/dist/router/spend-ledger.js.map +1 -0
  347. package/dist/router/telemetry.d.ts +48 -0
  348. package/dist/router/telemetry.d.ts.map +1 -0
  349. package/dist/router/telemetry.js +112 -0
  350. package/dist/router/telemetry.js.map +1 -0
  351. package/dist/router/types.d.ts +95 -0
  352. package/dist/router/types.d.ts.map +1 -0
  353. package/dist/router/types.js +16 -0
  354. package/dist/router/types.js.map +1 -0
  355. package/dist/single-shot.d.ts +60 -0
  356. package/dist/single-shot.d.ts.map +1 -0
  357. package/dist/single-shot.js +385 -0
  358. package/dist/single-shot.js.map +1 -0
  359. package/dist/skills/activator.d.ts +17 -0
  360. package/dist/skills/activator.d.ts.map +1 -0
  361. package/dist/skills/activator.js +24 -0
  362. package/dist/skills/activator.js.map +1 -0
  363. package/dist/skills/compose.d.ts +43 -0
  364. package/dist/skills/compose.d.ts.map +1 -0
  365. package/dist/skills/compose.js +53 -0
  366. package/dist/skills/compose.js.map +1 -0
  367. package/dist/skills/index.d.ts +17 -0
  368. package/dist/skills/index.d.ts.map +1 -0
  369. package/dist/skills/index.js +16 -0
  370. package/dist/skills/index.js.map +1 -0
  371. package/dist/skills/loader.d.ts +9 -0
  372. package/dist/skills/loader.d.ts.map +1 -0
  373. package/dist/skills/loader.js +49 -0
  374. package/dist/skills/loader.js.map +1 -0
  375. package/dist/skills/parser.d.ts +13 -0
  376. package/dist/skills/parser.d.ts.map +1 -0
  377. package/dist/skills/parser.js +60 -0
  378. package/dist/skills/parser.js.map +1 -0
  379. package/dist/skills/render.d.ts +11 -0
  380. package/dist/skills/render.d.ts.map +1 -0
  381. package/dist/skills/render.js +21 -0
  382. package/dist/skills/render.js.map +1 -0
  383. package/dist/skills/resolve-dir.d.ts +20 -0
  384. package/dist/skills/resolve-dir.d.ts.map +1 -0
  385. package/dist/skills/resolve-dir.js +30 -0
  386. package/dist/skills/resolve-dir.js.map +1 -0
  387. package/dist/skills/tool-policy.d.ts +26 -0
  388. package/dist/skills/tool-policy.d.ts.map +1 -0
  389. package/dist/skills/tool-policy.js +33 -0
  390. package/dist/skills/tool-policy.js.map +1 -0
  391. package/dist/skills/types.d.ts +42 -0
  392. package/dist/skills/types.d.ts.map +1 -0
  393. package/dist/skills/types.js +8 -0
  394. package/dist/skills/types.js.map +1 -0
  395. package/dist/stream-format.d.ts +100 -0
  396. package/dist/stream-format.d.ts.map +1 -0
  397. package/dist/stream-format.js +90 -0
  398. package/dist/stream-format.js.map +1 -0
  399. package/dist/telemetry/attributes.d.ts +38 -0
  400. package/dist/telemetry/attributes.d.ts.map +1 -0
  401. package/dist/telemetry/attributes.js +39 -0
  402. package/dist/telemetry/attributes.js.map +1 -0
  403. package/dist/telemetry/config.d.ts +30 -0
  404. package/dist/telemetry/config.d.ts.map +1 -0
  405. package/dist/telemetry/config.js +54 -0
  406. package/dist/telemetry/config.js.map +1 -0
  407. package/dist/telemetry/exporters.d.ts +10 -0
  408. package/dist/telemetry/exporters.d.ts.map +1 -0
  409. package/dist/telemetry/exporters.js +46 -0
  410. package/dist/telemetry/exporters.js.map +1 -0
  411. package/dist/telemetry/index.d.ts +15 -0
  412. package/dist/telemetry/index.d.ts.map +1 -0
  413. package/dist/telemetry/index.js +12 -0
  414. package/dist/telemetry/index.js.map +1 -0
  415. package/dist/telemetry/instrument.d.ts +36 -0
  416. package/dist/telemetry/instrument.d.ts.map +1 -0
  417. package/dist/telemetry/instrument.js +215 -0
  418. package/dist/telemetry/instrument.js.map +1 -0
  419. package/dist/telemetry/metrics.d.ts +45 -0
  420. package/dist/telemetry/metrics.d.ts.map +1 -0
  421. package/dist/telemetry/metrics.js +186 -0
  422. package/dist/telemetry/metrics.js.map +1 -0
  423. package/dist/telemetry/tracer.d.ts +33 -0
  424. package/dist/telemetry/tracer.d.ts.map +1 -0
  425. package/dist/telemetry/tracer.js +162 -0
  426. package/dist/telemetry/tracer.js.map +1 -0
  427. package/dist/tools/__tests__/builtin.test.d.ts +7 -0
  428. package/dist/tools/__tests__/builtin.test.d.ts.map +1 -0
  429. package/dist/tools/__tests__/builtin.test.js +242 -0
  430. package/dist/tools/__tests__/builtin.test.js.map +1 -0
  431. package/dist/tools/builtin.d.ts +29 -0
  432. package/dist/tools/builtin.d.ts.map +1 -0
  433. package/dist/tools/builtin.js +367 -0
  434. package/dist/tools/builtin.js.map +1 -0
  435. package/dist/tools/index.d.ts +4 -0
  436. package/dist/tools/index.d.ts.map +1 -0
  437. package/dist/tools/index.js +3 -0
  438. package/dist/tools/index.js.map +1 -0
  439. package/dist/tools/path-guard.d.ts +23 -0
  440. package/dist/tools/path-guard.d.ts.map +1 -0
  441. package/dist/tools/path-guard.js +66 -0
  442. package/dist/tools/path-guard.js.map +1 -0
  443. package/dist/tools/types.d.ts +45 -0
  444. package/dist/tools/types.d.ts.map +1 -0
  445. package/dist/tools/types.js +11 -0
  446. package/dist/tools/types.js.map +1 -0
  447. package/dist/types.d.ts +249 -0
  448. package/dist/types.d.ts.map +1 -0
  449. package/dist/types.js +22 -0
  450. package/dist/types.js.map +1 -0
  451. package/dist/upstream-error.d.ts +64 -0
  452. package/dist/upstream-error.d.ts.map +1 -0
  453. package/dist/upstream-error.js +105 -0
  454. package/dist/upstream-error.js.map +1 -0
  455. package/dist/version.d.ts +2 -0
  456. package/dist/version.d.ts.map +1 -0
  457. package/dist/version.js +2 -0
  458. package/dist/version.js.map +1 -0
  459. package/package.json +49 -0
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Token-bucket rate limiter — per-provider RPM (requests/min) + TPM
3
+ * (tokens/min) buckets.
4
+ *
5
+ * Phase 3 ships only the in-process implementation. Cross-process mode
6
+ * (SQLite advisory file) is a deferred add-on once the router has real
7
+ * users running multiple parallel cli invocations against shared keys.
8
+ *
9
+ * Behavior:
10
+ * - One bucket per (provider, scope) where scope is 'rpm' | 'tpm'.
11
+ * - Buckets refill linearly at `capacity / 60_000` tokens/ms.
12
+ * - `acquire(provider, estimatedTokens)` waits until both buckets have
13
+ * enough tokens, then deducts. Behavior on dry bucket follows
14
+ * RouterConfig.onRateLimit:
15
+ * - 'wait' (default) — sleep until tokens are available
16
+ * - 'fail' — throw immediately
17
+ * - 'fallback' — return false; caller falls back
18
+ *
19
+ * Defaults reflect published provider docs as of 2026-04-29; override
20
+ * via RouterConfig.rateLimit.
21
+ */
22
+ export const DEFAULT_RATE_LIMITS = {
23
+ // Anthropic Tier 4 default (Sonnet 4.6); Haiku is much higher.
24
+ claude: { rpm: 50, tpm: 80_000 },
25
+ // OpenAI Tier 1 default (gpt-4o RPM 500 / TPM 30k).
26
+ openai: { rpm: 500, tpm: 30_000 },
27
+ // Gemini 2.5 Pro default — 1000 RPM, 4M TPM in the AI Studio tier.
28
+ gemini: { rpm: 1000, tpm: 4_000_000 },
29
+ // OpenRouter aggregates upstream limits; default is conservative.
30
+ openrouter: { rpm: 200, tpm: 200_000 },
31
+ // Local providers — effectively unbounded.
32
+ ollama: {},
33
+ 'gemini-cli': {},
34
+ adk: {},
35
+ };
36
+ const realSleep = (ms) => new Promise((r) => setTimeout(r, ms));
37
+ export class RateLimitedError extends Error {
38
+ provider;
39
+ waitMs;
40
+ constructor(provider, waitMs) {
41
+ super(`rate limit for provider '${provider}' exhausted; wait ${waitMs}ms`);
42
+ this.name = 'RateLimitedError';
43
+ this.provider = provider;
44
+ this.waitMs = waitMs;
45
+ }
46
+ }
47
+ export class TokenBucketRateLimiter {
48
+ config;
49
+ buckets = new Map();
50
+ now;
51
+ sleep;
52
+ onRateLimit;
53
+ constructor(deps = {}) {
54
+ this.config = { ...DEFAULT_RATE_LIMITS, ...deps.config };
55
+ this.now = deps.now ?? Date.now;
56
+ this.sleep = deps.sleep ?? realSleep;
57
+ this.onRateLimit = deps.onRateLimit ?? 'wait';
58
+ }
59
+ /**
60
+ * Reserve 1 RPM token + N TPM tokens for the provider. If the bucket
61
+ * is dry the behavior depends on the configured `onRateLimit`:
62
+ * - 'wait' (default): awaits until available
63
+ * - 'fail': throws RateLimitedError
64
+ * - 'fallback': returns false; caller falls back
65
+ */
66
+ async acquire(provider, estimatedTokens) {
67
+ const cfg = this.config[provider] ?? {};
68
+ const rpm = cfg.rpm;
69
+ const tpm = cfg.tpm;
70
+ if (rpm === undefined && tpm === undefined)
71
+ return true; // unbounded
72
+ while (true) {
73
+ this.refillAll(provider);
74
+ const rpmBucket = rpm !== undefined ? this.bucketFor(provider, 'rpm', rpm) : null;
75
+ const tpmBucket = tpm !== undefined ? this.bucketFor(provider, 'tpm', tpm) : null;
76
+ const rpmShort = rpmBucket && rpmBucket.tokens < 1;
77
+ const tpmShort = tpmBucket && tpmBucket.tokens < estimatedTokens;
78
+ if (!rpmShort && !tpmShort) {
79
+ if (rpmBucket)
80
+ rpmBucket.tokens -= 1;
81
+ if (tpmBucket)
82
+ tpmBucket.tokens -= estimatedTokens;
83
+ return true;
84
+ }
85
+ const waitMs = Math.max(rpmBucket && rpmShort ? this.waitTime(rpmBucket, 1) : 0, tpmBucket && tpmShort ? this.waitTime(tpmBucket, estimatedTokens) : 0);
86
+ if (this.onRateLimit === 'fail') {
87
+ throw new RateLimitedError(provider, waitMs);
88
+ }
89
+ if (this.onRateLimit === 'fallback') {
90
+ return false;
91
+ }
92
+ await this.sleep(waitMs);
93
+ }
94
+ }
95
+ /** Best-effort introspection — returns current token counts. */
96
+ snapshot(provider) {
97
+ this.refillAll(provider);
98
+ return {
99
+ rpm: this.buckets.get(`${provider}:rpm`)?.tokens,
100
+ tpm: this.buckets.get(`${provider}:tpm`)?.tokens,
101
+ };
102
+ }
103
+ bucketFor(provider, scope, capacityPerMin) {
104
+ const key = `${provider}:${scope}`;
105
+ let b = this.buckets.get(key);
106
+ if (!b) {
107
+ b = { capacityPerMin, tokens: capacityPerMin, lastRefillMs: this.now() };
108
+ this.buckets.set(key, b);
109
+ }
110
+ else if (b.capacityPerMin !== capacityPerMin) {
111
+ b.capacityPerMin = capacityPerMin;
112
+ }
113
+ return b;
114
+ }
115
+ refillAll(provider) {
116
+ for (const scope of ['rpm', 'tpm']) {
117
+ const b = this.buckets.get(`${provider}:${scope}`);
118
+ if (!b)
119
+ continue;
120
+ const now = this.now();
121
+ const elapsed = now - b.lastRefillMs;
122
+ if (elapsed <= 0)
123
+ continue;
124
+ const refill = (elapsed / 60_000) * b.capacityPerMin;
125
+ b.tokens = Math.min(b.capacityPerMin, b.tokens + refill);
126
+ b.lastRefillMs = now;
127
+ }
128
+ }
129
+ waitTime(bucket, needed) {
130
+ const deficit = needed - bucket.tokens;
131
+ if (deficit <= 0)
132
+ return 0;
133
+ return Math.ceil((deficit / bucket.capacityPerMin) * 60_000);
134
+ }
135
+ }
136
+ //# sourceMappingURL=rate-limiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../src/router/rate-limiter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Resolver — given a capability + complexity + tier preference list, walks
3
+ * the model registry and returns a routing chain `{ primary, fallbacks }`
4
+ * suitable for `LlmRouter.invoke`.
5
+ *
6
+ * Pure function. No I/O. No mutation of the registry.
7
+ *
8
+ * Algorithm:
9
+ * 1. Filter: model.capabilities ⊇ {capability}
10
+ * ∧ rank(complexity) ≤ rank(model.complexity_max)
11
+ * ∧ availability[model.id]?.available !== false
12
+ * ∧ context_tokens, if requested, ≤ model.context_tokens
13
+ * 2. Group by tier
14
+ * 3. Walk tiers in `prefer` order; within tier, yaml-declared order
15
+ * 4. Concatenate → [primary, ...fallbacks]
16
+ * 5. If empty → ModelResolutionError with per-step diagnostic counts
17
+ */
18
+ import type { ModelRegistry, ModelCapability, ModelComplexity, ModelTier } from './model-registry.js';
19
+ import type { RouteFallback } from './types.js';
20
+ export interface ResolveModelOptions {
21
+ capability: ModelCapability;
22
+ complexity: ModelComplexity;
23
+ /** Tier preference order. Walked left-to-right; first non-empty tier wins. */
24
+ prefer: ModelTier[];
25
+ /** Optional minimum context window required by the call. */
26
+ minContextTokens?: number;
27
+ }
28
+ export interface ResolvedChain {
29
+ primary: string;
30
+ fallbacks: RouteFallback[];
31
+ }
32
+ export declare class ModelResolutionError extends Error {
33
+ readonly opts: ResolveModelOptions;
34
+ readonly diagnostic: ResolutionDiagnostic;
35
+ constructor(opts: ResolveModelOptions, diagnostic: ResolutionDiagnostic);
36
+ }
37
+ export interface ResolutionDiagnostic {
38
+ totalInRegistry: number;
39
+ matchedCapability: number;
40
+ matchedComplexity: number;
41
+ matchedContext: number;
42
+ matchedAvailability: number;
43
+ }
44
+ export declare function resolveModel(opts: ResolveModelOptions, registry: ModelRegistry): ResolvedChain;
45
+ //# sourceMappingURL=resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/router/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,eAAe,EACf,SAAS,EAEV,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,eAAe,CAAC;IAC5B,UAAU,EAAE,eAAe,CAAC;IAC5B,8EAA8E;IAC9E,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,qBAAa,oBAAqB,SAAQ,KAAK;aAE3B,IAAI,EAAE,mBAAmB;aACzB,UAAU,EAAE,oBAAoB;gBADhC,IAAI,EAAE,mBAAmB,EACzB,UAAU,EAAE,oBAAoB;CAKnD;AAED,MAAM,WAAW,oBAAoB;IACnC,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAID,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,aAAa,GAAG,aAAa,CAmD9F"}
@@ -0,0 +1,71 @@
1
+ export class ModelResolutionError extends Error {
2
+ opts;
3
+ diagnostic;
4
+ constructor(opts, diagnostic) {
5
+ super(formatDiagnostic(opts, diagnostic));
6
+ this.opts = opts;
7
+ this.diagnostic = diagnostic;
8
+ this.name = 'ModelResolutionError';
9
+ }
10
+ }
11
+ const COMPLEXITY_RANK = { S: 1, M: 2, L: 3 };
12
+ export function resolveModel(opts, registry) {
13
+ const requested = COMPLEXITY_RANK[opts.complexity];
14
+ const diag = {
15
+ totalInRegistry: registry.models.length,
16
+ matchedCapability: 0,
17
+ matchedComplexity: 0,
18
+ matchedContext: 0,
19
+ matchedAvailability: 0,
20
+ };
21
+ const passed = [];
22
+ for (const m of registry.models) {
23
+ if (!m.capabilities.includes(opts.capability))
24
+ continue;
25
+ diag.matchedCapability += 1;
26
+ if (COMPLEXITY_RANK[m.complexity_max] < requested)
27
+ continue;
28
+ diag.matchedComplexity += 1;
29
+ if (opts.minContextTokens !== undefined &&
30
+ m.context_tokens !== undefined &&
31
+ m.context_tokens < opts.minContextTokens) {
32
+ continue;
33
+ }
34
+ diag.matchedContext += 1;
35
+ if (registry.availability?.get(m.id)?.available === false)
36
+ continue;
37
+ diag.matchedAvailability += 1;
38
+ passed.push(m);
39
+ }
40
+ // Walk tier preference. Within a tier, preserve yaml-declared order
41
+ // (which is the order they appear in registry.models, since `passed`
42
+ // is built by iterating registry.models in order and we keep that).
43
+ const ordered = [];
44
+ for (const tier of opts.prefer) {
45
+ for (const m of passed) {
46
+ if (m.tier === tier)
47
+ ordered.push(m);
48
+ }
49
+ }
50
+ if (ordered.length === 0) {
51
+ throw new ModelResolutionError(opts, diag);
52
+ }
53
+ return {
54
+ primary: ordered[0].id,
55
+ fallbacks: ordered.slice(1).map((m) => ({ model: m.id })),
56
+ };
57
+ }
58
+ function formatDiagnostic(opts, d) {
59
+ const lines = [
60
+ `no model matches {capability: ${opts.capability}, complexity: ${opts.complexity}, prefer: [${opts.prefer.join(', ')}]}`,
61
+ ` registry has ${d.totalInRegistry} model(s);`,
62
+ ` ${d.matchedCapability} satisfied capability,`,
63
+ ` ${d.matchedComplexity} also satisfied complexity_max,`,
64
+ ` ${d.matchedContext} also satisfied context_tokens,`,
65
+ ` ${d.matchedAvailability} were available.`,
66
+ ` hint: add a matching model to ~/.anvil/models.yaml,`,
67
+ ` or relax stage policy to a less strict capability/complexity.`,
68
+ ];
69
+ return lines.join('\n');
70
+ }
71
+ //# sourceMappingURL=resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../src/router/resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Per-error retry engine.
3
+ *
4
+ * Drives a single attempt-loop against one adapter using `RetryPolicy`
5
+ * resolved from the active `ErrorClass`. The fallback walk (Phase 5)
6
+ * sits a layer up and consumes this primitive for each step.
7
+ *
8
+ * Default policy table per ADR R2:
9
+ * - rate_limit: 5 attempts, exponential, base 1000ms, max 30000ms
10
+ * - timeout: 3 attempts, linear, base 500ms, max 5000ms
11
+ * - server_5xx: 4 attempts, exponential, base 200ms, max 5000ms
12
+ * - auth: 0 attempts, constant (terminal — surface immediately)
13
+ * - content_policy: 0 attempts, constant (terminal)
14
+ * - invalid_request: 0 attempts, constant (terminal)
15
+ * - unknown: 1 attempt, constant, base 1000ms
16
+ *
17
+ * `Retry-After` headers — when present on the thrown error — override
18
+ * the computed backoff for that single delay.
19
+ */
20
+ import type { ErrorClass, RetryPolicy } from './types.js';
21
+ export declare const DEFAULT_RETRY_POLICY: Record<ErrorClass, RetryPolicy>;
22
+ export interface RetryAttempt {
23
+ index: number;
24
+ errorClass?: ErrorClass;
25
+ error?: Error;
26
+ delayMs: number;
27
+ durationMs: number;
28
+ }
29
+ export interface RunWithRetryResult<T> {
30
+ result?: T;
31
+ error?: Error;
32
+ attempts: RetryAttempt[];
33
+ }
34
+ export interface RunWithRetryDeps {
35
+ /** Resolve the retry policy for a given error class. */
36
+ policyFor: (cls: ErrorClass) => RetryPolicy;
37
+ /**
38
+ * Adapter-specific overrides for `classifyError`. Returning `undefined`
39
+ * falls back to the generic heuristic.
40
+ */
41
+ classify?: (err: unknown) => ErrorClass | undefined;
42
+ /** Sleep — injectable so tests can drive a fake clock. */
43
+ sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
44
+ /** Time source — injectable for deterministic durations. */
45
+ now?: () => number;
46
+ /** Random source for jitter — injectable for deterministic tests. */
47
+ random?: () => number;
48
+ signal?: AbortSignal;
49
+ }
50
+ /**
51
+ * Run `fn` under the active retry policy. Returns the success result
52
+ * once produced, or the final error after the policy budget is exhausted.
53
+ *
54
+ * Each invocation is recorded in `attempts[]` with its classification,
55
+ * pre-attempt delay, and wall-clock duration.
56
+ */
57
+ export declare function runWithRetry<T>(fn: () => Promise<T>, deps: RunWithRetryDeps): Promise<RunWithRetryResult<T>>;
58
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/router/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG1D,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,UAAU,EAAE,WAAW,CAQhE,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,MAAM,CAAC,EAAE,CAAC,CAAC;IACX,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,wDAAwD;IACxD,SAAS,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,WAAW,CAAC;IAC5C;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,UAAU,GAAG,SAAS,CAAC;IACpD,0DAA0D;IAC1D,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,4DAA4D;IAC5D,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAgBD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAClC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAwDhC"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Per-error retry engine.
3
+ *
4
+ * Drives a single attempt-loop against one adapter using `RetryPolicy`
5
+ * resolved from the active `ErrorClass`. The fallback walk (Phase 5)
6
+ * sits a layer up and consumes this primitive for each step.
7
+ *
8
+ * Default policy table per ADR R2:
9
+ * - rate_limit: 5 attempts, exponential, base 1000ms, max 30000ms
10
+ * - timeout: 3 attempts, linear, base 500ms, max 5000ms
11
+ * - server_5xx: 4 attempts, exponential, base 200ms, max 5000ms
12
+ * - auth: 0 attempts, constant (terminal — surface immediately)
13
+ * - content_policy: 0 attempts, constant (terminal)
14
+ * - invalid_request: 0 attempts, constant (terminal)
15
+ * - unknown: 1 attempt, constant, base 1000ms
16
+ *
17
+ * `Retry-After` headers — when present on the thrown error — override
18
+ * the computed backoff for that single delay.
19
+ */
20
+ import { classifyError, parseRetryAfterMs } from './errors.js';
21
+ export const DEFAULT_RETRY_POLICY = {
22
+ rate_limit: { attempts: 5, backoff: 'exponential', baseMs: 1000, maxMs: 30000 },
23
+ timeout: { attempts: 3, backoff: 'linear', baseMs: 500, maxMs: 5000 },
24
+ server_5xx: { attempts: 4, backoff: 'exponential', baseMs: 200, maxMs: 5000 },
25
+ auth: { attempts: 0, backoff: 'constant', baseMs: 0 },
26
+ content_policy: { attempts: 0, backoff: 'constant', baseMs: 0 },
27
+ invalid_request: { attempts: 0, backoff: 'constant', baseMs: 0 },
28
+ unknown: { attempts: 1, backoff: 'constant', baseMs: 1000 },
29
+ };
30
+ const realSleep = (ms, signal) => new Promise((resolve, reject) => {
31
+ if (signal?.aborted)
32
+ return reject(signal.reason);
33
+ const timer = setTimeout(resolve, ms);
34
+ signal?.addEventListener('abort', () => {
35
+ clearTimeout(timer);
36
+ reject(signal.reason);
37
+ }, { once: true });
38
+ });
39
+ /**
40
+ * Run `fn` under the active retry policy. Returns the success result
41
+ * once produced, or the final error after the policy budget is exhausted.
42
+ *
43
+ * Each invocation is recorded in `attempts[]` with its classification,
44
+ * pre-attempt delay, and wall-clock duration.
45
+ */
46
+ export async function runWithRetry(fn, deps) {
47
+ const sleep = deps.sleep ?? realSleep;
48
+ const now = deps.now ?? Date.now;
49
+ const random = deps.random ?? Math.random;
50
+ const attempts = [];
51
+ let attemptIndex = 0;
52
+ while (true) {
53
+ const startedAt = now();
54
+ let outcome;
55
+ try {
56
+ const value = await fn();
57
+ outcome = { ok: true, value };
58
+ }
59
+ catch (raw) {
60
+ outcome = { ok: false, err: raw instanceof Error ? raw : new Error(String(raw)) };
61
+ }
62
+ const durationMs = Math.max(0, now() - startedAt);
63
+ if (outcome.ok) {
64
+ attempts.push({ index: attemptIndex, delayMs: 0, durationMs });
65
+ return { result: outcome.value, attempts };
66
+ }
67
+ const cls = deps.classify?.(outcome.err) ?? classifyError(outcome.err);
68
+ const policy = deps.policyFor(cls);
69
+ attempts.push({
70
+ index: attemptIndex,
71
+ errorClass: cls,
72
+ error: outcome.err,
73
+ delayMs: 0,
74
+ durationMs,
75
+ });
76
+ // Budget exhausted (or terminal class with attempts: 0).
77
+ if (attemptIndex >= policy.attempts) {
78
+ return { error: outcome.err, attempts };
79
+ }
80
+ // Compute the next delay. `Retry-After` overrides if present.
81
+ const headerDelay = parseRetryAfterMs(outcome.err.headers);
82
+ const computed = headerDelay ?? computeDelay(policy, attemptIndex, random);
83
+ attempts[attempts.length - 1].delayMs = computed;
84
+ if (computed > 0) {
85
+ try {
86
+ await sleep(computed, deps.signal);
87
+ }
88
+ catch (e) {
89
+ return { error: e instanceof Error ? e : new Error(String(e)), attempts };
90
+ }
91
+ }
92
+ attemptIndex += 1;
93
+ }
94
+ }
95
+ function computeDelay(policy, attemptIndex, random) {
96
+ const useJitter = policy.jitter ?? true;
97
+ let base;
98
+ switch (policy.backoff) {
99
+ case 'constant':
100
+ base = policy.baseMs;
101
+ break;
102
+ case 'linear':
103
+ base = policy.baseMs * (attemptIndex + 1);
104
+ break;
105
+ case 'exponential':
106
+ base = policy.baseMs * Math.pow(2, attemptIndex);
107
+ break;
108
+ }
109
+ if (policy.maxMs !== undefined) {
110
+ base = Math.min(base, policy.maxMs);
111
+ }
112
+ if (!useJitter)
113
+ return Math.max(0, Math.round(base));
114
+ // ±25% jitter
115
+ const jitter = base * 0.25;
116
+ const value = base + (random() * 2 - 1) * jitter;
117
+ return Math.max(0, Math.round(value));
118
+ }
119
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/router/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAE/D,MAAM,CAAC,MAAM,oBAAoB,GAAoC;IACnE,UAAU,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;IAC/E,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE;IACrE,UAAU,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE;IAC7E,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE;IACrD,cAAc,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE;IAC/D,eAAe,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE;IAChE,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE;CAC5D,CAAC;AAiCF,MAAM,SAAS,GAAG,CAAC,EAAU,EAAE,MAAoB,EAAE,EAAE,CACrD,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;IACpC,IAAI,MAAM,EAAE,OAAO;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACtC,MAAM,EAAE,gBAAgB,CACtB,OAAO,EACP,GAAG,EAAE;QACH,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC,EACD,EAAE,IAAI,EAAE,IAAI,EAAE,CACf,CAAC;AACJ,CAAC,CAAC,CAAC;AAEL;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,EAAoB,EACpB,IAAsB;IAEtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACjC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;IAC1C,MAAM,QAAQ,GAAmB,EAAE,CAAC;IAEpC,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;QACxB,IAAI,OAA2D,CAAC;QAChE,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,EAAE,EAAE,CAAC;YACzB,OAAO,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QAChC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACpF,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;QAElD,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;YACf,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;YAC/D,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC;QAC7C,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACvE,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACnC,QAAQ,CAAC,IAAI,CAAC;YACZ,KAAK,EAAE,YAAY;YACnB,UAAU,EAAE,GAAG;YACf,KAAK,EAAE,OAAO,CAAC,GAAG;YAClB,OAAO,EAAE,CAAC;YACV,UAAU;SACX,CAAC,CAAC;QAEH,yDAAyD;QACzD,IAAI,YAAY,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC;QAC1C,CAAC;QAED,8DAA8D;QAC9D,MAAM,WAAW,GAAG,iBAAiB,CAClC,OAAO,CAAC,GAAwD,CAAC,OAAO,CAC1E,CAAC;QACF,MAAM,QAAQ,GAAG,WAAW,IAAI,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;QAC3E,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,QAAQ,CAAC;QAEjD,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YACjB,IAAI,CAAC;gBACH,MAAM,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACrC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,EAAE,KAAK,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;YAC5E,CAAC;QACH,CAAC;QAED,YAAY,IAAI,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CACnB,MAAmB,EACnB,YAAoB,EACpB,MAAoB;IAEpB,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC;IACxC,IAAI,IAAY,CAAC;IACjB,QAAQ,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,KAAK,UAAU;YACb,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;YACrB,MAAM;QACR,KAAK,QAAQ;YACX,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;YAC1C,MAAM;QACR,KAAK,aAAa;YAChB,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;YACjD,MAAM;IACV,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACrD,cAAc;IACd,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IAC3B,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;IACjD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,CAAC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * `LlmRouter` — single source of truth for routing, retries, fallbacks,
3
+ * rate-limits, spend tracking, and circuit breaking.
4
+ *
5
+ * Phase 5: walks the full fallback chain. Per-error gates control which
6
+ * fallback steps are eligible. content_policy / auth / invalid_request
7
+ * never trigger cross-provider fallback (security default).
8
+ */
9
+ import type { ErrorClass, InvokeOpts, RouteAttempt, RouteOutcome, RouterConfig } from './types.js';
10
+ import type { LanguageModel, LanguageModelInvokeOptions, InvokeResult } from '../types.js';
11
+ import { TokenBucketRateLimiter } from './rate-limiter.js';
12
+ import { SpendLedger } from './spend-ledger.js';
13
+ import { CircuitBreaker } from './circuit-breaker.js';
14
+ export interface AdapterResolver {
15
+ /** Resolve a model id to an executor. */
16
+ resolve(modelId: string): LanguageModel;
17
+ }
18
+ export interface LlmRouterDeps {
19
+ config: RouterConfig;
20
+ /**
21
+ * Resolves a model id → executor. Phase 5 wires this to ProviderRegistry.
22
+ * Tests inject fakes directly.
23
+ */
24
+ resolver?: AdapterResolver;
25
+ /**
26
+ * Pre-flight rate limiter. If omitted, the router constructs an internal
27
+ * TokenBucketRateLimiter from `config.rateLimit`.
28
+ */
29
+ rateLimiter?: TokenBucketRateLimiter;
30
+ /**
31
+ * Spend ledger. If omitted, no rows are recorded (useful for tests or
32
+ * embedded scenarios). Pass `new SpendLedger()` to use the default
33
+ * `~/.anvil/router/spend.sqlite` file.
34
+ */
35
+ ledger?: SpendLedger;
36
+ /**
37
+ * Per-provider circuit breaker. If omitted, the router constructs one
38
+ * from `config.circuitBreaker` (or defaults).
39
+ */
40
+ circuitBreaker?: CircuitBreaker;
41
+ /** Generate ledger row ids — injectable for deterministic tests. */
42
+ newId?: () => string;
43
+ /** Time source for deterministic tests. */
44
+ now?: () => number;
45
+ /** Sleep — injectable for deterministic tests. */
46
+ sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
47
+ /** Random source for jitter. */
48
+ random?: () => number;
49
+ /** Adapter-specific error classifiers (per-provider override). */
50
+ errorClassifiers?: Record<string, (err: unknown) => ErrorClass | undefined>;
51
+ }
52
+ export declare class LlmRouter {
53
+ protected readonly config: RouterConfig;
54
+ protected readonly resolver?: AdapterResolver;
55
+ protected readonly rateLimiter: TokenBucketRateLimiter;
56
+ protected readonly circuitBreaker: CircuitBreaker;
57
+ protected readonly ledger?: SpendLedger;
58
+ protected readonly newId: () => string;
59
+ protected readonly now: () => number;
60
+ protected readonly sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
61
+ protected readonly random?: () => number;
62
+ protected readonly errorClassifiers: Record<string, (err: unknown) => ErrorClass | undefined>;
63
+ constructor(deps: LlmRouterDeps);
64
+ /** Inspect the active config (immutable snapshot). */
65
+ getConfig(): Readonly<RouterConfig>;
66
+ /**
67
+ * Resolve the route for a tag (or pinned model) and walk the chain
68
+ * primary → fallback[0] → fallback[1] until either success or the
69
+ * chain is exhausted.
70
+ *
71
+ * Per ADR R5:
72
+ * - auth / content_policy / invalid_request never trigger fallback
73
+ * - rate_limit / server_5xx / timeout default to the full chain;
74
+ * RouteFallback.on can restrict per-step
75
+ * - All attempts are ledgered (including failed ones with cost)
76
+ */
77
+ invoke(opts: InvokeOpts): Promise<RouteOutcome>;
78
+ /** Build the ordered chain of (model, on-gate) steps for a given tag. */
79
+ protected buildChain(opts: InvokeOpts): Array<{
80
+ model: string;
81
+ on?: ErrorClass[];
82
+ }>;
83
+ /** Decide whether to try this fallback step given the prior error class. */
84
+ protected shouldTryFallback(fallback: {
85
+ on?: ErrorClass[];
86
+ }, priorClass: ErrorClass | undefined): boolean;
87
+ protected enforceBudgetPreflight(opts: InvokeOpts): void;
88
+ protected computeRemainingBudget(opts: InvokeOpts): number | undefined;
89
+ protected populateBudgetRemaining(outcome: RouteOutcome, opts: InvokeOpts): void;
90
+ protected recordSpend(opts: InvokeOpts, provider: string, modelId: string, attempts: ReadonlyArray<RouteAttempt>, result: InvokeResult | undefined, err: Error | undefined): void;
91
+ /**
92
+ * Rough token estimate for pre-flight rate-limit checks. Uses the
93
+ * standard ~4-chars-per-token heuristic over message content. We bias
94
+ * slightly high (with maxTokens) so the bucket reserves enough room
95
+ * for the response too.
96
+ */
97
+ protected estimateTokens(opts: LanguageModelInvokeOptions): number;
98
+ protected buildInvokeOpts(opts: InvokeOpts, modelId: string): LanguageModelInvokeOptions;
99
+ }
100
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/router/router.ts"],"names":[],"mappings":"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"}