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/core/src/models | |
| 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/core/src/models')
| -rw-r--r-- | packages/core/src/models/index.ts | 1 | ||||
| -rw-r--r-- | packages/core/src/models/registry.ts | 64 | ||||
| -rw-r--r-- | packages/core/src/models/resolver.ts | 88 |
3 files changed, 10 insertions, 143 deletions
diff --git a/packages/core/src/models/index.ts b/packages/core/src/models/index.ts index e5efcc8..cf59749 100644 --- a/packages/core/src/models/index.ts +++ b/packages/core/src/models/index.ts @@ -1,2 +1 @@ export { ModelRegistry } from "./registry.js"; -export { ModelResolver } from "./resolver.js"; diff --git a/packages/core/src/models/registry.ts b/packages/core/src/models/registry.ts index f78fe0e..9ea0b32 100644 --- a/packages/core/src/models/registry.ts +++ b/packages/core/src/models/registry.ts @@ -1,25 +1,20 @@ -import type { KeyDefinition, KeyState, ModelDefinition } from "../types/index.js"; +import type { KeyDefinition, KeyState } from "../types/index.js"; export class ModelRegistry { - private models: ModelDefinition[]; private keyStates: Map<string, KeyState>; - private fallbackOrder: string[]; + private keyOrder: string[]; - constructor(models: ModelDefinition[], keys: KeyDefinition[], fallbackOrder: string[]) { - this.models = []; + constructor(keys: KeyDefinition[]) { this.keyStates = new Map(); - this.fallbackOrder = []; - this._initConfig(models, keys, fallbackOrder, new Map()); + this.keyOrder = []; + this._initConfig(keys, new Map()); } private _initConfig( - models: ModelDefinition[], keys: KeyDefinition[], - fallbackOrder: string[], existingStates: Map<string, KeyState>, ): void { - this.models = [...models]; - this.fallbackOrder = this._buildFallbackOrder(keys, fallbackOrder); + this.keyOrder = keys.map((k) => k.id); const newStates = new Map<string, KeyState>(); for (const key of keys) { @@ -34,51 +29,12 @@ export class ModelRegistry { this.keyStates = newStates; } - private _buildFallbackOrder(keys: KeyDefinition[], fallbackOrder: string[]): string[] { - const ordered: string[] = []; - const keyIds = new Set(keys.map((k) => k.id)); - - // Add keys from fallbackOrder first (if they exist) - for (const id of fallbackOrder) { - if (keyIds.has(id) && !ordered.includes(id)) { - ordered.push(id); - } - } - - // Append remaining keys not in fallbackOrder - for (const key of keys) { - if (!ordered.includes(key.id)) { - ordered.push(key.id); - } - } - - return ordered; - } - - getModels(): ModelDefinition[] { - return [...this.models]; - } - getKeys(): KeyState[] { - return this.fallbackOrder + return this.keyOrder .map((id) => this.keyStates.get(id)) .filter((state): state is KeyState => state !== undefined); } - getModelsByTag(tag: string): ModelDefinition[] { - return this.models.filter((m) => m.tags.includes(tag)); - } - - getAllTags(): string[] { - const tags = new Set<string>(); - for (const model of this.models) { - for (const tag of model.tags) { - tags.add(tag); - } - } - return [...tags]; - } - markKeyExhausted(keyId: string, error?: string): void { const state = this.keyStates.get(keyId); if (!state) return; @@ -118,13 +74,13 @@ export class ModelRegistry { return true; } - updateConfig(models: ModelDefinition[], keys: KeyDefinition[], fallbackOrder: string[]): void { - this._initConfig(models, keys, fallbackOrder, this.keyStates); + updateConfig(keys: KeyDefinition[]): void { + this._initConfig(keys, this.keyStates); } // Internal: get ordered key states for a specific provider getOrderedKeysForProvider(provider: string): KeyState[] { - return this.fallbackOrder + return this.keyOrder .map((id) => this.keyStates.get(id)) .filter( (state): state is KeyState => diff --git a/packages/core/src/models/resolver.ts b/packages/core/src/models/resolver.ts deleted file mode 100644 index 3ada713..0000000 --- a/packages/core/src/models/resolver.ts +++ /dev/null @@ -1,88 +0,0 @@ -import type { ResolvedModel } from "../types/index.js"; -import type { ModelRegistry } from "./registry.js"; - -export class ModelResolver { - private registry: ModelRegistry; - - constructor(registry: ModelRegistry) { - this.registry = registry; - } - - resolve(tag: string): ResolvedModel | null { - const models = this.registry.getModelsByTag(tag); - const keys = this.registry.getKeys(); - - for (const keyState of keys) { - if (keyState.status !== "active") continue; - const model = models.find((m) => m.provider === keyState.definition.provider); - if (model) { - return { model, key: keyState.definition }; - } - } - - return null; - } - - async waitForKey( - tag: string, - options?: { - pollIntervalMs?: number; - signal?: AbortSignal; - onWaiting?: () => void; - onResume?: () => void; - }, - ): Promise<ResolvedModel | null> { - const pollIntervalMs = options?.pollIntervalMs ?? 60000; - const signal = options?.signal; - - // Try immediately first - const immediate = this.resolve(tag); - if (immediate) return immediate; - - // Check if aborted before entering wait state - if (signal?.aborted) return null; - - options?.onWaiting?.(); - - return new Promise<ResolvedModel | null>((resolve) => { - let timer: ReturnType<typeof setTimeout> | null = null; - - const cleanup = () => { - if (timer !== null) { - clearTimeout(timer); - timer = null; - } - }; - - const onAbort = () => { - cleanup(); - resolve(null); - }; - - if (signal) { - signal.addEventListener("abort", onAbort, { once: true }); - } - - const poll = () => { - if (signal?.aborted) { - resolve(null); - return; - } - - const result = this.resolve(tag); - if (result) { - if (signal) { - signal.removeEventListener("abort", onAbort); - } - options?.onResume?.(); - resolve(result); - return; - } - - timer = setTimeout(poll, pollIntervalMs); - }; - - timer = setTimeout(poll, pollIntervalMs); - }); - } -} |
