diff --git a/packages/types/src/__tests__/provider-identifiers.test.ts b/packages/types/src/__tests__/provider-identifiers.test.ts index 477f26dc1..11f9d90cc 100644 --- a/packages/types/src/__tests__/provider-identifiers.test.ts +++ b/packages/types/src/__tests__/provider-identifiers.test.ts @@ -1,6 +1,16 @@ import { + customProviders, + dynamicProviders, + fauxProviders, + internalProviders, + isCustomProvider, + isDynamicProvider, + isFauxProvider, + isInternalProvider, + isLocalProvider, isProviderName, isRetiredProvider, + localProviders, providerIdentifiers, providerNames, providerNamesSchema, @@ -81,6 +91,75 @@ describe("provider identifiers", () => { expect(retiredProviderNames).toEqual(retiredIdentifiers) }) + it("derives provider category collections from canonical identifiers", () => { + expect(dynamicProviders).toEqual([ + providerIdentifiers.openrouter, + providerIdentifiers.vercelAiGateway, + providerIdentifiers.zooGateway, + providerIdentifiers.litellm, + providerIdentifiers.requesty, + providerIdentifiers.unbound, + providerIdentifiers.poe, + providerIdentifiers.deepseek, + providerIdentifiers.moonshot, + providerIdentifiers.opencodeGo, + providerIdentifiers.kenari, + ]) + expect(localProviders).toEqual([providerIdentifiers.ollama, providerIdentifiers.lmstudio]) + expect(internalProviders).toEqual([providerIdentifiers.vscodeLm]) + expect(customProviders).toEqual([providerIdentifiers.openai]) + expect(fauxProviders).toEqual([providerIdentifiers.fakeAi]) + }) + + it("preserves provider category type guards", () => { + for (const identifier of dynamicProviders) { + expect(isDynamicProvider(identifier)).toBe(true) + } + + for (const identifier of localProviders) { + expect(isLocalProvider(identifier)).toBe(true) + } + + for (const identifier of internalProviders) { + expect(isInternalProvider(identifier)).toBe(true) + } + + for (const identifier of customProviders) { + expect(isCustomProvider(identifier)).toBe(true) + } + + for (const identifier of fauxProviders) { + expect(isFauxProvider(identifier)).toBe(true) + } + + expect(isDynamicProvider("unknown-provider")).toBe(false) + expect(isLocalProvider("unknown-provider")).toBe(false) + expect(isInternalProvider("unknown-provider")).toBe(false) + expect(isCustomProvider("unknown-provider")).toBe(false) + expect(isFauxProvider("unknown-provider")).toBe(false) + + const categoryRepresentatives = [ + providerIdentifiers.openrouter, + providerIdentifiers.ollama, + providerIdentifiers.vscodeLm, + providerIdentifiers.openai, + providerIdentifiers.fakeAi, + ] + const categoryGuards = [ + isDynamicProvider, + isLocalProvider, + isInternalProvider, + isCustomProvider, + isFauxProvider, + ] + + for (const [guardIndex, guard] of categoryGuards.entries()) { + for (const [identifierIndex, identifier] of categoryRepresentatives.entries()) { + expect(guard(identifier)).toBe(guardIndex === identifierIndex) + } + } + }) + it("keeps active and retired providers separate", () => { const activeIdentifiers = new Set(Object.values(providerIdentifiers)) const retiredIdentifiers = Object.values(retiredProviderIdentifiers) diff --git a/packages/types/src/provider-settings.ts b/packages/types/src/provider-settings.ts index c9b7c0104..194273f94 100644 --- a/packages/types/src/provider-settings.ts +++ b/packages/types/src/provider-settings.ts @@ -44,17 +44,17 @@ export const DEFAULT_CONSECUTIVE_MISTAKE_LIMIT = 3 */ export const dynamicProviders = [ - "openrouter", - "vercel-ai-gateway", - "zoo-gateway", - "litellm", - "requesty", - "unbound", - "poe", - "deepseek", - "moonshot", - "opencode-go", - "kenari", + providerIdentifiers.openrouter, + providerIdentifiers.vercelAiGateway, + providerIdentifiers.zooGateway, + providerIdentifiers.litellm, + providerIdentifiers.requesty, + providerIdentifiers.unbound, + providerIdentifiers.poe, + providerIdentifiers.deepseek, + providerIdentifiers.moonshot, + providerIdentifiers.opencodeGo, + providerIdentifiers.kenari, ] as const export type DynamicProvider = (typeof dynamicProviders)[number] @@ -68,7 +68,7 @@ export const isDynamicProvider = (key: string): key is DynamicProvider => * Local providers require localhost API calls in order to get the model list. */ -export const localProviders = ["ollama", "lmstudio"] as const +export const localProviders = [providerIdentifiers.ollama, providerIdentifiers.lmstudio] as const export type LocalProvider = (typeof localProviders)[number] @@ -81,7 +81,7 @@ export const isLocalProvider = (key: string): key is LocalProvider => localProvi * model list. */ -export const internalProviders = ["vscode-lm"] as const +export const internalProviders = [providerIdentifiers.vscodeLm] as const export type InternalProvider = (typeof internalProviders)[number] @@ -94,7 +94,7 @@ export const isInternalProvider = (key: string): key is InternalProvider => * Custom providers are completely configurable within Roo Code settings. */ -export const customProviders = ["openai"] as const +export const customProviders = [providerIdentifiers.openai] as const export type CustomProvider = (typeof customProviders)[number] @@ -107,7 +107,7 @@ export const isCustomProvider = (key: string): key is CustomProvider => customPr * model lists. */ -export const fauxProviders = ["fake-ai"] as const +export const fauxProviders = [providerIdentifiers.fakeAi] as const export type FauxProvider = (typeof fauxProviders)[number]