@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.
- package/README.md +142 -0
- package/dist/__tests__/adapter-enrichment.test.d.ts +12 -0
- package/dist/__tests__/adapter-enrichment.test.d.ts.map +1 -0
- package/dist/__tests__/adapter-enrichment.test.js +199 -0
- package/dist/__tests__/adapter-enrichment.test.js.map +1 -0
- package/dist/__tests__/adk-anthropic-llm.test.d.ts +18 -0
- package/dist/__tests__/adk-anthropic-llm.test.d.ts.map +1 -0
- package/dist/__tests__/adk-anthropic-llm.test.js +124 -0
- package/dist/__tests__/adk-anthropic-llm.test.js.map +1 -0
- package/dist/__tests__/cost-breakdown.test.d.ts +11 -0
- package/dist/__tests__/cost-breakdown.test.d.ts.map +1 -0
- package/dist/__tests__/cost-breakdown.test.js +163 -0
- package/dist/__tests__/cost-breakdown.test.js.map +1 -0
- package/dist/__tests__/mcp.test.d.ts +13 -0
- package/dist/__tests__/mcp.test.d.ts.map +1 -0
- package/dist/__tests__/mcp.test.js +413 -0
- package/dist/__tests__/mcp.test.js.map +1 -0
- package/dist/__tests__/ollama-adapter-agentic.test.d.ts +15 -0
- package/dist/__tests__/ollama-adapter-agentic.test.d.ts.map +1 -0
- package/dist/__tests__/ollama-adapter-agentic.test.js +268 -0
- package/dist/__tests__/ollama-adapter-agentic.test.js.map +1 -0
- package/dist/__tests__/ollama-adapter-executor.test.d.ts +10 -0
- package/dist/__tests__/ollama-adapter-executor.test.d.ts.map +1 -0
- package/dist/__tests__/ollama-adapter-executor.test.js +95 -0
- package/dist/__tests__/ollama-adapter-executor.test.js.map +1 -0
- package/dist/__tests__/openai-adapter-output.test.d.ts +17 -0
- package/dist/__tests__/openai-adapter-output.test.d.ts.map +1 -0
- package/dist/__tests__/openai-adapter-output.test.js +127 -0
- package/dist/__tests__/openai-adapter-output.test.js.map +1 -0
- package/dist/__tests__/opencode-adapter.test.d.ts +7 -0
- package/dist/__tests__/opencode-adapter.test.d.ts.map +1 -0
- package/dist/__tests__/opencode-adapter.test.js +141 -0
- package/dist/__tests__/opencode-adapter.test.js.map +1 -0
- package/dist/__tests__/openrouter-adapter-agentic.test.d.ts +11 -0
- package/dist/__tests__/openrouter-adapter-agentic.test.d.ts.map +1 -0
- package/dist/__tests__/openrouter-adapter-agentic.test.js +297 -0
- package/dist/__tests__/openrouter-adapter-agentic.test.js.map +1 -0
- package/dist/__tests__/router-circuit-breaker.test.d.ts +6 -0
- package/dist/__tests__/router-circuit-breaker.test.d.ts.map +1 -0
- package/dist/__tests__/router-circuit-breaker.test.js +253 -0
- package/dist/__tests__/router-circuit-breaker.test.js.map +1 -0
- package/dist/__tests__/router-config-loader.test.d.ts +8 -0
- package/dist/__tests__/router-config-loader.test.d.ts.map +1 -0
- package/dist/__tests__/router-config-loader.test.js +172 -0
- package/dist/__tests__/router-config-loader.test.js.map +1 -0
- package/dist/__tests__/router-discovery.test.d.ts +5 -0
- package/dist/__tests__/router-discovery.test.d.ts.map +1 -0
- package/dist/__tests__/router-discovery.test.js +129 -0
- package/dist/__tests__/router-discovery.test.js.map +1 -0
- package/dist/__tests__/router-fallback.test.d.ts +9 -0
- package/dist/__tests__/router-fallback.test.d.ts.map +1 -0
- package/dist/__tests__/router-fallback.test.js +283 -0
- package/dist/__tests__/router-fallback.test.js.map +1 -0
- package/dist/__tests__/router-local-executor.test.d.ts +6 -0
- package/dist/__tests__/router-local-executor.test.d.ts.map +1 -0
- package/dist/__tests__/router-local-executor.test.js +193 -0
- package/dist/__tests__/router-local-executor.test.js.map +1 -0
- package/dist/__tests__/router-model-registry.test.d.ts +8 -0
- package/dist/__tests__/router-model-registry.test.d.ts.map +1 -0
- package/dist/__tests__/router-model-registry.test.js +389 -0
- package/dist/__tests__/router-model-registry.test.js.map +1 -0
- package/dist/__tests__/router-rate-limiter.test.d.ts +8 -0
- package/dist/__tests__/router-rate-limiter.test.d.ts.map +1 -0
- package/dist/__tests__/router-rate-limiter.test.js +128 -0
- package/dist/__tests__/router-rate-limiter.test.js.map +1 -0
- package/dist/__tests__/router-resolver.test.d.ts +7 -0
- package/dist/__tests__/router-resolver.test.d.ts.map +1 -0
- package/dist/__tests__/router-resolver.test.js +110 -0
- package/dist/__tests__/router-resolver.test.js.map +1 -0
- package/dist/__tests__/router-retry.test.d.ts +7 -0
- package/dist/__tests__/router-retry.test.d.ts.map +1 -0
- package/dist/__tests__/router-retry.test.js +302 -0
- package/dist/__tests__/router-retry.test.js.map +1 -0
- package/dist/__tests__/router-scaffold.test.d.ts +11 -0
- package/dist/__tests__/router-scaffold.test.d.ts.map +1 -0
- package/dist/__tests__/router-scaffold.test.js +103 -0
- package/dist/__tests__/router-scaffold.test.js.map +1 -0
- package/dist/__tests__/router-spend-ledger.test.d.ts +8 -0
- package/dist/__tests__/router-spend-ledger.test.d.ts.map +1 -0
- package/dist/__tests__/router-spend-ledger.test.js +227 -0
- package/dist/__tests__/router-spend-ledger.test.js.map +1 -0
- package/dist/__tests__/router-telemetry.test.d.ts +11 -0
- package/dist/__tests__/router-telemetry.test.d.ts.map +1 -0
- package/dist/__tests__/router-telemetry.test.js +173 -0
- package/dist/__tests__/router-telemetry.test.js.map +1 -0
- package/dist/__tests__/single-shot.test.d.ts +12 -0
- package/dist/__tests__/single-shot.test.d.ts.map +1 -0
- package/dist/__tests__/single-shot.test.js +204 -0
- package/dist/__tests__/single-shot.test.js.map +1 -0
- package/dist/__tests__/skills-prompt.test.d.ts +11 -0
- package/dist/__tests__/skills-prompt.test.d.ts.map +1 -0
- package/dist/__tests__/skills-prompt.test.js +208 -0
- package/dist/__tests__/skills-prompt.test.js.map +1 -0
- package/dist/__tests__/skills.test.d.ts +11 -0
- package/dist/__tests__/skills.test.d.ts.map +1 -0
- package/dist/__tests__/skills.test.js +161 -0
- package/dist/__tests__/skills.test.js.map +1 -0
- package/dist/__tests__/telemetry-integration.test.d.ts +12 -0
- package/dist/__tests__/telemetry-integration.test.d.ts.map +1 -0
- package/dist/__tests__/telemetry-integration.test.js +153 -0
- package/dist/__tests__/telemetry-integration.test.js.map +1 -0
- package/dist/__tests__/telemetry.test.d.ts +13 -0
- package/dist/__tests__/telemetry.test.d.ts.map +1 -0
- package/dist/__tests__/telemetry.test.js +161 -0
- package/dist/__tests__/telemetry.test.js.map +1 -0
- package/dist/__tests__/upstream-error.test.d.ts +8 -0
- package/dist/__tests__/upstream-error.test.d.ts.map +1 -0
- package/dist/__tests__/upstream-error.test.js +186 -0
- package/dist/__tests__/upstream-error.test.js.map +1 -0
- package/dist/adk-adapter.d.ts +45 -0
- package/dist/adk-adapter.d.ts.map +1 -0
- package/dist/adk-adapter.js +403 -0
- package/dist/adk-adapter.js.map +1 -0
- package/dist/adk-anthropic-llm.d.ts +59 -0
- package/dist/adk-anthropic-llm.d.ts.map +1 -0
- package/dist/adk-anthropic-llm.js +397 -0
- package/dist/adk-anthropic-llm.js.map +1 -0
- package/dist/agent/index.d.ts +14 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +14 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/session/__tests__/bridge-tool-executor.test.d.ts +10 -0
- package/dist/agent/session/__tests__/bridge-tool-executor.test.d.ts.map +1 -0
- package/dist/agent/session/__tests__/bridge-tool-executor.test.js +152 -0
- package/dist/agent/session/__tests__/bridge-tool-executor.test.js.map +1 -0
- package/dist/agent/session/__tests__/collect-trajectory.test.d.ts +18 -0
- package/dist/agent/session/__tests__/collect-trajectory.test.d.ts.map +1 -0
- package/dist/agent/session/__tests__/collect-trajectory.test.js +208 -0
- package/dist/agent/session/__tests__/collect-trajectory.test.js.map +1 -0
- package/dist/agent/session/__tests__/run-with-agent.test.d.ts +8 -0
- package/dist/agent/session/__tests__/run-with-agent.test.d.ts.map +1 -0
- package/dist/agent/session/__tests__/run-with-agent.test.js +98 -0
- package/dist/agent/session/__tests__/run-with-agent.test.js.map +1 -0
- package/dist/agent/session/__tests__/runtime.test.d.ts +7 -0
- package/dist/agent/session/__tests__/runtime.test.d.ts.map +1 -0
- package/dist/agent/session/__tests__/runtime.test.js +361 -0
- package/dist/agent/session/__tests__/runtime.test.js.map +1 -0
- package/dist/agent/session/__tests__/skills-mcp-spawn.test.d.ts +15 -0
- package/dist/agent/session/__tests__/skills-mcp-spawn.test.d.ts.map +1 -0
- package/dist/agent/session/__tests__/skills-mcp-spawn.test.js +160 -0
- package/dist/agent/session/__tests__/skills-mcp-spawn.test.js.map +1 -0
- package/dist/agent/session/__tests__/spawn-telemetry.test.d.ts +13 -0
- package/dist/agent/session/__tests__/spawn-telemetry.test.d.ts.map +1 -0
- package/dist/agent/session/__tests__/spawn-telemetry.test.js +135 -0
- package/dist/agent/session/__tests__/spawn-telemetry.test.js.map +1 -0
- package/dist/agent/session/__tests__/types.test.d.ts +9 -0
- package/dist/agent/session/__tests__/types.test.d.ts.map +1 -0
- package/dist/agent/session/__tests__/types.test.js +220 -0
- package/dist/agent/session/__tests__/types.test.js.map +1 -0
- package/dist/agent/session/adapter.d.ts +108 -0
- package/dist/agent/session/adapter.d.ts.map +1 -0
- package/dist/agent/session/adapter.js +39 -0
- package/dist/agent/session/adapter.js.map +1 -0
- package/dist/agent/session/collect-trajectory.d.ts +36 -0
- package/dist/agent/session/collect-trajectory.d.ts.map +1 -0
- package/dist/agent/session/collect-trajectory.js +193 -0
- package/dist/agent/session/collect-trajectory.js.map +1 -0
- package/dist/agent/session/default-adapter-factory.d.ts +48 -0
- package/dist/agent/session/default-adapter-factory.d.ts.map +1 -0
- package/dist/agent/session/default-adapter-factory.js +227 -0
- package/dist/agent/session/default-adapter-factory.js.map +1 -0
- package/dist/agent/session/headless-types.d.ts +85 -0
- package/dist/agent/session/headless-types.d.ts.map +1 -0
- package/dist/agent/session/headless-types.js +16 -0
- package/dist/agent/session/headless-types.js.map +1 -0
- package/dist/agent/session/index.d.ts +18 -0
- package/dist/agent/session/index.d.ts.map +1 -0
- package/dist/agent/session/index.js +20 -0
- package/dist/agent/session/index.js.map +1 -0
- package/dist/agent/session/language-model-bridge.d.ts +84 -0
- package/dist/agent/session/language-model-bridge.d.ts.map +1 -0
- package/dist/agent/session/language-model-bridge.js +454 -0
- package/dist/agent/session/language-model-bridge.js.map +1 -0
- package/dist/agent/session/legacy-adapter-types.d.ts +63 -0
- package/dist/agent/session/legacy-adapter-types.d.ts.map +1 -0
- package/dist/agent/session/legacy-adapter-types.js +11 -0
- package/dist/agent/session/legacy-adapter-types.js.map +1 -0
- package/dist/agent/session/run-with-agent.d.ts +36 -0
- package/dist/agent/session/run-with-agent.d.ts.map +1 -0
- package/dist/agent/session/run-with-agent.js +81 -0
- package/dist/agent/session/run-with-agent.js.map +1 -0
- package/dist/agent/session/session-registry.d.ts +71 -0
- package/dist/agent/session/session-registry.d.ts.map +1 -0
- package/dist/agent/session/session-registry.js +209 -0
- package/dist/agent/session/session-registry.js.map +1 -0
- package/dist/agent/session/session.d.ts +76 -0
- package/dist/agent/session/session.d.ts.map +1 -0
- package/dist/agent/session/session.js +327 -0
- package/dist/agent/session/session.js.map +1 -0
- package/dist/agent/session/types.d.ts +230 -0
- package/dist/agent/session/types.d.ts.map +1 -0
- package/dist/agent/session/types.js +44 -0
- package/dist/agent/session/types.js.map +1 -0
- package/dist/checkpoint/__tests__/blob-store.test.d.ts +5 -0
- package/dist/checkpoint/__tests__/blob-store.test.d.ts.map +1 -0
- package/dist/checkpoint/__tests__/blob-store.test.js +82 -0
- package/dist/checkpoint/__tests__/blob-store.test.js.map +1 -0
- package/dist/checkpoint/__tests__/key.test.d.ts +7 -0
- package/dist/checkpoint/__tests__/key.test.d.ts.map +1 -0
- package/dist/checkpoint/__tests__/key.test.js +130 -0
- package/dist/checkpoint/__tests__/key.test.js.map +1 -0
- package/dist/checkpoint/__tests__/runner.test.d.ts +12 -0
- package/dist/checkpoint/__tests__/runner.test.d.ts.map +1 -0
- package/dist/checkpoint/__tests__/runner.test.js +201 -0
- package/dist/checkpoint/__tests__/runner.test.js.map +1 -0
- package/dist/checkpoint/__tests__/store.test.d.ts +6 -0
- package/dist/checkpoint/__tests__/store.test.d.ts.map +1 -0
- package/dist/checkpoint/__tests__/store.test.js +150 -0
- package/dist/checkpoint/__tests__/store.test.js.map +1 -0
- package/dist/checkpoint/blob-store.d.ts +41 -0
- package/dist/checkpoint/blob-store.d.ts.map +1 -0
- package/dist/checkpoint/blob-store.js +119 -0
- package/dist/checkpoint/blob-store.js.map +1 -0
- package/dist/checkpoint/index.d.ts +15 -0
- package/dist/checkpoint/index.d.ts.map +1 -0
- package/dist/checkpoint/index.js +14 -0
- package/dist/checkpoint/index.js.map +1 -0
- package/dist/checkpoint/key.d.ts +39 -0
- package/dist/checkpoint/key.d.ts.map +1 -0
- package/dist/checkpoint/key.js +112 -0
- package/dist/checkpoint/key.js.map +1 -0
- package/dist/checkpoint/runner.d.ts +83 -0
- package/dist/checkpoint/runner.d.ts.map +1 -0
- package/dist/checkpoint/runner.js +146 -0
- package/dist/checkpoint/runner.js.map +1 -0
- package/dist/checkpoint/store.d.ts +91 -0
- package/dist/checkpoint/store.d.ts.map +1 -0
- package/dist/checkpoint/store.js +292 -0
- package/dist/checkpoint/store.js.map +1 -0
- package/dist/checkpoint/types.d.ts +74 -0
- package/dist/checkpoint/types.d.ts.map +1 -0
- package/dist/checkpoint/types.js +16 -0
- package/dist/checkpoint/types.js.map +1 -0
- package/dist/claude-adapter.d.ts +23 -0
- package/dist/claude-adapter.d.ts.map +1 -0
- package/dist/claude-adapter.js +233 -0
- package/dist/claude-adapter.js.map +1 -0
- package/dist/cost.d.ts +67 -0
- package/dist/cost.d.ts.map +1 -0
- package/dist/cost.js +148 -0
- package/dist/cost.js.map +1 -0
- package/dist/data/model-prices.json +39681 -0
- package/dist/fallback-adapter.d.ts +51 -0
- package/dist/fallback-adapter.d.ts.map +1 -0
- package/dist/fallback-adapter.js +116 -0
- package/dist/fallback-adapter.js.map +1 -0
- package/dist/gemini-adapter.d.ts +22 -0
- package/dist/gemini-adapter.d.ts.map +1 -0
- package/dist/gemini-adapter.js +185 -0
- package/dist/gemini-adapter.js.map +1 -0
- package/dist/gemini-cli-adapter.d.ts +24 -0
- package/dist/gemini-cli-adapter.d.ts.map +1 -0
- package/dist/gemini-cli-adapter.js +169 -0
- package/dist/gemini-cli-adapter.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/client.d.ts +32 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +92 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/config-loader.d.ts +36 -0
- package/dist/mcp/config-loader.d.ts.map +1 -0
- package/dist/mcp/config-loader.js +129 -0
- package/dist/mcp/config-loader.js.map +1 -0
- package/dist/mcp/index.d.ts +12 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +11 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/tool-merger.d.ts +18 -0
- package/dist/mcp/tool-merger.d.ts.map +1 -0
- package/dist/mcp/tool-merger.js +34 -0
- package/dist/mcp/tool-merger.js.map +1 -0
- package/dist/mcp/types.d.ts +35 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +10 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/ollama-adapter.d.ts +95 -0
- package/dist/ollama-adapter.d.ts.map +1 -0
- package/dist/ollama-adapter.js +404 -0
- package/dist/ollama-adapter.js.map +1 -0
- package/dist/openai-adapter.d.ts +40 -0
- package/dist/openai-adapter.d.ts.map +1 -0
- package/dist/openai-adapter.js +81 -0
- package/dist/openai-adapter.js.map +1 -0
- package/dist/opencode-adapter.d.ts +39 -0
- package/dist/opencode-adapter.d.ts.map +1 -0
- package/dist/opencode-adapter.js +105 -0
- package/dist/opencode-adapter.js.map +1 -0
- package/dist/openrouter-adapter.d.ts +69 -0
- package/dist/openrouter-adapter.d.ts.map +1 -0
- package/dist/openrouter-adapter.js +481 -0
- package/dist/openrouter-adapter.js.map +1 -0
- package/dist/registry.d.ts +55 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +191 -0
- package/dist/registry.js.map +1 -0
- package/dist/router/circuit-breaker.d.ts +57 -0
- package/dist/router/circuit-breaker.d.ts.map +1 -0
- package/dist/router/circuit-breaker.js +110 -0
- package/dist/router/circuit-breaker.js.map +1 -0
- package/dist/router/config-loader.d.ts +43 -0
- package/dist/router/config-loader.d.ts.map +1 -0
- package/dist/router/config-loader.js +155 -0
- package/dist/router/config-loader.js.map +1 -0
- package/dist/router/discovery.d.ts +37 -0
- package/dist/router/discovery.d.ts.map +1 -0
- package/dist/router/discovery.js +54 -0
- package/dist/router/discovery.js.map +1 -0
- package/dist/router/errors.d.ts +39 -0
- package/dist/router/errors.d.ts.map +1 -0
- package/dist/router/errors.js +103 -0
- package/dist/router/errors.js.map +1 -0
- package/dist/router/index.d.ts +31 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +20 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/local-executor.d.ts +62 -0
- package/dist/router/local-executor.d.ts.map +1 -0
- package/dist/router/local-executor.js +161 -0
- package/dist/router/local-executor.js.map +1 -0
- package/dist/router/model-registry.d.ts +90 -0
- package/dist/router/model-registry.d.ts.map +1 -0
- package/dist/router/model-registry.js +242 -0
- package/dist/router/model-registry.js.map +1 -0
- package/dist/router/rate-limiter.d.ts +63 -0
- package/dist/router/rate-limiter.d.ts.map +1 -0
- package/dist/router/rate-limiter.js +136 -0
- package/dist/router/rate-limiter.js.map +1 -0
- package/dist/router/resolver.d.ts +45 -0
- package/dist/router/resolver.d.ts.map +1 -0
- package/dist/router/resolver.js +71 -0
- package/dist/router/resolver.js.map +1 -0
- package/dist/router/retry.d.ts +58 -0
- package/dist/router/retry.d.ts.map +1 -0
- package/dist/router/retry.js +119 -0
- package/dist/router/retry.js.map +1 -0
- package/dist/router/router.d.ts +100 -0
- package/dist/router/router.d.ts.map +1 -0
- package/dist/router/router.js +306 -0
- package/dist/router/router.js.map +1 -0
- package/dist/router/spend-ledger.d.ts +69 -0
- package/dist/router/spend-ledger.d.ts.map +1 -0
- package/dist/router/spend-ledger.js +191 -0
- package/dist/router/spend-ledger.js.map +1 -0
- package/dist/router/telemetry.d.ts +48 -0
- package/dist/router/telemetry.d.ts.map +1 -0
- package/dist/router/telemetry.js +112 -0
- package/dist/router/telemetry.js.map +1 -0
- package/dist/router/types.d.ts +95 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/router/types.js +16 -0
- package/dist/router/types.js.map +1 -0
- package/dist/single-shot.d.ts +60 -0
- package/dist/single-shot.d.ts.map +1 -0
- package/dist/single-shot.js +385 -0
- package/dist/single-shot.js.map +1 -0
- package/dist/skills/activator.d.ts +17 -0
- package/dist/skills/activator.d.ts.map +1 -0
- package/dist/skills/activator.js +24 -0
- package/dist/skills/activator.js.map +1 -0
- package/dist/skills/compose.d.ts +43 -0
- package/dist/skills/compose.d.ts.map +1 -0
- package/dist/skills/compose.js +53 -0
- package/dist/skills/compose.js.map +1 -0
- package/dist/skills/index.d.ts +17 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +16 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/loader.d.ts +9 -0
- package/dist/skills/loader.d.ts.map +1 -0
- package/dist/skills/loader.js +49 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/parser.d.ts +13 -0
- package/dist/skills/parser.d.ts.map +1 -0
- package/dist/skills/parser.js +60 -0
- package/dist/skills/parser.js.map +1 -0
- package/dist/skills/render.d.ts +11 -0
- package/dist/skills/render.d.ts.map +1 -0
- package/dist/skills/render.js +21 -0
- package/dist/skills/render.js.map +1 -0
- package/dist/skills/resolve-dir.d.ts +20 -0
- package/dist/skills/resolve-dir.d.ts.map +1 -0
- package/dist/skills/resolve-dir.js +30 -0
- package/dist/skills/resolve-dir.js.map +1 -0
- package/dist/skills/tool-policy.d.ts +26 -0
- package/dist/skills/tool-policy.d.ts.map +1 -0
- package/dist/skills/tool-policy.js +33 -0
- package/dist/skills/tool-policy.js.map +1 -0
- package/dist/skills/types.d.ts +42 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +8 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/stream-format.d.ts +100 -0
- package/dist/stream-format.d.ts.map +1 -0
- package/dist/stream-format.js +90 -0
- package/dist/stream-format.js.map +1 -0
- package/dist/telemetry/attributes.d.ts +38 -0
- package/dist/telemetry/attributes.d.ts.map +1 -0
- package/dist/telemetry/attributes.js +39 -0
- package/dist/telemetry/attributes.js.map +1 -0
- package/dist/telemetry/config.d.ts +30 -0
- package/dist/telemetry/config.d.ts.map +1 -0
- package/dist/telemetry/config.js +54 -0
- package/dist/telemetry/config.js.map +1 -0
- package/dist/telemetry/exporters.d.ts +10 -0
- package/dist/telemetry/exporters.d.ts.map +1 -0
- package/dist/telemetry/exporters.js +46 -0
- package/dist/telemetry/exporters.js.map +1 -0
- package/dist/telemetry/index.d.ts +15 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +12 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/instrument.d.ts +36 -0
- package/dist/telemetry/instrument.d.ts.map +1 -0
- package/dist/telemetry/instrument.js +215 -0
- package/dist/telemetry/instrument.js.map +1 -0
- package/dist/telemetry/metrics.d.ts +45 -0
- package/dist/telemetry/metrics.d.ts.map +1 -0
- package/dist/telemetry/metrics.js +186 -0
- package/dist/telemetry/metrics.js.map +1 -0
- package/dist/telemetry/tracer.d.ts +33 -0
- package/dist/telemetry/tracer.d.ts.map +1 -0
- package/dist/telemetry/tracer.js +162 -0
- package/dist/telemetry/tracer.js.map +1 -0
- package/dist/tools/__tests__/builtin.test.d.ts +7 -0
- package/dist/tools/__tests__/builtin.test.d.ts.map +1 -0
- package/dist/tools/__tests__/builtin.test.js +242 -0
- package/dist/tools/__tests__/builtin.test.js.map +1 -0
- package/dist/tools/builtin.d.ts +29 -0
- package/dist/tools/builtin.d.ts.map +1 -0
- package/dist/tools/builtin.js +367 -0
- package/dist/tools/builtin.js.map +1 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +3 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/path-guard.d.ts +23 -0
- package/dist/tools/path-guard.d.ts.map +1 -0
- package/dist/tools/path-guard.js +66 -0
- package/dist/tools/path-guard.js.map +1 -0
- package/dist/tools/types.d.ts +45 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +11 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/types.d.ts +249 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +22 -0
- package/dist/types.js.map +1 -0
- package/dist/upstream-error.d.ts +64 -0
- package/dist/upstream-error.d.ts.map +1 -0
- package/dist/upstream-error.js +105 -0
- package/dist/upstream-error.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- 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":"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"}
|
|
@@ -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"}
|