@kb-labs/llm-router 1.0.0 → 1.2.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/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +15 -15
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/resolver.ts","../src/router.ts","../src/manifest.ts"],"names":["TIER_ORDER"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @module @kb-labs/llm-router/resolver\n * Tier resolution logic with adaptive escalation/degradation.\n */\n\nimport type { LLMTier, LLMCapability } from '@kb-labs/core-platform';\nimport { TIER_ORDER } from '@kb-labs/core-platform';\n\n/**\n * Resolution result.\n */\nexport interface ResolveResult {\n /** Actual tier to use */\n tier: LLMTier;\n /** Whether adaptation occurred */\n adapted: boolean;\n /** Warning message (only for degradation) */\n warning?: string;\n}\n\n/**\n * Tier resolver with adaptive escalation/degradation.\n *\n * Resolution rules:\n * - Exact match → use as-is\n * - Request lower than configured → escalate silently (small → medium)\n * - Request higher than configured → degrade with warning (large → medium)\n */\nexport class TierResolver {\n private configuredIndex: number;\n\n constructor(private configuredTier: LLMTier) {\n this.configuredIndex = TIER_ORDER.indexOf(configuredTier);\n }\n\n /**\n * Resolve requested tier to actual tier.\n *\n * @param requestedTier - Tier requested by plugin (or undefined for default)\n * @returns Resolution result with actual tier and adaptation info\n */\n resolve(requestedTier?: LLMTier): ResolveResult {\n // No request → use configured default\n if (!requestedTier) {\n return { tier: this.configuredTier, adapted: false };\n }\n\n const requestedIndex = TIER_ORDER.indexOf(requestedTier);\n\n // Exact match\n if (requestedIndex === this.configuredIndex) {\n return { tier: this.configuredTier, adapted: false };\n }\n\n // Escalation: requested < configured (e.g., small → medium)\n // This is fine - plugin asked for less, we give more\n if (requestedIndex < this.configuredIndex) {\n return {\n tier: this.configuredTier,\n adapted: true,\n // No warning - escalation is acceptable\n };\n }\n\n // Degradation: requested > configured (e.g., large → medium)\n // This needs a warning - plugin wanted more than available\n return {\n tier: this.configuredTier,\n adapted: true,\n warning: `Requested '${requestedTier}' tier but only '${this.configuredTier}' available. Using ${this.configuredTier}.`,\n };\n }\n\n /**\n * Get the configured tier.\n */\n getConfiguredTier(): LLMTier {\n return this.configuredTier;\n }\n}\n\n/**\n * Capability resolver.\n *\n * For simple config: assumes all capabilities available.\n * For advanced config: checks against capability mapping.\n */\nexport class CapabilityResolver {\n constructor(private availableCapabilities: Set<LLMCapability> = new Set()) {}\n\n /**\n * Check if capability is available.\n */\n hasCapability(capability: LLMCapability): boolean {\n // If no capabilities configured, assume all available (simple config)\n if (this.availableCapabilities.size === 0) {\n return true;\n }\n return this.availableCapabilities.has(capability);\n }\n\n /**\n * Check if all requested capabilities are available.\n */\n hasAllCapabilities(capabilities: LLMCapability[]): boolean {\n return capabilities.every((cap) => this.hasCapability(cap));\n }\n\n /**\n * Get available capabilities.\n */\n getCapabilities(): LLMCapability[] {\n // If no capabilities configured, return all (simple config)\n if (this.availableCapabilities.size === 0) {\n return ['reasoning', 'coding', 'vision', 'fast'];\n }\n return Array.from(this.availableCapabilities);\n }\n}\n","/**\n * @module @kb-labs/llm-router/router\n * LLM Router - adaptive routing with tier-based model selection.\n * Supports multiple adapters per tier for maximum flexibility.\n */\n\nimport type {\n ILLM,\n LLMOptions,\n LLMResponse,\n LLMMessage,\n LLMToolCallOptions,\n LLMToolCallResponse,\n LLMTier,\n LLMCapability,\n UseLLMOptions,\n LLMResolution,\n LLMAdapterBinding,\n ILLMRouter,\n ILogger,\n LLMRequestMetadata,\n LLMProtocolCapabilities,\n} from '@kb-labs/core-platform';\nimport { TierResolver, CapabilityResolver } from './resolver.js';\n\n/**\n * Model entry in tier mapping.\n * Can optionally specify a different adapter per model.\n */\nexport interface TierModelEntry {\n /** Model identifier */\n model: string;\n /** Priority (lower = higher priority) */\n priority: number;\n /** Model capabilities */\n capabilities?: LLMCapability[];\n /**\n * Provider identifier (e.g., 'openai', 'anthropic', 'vibeproxy').\n * Used to construct resource name: `llm:${provider}`\n */\n provider?: string;\n /**\n * @deprecated Use `provider` instead. Adapter package to use for this model.\n * Will be removed in future versions.\n */\n adapter?: string;\n}\n\n/**\n * Helper to extract provider from entry (supports both new `provider` and legacy `adapter`).\n */\nfunction getProviderFromEntry(entry: TierModelEntry): string {\n // Prefer explicit provider\n if (entry.provider) {\n return entry.provider;\n }\n // Extract from adapter package name: \"@kb-labs/adapters-openai\" → \"openai\"\n // eslint-disable-next-line deprecation/deprecation\n const adapter = entry.adapter;\n if (adapter) {\n const match = adapter.match(/adapters-(\\w+)/);\n if (match?.[1]) {\n return match[1];\n }\n // Fallback: use last segment\n const segments = adapter.split(/[-/]/);\n const lastSegment = segments[segments.length - 1];\n return lastSegment ?? 'default';\n }\n return 'default';\n}\n\n/**\n * Tier mapping configuration.\n */\nexport interface TierMapping {\n small?: TierModelEntry[];\n medium?: TierModelEntry[];\n large?: TierModelEntry[];\n}\n\n/**\n * Function to load an adapter by package name.\n */\nexport type AdapterLoader = (adapterPackage: string) => Promise<ILLM>;\n\n/**\n * LLM Router configuration.\n */\nexport interface LLMRouterConfig {\n /** Default tier when none specified */\n defaultTier: LLMTier;\n /** Tier to model mapping */\n tierMapping?: TierMapping;\n /** Function to load adapters by package name (required for multi-adapter) */\n adapterLoader?: AdapterLoader;\n /** Legacy: single tier (for simple config) */\n tier?: LLMTier;\n /** Legacy: available capabilities */\n capabilities?: LLMCapability[];\n}\n\n/**\n * Resolved entry with adapter and model.\n */\ninterface ResolvedEntry {\n entry: TierModelEntry;\n adapter: ILLM;\n}\n\n/**\n * LLM Router - wraps ILLM adapters with tier-based routing.\n *\n * Features:\n * - Adaptive tier resolution (escalation/degradation)\n * - Model selection from tierMapping\n * - Multi-adapter support (different adapters per tier/model)\n * - Capability-based filtering\n * - Transparent ILLM delegation\n *\n * @example\n * ```typescript\n * // Single adapter (simple)\n * const router = new LLMRouter(openaiAdapter, {\n * defaultTier: 'medium',\n * tierMapping: {\n * small: [{ model: 'gpt-4o-mini', priority: 1 }],\n * medium: [{ model: 'gpt-4o', priority: 1 }],\n * }\n * }, logger);\n *\n * // Multi-adapter (different adapters per tier)\n * const router = new LLMRouter(defaultAdapter, {\n * defaultTier: 'small',\n * tierMapping: {\n * small: [{ adapter: '@kb-labs/adapters-openai', model: 'gpt-4o-mini', priority: 1 }],\n * medium: [{ adapter: '@kb-labs/adapters-vibeproxy', model: 'claude-sonnet-4-5', priority: 1 }],\n * large: [{ adapter: '@kb-labs/adapters-vibeproxy', model: 'claude-opus-4-5', priority: 1 }],\n * },\n * adapterLoader: async (pkg) => loadAdapter(pkg),\n * }, logger);\n * ```\n */\nexport class LLMRouter implements ILLM, ILLMRouter {\n private tierResolver: TierResolver;\n private capabilityResolver: CapabilityResolver;\n private currentModel: string | undefined;\n private currentAdapter: ILLM;\n private currentAdapterPackage: string | undefined;\n /** Current tier for metadata */\n private currentTier: LLMTier;\n /** Current provider for metadata */\n private currentProvider: string = 'default';\n /** Current resource name for metadata */\n private currentResource: string = 'llm:default';\n\n /** Cache of loaded adapters by package name */\n private adapterCache: Map<string, ILLM> = new Map();\n\n constructor(\n private defaultAdapter: ILLM,\n private config: LLMRouterConfig,\n private logger?: ILogger\n ) {\n // Use defaultTier or legacy tier field\n const effectiveTier = config.defaultTier ?? config.tier ?? 'small';\n this.tierResolver = new TierResolver(effectiveTier);\n this.currentTier = effectiveTier;\n\n // Build capabilities from tierMapping or legacy config\n const allCapabilities = this.extractCapabilities();\n this.capabilityResolver = new CapabilityResolver(\n allCapabilities.size > 0 ? allCapabilities : undefined\n );\n\n // Set initial adapter and model from default tier\n this.currentAdapter = defaultAdapter;\n const entry = this.getEntryForTier(effectiveTier);\n if (entry) {\n this.currentModel = entry.model;\n // eslint-disable-next-line deprecation/deprecation\n this.currentAdapterPackage = entry.adapter;\n this.currentProvider = getProviderFromEntry(entry);\n this.currentResource = `llm:${this.currentProvider}`;\n }\n\n if (this.logger && this.currentModel) {\n this.logger.debug(\n `LLMRouter initialized: model=${this.currentModel}, provider=${this.currentProvider}`\n );\n }\n }\n\n /**\n * Extract all capabilities from tierMapping.\n */\n private extractCapabilities(): Set<LLMCapability> {\n const caps = new Set<LLMCapability>();\n\n if (this.config.tierMapping) {\n for (const entries of Object.values(this.config.tierMapping)) {\n if (entries) {\n for (const entry of entries) {\n if (entry.capabilities) {\n entry.capabilities.forEach((c: LLMCapability) => caps.add(c));\n }\n }\n }\n }\n }\n\n // Include legacy capabilities\n if (this.config.capabilities) {\n this.config.capabilities.forEach((c) => caps.add(c));\n }\n\n return caps;\n }\n\n /**\n * Get entry for a given tier (highest priority).\n */\n private getEntryForTier(\n tier: LLMTier,\n requiredCapabilities?: LLMCapability[]\n ): TierModelEntry | undefined {\n if (!this.config.tierMapping) {\n return undefined;\n }\n\n const entries = this.config.tierMapping[tier];\n if (!entries || entries.length === 0) {\n return undefined;\n }\n\n // Sort by priority (lower = higher priority)\n const sorted = [...entries].sort((a, b) => a.priority - b.priority);\n\n // If capabilities required, filter\n if (requiredCapabilities && requiredCapabilities.length > 0) {\n const matching = sorted.find((entry) =>\n requiredCapabilities.every((cap) => entry.capabilities?.includes(cap))\n );\n if (matching) {\n return matching;\n }\n }\n\n // Return first entry (highest priority)\n return sorted[0];\n }\n\n /**\n * Get adapter for a given package (from cache or load).\n */\n private async getAdapter(adapterPackage?: string): Promise<ILLM> {\n // No package specified or no loader → use default\n if (!adapterPackage || !this.config.adapterLoader) {\n return this.defaultAdapter;\n }\n\n // Check cache\n const cached = this.adapterCache.get(adapterPackage);\n if (cached) {\n return cached;\n }\n\n // Load and cache\n try {\n const adapter = await this.config.adapterLoader(adapterPackage);\n this.adapterCache.set(adapterPackage, adapter);\n this.logger?.debug(`LLMRouter loaded adapter: ${adapterPackage}`);\n return adapter;\n } catch (error) {\n this.logger?.warn(`LLMRouter failed to load adapter ${adapterPackage}, using default`, {\n error: error instanceof Error ? error.message : String(error),\n });\n return this.defaultAdapter;\n }\n }\n\n /**\n * Ensure current adapter is loaded (async).\n */\n private async ensureAdapter(): Promise<ILLM> {\n if (!this.currentAdapterPackage) {\n return this.defaultAdapter;\n }\n\n const adapter = await this.getAdapter(this.currentAdapterPackage);\n this.currentAdapter = adapter;\n return adapter;\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // ILLMRouter implementation\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Get configured default tier.\n */\n getConfiguredTier(): LLMTier {\n return this.config.defaultTier ?? this.config.tier ?? 'small';\n }\n\n /**\n * Resolve tier request to actual model and adapter.\n */\n resolve(options?: UseLLMOptions): LLMResolution {\n const requestedTier = options?.tier;\n const defaultTier = this.getConfiguredTier();\n\n // Determine which tier to use\n let actualTier: LLMTier;\n let adapted = false;\n let warning: string | undefined;\n\n if (this.config.tierMapping) {\n // With tierMapping: honor requested tier if it has models defined\n const tierToUse = requestedTier ?? defaultTier;\n const hasModels = (this.config.tierMapping[tierToUse]?.length ?? 0) > 0;\n\n if (hasModels) {\n actualTier = tierToUse;\n adapted = requestedTier !== undefined && requestedTier !== defaultTier;\n } else {\n // Fall back to default tier if requested tier has no models\n actualTier = defaultTier;\n adapted = requestedTier !== undefined;\n if (requestedTier && requestedTier !== defaultTier) {\n warning = `Requested '${requestedTier}' tier has no models configured. Using '${actualTier}'.`;\n if (this.logger) {\n this.logger.warn(warning);\n }\n }\n }\n } else {\n // Without tierMapping: use legacy TierResolver logic\n const tierResult = this.tierResolver.resolve(requestedTier);\n actualTier = tierResult.tier;\n adapted = tierResult.adapted;\n warning = tierResult.warning;\n\n if (warning && this.logger) {\n this.logger.warn(warning);\n }\n }\n\n // Get entry for the actual tier\n const entry = this.getEntryForTier(actualTier, options?.capabilities);\n const model = entry?.model;\n // eslint-disable-next-line deprecation/deprecation\n const adapterPackage = entry?.adapter;\n const provider = entry ? getProviderFromEntry(entry) : 'default';\n const resource = `llm:${provider}`;\n\n // Update current state for subsequent calls\n this.currentTier = actualTier;\n this.currentProvider = provider;\n this.currentResource = resource;\n if (model) {\n this.currentModel = model;\n this.currentAdapterPackage = adapterPackage;\n if (this.logger) {\n this.logger.debug(\n `LLMRouter resolved: tier=${actualTier}, model=${model}, provider=${provider}, resource=${resource}`\n );\n }\n }\n\n // Check capabilities if requested\n if (options?.capabilities && options.capabilities.length > 0) {\n const missingCaps = options.capabilities.filter(\n (cap) => !this.capabilityResolver.hasCapability(cap)\n );\n\n if (missingCaps.length > 0 && this.logger) {\n this.logger.warn(\n `Requested capabilities [${missingCaps.join(', ')}] may not be available`\n );\n }\n }\n\n return {\n provider,\n model: model ?? 'default',\n resource,\n requestedTier: requestedTier,\n actualTier: actualTier,\n adapted: adapted,\n warning: warning,\n };\n }\n\n /**\n * Check if capability is available.\n */\n hasCapability(capability: LLMCapability): boolean {\n return this.capabilityResolver.hasCapability(capability);\n }\n\n /**\n * Get available capabilities.\n */\n getCapabilities(): LLMCapability[] {\n return this.capabilityResolver.getCapabilities();\n }\n\n /**\n * Resolve tier and return an immutable adapter binding.\n * Does NOT mutate router state — safe for concurrent useLLM() calls.\n */\n async resolveAdapter(options?: UseLLMOptions): Promise<LLMAdapterBinding> {\n const requestedTier = options?.tier;\n const defaultTier = this.getConfiguredTier();\n\n // Determine actualTier without mutating this.*\n let actualTier: LLMTier;\n if (this.config.tierMapping) {\n const tierToUse = requestedTier ?? defaultTier;\n const hasModels = (this.config.tierMapping[tierToUse]?.length ?? 0) > 0;\n if (hasModels) {\n actualTier = tierToUse;\n } else {\n actualTier = defaultTier;\n if (requestedTier && requestedTier !== defaultTier && this.logger) {\n this.logger.warn(\n `resolveAdapter: requested '${requestedTier}' tier has no models. Using '${actualTier}'.`\n );\n }\n }\n } else {\n const tierResult = this.tierResolver.resolve(requestedTier);\n actualTier = tierResult.tier;\n if (tierResult.warning && this.logger) {\n this.logger.warn(tierResult.warning);\n }\n }\n\n const entry = this.getEntryForTier(actualTier, options?.capabilities);\n const model = entry?.model ?? this.currentModel ?? 'default';\n // eslint-disable-next-line deprecation/deprecation\n const adapterPackage = entry?.adapter;\n\n const adapter = await this.getAdapter(adapterPackage);\n\n this.logger?.debug(`resolveAdapter: tier=${actualTier}, model=${model}`);\n\n return { adapter, model, tier: actualTier };\n }\n\n /**\n * Get current selected model.\n */\n getCurrentModel(): string | undefined {\n return this.currentModel;\n }\n\n /**\n * Get current adapter package (or undefined for default).\n */\n getCurrentAdapterPackage(): string | undefined {\n return this.currentAdapterPackage;\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // ILLM implementation (delegate to current adapter with model override)\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Merge options with current model and routing metadata.\n * Metadata is used by AnalyticsLLM to track tier/provider/resource.\n */\n private withModelAndMetadata(options?: LLMOptions): LLMOptions {\n const metadata: LLMRequestMetadata = {\n tier: this.currentTier,\n provider: this.currentProvider,\n resource: this.currentResource,\n };\n\n return {\n ...options,\n model: options?.model ?? this.currentModel,\n metadata: {\n ...metadata,\n ...options?.metadata, // Allow override if needed\n },\n };\n }\n\n /**\n * Generate a completion.\n */\n async complete(prompt: string, options?: LLMOptions): Promise<LLMResponse> {\n const adapter = await this.ensureAdapter();\n return adapter.complete(prompt, this.withModelAndMetadata(options));\n }\n\n /**\n * Stream a completion.\n */\n async *stream(prompt: string, options?: LLMOptions): AsyncIterable<string> {\n const adapter = await this.ensureAdapter();\n yield* adapter.stream(prompt, this.withModelAndMetadata(options));\n }\n\n /**\n * Return protocol capabilities of the currently resolved adapter.\n */\n async getProtocolCapabilities(): Promise<LLMProtocolCapabilities> {\n const adapter = await this.ensureAdapter();\n if (!adapter.getProtocolCapabilities) {\n return {\n cache: { supported: false },\n stream: { supported: true },\n };\n }\n return adapter.getProtocolCapabilities();\n }\n\n /**\n * Chat with native tool calling support.\n */\n async chatWithTools(\n messages: LLMMessage[],\n options: LLMToolCallOptions\n ): Promise<LLMToolCallResponse> {\n const adapter = await this.ensureAdapter();\n if (!adapter.chatWithTools) {\n throw new Error('Current adapter does not support chatWithTools');\n }\n return adapter.chatWithTools(messages, this.withModelAndMetadata(options) as LLMToolCallOptions);\n }\n\n /**\n * Check if chatWithTools is supported by current adapter.\n */\n get supportsChatWithTools(): boolean {\n return typeof this.currentAdapter.chatWithTools === 'function';\n }\n}\n","/**\n * @module @kb-labs/llm-router/manifest\n * Adapter manifest for LLM Router.\n */\n\nimport type { AdapterManifest } from '@kb-labs/core-platform';\n\n/**\n * LLM Router adapter manifest.\n */\nexport const manifest: AdapterManifest = {\n manifestVersion: '1.0.0',\n id: 'llm-router',\n name: 'LLM Router',\n version: '0.1.0',\n type: 'proxy', // Wraps/delegates to underlying LLM adapter\n description: 'Adaptive LLM router with tier-based model selection',\n implements: 'ILLM',\n capabilities: {\n streaming: true,\n batch: false,\n },\n // No runtime contexts needed\n contexts: [],\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/resolver.ts","../src/router.ts","../src/manifest.ts"],"names":["TIER_ORDER"],"mappings":";;;;;AA4BO,IAAM,eAAN,MAAmB;AAAA,EAGxB,YAAoB,cAAA,EAAyB;AAAzB,IAAA,IAAA,CAAA,cAAA,GAAA,cAAA;AAClB,IAAA,IAAA,CAAK,eAAA,GAAkBA,uBAAA,CAAW,OAAA,CAAQ,cAAc,CAAA;AAAA,EAC1D;AAAA,EAJQ,eAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYR,QAAQ,aAAA,EAAwC;AAE9C,IAAA,IAAI,CAAC,aAAA,EAAe;AAClB,MAAA,OAAO,EAAE,IAAA,EAAM,IAAA,CAAK,cAAA,EAAgB,SAAS,KAAA,EAAM;AAAA,IACrD;AAEA,IAAA,MAAM,cAAA,GAAiBA,uBAAA,CAAW,OAAA,CAAQ,aAAa,CAAA;AAGvD,IAAA,IAAI,cAAA,KAAmB,KAAK,eAAA,EAAiB;AAC3C,MAAA,OAAO,EAAE,IAAA,EAAM,IAAA,CAAK,cAAA,EAAgB,SAAS,KAAA,EAAM;AAAA,IACrD;AAIA,IAAA,IAAI,cAAA,GAAiB,KAAK,eAAA,EAAiB;AACzC,MAAA,OAAO;AAAA,QACL,MAAM,IAAA,CAAK,cAAA;AAAA,QACX,OAAA,EAAS;AAAA;AAAA,OAEX;AAAA,IACF;AAIA,IAAA,OAAO;AAAA,MACL,MAAM,IAAA,CAAK,cAAA;AAAA,MACX,OAAA,EAAS,IAAA;AAAA,MACT,OAAA,EAAS,cAAc,aAAa,CAAA,iBAAA,EAAoB,KAAK,cAAc,CAAA,mBAAA,EAAsB,KAAK,cAAc,CAAA,CAAA;AAAA,KACtH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAA,GAA6B;AAC3B,IAAA,OAAO,IAAA,CAAK,cAAA;AAAA,EACd;AACF;AAQO,IAAM,qBAAN,MAAyB;AAAA,EAC9B,WAAA,CAAoB,qBAAA,mBAA4C,IAAI,GAAA,EAAI,EAAG;AAAvD,IAAA,IAAA,CAAA,qBAAA,GAAA,qBAAA;AAAA,EAAwD;AAAA;AAAA;AAAA;AAAA,EAK5E,cAAc,UAAA,EAAoC;AAEhD,IAAA,IAAI,IAAA,CAAK,qBAAA,CAAsB,IAAA,KAAS,CAAA,EAAG;AACzC,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO,IAAA,CAAK,qBAAA,CAAsB,GAAA,CAAI,UAAU,CAAA;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAmB,YAAA,EAAwC;AACzD,IAAA,OAAO,aAAa,KAAA,CAAM,CAAC,QAAQ,IAAA,CAAK,aAAA,CAAc,GAAG,CAAC,CAAA;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,GAAmC;AAEjC,IAAA,IAAI,IAAA,CAAK,qBAAA,CAAsB,IAAA,KAAS,CAAA,EAAG;AACzC,MAAA,OAAO,CAAC,WAAA,EAAa,QAAA,EAAU,QAAA,EAAU,MAAM,CAAA;AAAA,IACjD;AACA,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,qBAAqB,CAAA;AAAA,EAC9C;AACF;;;ACnEA,SAAS,qBAAqB,KAAA,EAA+B;AAE3D,EAAA,IAAI,MAAM,QAAA,EAAU;AAClB,IAAA,OAAO,KAAA,CAAM,QAAA;AAAA,EACf;AAEA,EAAA,MAAM,UAAU,KAAA,CAAM,OAAA;AACtB,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,gBAAgB,CAAA;AAC5C,IAAA,IAAI,KAAA,GAAQ,CAAC,CAAA,EAAG;AACd,MAAA,OAAO,MAAM,CAAC,CAAA;AAAA,IAChB;AAEA,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,MAAM,CAAA;AACrC,IAAA,MAAM,WAAA,GAAc,QAAA,CAAS,QAAA,CAAS,MAAA,GAAS,CAAC,CAAA;AAChD,IAAA,OAAO,WAAA,IAAe,SAAA;AAAA,EACxB;AACA,EAAA,OAAO,SAAA;AACT;AAyEO,IAAM,YAAN,MAA4C;AAAA,EAgBjD,WAAA,CACU,cAAA,EACA,MAAA,EACA,MAAA,EACR;AAHQ,IAAA,IAAA,CAAA,cAAA,GAAA,cAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAGR,IAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,WAAA,IAAe,MAAA,CAAO,IAAA,IAAQ,OAAA;AAC3D,IAAA,IAAA,CAAK,YAAA,GAAe,IAAI,YAAA,CAAa,aAAa,CAAA;AAClD,IAAA,IAAA,CAAK,WAAA,GAAc,aAAA;AAGnB,IAAA,MAAM,eAAA,GAAkB,KAAK,mBAAA,EAAoB;AACjD,IAAA,IAAA,CAAK,qBAAqB,IAAI,kBAAA;AAAA,MAC5B,eAAA,CAAgB,IAAA,GAAO,CAAA,GAAI,eAAA,GAAkB;AAAA,KAC/C;AAGA,IAAA,IAAA,CAAK,cAAA,GAAiB,cAAA;AACtB,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,eAAA,CAAgB,aAAa,CAAA;AAChD,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,IAAA,CAAK,eAAe,KAAA,CAAM,KAAA;AAC1B,MAAA,IAAA,CAAK,wBAAwB,KAAA,CAAM,OAAA;AACnC,MAAA,IAAA,CAAK,eAAA,GAAkB,qBAAqB,KAAK,CAAA;AACjD,MAAA,IAAA,CAAK,eAAA,GAAkB,CAAA,IAAA,EAAO,IAAA,CAAK,eAAe,CAAA,CAAA;AAAA,IACpD;AAEA,IAAA,IAAI,IAAA,CAAK,MAAA,IAAU,IAAA,CAAK,YAAA,EAAc;AACpC,MAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACV,CAAA,6BAAA,EAAgC,IAAA,CAAK,YAAY,CAAA,WAAA,EAAc,KAAK,eAAe,CAAA;AAAA,OACrF;AAAA,IACF;AAAA,EACF;AAAA,EA9CQ,YAAA;AAAA,EACA,kBAAA;AAAA,EACA,YAAA;AAAA,EACA,cAAA;AAAA,EACA,qBAAA;AAAA;AAAA,EAEA,WAAA;AAAA;AAAA,EAEA,eAAA,GAA0B,SAAA;AAAA;AAAA,EAE1B,eAAA,GAA0B,aAAA;AAAA;AAAA,EAG1B,YAAA,uBAAsC,GAAA,EAAI;AAAA;AAAA;AAAA;AAAA,EAsC1C,mBAAA,GAA0C;AAChD,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAmB;AAEpC,IAAA,IAAI,IAAA,CAAK,OAAO,WAAA,EAAa;AAC3B,MAAA,KAAA,MAAW,WAAW,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,WAAW,CAAA,EAAG;AAC5D,QAAA,IAAI,OAAA,EAAS;AACX,UAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,YAAA,IAAI,MAAM,YAAA,EAAc;AACtB,cAAA,KAAA,CAAM,aAAa,OAAA,CAAQ,CAAC,MAAqB,IAAA,CAAK,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,YAC9D;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,IAAA,IAAI,IAAA,CAAK,OAAO,YAAA,EAAc;AAC5B,MAAA,IAAA,CAAK,MAAA,CAAO,aAAa,OAAA,CAAQ,CAAC,MAAM,IAAA,CAAK,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,IACrD;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAA,CACN,MACA,oBAAA,EAC4B;AAC5B,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,WAAA,EAAa;AAC5B,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,MAAA,CAAO,WAAA,CAAY,IAAI,CAAA;AAC5C,IAAA,IAAI,CAAC,OAAA,IAAW,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG;AACpC,MAAA,OAAO,MAAA;AAAA,IACT;AAGA,IAAA,MAAM,MAAA,GAAS,CAAC,GAAG,OAAO,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,QAAA,GAAW,CAAA,CAAE,QAAQ,CAAA;AAGlE,IAAA,IAAI,oBAAA,IAAwB,oBAAA,CAAqB,MAAA,GAAS,CAAA,EAAG;AAC3D,MAAA,MAAM,WAAW,MAAA,CAAO,IAAA;AAAA,QAAK,CAAC,KAAA,KAC5B,oBAAA,CAAqB,KAAA,CAAM,CAAC,QAAQ,KAAA,CAAM,YAAA,EAAc,QAAA,CAAS,GAAG,CAAC;AAAA,OACvE;AACA,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,OAAO,QAAA;AAAA,MACT;AAAA,IACF;AAGA,IAAA,OAAO,OAAO,CAAC,CAAA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,WAAW,cAAA,EAAwC;AAE/D,IAAA,IAAI,CAAC,cAAA,IAAkB,CAAC,IAAA,CAAK,OAAO,aAAA,EAAe;AACjD,MAAA,OAAO,IAAA,CAAK,cAAA;AAAA,IACd;AAGA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,cAAc,CAAA;AACnD,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,OAAO,MAAA;AAAA,IACT;AAGA,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,MAAA,CAAO,cAAc,cAAc,CAAA;AAC9D,MAAA,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,cAAA,EAAgB,OAAO,CAAA;AAC7C,MAAA,IAAA,CAAK,MAAA,EAAQ,KAAA,CAAM,CAAA,0BAAA,EAA6B,cAAc,CAAA,CAAE,CAAA;AAChE,MAAA,OAAO,OAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,CAAA,iCAAA,EAAoC,cAAc,CAAA,eAAA,CAAA,EAAmB;AAAA,QACrF,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,OAC7D,CAAA;AACD,MAAA,OAAO,IAAA,CAAK,cAAA;AAAA,IACd;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,aAAA,GAA+B;AAC3C,IAAA,IAAI,CAAC,KAAK,qBAAA,EAAuB;AAC/B,MAAA,OAAO,IAAA,CAAK,cAAA;AAAA,IACd;AAEA,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,UAAA,CAAW,KAAK,qBAAqB,CAAA;AAChE,IAAA,IAAA,CAAK,cAAA,GAAiB,OAAA;AACtB,IAAA,OAAO,OAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,iBAAA,GAA6B;AAC3B,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,WAAA,IAAe,IAAA,CAAK,OAAO,IAAA,IAAQ,OAAA;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,OAAA,EAAwC;AAC9C,IAAA,MAAM,gBAAgB,OAAA,EAAS,IAAA;AAC/B,IAAA,MAAM,WAAA,GAAc,KAAK,iBAAA,EAAkB;AAG3C,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI,OAAA,GAAU,KAAA;AACd,IAAA,IAAI,OAAA;AAEJ,IAAA,IAAI,IAAA,CAAK,OAAO,WAAA,EAAa;AAE3B,MAAA,MAAM,YAAY,aAAA,IAAiB,WAAA;AACnC,MAAA,MAAM,aAAa,IAAA,CAAK,MAAA,CAAO,YAAY,SAAS,CAAA,EAAG,UAAU,CAAA,IAAK,CAAA;AAEtE,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,UAAA,GAAa,SAAA;AACb,QAAA,OAAA,GAAU,aAAA,KAAkB,UAAa,aAAA,KAAkB,WAAA;AAAA,MAC7D,CAAA,MAAO;AAEL,QAAA,UAAA,GAAa,WAAA;AACb,QAAA,OAAA,GAAU,aAAA,KAAkB,MAAA;AAC5B,QAAA,IAAI,aAAA,IAAiB,kBAAkB,WAAA,EAAa;AAClD,UAAA,OAAA,GAAU,CAAA,WAAA,EAAc,aAAa,CAAA,wCAAA,EAA2C,UAAU,CAAA,EAAA,CAAA;AAC1F,UAAA,IAAI,KAAK,MAAA,EAAQ;AACf,YAAA,IAAA,CAAK,MAAA,CAAO,KAAK,OAAO,CAAA;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,YAAA,CAAa,OAAA,CAAQ,aAAa,CAAA;AAC1D,MAAA,UAAA,GAAa,UAAA,CAAW,IAAA;AACxB,MAAA,OAAA,GAAU,UAAA,CAAW,OAAA;AACrB,MAAA,OAAA,GAAU,UAAA,CAAW,OAAA;AAErB,MAAA,IAAI,OAAA,IAAW,KAAK,MAAA,EAAQ;AAC1B,QAAA,IAAA,CAAK,MAAA,CAAO,KAAK,OAAO,CAAA;AAAA,MAC1B;AAAA,IACF;AAGA,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,eAAA,CAAgB,UAAA,EAAY,SAAS,YAAY,CAAA;AACpE,IAAA,MAAM,QAAQ,KAAA,EAAO,KAAA;AACrB,IAAA,MAAM,iBAAiB,KAAA,EAAO,OAAA;AAC9B,IAAA,MAAM,QAAA,GAAW,KAAA,GAAQ,oBAAA,CAAqB,KAAK,CAAA,GAAI,SAAA;AACvD,IAAA,MAAM,QAAA,GAAW,OAAO,QAAQ,CAAA,CAAA;AAGhC,IAAA,IAAA,CAAK,WAAA,GAAc,UAAA;AACnB,IAAA,IAAA,CAAK,eAAA,GAAkB,QAAA;AACvB,IAAA,IAAA,CAAK,eAAA,GAAkB,QAAA;AACvB,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,IAAA,CAAK,YAAA,GAAe,KAAA;AACpB,MAAA,IAAA,CAAK,qBAAA,GAAwB,cAAA;AAC7B,MAAA,IAAI,KAAK,MAAA,EAAQ;AACf,QAAA,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,UACV,4BAA4B,UAAU,CAAA,QAAA,EAAW,KAAK,CAAA,WAAA,EAAc,QAAQ,cAAc,QAAQ,CAAA;AAAA,SACpG;AAAA,MACF;AAAA,IACF;AAGA,IAAA,IAAI,OAAA,EAAS,YAAA,IAAgB,OAAA,CAAQ,YAAA,CAAa,SAAS,CAAA,EAAG;AAC5D,MAAA,MAAM,WAAA,GAAc,QAAQ,YAAA,CAAa,MAAA;AAAA,QACvC,CAAC,GAAA,KAAQ,CAAC,IAAA,CAAK,kBAAA,CAAmB,cAAc,GAAG;AAAA,OACrD;AAEA,MAAA,IAAI,WAAA,CAAY,MAAA,GAAS,CAAA,IAAK,IAAA,CAAK,MAAA,EAAQ;AACzC,QAAA,IAAA,CAAK,MAAA,CAAO,IAAA;AAAA,UACV,CAAA,wBAAA,EAA2B,WAAA,CAAY,IAAA,CAAK,IAAI,CAAC,CAAA,sBAAA;AAAA,SACnD;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,QAAA;AAAA,MACA,OAAO,KAAA,IAAS,SAAA;AAAA,MAChB,QAAA;AAAA,MACA,aAAA;AAAA,MACA,UAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,UAAA,EAAoC;AAChD,IAAA,OAAO,IAAA,CAAK,kBAAA,CAAmB,aAAA,CAAc,UAAU,CAAA;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,GAAmC;AACjC,IAAA,OAAO,IAAA,CAAK,mBAAmB,eAAA,EAAgB;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,eAAe,OAAA,EAAqD;AACxE,IAAA,MAAM,gBAAgB,OAAA,EAAS,IAAA;AAC/B,IAAA,MAAM,WAAA,GAAc,KAAK,iBAAA,EAAkB;AAG3C,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI,IAAA,CAAK,OAAO,WAAA,EAAa;AAC3B,MAAA,MAAM,YAAY,aAAA,IAAiB,WAAA;AACnC,MAAA,MAAM,aAAa,IAAA,CAAK,MAAA,CAAO,YAAY,SAAS,CAAA,EAAG,UAAU,CAAA,IAAK,CAAA;AACtE,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,UAAA,GAAa,SAAA;AAAA,MACf,CAAA,MAAO;AACL,QAAA,UAAA,GAAa,WAAA;AACb,QAAA,IAAI,aAAA,IAAiB,aAAA,KAAkB,WAAA,IAAe,IAAA,CAAK,MAAA,EAAQ;AACjE,UAAA,IAAA,CAAK,MAAA,CAAO,IAAA;AAAA,YACV,CAAA,2BAAA,EAA8B,aAAa,CAAA,6BAAA,EAAgC,UAAU,CAAA,EAAA;AAAA,WACvF;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAA,MAAO;AACL,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,YAAA,CAAa,OAAA,CAAQ,aAAa,CAAA;AAC1D,MAAA,UAAA,GAAa,UAAA,CAAW,IAAA;AACxB,MAAA,IAAI,UAAA,CAAW,OAAA,IAAW,IAAA,CAAK,MAAA,EAAQ;AACrC,QAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,UAAA,CAAW,OAAO,CAAA;AAAA,MACrC;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,eAAA,CAAgB,UAAA,EAAY,SAAS,YAAY,CAAA;AACpE,IAAA,MAAM,KAAA,GAAQ,KAAA,EAAO,KAAA,IAAS,IAAA,CAAK,YAAA,IAAgB,SAAA;AACnD,IAAA,MAAM,iBAAiB,KAAA,EAAO,OAAA;AAE9B,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,UAAA,CAAW,cAAc,CAAA;AAEpD,IAAA,IAAA,CAAK,QAAQ,KAAA,CAAM,CAAA,qBAAA,EAAwB,UAAU,CAAA,QAAA,EAAW,KAAK,CAAA,CAAE,CAAA;AAEvE,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,IAAA,EAAM,UAAA,EAAW;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,GAAsC;AACpC,IAAA,OAAO,IAAA,CAAK,YAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,wBAAA,GAA+C;AAC7C,IAAA,OAAO,IAAA,CAAK,qBAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,qBAAqB,OAAA,EAAkC;AAC7D,IAAA,MAAM,QAAA,GAA+B;AAAA,MACnC,MAAM,IAAA,CAAK,WAAA;AAAA,MACX,UAAU,IAAA,CAAK,eAAA;AAAA,MACf,UAAU,IAAA,CAAK;AAAA,KACjB;AAEA,IAAA,OAAO;AAAA,MACL,GAAG,OAAA;AAAA,MACH,KAAA,EAAO,OAAA,EAAS,KAAA,IAAS,IAAA,CAAK,YAAA;AAAA,MAC9B,QAAA,EAAU;AAAA,QACR,GAAG,QAAA;AAAA,QACH,GAAG,OAAA,EAAS;AAAA;AAAA;AACd,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAA,CAAS,MAAA,EAAgB,OAAA,EAA4C;AACzE,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,aAAA,EAAc;AACzC,IAAA,OAAO,QAAQ,QAAA,CAAS,MAAA,EAAQ,IAAA,CAAK,oBAAA,CAAqB,OAAO,CAAC,CAAA;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,MAAA,CAAO,MAAA,EAAgB,OAAA,EAA6C;AACzE,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,aAAA,EAAc;AACzC,IAAA,OAAO,QAAQ,MAAA,CAAO,MAAA,EAAQ,IAAA,CAAK,oBAAA,CAAqB,OAAO,CAAC,CAAA;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,uBAAA,GAA4D;AAChE,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,aAAA,EAAc;AACzC,IAAA,IAAI,CAAC,QAAQ,uBAAA,EAAyB;AACpC,MAAA,OAAO;AAAA,QACL,KAAA,EAAO,EAAE,SAAA,EAAW,KAAA,EAAM;AAAA,QAC1B,MAAA,EAAQ,EAAE,SAAA,EAAW,IAAA;AAAK,OAC5B;AAAA,IACF;AACA,IAAA,OAAO,QAAQ,uBAAA,EAAwB;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAA,CACJ,QAAA,EACA,OAAA,EAC8B;AAC9B,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,aAAA,EAAc;AACzC,IAAA,IAAI,CAAC,QAAQ,aAAA,EAAe;AAC1B,MAAA,MAAM,IAAI,MAAM,gDAAgD,CAAA;AAAA,IAClE;AACA,IAAA,OAAO,QAAQ,aAAA,CAAc,QAAA,EAAU,IAAA,CAAK,oBAAA,CAAqB,OAAO,CAAuB,CAAA;AAAA,EACjG;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,qBAAA,GAAiC;AACnC,IAAA,OAAO,OAAO,IAAA,CAAK,cAAA,CAAe,aAAA,KAAkB,UAAA;AAAA,EACtD;AACF;;;AC9gBO,IAAM,QAAA,GAA4B;AAAA,EACvC,eAAA,EAAiB,OAAA;AAAA,EACjB,EAAA,EAAI,YAAA;AAAA,EACJ,IAAA,EAAM,YAAA;AAAA,EACN,OAAA,EAAS,OAAA;AAAA,EACT,IAAA,EAAM,OAAA;AAAA;AAAA,EACN,WAAA,EAAa,qDAAA;AAAA,EACb,UAAA,EAAY,MAAA;AAAA,EACZ,YAAA,EAAc;AAAA,IACZ,SAAA,EAAW,IAAA;AAAA,IACX,KAAA,EAAO;AAAA,GACT;AAAA;AAAA,EAEA,UAAU;AACZ","file":"index.cjs","sourcesContent":["/**\n * @module @kb-labs/llm-router/resolver\n * Tier resolution logic with adaptive escalation/degradation.\n */\n\nimport type { LLMTier, LLMCapability } from '@kb-labs/core-platform';\nimport { TIER_ORDER } from '@kb-labs/core-platform';\n\n/**\n * Resolution result.\n */\nexport interface ResolveResult {\n /** Actual tier to use */\n tier: LLMTier;\n /** Whether adaptation occurred */\n adapted: boolean;\n /** Warning message (only for degradation) */\n warning?: string;\n}\n\n/**\n * Tier resolver with adaptive escalation/degradation.\n *\n * Resolution rules:\n * - Exact match → use as-is\n * - Request lower than configured → escalate silently (small → medium)\n * - Request higher than configured → degrade with warning (large → medium)\n */\nexport class TierResolver {\n private configuredIndex: number;\n\n constructor(private configuredTier: LLMTier) {\n this.configuredIndex = TIER_ORDER.indexOf(configuredTier);\n }\n\n /**\n * Resolve requested tier to actual tier.\n *\n * @param requestedTier - Tier requested by plugin (or undefined for default)\n * @returns Resolution result with actual tier and adaptation info\n */\n resolve(requestedTier?: LLMTier): ResolveResult {\n // No request → use configured default\n if (!requestedTier) {\n return { tier: this.configuredTier, adapted: false };\n }\n\n const requestedIndex = TIER_ORDER.indexOf(requestedTier);\n\n // Exact match\n if (requestedIndex === this.configuredIndex) {\n return { tier: this.configuredTier, adapted: false };\n }\n\n // Escalation: requested < configured (e.g., small → medium)\n // This is fine - plugin asked for less, we give more\n if (requestedIndex < this.configuredIndex) {\n return {\n tier: this.configuredTier,\n adapted: true,\n // No warning - escalation is acceptable\n };\n }\n\n // Degradation: requested > configured (e.g., large → medium)\n // This needs a warning - plugin wanted more than available\n return {\n tier: this.configuredTier,\n adapted: true,\n warning: `Requested '${requestedTier}' tier but only '${this.configuredTier}' available. Using ${this.configuredTier}.`,\n };\n }\n\n /**\n * Get the configured tier.\n */\n getConfiguredTier(): LLMTier {\n return this.configuredTier;\n }\n}\n\n/**\n * Capability resolver.\n *\n * For simple config: assumes all capabilities available.\n * For advanced config: checks against capability mapping.\n */\nexport class CapabilityResolver {\n constructor(private availableCapabilities: Set<LLMCapability> = new Set()) {}\n\n /**\n * Check if capability is available.\n */\n hasCapability(capability: LLMCapability): boolean {\n // If no capabilities configured, assume all available (simple config)\n if (this.availableCapabilities.size === 0) {\n return true;\n }\n return this.availableCapabilities.has(capability);\n }\n\n /**\n * Check if all requested capabilities are available.\n */\n hasAllCapabilities(capabilities: LLMCapability[]): boolean {\n return capabilities.every((cap) => this.hasCapability(cap));\n }\n\n /**\n * Get available capabilities.\n */\n getCapabilities(): LLMCapability[] {\n // If no capabilities configured, return all (simple config)\n if (this.availableCapabilities.size === 0) {\n return ['reasoning', 'coding', 'vision', 'fast'];\n }\n return Array.from(this.availableCapabilities);\n }\n}\n","/**\n * @module @kb-labs/llm-router/router\n * LLM Router - adaptive routing with tier-based model selection.\n * Supports multiple adapters per tier for maximum flexibility.\n */\n\nimport type {\n ILLM,\n LLMOptions,\n LLMResponse,\n LLMMessage,\n LLMToolCallOptions,\n LLMToolCallResponse,\n LLMTier,\n LLMCapability,\n UseLLMOptions,\n LLMResolution,\n LLMAdapterBinding,\n ILLMRouter,\n ILogger,\n LLMRequestMetadata,\n LLMProtocolCapabilities,\n} from '@kb-labs/core-platform';\nimport { TierResolver, CapabilityResolver } from './resolver.js';\n\n/**\n * Model entry in tier mapping.\n * Can optionally specify a different adapter per model.\n */\nexport interface TierModelEntry {\n /** Model identifier */\n model: string;\n /** Priority (lower = higher priority) */\n priority: number;\n /** Model capabilities */\n capabilities?: LLMCapability[];\n /**\n * Provider identifier (e.g., 'openai', 'anthropic', 'vibeproxy').\n * Used to construct resource name: `llm:${provider}`\n */\n provider?: string;\n /**\n * @deprecated Use `provider` instead. Adapter package to use for this model.\n * Will be removed in future versions.\n */\n adapter?: string;\n}\n\n/**\n * Helper to extract provider from entry (supports both new `provider` and legacy `adapter`).\n */\nfunction getProviderFromEntry(entry: TierModelEntry): string {\n // Prefer explicit provider\n if (entry.provider) {\n return entry.provider;\n }\n // Extract from adapter package name: \"@kb-labs/adapters-openai\" → \"openai\"\n const adapter = entry.adapter;\n if (adapter) {\n const match = adapter.match(/adapters-(\\w+)/);\n if (match?.[1]) {\n return match[1];\n }\n // Fallback: use last segment\n const segments = adapter.split(/[-/]/);\n const lastSegment = segments[segments.length - 1];\n return lastSegment ?? 'default';\n }\n return 'default';\n}\n\n/**\n * Tier mapping configuration.\n */\nexport interface TierMapping {\n small?: TierModelEntry[];\n medium?: TierModelEntry[];\n large?: TierModelEntry[];\n}\n\n/**\n * Function to load an adapter by package name.\n */\nexport type AdapterLoader = (adapterPackage: string) => Promise<ILLM>;\n\n/**\n * LLM Router configuration.\n */\nexport interface LLMRouterConfig {\n /** Default tier when none specified */\n defaultTier: LLMTier;\n /** Tier to model mapping */\n tierMapping?: TierMapping;\n /** Function to load adapters by package name (required for multi-adapter) */\n adapterLoader?: AdapterLoader;\n /** Legacy: single tier (for simple config) */\n tier?: LLMTier;\n /** Legacy: available capabilities */\n capabilities?: LLMCapability[];\n}\n\n/**\n * Resolved entry with adapter and model.\n */\ninterface ResolvedEntry {\n entry: TierModelEntry;\n adapter: ILLM;\n}\n\n/**\n * LLM Router - wraps ILLM adapters with tier-based routing.\n *\n * Features:\n * - Adaptive tier resolution (escalation/degradation)\n * - Model selection from tierMapping\n * - Multi-adapter support (different adapters per tier/model)\n * - Capability-based filtering\n * - Transparent ILLM delegation\n *\n * @example\n * ```typescript\n * // Single adapter (simple)\n * const router = new LLMRouter(openaiAdapter, {\n * defaultTier: 'medium',\n * tierMapping: {\n * small: [{ model: 'gpt-4o-mini', priority: 1 }],\n * medium: [{ model: 'gpt-4o', priority: 1 }],\n * }\n * }, logger);\n *\n * // Multi-adapter (different adapters per tier)\n * const router = new LLMRouter(defaultAdapter, {\n * defaultTier: 'small',\n * tierMapping: {\n * small: [{ adapter: '@kb-labs/adapters-openai', model: 'gpt-4o-mini', priority: 1 }],\n * medium: [{ adapter: '@kb-labs/adapters-vibeproxy', model: 'claude-sonnet-4-5', priority: 1 }],\n * large: [{ adapter: '@kb-labs/adapters-vibeproxy', model: 'claude-opus-4-5', priority: 1 }],\n * },\n * adapterLoader: async (pkg) => loadAdapter(pkg),\n * }, logger);\n * ```\n */\nexport class LLMRouter implements ILLM, ILLMRouter {\n private tierResolver: TierResolver;\n private capabilityResolver: CapabilityResolver;\n private currentModel: string | undefined;\n private currentAdapter: ILLM;\n private currentAdapterPackage: string | undefined;\n /** Current tier for metadata */\n private currentTier: LLMTier;\n /** Current provider for metadata */\n private currentProvider: string = 'default';\n /** Current resource name for metadata */\n private currentResource: string = 'llm:default';\n\n /** Cache of loaded adapters by package name */\n private adapterCache: Map<string, ILLM> = new Map();\n\n constructor(\n private defaultAdapter: ILLM,\n private config: LLMRouterConfig,\n private logger?: ILogger\n ) {\n // Use defaultTier or legacy tier field\n const effectiveTier = config.defaultTier ?? config.tier ?? 'small';\n this.tierResolver = new TierResolver(effectiveTier);\n this.currentTier = effectiveTier;\n\n // Build capabilities from tierMapping or legacy config\n const allCapabilities = this.extractCapabilities();\n this.capabilityResolver = new CapabilityResolver(\n allCapabilities.size > 0 ? allCapabilities : undefined\n );\n\n // Set initial adapter and model from default tier\n this.currentAdapter = defaultAdapter;\n const entry = this.getEntryForTier(effectiveTier);\n if (entry) {\n this.currentModel = entry.model;\n this.currentAdapterPackage = entry.adapter;\n this.currentProvider = getProviderFromEntry(entry);\n this.currentResource = `llm:${this.currentProvider}`;\n }\n\n if (this.logger && this.currentModel) {\n this.logger.debug(\n `LLMRouter initialized: model=${this.currentModel}, provider=${this.currentProvider}`\n );\n }\n }\n\n /**\n * Extract all capabilities from tierMapping.\n */\n private extractCapabilities(): Set<LLMCapability> {\n const caps = new Set<LLMCapability>();\n\n if (this.config.tierMapping) {\n for (const entries of Object.values(this.config.tierMapping)) {\n if (entries) {\n for (const entry of entries) {\n if (entry.capabilities) {\n entry.capabilities.forEach((c: LLMCapability) => caps.add(c));\n }\n }\n }\n }\n }\n\n // Include legacy capabilities\n if (this.config.capabilities) {\n this.config.capabilities.forEach((c) => caps.add(c));\n }\n\n return caps;\n }\n\n /**\n * Get entry for a given tier (highest priority).\n */\n private getEntryForTier(\n tier: LLMTier,\n requiredCapabilities?: LLMCapability[]\n ): TierModelEntry | undefined {\n if (!this.config.tierMapping) {\n return undefined;\n }\n\n const entries = this.config.tierMapping[tier];\n if (!entries || entries.length === 0) {\n return undefined;\n }\n\n // Sort by priority (lower = higher priority)\n const sorted = [...entries].sort((a, b) => a.priority - b.priority);\n\n // If capabilities required, filter\n if (requiredCapabilities && requiredCapabilities.length > 0) {\n const matching = sorted.find((entry) =>\n requiredCapabilities.every((cap) => entry.capabilities?.includes(cap))\n );\n if (matching) {\n return matching;\n }\n }\n\n // Return first entry (highest priority)\n return sorted[0];\n }\n\n /**\n * Get adapter for a given package (from cache or load).\n */\n private async getAdapter(adapterPackage?: string): Promise<ILLM> {\n // No package specified or no loader → use default\n if (!adapterPackage || !this.config.adapterLoader) {\n return this.defaultAdapter;\n }\n\n // Check cache\n const cached = this.adapterCache.get(adapterPackage);\n if (cached) {\n return cached;\n }\n\n // Load and cache\n try {\n const adapter = await this.config.adapterLoader(adapterPackage);\n this.adapterCache.set(adapterPackage, adapter);\n this.logger?.debug(`LLMRouter loaded adapter: ${adapterPackage}`);\n return adapter;\n } catch (error) {\n this.logger?.warn(`LLMRouter failed to load adapter ${adapterPackage}, using default`, {\n error: error instanceof Error ? error.message : String(error),\n });\n return this.defaultAdapter;\n }\n }\n\n /**\n * Ensure current adapter is loaded (async).\n */\n private async ensureAdapter(): Promise<ILLM> {\n if (!this.currentAdapterPackage) {\n return this.defaultAdapter;\n }\n\n const adapter = await this.getAdapter(this.currentAdapterPackage);\n this.currentAdapter = adapter;\n return adapter;\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // ILLMRouter implementation\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Get configured default tier.\n */\n getConfiguredTier(): LLMTier {\n return this.config.defaultTier ?? this.config.tier ?? 'small';\n }\n\n /**\n * Resolve tier request to actual model and adapter.\n */\n resolve(options?: UseLLMOptions): LLMResolution {\n const requestedTier = options?.tier;\n const defaultTier = this.getConfiguredTier();\n\n // Determine which tier to use\n let actualTier: LLMTier;\n let adapted = false;\n let warning: string | undefined;\n\n if (this.config.tierMapping) {\n // With tierMapping: honor requested tier if it has models defined\n const tierToUse = requestedTier ?? defaultTier;\n const hasModels = (this.config.tierMapping[tierToUse]?.length ?? 0) > 0;\n\n if (hasModels) {\n actualTier = tierToUse;\n adapted = requestedTier !== undefined && requestedTier !== defaultTier;\n } else {\n // Fall back to default tier if requested tier has no models\n actualTier = defaultTier;\n adapted = requestedTier !== undefined;\n if (requestedTier && requestedTier !== defaultTier) {\n warning = `Requested '${requestedTier}' tier has no models configured. Using '${actualTier}'.`;\n if (this.logger) {\n this.logger.warn(warning);\n }\n }\n }\n } else {\n // Without tierMapping: use legacy TierResolver logic\n const tierResult = this.tierResolver.resolve(requestedTier);\n actualTier = tierResult.tier;\n adapted = tierResult.adapted;\n warning = tierResult.warning;\n\n if (warning && this.logger) {\n this.logger.warn(warning);\n }\n }\n\n // Get entry for the actual tier\n const entry = this.getEntryForTier(actualTier, options?.capabilities);\n const model = entry?.model;\n const adapterPackage = entry?.adapter;\n const provider = entry ? getProviderFromEntry(entry) : 'default';\n const resource = `llm:${provider}`;\n\n // Update current state for subsequent calls\n this.currentTier = actualTier;\n this.currentProvider = provider;\n this.currentResource = resource;\n if (model) {\n this.currentModel = model;\n this.currentAdapterPackage = adapterPackage;\n if (this.logger) {\n this.logger.debug(\n `LLMRouter resolved: tier=${actualTier}, model=${model}, provider=${provider}, resource=${resource}`\n );\n }\n }\n\n // Check capabilities if requested\n if (options?.capabilities && options.capabilities.length > 0) {\n const missingCaps = options.capabilities.filter(\n (cap) => !this.capabilityResolver.hasCapability(cap)\n );\n\n if (missingCaps.length > 0 && this.logger) {\n this.logger.warn(\n `Requested capabilities [${missingCaps.join(', ')}] may not be available`\n );\n }\n }\n\n return {\n provider,\n model: model ?? 'default',\n resource,\n requestedTier: requestedTier,\n actualTier: actualTier,\n adapted: adapted,\n warning: warning,\n };\n }\n\n /**\n * Check if capability is available.\n */\n hasCapability(capability: LLMCapability): boolean {\n return this.capabilityResolver.hasCapability(capability);\n }\n\n /**\n * Get available capabilities.\n */\n getCapabilities(): LLMCapability[] {\n return this.capabilityResolver.getCapabilities();\n }\n\n /**\n * Resolve tier and return an immutable adapter binding.\n * Does NOT mutate router state — safe for concurrent useLLM() calls.\n */\n async resolveAdapter(options?: UseLLMOptions): Promise<LLMAdapterBinding> {\n const requestedTier = options?.tier;\n const defaultTier = this.getConfiguredTier();\n\n // Determine actualTier without mutating this.*\n let actualTier: LLMTier;\n if (this.config.tierMapping) {\n const tierToUse = requestedTier ?? defaultTier;\n const hasModels = (this.config.tierMapping[tierToUse]?.length ?? 0) > 0;\n if (hasModels) {\n actualTier = tierToUse;\n } else {\n actualTier = defaultTier;\n if (requestedTier && requestedTier !== defaultTier && this.logger) {\n this.logger.warn(\n `resolveAdapter: requested '${requestedTier}' tier has no models. Using '${actualTier}'.`\n );\n }\n }\n } else {\n const tierResult = this.tierResolver.resolve(requestedTier);\n actualTier = tierResult.tier;\n if (tierResult.warning && this.logger) {\n this.logger.warn(tierResult.warning);\n }\n }\n\n const entry = this.getEntryForTier(actualTier, options?.capabilities);\n const model = entry?.model ?? this.currentModel ?? 'default';\n const adapterPackage = entry?.adapter;\n\n const adapter = await this.getAdapter(adapterPackage);\n\n this.logger?.debug(`resolveAdapter: tier=${actualTier}, model=${model}`);\n\n return { adapter, model, tier: actualTier };\n }\n\n /**\n * Get current selected model.\n */\n getCurrentModel(): string | undefined {\n return this.currentModel;\n }\n\n /**\n * Get current adapter package (or undefined for default).\n */\n getCurrentAdapterPackage(): string | undefined {\n return this.currentAdapterPackage;\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // ILLM implementation (delegate to current adapter with model override)\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Merge options with current model and routing metadata.\n * Metadata is used by AnalyticsLLM to track tier/provider/resource.\n */\n private withModelAndMetadata(options?: LLMOptions): LLMOptions {\n const metadata: LLMRequestMetadata = {\n tier: this.currentTier,\n provider: this.currentProvider,\n resource: this.currentResource,\n };\n\n return {\n ...options,\n model: options?.model ?? this.currentModel,\n metadata: {\n ...metadata,\n ...options?.metadata, // Allow override if needed\n },\n };\n }\n\n /**\n * Generate a completion.\n */\n async complete(prompt: string, options?: LLMOptions): Promise<LLMResponse> {\n const adapter = await this.ensureAdapter();\n return adapter.complete(prompt, this.withModelAndMetadata(options));\n }\n\n /**\n * Stream a completion.\n */\n async *stream(prompt: string, options?: LLMOptions): AsyncIterable<string> {\n const adapter = await this.ensureAdapter();\n yield* adapter.stream(prompt, this.withModelAndMetadata(options));\n }\n\n /**\n * Return protocol capabilities of the currently resolved adapter.\n */\n async getProtocolCapabilities(): Promise<LLMProtocolCapabilities> {\n const adapter = await this.ensureAdapter();\n if (!adapter.getProtocolCapabilities) {\n return {\n cache: { supported: false },\n stream: { supported: true },\n };\n }\n return adapter.getProtocolCapabilities();\n }\n\n /**\n * Chat with native tool calling support.\n */\n async chatWithTools(\n messages: LLMMessage[],\n options: LLMToolCallOptions\n ): Promise<LLMToolCallResponse> {\n const adapter = await this.ensureAdapter();\n if (!adapter.chatWithTools) {\n throw new Error('Current adapter does not support chatWithTools');\n }\n return adapter.chatWithTools(messages, this.withModelAndMetadata(options) as LLMToolCallOptions);\n }\n\n /**\n * Check if chatWithTools is supported by current adapter.\n */\n get supportsChatWithTools(): boolean {\n return typeof this.currentAdapter.chatWithTools === 'function';\n }\n}\n","/**\n * @module @kb-labs/llm-router/manifest\n * Adapter manifest for LLM Router.\n */\n\nimport type { AdapterManifest } from '@kb-labs/core-platform';\n\n/**\n * LLM Router adapter manifest.\n */\nexport const manifest: AdapterManifest = {\n manifestVersion: '1.0.0',\n id: 'llm-router',\n name: 'LLM Router',\n version: '0.1.0',\n type: 'proxy', // Wraps/delegates to underlying LLM adapter\n description: 'Adaptive LLM router with tier-based model selection',\n implements: 'ILLM',\n capabilities: {\n streaming: true,\n batch: false,\n },\n // No runtime contexts needed\n contexts: [],\n};\n"]}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/resolver.ts","../src/router.ts","../src/manifest.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @module @kb-labs/llm-router/resolver\n * Tier resolution logic with adaptive escalation/degradation.\n */\n\nimport type { LLMTier, LLMCapability } from '@kb-labs/core-platform';\nimport { TIER_ORDER } from '@kb-labs/core-platform';\n\n/**\n * Resolution result.\n */\nexport interface ResolveResult {\n /** Actual tier to use */\n tier: LLMTier;\n /** Whether adaptation occurred */\n adapted: boolean;\n /** Warning message (only for degradation) */\n warning?: string;\n}\n\n/**\n * Tier resolver with adaptive escalation/degradation.\n *\n * Resolution rules:\n * - Exact match → use as-is\n * - Request lower than configured → escalate silently (small → medium)\n * - Request higher than configured → degrade with warning (large → medium)\n */\nexport class TierResolver {\n private configuredIndex: number;\n\n constructor(private configuredTier: LLMTier) {\n this.configuredIndex = TIER_ORDER.indexOf(configuredTier);\n }\n\n /**\n * Resolve requested tier to actual tier.\n *\n * @param requestedTier - Tier requested by plugin (or undefined for default)\n * @returns Resolution result with actual tier and adaptation info\n */\n resolve(requestedTier?: LLMTier): ResolveResult {\n // No request → use configured default\n if (!requestedTier) {\n return { tier: this.configuredTier, adapted: false };\n }\n\n const requestedIndex = TIER_ORDER.indexOf(requestedTier);\n\n // Exact match\n if (requestedIndex === this.configuredIndex) {\n return { tier: this.configuredTier, adapted: false };\n }\n\n // Escalation: requested < configured (e.g., small → medium)\n // This is fine - plugin asked for less, we give more\n if (requestedIndex < this.configuredIndex) {\n return {\n tier: this.configuredTier,\n adapted: true,\n // No warning - escalation is acceptable\n };\n }\n\n // Degradation: requested > configured (e.g., large → medium)\n // This needs a warning - plugin wanted more than available\n return {\n tier: this.configuredTier,\n adapted: true,\n warning: `Requested '${requestedTier}' tier but only '${this.configuredTier}' available. Using ${this.configuredTier}.`,\n };\n }\n\n /**\n * Get the configured tier.\n */\n getConfiguredTier(): LLMTier {\n return this.configuredTier;\n }\n}\n\n/**\n * Capability resolver.\n *\n * For simple config: assumes all capabilities available.\n * For advanced config: checks against capability mapping.\n */\nexport class CapabilityResolver {\n constructor(private availableCapabilities: Set<LLMCapability> = new Set()) {}\n\n /**\n * Check if capability is available.\n */\n hasCapability(capability: LLMCapability): boolean {\n // If no capabilities configured, assume all available (simple config)\n if (this.availableCapabilities.size === 0) {\n return true;\n }\n return this.availableCapabilities.has(capability);\n }\n\n /**\n * Check if all requested capabilities are available.\n */\n hasAllCapabilities(capabilities: LLMCapability[]): boolean {\n return capabilities.every((cap) => this.hasCapability(cap));\n }\n\n /**\n * Get available capabilities.\n */\n getCapabilities(): LLMCapability[] {\n // If no capabilities configured, return all (simple config)\n if (this.availableCapabilities.size === 0) {\n return ['reasoning', 'coding', 'vision', 'fast'];\n }\n return Array.from(this.availableCapabilities);\n }\n}\n","/**\n * @module @kb-labs/llm-router/router\n * LLM Router - adaptive routing with tier-based model selection.\n * Supports multiple adapters per tier for maximum flexibility.\n */\n\nimport type {\n ILLM,\n LLMOptions,\n LLMResponse,\n LLMMessage,\n LLMToolCallOptions,\n LLMToolCallResponse,\n LLMTier,\n LLMCapability,\n UseLLMOptions,\n LLMResolution,\n LLMAdapterBinding,\n ILLMRouter,\n ILogger,\n LLMRequestMetadata,\n LLMProtocolCapabilities,\n} from '@kb-labs/core-platform';\nimport { TierResolver, CapabilityResolver } from './resolver.js';\n\n/**\n * Model entry in tier mapping.\n * Can optionally specify a different adapter per model.\n */\nexport interface TierModelEntry {\n /** Model identifier */\n model: string;\n /** Priority (lower = higher priority) */\n priority: number;\n /** Model capabilities */\n capabilities?: LLMCapability[];\n /**\n * Provider identifier (e.g., 'openai', 'anthropic', 'vibeproxy').\n * Used to construct resource name: `llm:${provider}`\n */\n provider?: string;\n /**\n * @deprecated Use `provider` instead. Adapter package to use for this model.\n * Will be removed in future versions.\n */\n adapter?: string;\n}\n\n/**\n * Helper to extract provider from entry (supports both new `provider` and legacy `adapter`).\n */\nfunction getProviderFromEntry(entry: TierModelEntry): string {\n // Prefer explicit provider\n if (entry.provider) {\n return entry.provider;\n }\n // Extract from adapter package name: \"@kb-labs/adapters-openai\" → \"openai\"\n // eslint-disable-next-line deprecation/deprecation\n const adapter = entry.adapter;\n if (adapter) {\n const match = adapter.match(/adapters-(\\w+)/);\n if (match?.[1]) {\n return match[1];\n }\n // Fallback: use last segment\n const segments = adapter.split(/[-/]/);\n const lastSegment = segments[segments.length - 1];\n return lastSegment ?? 'default';\n }\n return 'default';\n}\n\n/**\n * Tier mapping configuration.\n */\nexport interface TierMapping {\n small?: TierModelEntry[];\n medium?: TierModelEntry[];\n large?: TierModelEntry[];\n}\n\n/**\n * Function to load an adapter by package name.\n */\nexport type AdapterLoader = (adapterPackage: string) => Promise<ILLM>;\n\n/**\n * LLM Router configuration.\n */\nexport interface LLMRouterConfig {\n /** Default tier when none specified */\n defaultTier: LLMTier;\n /** Tier to model mapping */\n tierMapping?: TierMapping;\n /** Function to load adapters by package name (required for multi-adapter) */\n adapterLoader?: AdapterLoader;\n /** Legacy: single tier (for simple config) */\n tier?: LLMTier;\n /** Legacy: available capabilities */\n capabilities?: LLMCapability[];\n}\n\n/**\n * Resolved entry with adapter and model.\n */\ninterface ResolvedEntry {\n entry: TierModelEntry;\n adapter: ILLM;\n}\n\n/**\n * LLM Router - wraps ILLM adapters with tier-based routing.\n *\n * Features:\n * - Adaptive tier resolution (escalation/degradation)\n * - Model selection from tierMapping\n * - Multi-adapter support (different adapters per tier/model)\n * - Capability-based filtering\n * - Transparent ILLM delegation\n *\n * @example\n * ```typescript\n * // Single adapter (simple)\n * const router = new LLMRouter(openaiAdapter, {\n * defaultTier: 'medium',\n * tierMapping: {\n * small: [{ model: 'gpt-4o-mini', priority: 1 }],\n * medium: [{ model: 'gpt-4o', priority: 1 }],\n * }\n * }, logger);\n *\n * // Multi-adapter (different adapters per tier)\n * const router = new LLMRouter(defaultAdapter, {\n * defaultTier: 'small',\n * tierMapping: {\n * small: [{ adapter: '@kb-labs/adapters-openai', model: 'gpt-4o-mini', priority: 1 }],\n * medium: [{ adapter: '@kb-labs/adapters-vibeproxy', model: 'claude-sonnet-4-5', priority: 1 }],\n * large: [{ adapter: '@kb-labs/adapters-vibeproxy', model: 'claude-opus-4-5', priority: 1 }],\n * },\n * adapterLoader: async (pkg) => loadAdapter(pkg),\n * }, logger);\n * ```\n */\nexport class LLMRouter implements ILLM, ILLMRouter {\n private tierResolver: TierResolver;\n private capabilityResolver: CapabilityResolver;\n private currentModel: string | undefined;\n private currentAdapter: ILLM;\n private currentAdapterPackage: string | undefined;\n /** Current tier for metadata */\n private currentTier: LLMTier;\n /** Current provider for metadata */\n private currentProvider: string = 'default';\n /** Current resource name for metadata */\n private currentResource: string = 'llm:default';\n\n /** Cache of loaded adapters by package name */\n private adapterCache: Map<string, ILLM> = new Map();\n\n constructor(\n private defaultAdapter: ILLM,\n private config: LLMRouterConfig,\n private logger?: ILogger\n ) {\n // Use defaultTier or legacy tier field\n const effectiveTier = config.defaultTier ?? config.tier ?? 'small';\n this.tierResolver = new TierResolver(effectiveTier);\n this.currentTier = effectiveTier;\n\n // Build capabilities from tierMapping or legacy config\n const allCapabilities = this.extractCapabilities();\n this.capabilityResolver = new CapabilityResolver(\n allCapabilities.size > 0 ? allCapabilities : undefined\n );\n\n // Set initial adapter and model from default tier\n this.currentAdapter = defaultAdapter;\n const entry = this.getEntryForTier(effectiveTier);\n if (entry) {\n this.currentModel = entry.model;\n // eslint-disable-next-line deprecation/deprecation\n this.currentAdapterPackage = entry.adapter;\n this.currentProvider = getProviderFromEntry(entry);\n this.currentResource = `llm:${this.currentProvider}`;\n }\n\n if (this.logger && this.currentModel) {\n this.logger.debug(\n `LLMRouter initialized: model=${this.currentModel}, provider=${this.currentProvider}`\n );\n }\n }\n\n /**\n * Extract all capabilities from tierMapping.\n */\n private extractCapabilities(): Set<LLMCapability> {\n const caps = new Set<LLMCapability>();\n\n if (this.config.tierMapping) {\n for (const entries of Object.values(this.config.tierMapping)) {\n if (entries) {\n for (const entry of entries) {\n if (entry.capabilities) {\n entry.capabilities.forEach((c: LLMCapability) => caps.add(c));\n }\n }\n }\n }\n }\n\n // Include legacy capabilities\n if (this.config.capabilities) {\n this.config.capabilities.forEach((c) => caps.add(c));\n }\n\n return caps;\n }\n\n /**\n * Get entry for a given tier (highest priority).\n */\n private getEntryForTier(\n tier: LLMTier,\n requiredCapabilities?: LLMCapability[]\n ): TierModelEntry | undefined {\n if (!this.config.tierMapping) {\n return undefined;\n }\n\n const entries = this.config.tierMapping[tier];\n if (!entries || entries.length === 0) {\n return undefined;\n }\n\n // Sort by priority (lower = higher priority)\n const sorted = [...entries].sort((a, b) => a.priority - b.priority);\n\n // If capabilities required, filter\n if (requiredCapabilities && requiredCapabilities.length > 0) {\n const matching = sorted.find((entry) =>\n requiredCapabilities.every((cap) => entry.capabilities?.includes(cap))\n );\n if (matching) {\n return matching;\n }\n }\n\n // Return first entry (highest priority)\n return sorted[0];\n }\n\n /**\n * Get adapter for a given package (from cache or load).\n */\n private async getAdapter(adapterPackage?: string): Promise<ILLM> {\n // No package specified or no loader → use default\n if (!adapterPackage || !this.config.adapterLoader) {\n return this.defaultAdapter;\n }\n\n // Check cache\n const cached = this.adapterCache.get(adapterPackage);\n if (cached) {\n return cached;\n }\n\n // Load and cache\n try {\n const adapter = await this.config.adapterLoader(adapterPackage);\n this.adapterCache.set(adapterPackage, adapter);\n this.logger?.debug(`LLMRouter loaded adapter: ${adapterPackage}`);\n return adapter;\n } catch (error) {\n this.logger?.warn(`LLMRouter failed to load adapter ${adapterPackage}, using default`, {\n error: error instanceof Error ? error.message : String(error),\n });\n return this.defaultAdapter;\n }\n }\n\n /**\n * Ensure current adapter is loaded (async).\n */\n private async ensureAdapter(): Promise<ILLM> {\n if (!this.currentAdapterPackage) {\n return this.defaultAdapter;\n }\n\n const adapter = await this.getAdapter(this.currentAdapterPackage);\n this.currentAdapter = adapter;\n return adapter;\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // ILLMRouter implementation\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Get configured default tier.\n */\n getConfiguredTier(): LLMTier {\n return this.config.defaultTier ?? this.config.tier ?? 'small';\n }\n\n /**\n * Resolve tier request to actual model and adapter.\n */\n resolve(options?: UseLLMOptions): LLMResolution {\n const requestedTier = options?.tier;\n const defaultTier = this.getConfiguredTier();\n\n // Determine which tier to use\n let actualTier: LLMTier;\n let adapted = false;\n let warning: string | undefined;\n\n if (this.config.tierMapping) {\n // With tierMapping: honor requested tier if it has models defined\n const tierToUse = requestedTier ?? defaultTier;\n const hasModels = (this.config.tierMapping[tierToUse]?.length ?? 0) > 0;\n\n if (hasModels) {\n actualTier = tierToUse;\n adapted = requestedTier !== undefined && requestedTier !== defaultTier;\n } else {\n // Fall back to default tier if requested tier has no models\n actualTier = defaultTier;\n adapted = requestedTier !== undefined;\n if (requestedTier && requestedTier !== defaultTier) {\n warning = `Requested '${requestedTier}' tier has no models configured. Using '${actualTier}'.`;\n if (this.logger) {\n this.logger.warn(warning);\n }\n }\n }\n } else {\n // Without tierMapping: use legacy TierResolver logic\n const tierResult = this.tierResolver.resolve(requestedTier);\n actualTier = tierResult.tier;\n adapted = tierResult.adapted;\n warning = tierResult.warning;\n\n if (warning && this.logger) {\n this.logger.warn(warning);\n }\n }\n\n // Get entry for the actual tier\n const entry = this.getEntryForTier(actualTier, options?.capabilities);\n const model = entry?.model;\n // eslint-disable-next-line deprecation/deprecation\n const adapterPackage = entry?.adapter;\n const provider = entry ? getProviderFromEntry(entry) : 'default';\n const resource = `llm:${provider}`;\n\n // Update current state for subsequent calls\n this.currentTier = actualTier;\n this.currentProvider = provider;\n this.currentResource = resource;\n if (model) {\n this.currentModel = model;\n this.currentAdapterPackage = adapterPackage;\n if (this.logger) {\n this.logger.debug(\n `LLMRouter resolved: tier=${actualTier}, model=${model}, provider=${provider}, resource=${resource}`\n );\n }\n }\n\n // Check capabilities if requested\n if (options?.capabilities && options.capabilities.length > 0) {\n const missingCaps = options.capabilities.filter(\n (cap) => !this.capabilityResolver.hasCapability(cap)\n );\n\n if (missingCaps.length > 0 && this.logger) {\n this.logger.warn(\n `Requested capabilities [${missingCaps.join(', ')}] may not be available`\n );\n }\n }\n\n return {\n provider,\n model: model ?? 'default',\n resource,\n requestedTier: requestedTier,\n actualTier: actualTier,\n adapted: adapted,\n warning: warning,\n };\n }\n\n /**\n * Check if capability is available.\n */\n hasCapability(capability: LLMCapability): boolean {\n return this.capabilityResolver.hasCapability(capability);\n }\n\n /**\n * Get available capabilities.\n */\n getCapabilities(): LLMCapability[] {\n return this.capabilityResolver.getCapabilities();\n }\n\n /**\n * Resolve tier and return an immutable adapter binding.\n * Does NOT mutate router state — safe for concurrent useLLM() calls.\n */\n async resolveAdapter(options?: UseLLMOptions): Promise<LLMAdapterBinding> {\n const requestedTier = options?.tier;\n const defaultTier = this.getConfiguredTier();\n\n // Determine actualTier without mutating this.*\n let actualTier: LLMTier;\n if (this.config.tierMapping) {\n const tierToUse = requestedTier ?? defaultTier;\n const hasModels = (this.config.tierMapping[tierToUse]?.length ?? 0) > 0;\n if (hasModels) {\n actualTier = tierToUse;\n } else {\n actualTier = defaultTier;\n if (requestedTier && requestedTier !== defaultTier && this.logger) {\n this.logger.warn(\n `resolveAdapter: requested '${requestedTier}' tier has no models. Using '${actualTier}'.`\n );\n }\n }\n } else {\n const tierResult = this.tierResolver.resolve(requestedTier);\n actualTier = tierResult.tier;\n if (tierResult.warning && this.logger) {\n this.logger.warn(tierResult.warning);\n }\n }\n\n const entry = this.getEntryForTier(actualTier, options?.capabilities);\n const model = entry?.model ?? this.currentModel ?? 'default';\n // eslint-disable-next-line deprecation/deprecation\n const adapterPackage = entry?.adapter;\n\n const adapter = await this.getAdapter(adapterPackage);\n\n this.logger?.debug(`resolveAdapter: tier=${actualTier}, model=${model}`);\n\n return { adapter, model, tier: actualTier };\n }\n\n /**\n * Get current selected model.\n */\n getCurrentModel(): string | undefined {\n return this.currentModel;\n }\n\n /**\n * Get current adapter package (or undefined for default).\n */\n getCurrentAdapterPackage(): string | undefined {\n return this.currentAdapterPackage;\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // ILLM implementation (delegate to current adapter with model override)\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Merge options with current model and routing metadata.\n * Metadata is used by AnalyticsLLM to track tier/provider/resource.\n */\n private withModelAndMetadata(options?: LLMOptions): LLMOptions {\n const metadata: LLMRequestMetadata = {\n tier: this.currentTier,\n provider: this.currentProvider,\n resource: this.currentResource,\n };\n\n return {\n ...options,\n model: options?.model ?? this.currentModel,\n metadata: {\n ...metadata,\n ...options?.metadata, // Allow override if needed\n },\n };\n }\n\n /**\n * Generate a completion.\n */\n async complete(prompt: string, options?: LLMOptions): Promise<LLMResponse> {\n const adapter = await this.ensureAdapter();\n return adapter.complete(prompt, this.withModelAndMetadata(options));\n }\n\n /**\n * Stream a completion.\n */\n async *stream(prompt: string, options?: LLMOptions): AsyncIterable<string> {\n const adapter = await this.ensureAdapter();\n yield* adapter.stream(prompt, this.withModelAndMetadata(options));\n }\n\n /**\n * Return protocol capabilities of the currently resolved adapter.\n */\n async getProtocolCapabilities(): Promise<LLMProtocolCapabilities> {\n const adapter = await this.ensureAdapter();\n if (!adapter.getProtocolCapabilities) {\n return {\n cache: { supported: false },\n stream: { supported: true },\n };\n }\n return adapter.getProtocolCapabilities();\n }\n\n /**\n * Chat with native tool calling support.\n */\n async chatWithTools(\n messages: LLMMessage[],\n options: LLMToolCallOptions\n ): Promise<LLMToolCallResponse> {\n const adapter = await this.ensureAdapter();\n if (!adapter.chatWithTools) {\n throw new Error('Current adapter does not support chatWithTools');\n }\n return adapter.chatWithTools(messages, this.withModelAndMetadata(options) as LLMToolCallOptions);\n }\n\n /**\n * Check if chatWithTools is supported by current adapter.\n */\n get supportsChatWithTools(): boolean {\n return typeof this.currentAdapter.chatWithTools === 'function';\n }\n}\n","/**\n * @module @kb-labs/llm-router/manifest\n * Adapter manifest for LLM Router.\n */\n\nimport type { AdapterManifest } from '@kb-labs/core-platform';\n\n/**\n * LLM Router adapter manifest.\n */\nexport const manifest: AdapterManifest = {\n manifestVersion: '1.0.0',\n id: 'llm-router',\n name: 'LLM Router',\n version: '0.1.0',\n type: 'proxy', // Wraps/delegates to underlying LLM adapter\n description: 'Adaptive LLM router with tier-based model selection',\n implements: 'ILLM',\n capabilities: {\n streaming: true,\n batch: false,\n },\n // No runtime contexts needed\n contexts: [],\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/resolver.ts","../src/router.ts","../src/manifest.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @module @kb-labs/llm-router/resolver\n * Tier resolution logic with adaptive escalation/degradation.\n */\n\nimport type { LLMTier, LLMCapability } from '@kb-labs/core-platform';\nimport { TIER_ORDER } from '@kb-labs/core-platform';\n\n/**\n * Resolution result.\n */\nexport interface ResolveResult {\n /** Actual tier to use */\n tier: LLMTier;\n /** Whether adaptation occurred */\n adapted: boolean;\n /** Warning message (only for degradation) */\n warning?: string;\n}\n\n/**\n * Tier resolver with adaptive escalation/degradation.\n *\n * Resolution rules:\n * - Exact match → use as-is\n * - Request lower than configured → escalate silently (small → medium)\n * - Request higher than configured → degrade with warning (large → medium)\n */\nexport class TierResolver {\n private configuredIndex: number;\n\n constructor(private configuredTier: LLMTier) {\n this.configuredIndex = TIER_ORDER.indexOf(configuredTier);\n }\n\n /**\n * Resolve requested tier to actual tier.\n *\n * @param requestedTier - Tier requested by plugin (or undefined for default)\n * @returns Resolution result with actual tier and adaptation info\n */\n resolve(requestedTier?: LLMTier): ResolveResult {\n // No request → use configured default\n if (!requestedTier) {\n return { tier: this.configuredTier, adapted: false };\n }\n\n const requestedIndex = TIER_ORDER.indexOf(requestedTier);\n\n // Exact match\n if (requestedIndex === this.configuredIndex) {\n return { tier: this.configuredTier, adapted: false };\n }\n\n // Escalation: requested < configured (e.g., small → medium)\n // This is fine - plugin asked for less, we give more\n if (requestedIndex < this.configuredIndex) {\n return {\n tier: this.configuredTier,\n adapted: true,\n // No warning - escalation is acceptable\n };\n }\n\n // Degradation: requested > configured (e.g., large → medium)\n // This needs a warning - plugin wanted more than available\n return {\n tier: this.configuredTier,\n adapted: true,\n warning: `Requested '${requestedTier}' tier but only '${this.configuredTier}' available. Using ${this.configuredTier}.`,\n };\n }\n\n /**\n * Get the configured tier.\n */\n getConfiguredTier(): LLMTier {\n return this.configuredTier;\n }\n}\n\n/**\n * Capability resolver.\n *\n * For simple config: assumes all capabilities available.\n * For advanced config: checks against capability mapping.\n */\nexport class CapabilityResolver {\n constructor(private availableCapabilities: Set<LLMCapability> = new Set()) {}\n\n /**\n * Check if capability is available.\n */\n hasCapability(capability: LLMCapability): boolean {\n // If no capabilities configured, assume all available (simple config)\n if (this.availableCapabilities.size === 0) {\n return true;\n }\n return this.availableCapabilities.has(capability);\n }\n\n /**\n * Check if all requested capabilities are available.\n */\n hasAllCapabilities(capabilities: LLMCapability[]): boolean {\n return capabilities.every((cap) => this.hasCapability(cap));\n }\n\n /**\n * Get available capabilities.\n */\n getCapabilities(): LLMCapability[] {\n // If no capabilities configured, return all (simple config)\n if (this.availableCapabilities.size === 0) {\n return ['reasoning', 'coding', 'vision', 'fast'];\n }\n return Array.from(this.availableCapabilities);\n }\n}\n","/**\n * @module @kb-labs/llm-router/router\n * LLM Router - adaptive routing with tier-based model selection.\n * Supports multiple adapters per tier for maximum flexibility.\n */\n\nimport type {\n ILLM,\n LLMOptions,\n LLMResponse,\n LLMMessage,\n LLMToolCallOptions,\n LLMToolCallResponse,\n LLMTier,\n LLMCapability,\n UseLLMOptions,\n LLMResolution,\n LLMAdapterBinding,\n ILLMRouter,\n ILogger,\n LLMRequestMetadata,\n LLMProtocolCapabilities,\n} from '@kb-labs/core-platform';\nimport { TierResolver, CapabilityResolver } from './resolver.js';\n\n/**\n * Model entry in tier mapping.\n * Can optionally specify a different adapter per model.\n */\nexport interface TierModelEntry {\n /** Model identifier */\n model: string;\n /** Priority (lower = higher priority) */\n priority: number;\n /** Model capabilities */\n capabilities?: LLMCapability[];\n /**\n * Provider identifier (e.g., 'openai', 'anthropic', 'vibeproxy').\n * Used to construct resource name: `llm:${provider}`\n */\n provider?: string;\n /**\n * @deprecated Use `provider` instead. Adapter package to use for this model.\n * Will be removed in future versions.\n */\n adapter?: string;\n}\n\n/**\n * Helper to extract provider from entry (supports both new `provider` and legacy `adapter`).\n */\nfunction getProviderFromEntry(entry: TierModelEntry): string {\n // Prefer explicit provider\n if (entry.provider) {\n return entry.provider;\n }\n // Extract from adapter package name: \"@kb-labs/adapters-openai\" → \"openai\"\n const adapter = entry.adapter;\n if (adapter) {\n const match = adapter.match(/adapters-(\\w+)/);\n if (match?.[1]) {\n return match[1];\n }\n // Fallback: use last segment\n const segments = adapter.split(/[-/]/);\n const lastSegment = segments[segments.length - 1];\n return lastSegment ?? 'default';\n }\n return 'default';\n}\n\n/**\n * Tier mapping configuration.\n */\nexport interface TierMapping {\n small?: TierModelEntry[];\n medium?: TierModelEntry[];\n large?: TierModelEntry[];\n}\n\n/**\n * Function to load an adapter by package name.\n */\nexport type AdapterLoader = (adapterPackage: string) => Promise<ILLM>;\n\n/**\n * LLM Router configuration.\n */\nexport interface LLMRouterConfig {\n /** Default tier when none specified */\n defaultTier: LLMTier;\n /** Tier to model mapping */\n tierMapping?: TierMapping;\n /** Function to load adapters by package name (required for multi-adapter) */\n adapterLoader?: AdapterLoader;\n /** Legacy: single tier (for simple config) */\n tier?: LLMTier;\n /** Legacy: available capabilities */\n capabilities?: LLMCapability[];\n}\n\n/**\n * Resolved entry with adapter and model.\n */\ninterface ResolvedEntry {\n entry: TierModelEntry;\n adapter: ILLM;\n}\n\n/**\n * LLM Router - wraps ILLM adapters with tier-based routing.\n *\n * Features:\n * - Adaptive tier resolution (escalation/degradation)\n * - Model selection from tierMapping\n * - Multi-adapter support (different adapters per tier/model)\n * - Capability-based filtering\n * - Transparent ILLM delegation\n *\n * @example\n * ```typescript\n * // Single adapter (simple)\n * const router = new LLMRouter(openaiAdapter, {\n * defaultTier: 'medium',\n * tierMapping: {\n * small: [{ model: 'gpt-4o-mini', priority: 1 }],\n * medium: [{ model: 'gpt-4o', priority: 1 }],\n * }\n * }, logger);\n *\n * // Multi-adapter (different adapters per tier)\n * const router = new LLMRouter(defaultAdapter, {\n * defaultTier: 'small',\n * tierMapping: {\n * small: [{ adapter: '@kb-labs/adapters-openai', model: 'gpt-4o-mini', priority: 1 }],\n * medium: [{ adapter: '@kb-labs/adapters-vibeproxy', model: 'claude-sonnet-4-5', priority: 1 }],\n * large: [{ adapter: '@kb-labs/adapters-vibeproxy', model: 'claude-opus-4-5', priority: 1 }],\n * },\n * adapterLoader: async (pkg) => loadAdapter(pkg),\n * }, logger);\n * ```\n */\nexport class LLMRouter implements ILLM, ILLMRouter {\n private tierResolver: TierResolver;\n private capabilityResolver: CapabilityResolver;\n private currentModel: string | undefined;\n private currentAdapter: ILLM;\n private currentAdapterPackage: string | undefined;\n /** Current tier for metadata */\n private currentTier: LLMTier;\n /** Current provider for metadata */\n private currentProvider: string = 'default';\n /** Current resource name for metadata */\n private currentResource: string = 'llm:default';\n\n /** Cache of loaded adapters by package name */\n private adapterCache: Map<string, ILLM> = new Map();\n\n constructor(\n private defaultAdapter: ILLM,\n private config: LLMRouterConfig,\n private logger?: ILogger\n ) {\n // Use defaultTier or legacy tier field\n const effectiveTier = config.defaultTier ?? config.tier ?? 'small';\n this.tierResolver = new TierResolver(effectiveTier);\n this.currentTier = effectiveTier;\n\n // Build capabilities from tierMapping or legacy config\n const allCapabilities = this.extractCapabilities();\n this.capabilityResolver = new CapabilityResolver(\n allCapabilities.size > 0 ? allCapabilities : undefined\n );\n\n // Set initial adapter and model from default tier\n this.currentAdapter = defaultAdapter;\n const entry = this.getEntryForTier(effectiveTier);\n if (entry) {\n this.currentModel = entry.model;\n this.currentAdapterPackage = entry.adapter;\n this.currentProvider = getProviderFromEntry(entry);\n this.currentResource = `llm:${this.currentProvider}`;\n }\n\n if (this.logger && this.currentModel) {\n this.logger.debug(\n `LLMRouter initialized: model=${this.currentModel}, provider=${this.currentProvider}`\n );\n }\n }\n\n /**\n * Extract all capabilities from tierMapping.\n */\n private extractCapabilities(): Set<LLMCapability> {\n const caps = new Set<LLMCapability>();\n\n if (this.config.tierMapping) {\n for (const entries of Object.values(this.config.tierMapping)) {\n if (entries) {\n for (const entry of entries) {\n if (entry.capabilities) {\n entry.capabilities.forEach((c: LLMCapability) => caps.add(c));\n }\n }\n }\n }\n }\n\n // Include legacy capabilities\n if (this.config.capabilities) {\n this.config.capabilities.forEach((c) => caps.add(c));\n }\n\n return caps;\n }\n\n /**\n * Get entry for a given tier (highest priority).\n */\n private getEntryForTier(\n tier: LLMTier,\n requiredCapabilities?: LLMCapability[]\n ): TierModelEntry | undefined {\n if (!this.config.tierMapping) {\n return undefined;\n }\n\n const entries = this.config.tierMapping[tier];\n if (!entries || entries.length === 0) {\n return undefined;\n }\n\n // Sort by priority (lower = higher priority)\n const sorted = [...entries].sort((a, b) => a.priority - b.priority);\n\n // If capabilities required, filter\n if (requiredCapabilities && requiredCapabilities.length > 0) {\n const matching = sorted.find((entry) =>\n requiredCapabilities.every((cap) => entry.capabilities?.includes(cap))\n );\n if (matching) {\n return matching;\n }\n }\n\n // Return first entry (highest priority)\n return sorted[0];\n }\n\n /**\n * Get adapter for a given package (from cache or load).\n */\n private async getAdapter(adapterPackage?: string): Promise<ILLM> {\n // No package specified or no loader → use default\n if (!adapterPackage || !this.config.adapterLoader) {\n return this.defaultAdapter;\n }\n\n // Check cache\n const cached = this.adapterCache.get(adapterPackage);\n if (cached) {\n return cached;\n }\n\n // Load and cache\n try {\n const adapter = await this.config.adapterLoader(adapterPackage);\n this.adapterCache.set(adapterPackage, adapter);\n this.logger?.debug(`LLMRouter loaded adapter: ${adapterPackage}`);\n return adapter;\n } catch (error) {\n this.logger?.warn(`LLMRouter failed to load adapter ${adapterPackage}, using default`, {\n error: error instanceof Error ? error.message : String(error),\n });\n return this.defaultAdapter;\n }\n }\n\n /**\n * Ensure current adapter is loaded (async).\n */\n private async ensureAdapter(): Promise<ILLM> {\n if (!this.currentAdapterPackage) {\n return this.defaultAdapter;\n }\n\n const adapter = await this.getAdapter(this.currentAdapterPackage);\n this.currentAdapter = adapter;\n return adapter;\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // ILLMRouter implementation\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Get configured default tier.\n */\n getConfiguredTier(): LLMTier {\n return this.config.defaultTier ?? this.config.tier ?? 'small';\n }\n\n /**\n * Resolve tier request to actual model and adapter.\n */\n resolve(options?: UseLLMOptions): LLMResolution {\n const requestedTier = options?.tier;\n const defaultTier = this.getConfiguredTier();\n\n // Determine which tier to use\n let actualTier: LLMTier;\n let adapted = false;\n let warning: string | undefined;\n\n if (this.config.tierMapping) {\n // With tierMapping: honor requested tier if it has models defined\n const tierToUse = requestedTier ?? defaultTier;\n const hasModels = (this.config.tierMapping[tierToUse]?.length ?? 0) > 0;\n\n if (hasModels) {\n actualTier = tierToUse;\n adapted = requestedTier !== undefined && requestedTier !== defaultTier;\n } else {\n // Fall back to default tier if requested tier has no models\n actualTier = defaultTier;\n adapted = requestedTier !== undefined;\n if (requestedTier && requestedTier !== defaultTier) {\n warning = `Requested '${requestedTier}' tier has no models configured. Using '${actualTier}'.`;\n if (this.logger) {\n this.logger.warn(warning);\n }\n }\n }\n } else {\n // Without tierMapping: use legacy TierResolver logic\n const tierResult = this.tierResolver.resolve(requestedTier);\n actualTier = tierResult.tier;\n adapted = tierResult.adapted;\n warning = tierResult.warning;\n\n if (warning && this.logger) {\n this.logger.warn(warning);\n }\n }\n\n // Get entry for the actual tier\n const entry = this.getEntryForTier(actualTier, options?.capabilities);\n const model = entry?.model;\n const adapterPackage = entry?.adapter;\n const provider = entry ? getProviderFromEntry(entry) : 'default';\n const resource = `llm:${provider}`;\n\n // Update current state for subsequent calls\n this.currentTier = actualTier;\n this.currentProvider = provider;\n this.currentResource = resource;\n if (model) {\n this.currentModel = model;\n this.currentAdapterPackage = adapterPackage;\n if (this.logger) {\n this.logger.debug(\n `LLMRouter resolved: tier=${actualTier}, model=${model}, provider=${provider}, resource=${resource}`\n );\n }\n }\n\n // Check capabilities if requested\n if (options?.capabilities && options.capabilities.length > 0) {\n const missingCaps = options.capabilities.filter(\n (cap) => !this.capabilityResolver.hasCapability(cap)\n );\n\n if (missingCaps.length > 0 && this.logger) {\n this.logger.warn(\n `Requested capabilities [${missingCaps.join(', ')}] may not be available`\n );\n }\n }\n\n return {\n provider,\n model: model ?? 'default',\n resource,\n requestedTier: requestedTier,\n actualTier: actualTier,\n adapted: adapted,\n warning: warning,\n };\n }\n\n /**\n * Check if capability is available.\n */\n hasCapability(capability: LLMCapability): boolean {\n return this.capabilityResolver.hasCapability(capability);\n }\n\n /**\n * Get available capabilities.\n */\n getCapabilities(): LLMCapability[] {\n return this.capabilityResolver.getCapabilities();\n }\n\n /**\n * Resolve tier and return an immutable adapter binding.\n * Does NOT mutate router state — safe for concurrent useLLM() calls.\n */\n async resolveAdapter(options?: UseLLMOptions): Promise<LLMAdapterBinding> {\n const requestedTier = options?.tier;\n const defaultTier = this.getConfiguredTier();\n\n // Determine actualTier without mutating this.*\n let actualTier: LLMTier;\n if (this.config.tierMapping) {\n const tierToUse = requestedTier ?? defaultTier;\n const hasModels = (this.config.tierMapping[tierToUse]?.length ?? 0) > 0;\n if (hasModels) {\n actualTier = tierToUse;\n } else {\n actualTier = defaultTier;\n if (requestedTier && requestedTier !== defaultTier && this.logger) {\n this.logger.warn(\n `resolveAdapter: requested '${requestedTier}' tier has no models. Using '${actualTier}'.`\n );\n }\n }\n } else {\n const tierResult = this.tierResolver.resolve(requestedTier);\n actualTier = tierResult.tier;\n if (tierResult.warning && this.logger) {\n this.logger.warn(tierResult.warning);\n }\n }\n\n const entry = this.getEntryForTier(actualTier, options?.capabilities);\n const model = entry?.model ?? this.currentModel ?? 'default';\n const adapterPackage = entry?.adapter;\n\n const adapter = await this.getAdapter(adapterPackage);\n\n this.logger?.debug(`resolveAdapter: tier=${actualTier}, model=${model}`);\n\n return { adapter, model, tier: actualTier };\n }\n\n /**\n * Get current selected model.\n */\n getCurrentModel(): string | undefined {\n return this.currentModel;\n }\n\n /**\n * Get current adapter package (or undefined for default).\n */\n getCurrentAdapterPackage(): string | undefined {\n return this.currentAdapterPackage;\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // ILLM implementation (delegate to current adapter with model override)\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Merge options with current model and routing metadata.\n * Metadata is used by AnalyticsLLM to track tier/provider/resource.\n */\n private withModelAndMetadata(options?: LLMOptions): LLMOptions {\n const metadata: LLMRequestMetadata = {\n tier: this.currentTier,\n provider: this.currentProvider,\n resource: this.currentResource,\n };\n\n return {\n ...options,\n model: options?.model ?? this.currentModel,\n metadata: {\n ...metadata,\n ...options?.metadata, // Allow override if needed\n },\n };\n }\n\n /**\n * Generate a completion.\n */\n async complete(prompt: string, options?: LLMOptions): Promise<LLMResponse> {\n const adapter = await this.ensureAdapter();\n return adapter.complete(prompt, this.withModelAndMetadata(options));\n }\n\n /**\n * Stream a completion.\n */\n async *stream(prompt: string, options?: LLMOptions): AsyncIterable<string> {\n const adapter = await this.ensureAdapter();\n yield* adapter.stream(prompt, this.withModelAndMetadata(options));\n }\n\n /**\n * Return protocol capabilities of the currently resolved adapter.\n */\n async getProtocolCapabilities(): Promise<LLMProtocolCapabilities> {\n const adapter = await this.ensureAdapter();\n if (!adapter.getProtocolCapabilities) {\n return {\n cache: { supported: false },\n stream: { supported: true },\n };\n }\n return adapter.getProtocolCapabilities();\n }\n\n /**\n * Chat with native tool calling support.\n */\n async chatWithTools(\n messages: LLMMessage[],\n options: LLMToolCallOptions\n ): Promise<LLMToolCallResponse> {\n const adapter = await this.ensureAdapter();\n if (!adapter.chatWithTools) {\n throw new Error('Current adapter does not support chatWithTools');\n }\n return adapter.chatWithTools(messages, this.withModelAndMetadata(options) as LLMToolCallOptions);\n }\n\n /**\n * Check if chatWithTools is supported by current adapter.\n */\n get supportsChatWithTools(): boolean {\n return typeof this.currentAdapter.chatWithTools === 'function';\n }\n}\n","/**\n * @module @kb-labs/llm-router/manifest\n * Adapter manifest for LLM Router.\n */\n\nimport type { AdapterManifest } from '@kb-labs/core-platform';\n\n/**\n * LLM Router adapter manifest.\n */\nexport const manifest: AdapterManifest = {\n manifestVersion: '1.0.0',\n id: 'llm-router',\n name: 'LLM Router',\n version: '0.1.0',\n type: 'proxy', // Wraps/delegates to underlying LLM adapter\n description: 'Adaptive LLM router with tier-based model selection',\n implements: 'ILLM',\n capabilities: {\n streaming: true,\n batch: false,\n },\n // No runtime contexts needed\n contexts: [],\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kb-labs/llm-router",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Adaptive LLM router with tier-based model selection and fallback support.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -16,15 +16,26 @@
|
|
|
16
16
|
"files": [
|
|
17
17
|
"dist"
|
|
18
18
|
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup",
|
|
21
|
+
"clean": "rimraf dist",
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"test": "vitest run --passWithNoTests",
|
|
24
|
+
"test:watch": "vitest",
|
|
25
|
+
"dev": "tsup --config tsup.config.ts --watch",
|
|
26
|
+
"lint": "eslint src --ext .ts",
|
|
27
|
+
"lint:fix": "eslint . --fix",
|
|
28
|
+
"type-check": "tsc --noEmit"
|
|
29
|
+
},
|
|
19
30
|
"dependencies": {
|
|
20
|
-
"@kb-labs/core-platform": "
|
|
31
|
+
"@kb-labs/core-platform": "workspace:*"
|
|
21
32
|
},
|
|
22
33
|
"devDependencies": {
|
|
23
34
|
"tsup": "^8.5.0",
|
|
24
35
|
"typescript": "^5.6.3",
|
|
25
36
|
"rimraf": "^6.0.1",
|
|
26
37
|
"vitest": "^3.2.4",
|
|
27
|
-
"@kb-labs/devkit": "
|
|
38
|
+
"@kb-labs/devkit": "^1.0.0",
|
|
28
39
|
"@types/node": "^24.3.3"
|
|
29
40
|
},
|
|
30
41
|
"keywords": [
|
|
@@ -47,16 +58,5 @@
|
|
|
47
58
|
},
|
|
48
59
|
"publishConfig": {
|
|
49
60
|
"access": "public"
|
|
50
|
-
},
|
|
51
|
-
"scripts": {
|
|
52
|
-
"build": "tsup",
|
|
53
|
-
"clean": "rimraf dist",
|
|
54
|
-
"typecheck": "tsc --noEmit",
|
|
55
|
-
"test": "vitest run --passWithNoTests",
|
|
56
|
-
"test:watch": "vitest",
|
|
57
|
-
"dev": "tsup --config tsup.config.ts --watch",
|
|
58
|
-
"lint": "eslint src --ext .ts",
|
|
59
|
-
"lint:fix": "eslint . --fix",
|
|
60
|
-
"type-check": "tsc --noEmit"
|
|
61
61
|
}
|
|
62
|
-
}
|
|
62
|
+
}
|