diff options
| author | Adam Malczewski <[email protected]> | 2026-05-21 19:06:15 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-05-21 19:06:15 +0900 |
| commit | 55633c90c0d96e62153a4b6655f3f833a3b46ad4 (patch) | |
| tree | a75f97b48071eb1ba9e8366d8053a376dde69af5 /packages/api/src | |
| parent | d6b208342edf97bafa5b1dcc986b782f9879d141 (diff) | |
| download | dispatch-55633c90c0d96e62153a4b6655f3f833a3b46ad4.tar.gz dispatch-55633c90c0d96e62153a4b6655f3f833a3b46ad4.zip | |
refactor: gut model/tag/fallback/agent-template system, fix Docker setup
- Remove ModelResolver, model definitions, model tags, fallback order, agent templates
- Remove all [[models]], [agents], and fallback from dispatch.toml and config schema
- ModelRegistry is now a pure key-state manager
- dispatch.toml reduced to keys + permissions only
- Docker: fix entrypoint for existing UID, skip bun install in frontend container
- Docker: scoped build cache prune in bin/clean
Diffstat (limited to 'packages/api/src')
| -rw-r--r-- | packages/api/src/agent-manager.ts | 59 | ||||
| -rw-r--r-- | packages/api/src/routes/models.ts | 44 |
2 files changed, 7 insertions, 96 deletions
diff --git a/packages/api/src/agent-manager.ts b/packages/api/src/agent-manager.ts index 92396b6..6e78ad7 100644 --- a/packages/api/src/agent-manager.ts +++ b/packages/api/src/agent-manager.ts @@ -16,7 +16,6 @@ import { loadSkills, createSkillsWatcher, ModelRegistry, - ModelResolver, TaskList, createTaskListTool, type ClaudeAccount, @@ -53,7 +52,6 @@ export class AgentManager { private config: DispatchConfig; private skillsData: { skills: SkillDefinition[]; mappings: AgentSkillMapping[] }; private modelRegistry: ModelRegistry | null = null; - private modelResolver: ModelResolver | null = null; private taskList: TaskList; private configWatcher: { close(): void } | null = null; @@ -89,7 +87,6 @@ export class AgentManager { setSkillsGetter(() => this.skillsData); setModelsGetter( () => this.modelRegistry, - () => this.modelResolver, ); setAccountsGetter(() => this.claudeAccounts); @@ -135,17 +132,14 @@ export class AgentManager { } private _initModelRegistry(config: DispatchConfig): void { - if (config.models && config.keys) { + if (config.keys) { if (this.modelRegistry) { - this.modelRegistry.updateConfig(config.models, config.keys, config.fallback ?? []); + this.modelRegistry.updateConfig(config.keys); } else { - this.modelRegistry = new ModelRegistry(config.models, config.keys, config.fallback ?? []); - this.modelResolver = new ModelResolver(this.modelRegistry); + this.modelRegistry = new ModelRegistry(config.keys); } } else { - // Models/keys removed from config — clear the registry this.modelRegistry = null; - this.modelResolver = null; } } @@ -263,7 +257,7 @@ export class AgentManager { } } } else { - console.warn(`dispatch: key "${effectiveKeyId}" not found in model registry, falling back to tag-based resolution`); + console.warn(`dispatch: key "${effectiveKeyId}" not found in model registry`); } } @@ -273,51 +267,6 @@ export class AgentManager { this.activeModelId = null; } - if (!useOverride && this.modelRegistry && this.modelResolver) { - // Try to get model_tag from default agent template, fall back to "heavy" - const defaultAgent = this.config.agents?.["default"]; - const tag = defaultAgent?.model_tag ?? "heavy"; - const resolved = this.modelResolver.resolve(tag); - if (resolved) { - model = resolved.model.id; - baseURL = resolved.key.base_url; - // Check if resolved key is anthropic - if (resolved.key.provider === "anthropic") { - const credFile = resolved.key.credentials_file; - const account = this.claudeAccounts.find((a) => a.id === resolved.key.id) - ?? (credFile ? this.claudeAccounts.find((a) => a.source === credFile) : this.claudeAccounts[0]); - if (account) { - let creds = refreshAccountCredentials(account); - if (!creds || creds.expiresAt <= Date.now() + 60_000) { - creds = await refreshAccountCredentialsAsync(account); - if (creds) account.credentials = creds; - } - if (creds) { - claudeCredentials = { accessToken: creds.accessToken }; - apiKey = creds.accessToken; - provider = "anthropic"; - } else { - console.warn(`dispatch: no valid Claude credentials for key "${resolved.key.id}"`); - } - } else { - console.warn(`dispatch: no Claude credentials found for key "${resolved.key.id}"`); - } - } else { - const envKey = resolveApiKey(resolved.key.id); - if (envKey) { - apiKey = envKey; - } else { - console.warn(`dispatch: env var not set for key "${resolved.key.id}", falling back to defaults`); - model = "deepseek-v4-flash"; - baseURL = "https://opencode.ai/zen/go/v1"; - apiKey = ""; - } - } - } else { - console.warn(`dispatch: could not resolve model for tag "${tag}", falling back to env vars`); - } - } - this.agent = new Agent({ model, apiKey, diff --git a/packages/api/src/routes/models.ts b/packages/api/src/routes/models.ts index ca58e38..86411f1 100644 --- a/packages/api/src/routes/models.ts +++ b/packages/api/src/routes/models.ts @@ -1,4 +1,4 @@ -import type { ModelRegistry, ModelResolver } from "@dispatch/core"; +import type { ModelRegistry } from "@dispatch/core"; import { ANTHROPIC_MODELS_FALLBACK, type ClaudeAccount, @@ -20,15 +20,12 @@ import { import { Hono } from "hono"; let getRegistry: () => ModelRegistry | null = () => null; -let getResolver: () => ModelResolver | null = () => null; let getAccounts: () => ClaudeAccount[] = () => []; export function setModelsGetter( registryGetter: () => ModelRegistry | null, - resolverGetter: () => ModelResolver | null, ): void { getRegistry = registryGetter; - getResolver = resolverGetter; } export function setAccountsGetter(getter: () => ClaudeAccount[]): void { @@ -45,11 +42,9 @@ export const modelsRoutes = new Hono(); modelsRoutes.get("/", (c) => { const registry = getRegistry(); if (!registry) { - return c.json({ models: [], tags: [], keys: [] }); + return c.json({ keys: [] }); } - const models = registry.getModels(); - const tags = registry.getAllTags(); const keyStates = registry.getKeys(); const keys = keyStates.map((ks) => ({ @@ -60,40 +55,7 @@ modelsRoutes.get("/", (c) => { exhaustedAt: ks.exhaustedAt ?? null, })); - return c.json({ models, tags, keys }); -}); - -modelsRoutes.get("/resolve", (c) => { - const registry = getRegistry(); - const resolver = getResolver(); - if (!registry || !resolver) { - return c.json({ resolved: null, reason: "no models configured" }); - } - - const tag = c.req.query("tag"); - if (!tag) { - return c.json({ error: "tag query parameter is required" }, 400); - } - - const matchingModels = registry.getModelsByTag(tag); - if (matchingModels.length === 0) { - return c.json({ resolved: null, reason: "no models match tag" }); - } - - const resolved = resolver.resolve(tag); - if (!resolved) { - return c.json({ resolved: null, reason: "all keys exhausted for matching providers" }); - } - - return c.json({ - resolved: { - model: resolved.model, - key: { - id: resolved.key.id, - provider: resolved.key.provider, - }, - }, - }); + return c.json({ keys }); }); // Fetch available models for a specific provider key. |
