@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,161 @@
1
+ /**
2
+ * LocalExecutor — process-local FIFO single-slot queue for exclusive
3
+ * local models (Ollama big-model slots that can't co-reside on a 16GB
4
+ * GPU). Embedding + reranker models bypass this entirely.
5
+ *
6
+ * Contract:
7
+ * • At most ONE exclusive model is loaded at a time.
8
+ * • Concurrent callers are serialized in FIFO order — no deadlock,
9
+ * no priority inversion.
10
+ * • Switching from model A → model B triggers a synchronous eviction
11
+ * of A via Ollama's `POST /api/generate {model: A, prompt: '',
12
+ * keep_alive: 0}`, then polls `/api/ps` until A is no longer
13
+ * resident before letting B's call go through. Confirmed eviction
14
+ * prevents the GPU from briefly holding both.
15
+ * • Before every load, the executor probes `/api/ps` for OUT-OF-BAND
16
+ * resident exclusive models (e.g. an Ollama CLI session on the
17
+ * host loaded one independently). Intruders are evicted before B
18
+ * loads, so no two exclusive models are ever resident at once.
19
+ * • If `fn` throws, the slot is released and the queue keeps moving.
20
+ * • Same-id consecutive calls do NOT trigger eviction.
21
+ */
22
+ export class LocalExecutor {
23
+ loaded = null;
24
+ queue = [];
25
+ busy = false;
26
+ deps;
27
+ constructor(deps = {}) {
28
+ this.deps = {
29
+ evict: deps.evict ?? defaultEvict,
30
+ // Default probe is a sync no-op so unit tests don't pay an extra
31
+ // microtask tick for a network round-trip they don't care about.
32
+ // Production wires `defaultProbeResident` via the exported
33
+ // singleton at the bottom of this file.
34
+ probeResident: deps.probeResident ?? (async () => []),
35
+ isExclusive: deps.isExclusive ?? (() => true),
36
+ now: deps.now ?? Date.now,
37
+ };
38
+ }
39
+ withModel(modelId, fn) {
40
+ return new Promise((resolve, reject) => {
41
+ this.queue.push({
42
+ modelId,
43
+ run: fn,
44
+ resolve: resolve,
45
+ reject,
46
+ });
47
+ void this.pump();
48
+ });
49
+ }
50
+ inspect() {
51
+ return { loaded: this.loaded, queueDepth: this.queue.length };
52
+ }
53
+ async pump() {
54
+ if (this.busy)
55
+ return;
56
+ this.busy = true;
57
+ try {
58
+ while (this.queue.length > 0) {
59
+ const item = this.queue.shift();
60
+ try {
61
+ // 1. Detect out-of-band intruders — exclusive models loaded
62
+ // by something other than this executor (e.g. an Ollama
63
+ // CLI session on the same host). Evict each before we
64
+ // proceed; no co-residence ever.
65
+ let resident = [];
66
+ try {
67
+ resident = await this.deps.probeResident();
68
+ }
69
+ catch {
70
+ resident = [];
71
+ }
72
+ for (const r of resident) {
73
+ if (r === item.modelId)
74
+ continue; // already loaded — nothing to do
75
+ if (r === this.loaded)
76
+ continue; // tracked below
77
+ if (!this.deps.isExclusive(r))
78
+ continue; // co-resident utility — exempt
79
+ await this.deps.evict(r);
80
+ }
81
+ // 2. Tracked switch — A → B triggers our own eviction.
82
+ if (this.loaded !== null && this.loaded !== item.modelId) {
83
+ await this.deps.evict(this.loaded);
84
+ }
85
+ this.loaded = item.modelId;
86
+ const result = await item.run();
87
+ item.resolve(result);
88
+ }
89
+ catch (err) {
90
+ item.reject(err);
91
+ }
92
+ }
93
+ }
94
+ finally {
95
+ this.busy = false;
96
+ }
97
+ }
98
+ }
99
+ /**
100
+ * Confirmed eviction. Sends keep_alive:0 to Ollama, then polls /api/ps
101
+ * until the model is no longer resident or we hit the deadline. Eight
102
+ * seconds is generous for unloading a 14B model — most unloads complete
103
+ * sub-second once the daemon receives the signal.
104
+ */
105
+ async function defaultEvict(modelId) {
106
+ const baseUrl = (process.env.OLLAMA_HOST ?? 'http://localhost:11434').replace(/\/+$/, '');
107
+ await fetch(`${baseUrl}/api/generate`, {
108
+ method: 'POST',
109
+ headers: { 'Content-Type': 'application/json' },
110
+ body: JSON.stringify({ model: modelId, prompt: '', keep_alive: 0 }),
111
+ }).catch(() => {
112
+ // Eviction is best-effort; if Ollama is unreachable, the next /api/chat
113
+ // will surface the real error. Don't double-fail here.
114
+ });
115
+ const deadline = Date.now() + 8000;
116
+ while (Date.now() < deadline) {
117
+ let stillLoaded = false;
118
+ try {
119
+ const ps = await fetch(`${baseUrl}/api/ps`).then((r) => r.json());
120
+ stillLoaded = (ps.models ?? []).some((m) => m.name === modelId || m.model === modelId);
121
+ }
122
+ catch {
123
+ return; // probe failed — trust the unload, don't loop forever
124
+ }
125
+ if (!stillLoaded)
126
+ return;
127
+ await new Promise((r) => setTimeout(r, 200));
128
+ }
129
+ // Timed out waiting for unload — not fatal; the next chat call will
130
+ // either succeed (Ollama swaps fine) or fail with a clear OOM message.
131
+ }
132
+ async function defaultProbeResident() {
133
+ const baseUrl = (process.env.OLLAMA_HOST ?? 'http://localhost:11434').replace(/\/+$/, '');
134
+ try {
135
+ const ps = await fetch(`${baseUrl}/api/ps`).then((r) => r.json());
136
+ const names = [];
137
+ for (const m of ps.models ?? []) {
138
+ const id = m.name ?? m.model;
139
+ if (id)
140
+ names.push(id);
141
+ }
142
+ return names;
143
+ }
144
+ catch {
145
+ return [];
146
+ }
147
+ }
148
+ /**
149
+ * Process-local singleton. Modules that wrap exclusive-slot calls
150
+ * import this directly; tests construct their own instance to avoid
151
+ * cross-test pollution.
152
+ *
153
+ * The singleton is wired with the real Ollama probe so production
154
+ * intruder-detection works; per-test instances default to a no-op
155
+ * probe so they don't pay for a network round-trip they don't care
156
+ * about.
157
+ */
158
+ export const localExecutor = new LocalExecutor({
159
+ probeResident: defaultProbeResident,
160
+ });
161
+ //# sourceMappingURL=local-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-executor.js","sourceRoot":"","sources":["../../src/router/local-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AA8BH,MAAM,OAAO,aAAa;IAChB,MAAM,GAAkB,IAAI,CAAC;IAC7B,KAAK,GAAgB,EAAE,CAAC;IACxB,IAAI,GAAG,KAAK,CAAC;IACJ,IAAI,CAA8B;IAEnD,YAAY,OAA0B,EAAE;QACtC,IAAI,CAAC,IAAI,GAAG;YACV,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,YAAY;YACjC,iEAAiE;YACjE,iEAAiE;YACjE,2DAA2D;YAC3D,wCAAwC;YACxC,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;YACrD,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;YAC7C,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG;SAC1B,CAAC;IACJ,CAAC;IAED,SAAS,CAAI,OAAe,EAAE,EAAoB;QAChD,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;gBACd,OAAO;gBACP,GAAG,EAAE,EAA4B;gBACjC,OAAO,EAAE,OAA+B;gBACxC,MAAM;aACP,CAAC,CAAC;YACH,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;IAChE,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,IAAI,IAAI,CAAC,IAAI;YAAE,OAAO;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAG,CAAC;gBACjC,IAAI,CAAC;oBACH,4DAA4D;oBAC5D,2DAA2D;oBAC3D,yDAAyD;oBACzD,oCAAoC;oBACpC,IAAI,QAAQ,GAAa,EAAE,CAAC;oBAC5B,IAAI,CAAC;wBACH,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;oBAC7C,CAAC;oBAAC,MAAM,CAAC;wBACP,QAAQ,GAAG,EAAE,CAAC;oBAChB,CAAC;oBACD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;wBACzB,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO;4BAAE,SAAS,CAAkB,iCAAiC;wBACpF,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM;4BAAE,SAAS,CAAmB,gBAAgB;wBACnE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;4BAAE,SAAS,CAAW,+BAA+B;wBAClF,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBAC3B,CAAC;oBAED,uDAAuD;oBACvD,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;wBACzD,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBACrC,CAAC;oBAED,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;oBAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;oBAChC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBACvB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACnB,CAAC;YACH,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;QACpB,CAAC;IACH,CAAC;CACF;AAED;;;;;GAKG;AACH,KAAK,UAAU,YAAY,CAAC,OAAe;IACzC,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,wBAAwB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC1F,MAAM,KAAK,CAAC,GAAG,OAAO,eAAe,EAAE;QACrC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;KACpE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;QACZ,wEAAwE;QACxE,uDAAuD;IACzD,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IACnC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAE5D,CAAC,CAAC;YACJ,WAAW,GAAG,CAAC,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO,CACjD,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,sDAAsD;QAChE,CAAC;QACD,IAAI,CAAC,WAAW;YAAE,OAAO;QACzB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,oEAAoE;IACpE,uEAAuE;AACzE,CAAC;AAED,KAAK,UAAU,oBAAoB;IACjC,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,wBAAwB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC1F,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAE5D,CAAC,CAAC;QACJ,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YAChC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC;YAC7B,IAAI,EAAE;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC;IAC7C,aAAa,EAAE,oBAAoB;CACpC,CAAC,CAAC"}
@@ -0,0 +1,90 @@
1
+ import type { ProviderName } from '../types.js';
2
+ export type ModelCapability = 'embed' | 'rerank' | 'code' | 'reasoning' | 'vision';
3
+ export type ModelComplexity = 'S' | 'M' | 'L';
4
+ export type ModelTier = 'local' | 'cheap' | 'premium';
5
+ export type ModelConsumer = 'agent-core' | 'knowledge-core';
6
+ export interface ModelEntry {
7
+ id: string;
8
+ provider: ProviderName;
9
+ tier: ModelTier;
10
+ capabilities: ModelCapability[];
11
+ complexity_max: ModelComplexity;
12
+ vram_gb: number;
13
+ exclusive_slot: boolean;
14
+ context_tokens?: number;
15
+ /**
16
+ * Ollama `num_ctx` cap — bounds VRAM cost of context. Set to a value
17
+ * smaller than the model's max so context tokens don't eat the GPU
18
+ * headroom needed by weights. Ignored for cloud providers.
19
+ */
20
+ context_window?: number;
21
+ consumed_by?: ModelConsumer;
22
+ /** Optional non-Ollama HTTP endpoint. Reserved for future providers. */
23
+ endpoint?: string;
24
+ }
25
+ /**
26
+ * Walker tunables — controls how the dashboard's chain walker behaves.
27
+ *
28
+ * Lives at the top level of `models.yaml` so end users can adjust the
29
+ * routing/fallback policy in the same place they manage models. All
30
+ * fields are optional; missing values fall back to compiled-in defaults.
31
+ *
32
+ * ```yaml
33
+ * walker:
34
+ * liveness_ttl_ms: 30000 # provider-liveness cache TTL (ms)
35
+ * max_attempts: 5 # max chain-fallback attempts per stage
36
+ * ```
37
+ */
38
+ export interface WalkerConfig {
39
+ /**
40
+ * How long a per-provider liveness verdict is cached. Default 30000.
41
+ * Lower values catch a recovering provider faster but cost more
42
+ * probes per run. Set to 0 to disable caching entirely.
43
+ */
44
+ liveness_ttl_ms: number;
45
+ /**
46
+ * Max chain-fallback attempts per stage entry. Default 5. After this
47
+ * many UpstreamError(retryable) burns the runner gives up and bubbles
48
+ * the last error to the user.
49
+ */
50
+ max_attempts: number;
51
+ }
52
+ /** Compiled-in defaults — used when models.yaml omits the walker block. */
53
+ export declare const DEFAULT_WALKER_CONFIG: Readonly<WalkerConfig>;
54
+ export interface ModelRegistry {
55
+ models: ModelEntry[];
56
+ /** Walker tunables — always populated; defaults applied at load time. */
57
+ walker: WalkerConfig;
58
+ /** Live availability annotation; populated by Phase 5 discovery, never by the loader. */
59
+ availability?: Map<string, ModelAvailability>;
60
+ }
61
+ export interface ModelAvailability {
62
+ available: boolean;
63
+ lastChecked: number;
64
+ error?: string;
65
+ }
66
+ export declare class ModelRegistryParseError extends Error {
67
+ readonly path: string;
68
+ readonly cause: unknown;
69
+ constructor(path: string, cause: unknown);
70
+ }
71
+ export declare class ModelRegistryValidationError extends Error {
72
+ constructor(message: string);
73
+ }
74
+ export interface LoadModelRegistryOptions {
75
+ workspaceRoot?: string;
76
+ env?: NodeJS.ProcessEnv;
77
+ homeDir?: string;
78
+ }
79
+ export declare function findModelsConfigPath(opts?: LoadModelRegistryOptions): string | undefined;
80
+ /**
81
+ * Load + validate the models registry. Missing file → empty registry.
82
+ * Malformed yaml or invalid schema throws.
83
+ */
84
+ export declare function loadModelRegistry(opts?: LoadModelRegistryOptions): ModelRegistry;
85
+ /**
86
+ * Parse a previously-deserialized yaml object. Exposed for tests so they
87
+ * can feed in-memory yaml strings without touching the filesystem.
88
+ */
89
+ export declare function parseModelRegistry(raw: unknown, sourcePath?: string): ModelRegistry;
90
+ //# sourceMappingURL=model-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-registry.d.ts","sourceRoot":"","sources":["../../src/router/model-registry.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;AACnF,MAAM,MAAM,eAAe,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAC9C,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;AACtD,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,gBAAgB,CAAC;AAU5D,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,YAAY,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;IAChB,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,cAAc,EAAE,eAAe,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,2EAA2E;AAC3E,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,YAAY,CAGvD,CAAC;AAEH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,yEAAyE;IACzE,MAAM,EAAE,YAAY,CAAC;IACrB,yFAAyF;IACzF,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,uBAAwB,SAAQ,KAAK;aACpB,IAAI,EAAE,MAAM;aAAkB,KAAK,EAAE,OAAO;gBAA5C,IAAI,EAAE,MAAM,EAAkB,KAAK,EAAE,OAAO;CAIzE;AAED,qBAAa,4BAA6B,SAAQ,KAAK;gBACzC,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,oBAAoB,CAAC,IAAI,GAAE,wBAA6B,GAAG,MAAM,GAAG,SAAS,CAc5F;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,wBAA6B,GAAG,aAAa,CAYpF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,SAAa,GAAG,aAAa,CA6BvF"}
@@ -0,0 +1,242 @@
1
+ /**
2
+ * Model registry — capability/complexity-tagged catalog of models the
3
+ * resolver picks from. Source-of-truth file is `~/.anvil/models.yaml`.
4
+ *
5
+ * The registry holds CURATED facts (capabilities, tier, complexity_max,
6
+ * VRAM, exclusive_slot) loaded from yaml. Live state (availability,
7
+ * pricing) is augmented at runtime by the discovery pass — the loader
8
+ * itself never makes network calls.
9
+ *
10
+ * Resolution order for the yaml file:
11
+ * 1. process.env.ANVIL_MODELS_CONFIG (full path)
12
+ * 2. <workspaceRoot>/.anvil/models.yaml
13
+ * 3. ${ANVIL_HOME or $HOME/.anvil}/models.yaml
14
+ * 4. (no file) → returns { models: [] } and the resolver throws on use.
15
+ */
16
+ import { existsSync, readFileSync } from 'node:fs';
17
+ import { join } from 'node:path';
18
+ import { homedir } from 'node:os';
19
+ import * as YAML from 'yaml';
20
+ const PROVIDERS = [
21
+ 'claude', 'openai', 'gemini', 'openrouter', 'ollama', 'gemini-cli', 'adk', 'opencode',
22
+ ];
23
+ const CAPABILITIES = ['embed', 'rerank', 'code', 'reasoning', 'vision'];
24
+ const COMPLEXITIES = ['S', 'M', 'L'];
25
+ const TIERS = ['local', 'cheap', 'premium'];
26
+ const CONSUMERS = ['agent-core', 'knowledge-core'];
27
+ /** Compiled-in defaults — used when models.yaml omits the walker block. */
28
+ export const DEFAULT_WALKER_CONFIG = Object.freeze({
29
+ liveness_ttl_ms: 30_000,
30
+ max_attempts: 5,
31
+ });
32
+ export class ModelRegistryParseError extends Error {
33
+ path;
34
+ cause;
35
+ constructor(path, cause) {
36
+ super(`Failed to parse models.yaml at ${path}: ${cause instanceof Error ? cause.message : String(cause)}`);
37
+ this.path = path;
38
+ this.cause = cause;
39
+ this.name = 'ModelRegistryParseError';
40
+ }
41
+ }
42
+ export class ModelRegistryValidationError extends Error {
43
+ constructor(message) {
44
+ super(`models.yaml validation failed: ${message}`);
45
+ this.name = 'ModelRegistryValidationError';
46
+ }
47
+ }
48
+ export function findModelsConfigPath(opts = {}) {
49
+ const env = opts.env ?? process.env;
50
+ const home = opts.homeDir ?? homedir();
51
+ const anvilHome = env.ANVIL_HOME ?? join(home, '.anvil');
52
+ const candidates = [];
53
+ if (env.ANVIL_MODELS_CONFIG)
54
+ candidates.push(env.ANVIL_MODELS_CONFIG);
55
+ if (opts.workspaceRoot)
56
+ candidates.push(join(opts.workspaceRoot, '.anvil', 'models.yaml'));
57
+ candidates.push(join(anvilHome, 'models.yaml'));
58
+ for (const c of candidates) {
59
+ if (existsSync(c))
60
+ return c;
61
+ }
62
+ return undefined;
63
+ }
64
+ /**
65
+ * Load + validate the models registry. Missing file → empty registry.
66
+ * Malformed yaml or invalid schema throws.
67
+ */
68
+ export function loadModelRegistry(opts = {}) {
69
+ const path = findModelsConfigPath(opts);
70
+ if (!path)
71
+ return { models: [], walker: { ...DEFAULT_WALKER_CONFIG } };
72
+ let raw;
73
+ try {
74
+ raw = YAML.parse(readFileSync(path, 'utf8'));
75
+ }
76
+ catch (err) {
77
+ throw new ModelRegistryParseError(path, err);
78
+ }
79
+ return parseModelRegistry(raw, path);
80
+ }
81
+ /**
82
+ * Parse a previously-deserialized yaml object. Exposed for tests so they
83
+ * can feed in-memory yaml strings without touching the filesystem.
84
+ */
85
+ export function parseModelRegistry(raw, sourcePath = '<inline>') {
86
+ if (raw === null || raw === undefined)
87
+ return { models: [], walker: { ...DEFAULT_WALKER_CONFIG } };
88
+ if (typeof raw !== 'object' || Array.isArray(raw)) {
89
+ throw new ModelRegistryValidationError(`expected top-level object, got ${describe(raw)} (${sourcePath})`);
90
+ }
91
+ const top = raw;
92
+ const walker = parseWalkerConfig(top.walker);
93
+ const modelsRaw = top.models;
94
+ if (modelsRaw === undefined)
95
+ return { models: [], walker };
96
+ if (!Array.isArray(modelsRaw)) {
97
+ throw new ModelRegistryValidationError(`'models' must be an array, got ${describe(modelsRaw)}`);
98
+ }
99
+ const models = [];
100
+ const seenIds = new Set();
101
+ for (let i = 0; i < modelsRaw.length; i++) {
102
+ const entry = validateEntry(modelsRaw[i], i);
103
+ if (seenIds.has(entry.id)) {
104
+ throw new ModelRegistryValidationError(`duplicate model id "${entry.id}" at index ${i}`);
105
+ }
106
+ seenIds.add(entry.id);
107
+ enforceExclusiveSlotInvariant(entry, i);
108
+ models.push(entry);
109
+ }
110
+ return { models, walker };
111
+ }
112
+ /**
113
+ * Parse the optional `walker:` block. Missing block → defaults; partial
114
+ * block → defaults filled in for unspecified keys. Unknown keys throw
115
+ * (catches typos like `livenessTTL` or `maxRetries` early).
116
+ */
117
+ function parseWalkerConfig(raw) {
118
+ if (raw === undefined || raw === null)
119
+ return { ...DEFAULT_WALKER_CONFIG };
120
+ if (typeof raw !== 'object' || Array.isArray(raw)) {
121
+ throw new ModelRegistryValidationError(`'walker' must be an object, got ${describe(raw)}`);
122
+ }
123
+ const w = raw;
124
+ const allowed = new Set(['liveness_ttl_ms', 'max_attempts']);
125
+ for (const k of Object.keys(w)) {
126
+ if (!allowed.has(k)) {
127
+ throw new ModelRegistryValidationError(`walker.${k}: unknown key. Supported: [${[...allowed].join(', ')}]`);
128
+ }
129
+ }
130
+ const out = { ...DEFAULT_WALKER_CONFIG };
131
+ if (w.liveness_ttl_ms !== undefined) {
132
+ out.liveness_ttl_ms = requireNumber(w.liveness_ttl_ms, 'walker.liveness_ttl_ms', { min: 0 });
133
+ }
134
+ if (w.max_attempts !== undefined) {
135
+ const n = requireNumber(w.max_attempts, 'walker.max_attempts', { min: 1 });
136
+ if (!Number.isInteger(n)) {
137
+ throw new ModelRegistryValidationError(`walker.max_attempts: expected integer, got ${n}`);
138
+ }
139
+ out.max_attempts = n;
140
+ }
141
+ return out;
142
+ }
143
+ /**
144
+ * Big GPU-resident models MUST set `exclusive_slot: true` so the
145
+ * `LocalExecutor` FIFO can serialize them. Co-resident utility models
146
+ * (embed, rerank consumed by knowledge-core) are exempt — they share VRAM
147
+ * with the held big-slot model by design.
148
+ */
149
+ const EXCLUSIVE_SLOT_VRAM_THRESHOLD_GB = 5;
150
+ function enforceExclusiveSlotInvariant(entry, index) {
151
+ if (entry.provider !== 'ollama')
152
+ return; // cloud providers don't use the slot
153
+ if (entry.consumed_by === 'knowledge-core')
154
+ return; // co-residents are exempt
155
+ if (entry.vram_gb < EXCLUSIVE_SLOT_VRAM_THRESHOLD_GB)
156
+ return;
157
+ if (entry.exclusive_slot)
158
+ return;
159
+ throw new ModelRegistryValidationError(`models[${index}] (${entry.id}): vram_gb=${entry.vram_gb} ≥ ${EXCLUSIVE_SLOT_VRAM_THRESHOLD_GB} requires exclusive_slot:true ` +
160
+ `to prevent VRAM thrashing. Set exclusive_slot:true, or mark consumed_by:knowledge-core if it is a co-resident utility model.`);
161
+ }
162
+ function validateEntry(rawEntry, index) {
163
+ const ctx = `models[${index}]`;
164
+ if (!rawEntry || typeof rawEntry !== 'object' || Array.isArray(rawEntry)) {
165
+ throw new ModelRegistryValidationError(`${ctx}: expected object, got ${describe(rawEntry)}`);
166
+ }
167
+ const e = rawEntry;
168
+ const id = requireString(e.id, `${ctx}.id`);
169
+ const provider = requireEnum(e.provider, PROVIDERS, `${ctx}.provider`);
170
+ const tier = requireEnum(e.tier, TIERS, `${ctx}.tier`);
171
+ if (!Array.isArray(e.capabilities) || e.capabilities.length === 0) {
172
+ throw new ModelRegistryValidationError(`${ctx}.capabilities: must be a non-empty array`);
173
+ }
174
+ const capabilities = [];
175
+ for (let j = 0; j < e.capabilities.length; j++) {
176
+ capabilities.push(requireEnum(e.capabilities[j], CAPABILITIES, `${ctx}.capabilities[${j}]`));
177
+ }
178
+ const complexity_max = requireEnum(e.complexity_max, COMPLEXITIES, `${ctx}.complexity_max`);
179
+ const vram_gb = requireNumber(e.vram_gb, `${ctx}.vram_gb`, { min: 0 });
180
+ const exclusive_slot = requireBoolean(e.exclusive_slot, `${ctx}.exclusive_slot`);
181
+ const out = {
182
+ id,
183
+ provider,
184
+ tier,
185
+ capabilities,
186
+ complexity_max,
187
+ vram_gb,
188
+ exclusive_slot,
189
+ };
190
+ if (e.context_tokens !== undefined) {
191
+ out.context_tokens = requireNumber(e.context_tokens, `${ctx}.context_tokens`, { min: 1, integer: true });
192
+ }
193
+ if (e.context_window !== undefined) {
194
+ out.context_window = requireNumber(e.context_window, `${ctx}.context_window`, { min: 256, integer: true });
195
+ }
196
+ if (e.consumed_by !== undefined) {
197
+ out.consumed_by = requireEnum(e.consumed_by, CONSUMERS, `${ctx}.consumed_by`);
198
+ }
199
+ if (e.endpoint !== undefined) {
200
+ out.endpoint = requireString(e.endpoint, `${ctx}.endpoint`);
201
+ }
202
+ return out;
203
+ }
204
+ // — Validation primitives —
205
+ function requireString(v, ctx) {
206
+ if (typeof v !== 'string' || v.length === 0) {
207
+ throw new ModelRegistryValidationError(`${ctx}: expected non-empty string, got ${describe(v)}`);
208
+ }
209
+ return v;
210
+ }
211
+ function requireEnum(v, allowed, ctx) {
212
+ if (typeof v !== 'string' || !allowed.includes(v)) {
213
+ throw new ModelRegistryValidationError(`${ctx}: expected one of [${allowed.join(', ')}], got ${describe(v)}`);
214
+ }
215
+ return v;
216
+ }
217
+ function requireNumber(v, ctx, opts = {}) {
218
+ if (typeof v !== 'number' || !Number.isFinite(v)) {
219
+ throw new ModelRegistryValidationError(`${ctx}: expected number, got ${describe(v)}`);
220
+ }
221
+ if (opts.integer && !Number.isInteger(v)) {
222
+ throw new ModelRegistryValidationError(`${ctx}: expected integer, got ${v}`);
223
+ }
224
+ if (opts.min !== undefined && v < opts.min) {
225
+ throw new ModelRegistryValidationError(`${ctx}: must be >= ${opts.min}, got ${v}`);
226
+ }
227
+ return v;
228
+ }
229
+ function requireBoolean(v, ctx) {
230
+ if (typeof v !== 'boolean') {
231
+ throw new ModelRegistryValidationError(`${ctx}: expected boolean, got ${describe(v)}`);
232
+ }
233
+ return v;
234
+ }
235
+ function describe(v) {
236
+ if (v === null)
237
+ return 'null';
238
+ if (Array.isArray(v))
239
+ return 'array';
240
+ return typeof v;
241
+ }
242
+ //# sourceMappingURL=model-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-registry.js","sourceRoot":"","sources":["../../src/router/model-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
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
+ import type { RateLimitProviderConfig } from './types.js';
23
+ export declare const DEFAULT_RATE_LIMITS: Record<string, RateLimitProviderConfig>;
24
+ export interface RateLimiterDeps {
25
+ /** Per-provider override map. Falls back to DEFAULT_RATE_LIMITS. */
26
+ config?: Record<string, RateLimitProviderConfig>;
27
+ /** Time source — injectable for deterministic tests. */
28
+ now?: () => number;
29
+ /** Sleep — injectable for deterministic tests. */
30
+ sleep?: (ms: number) => Promise<void>;
31
+ /** Behavior when bucket dry. Default 'wait'. */
32
+ onRateLimit?: 'wait' | 'fail' | 'fallback';
33
+ }
34
+ export declare class RateLimitedError extends Error {
35
+ readonly provider: string;
36
+ readonly waitMs: number;
37
+ constructor(provider: string, waitMs: number);
38
+ }
39
+ export declare class TokenBucketRateLimiter {
40
+ private readonly config;
41
+ private readonly buckets;
42
+ private readonly now;
43
+ private readonly sleep;
44
+ private readonly onRateLimit;
45
+ constructor(deps?: RateLimiterDeps);
46
+ /**
47
+ * Reserve 1 RPM token + N TPM tokens for the provider. If the bucket
48
+ * is dry the behavior depends on the configured `onRateLimit`:
49
+ * - 'wait' (default): awaits until available
50
+ * - 'fail': throws RateLimitedError
51
+ * - 'fallback': returns false; caller falls back
52
+ */
53
+ acquire(provider: string, estimatedTokens: number): Promise<boolean>;
54
+ /** Best-effort introspection — returns current token counts. */
55
+ snapshot(provider: string): {
56
+ rpm?: number;
57
+ tpm?: number;
58
+ };
59
+ private bucketFor;
60
+ private refillAll;
61
+ private waitTime;
62
+ }
63
+ //# sourceMappingURL=rate-limiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../src/router/rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE1D,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAavE,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IACjD,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,kDAAkD;IAClD,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;CAC5C;AAUD,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAM7C;AAED,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IACjE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;IACtD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;gBAE/C,IAAI,GAAE,eAAoB;IAOtC;;;;;;OAMG;IACG,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkC1E,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE;IAQ1D,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,QAAQ;CAKjB"}