Skip to content

Commit 9af2023

Browse files
committed
make server side provider registry
1 parent 54c075c commit 9af2023

File tree

3 files changed

+136
-97
lines changed

3 files changed

+136
-97
lines changed

apps/sim/providers/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { getCostMultiplier } from '@/lib/core/config/feature-flags'
22
import { createLogger } from '@/lib/logs/console/logger'
33
import type { StreamingExecution } from '@/executor/types'
4-
import type { ProviderRequest, ProviderResponse } from '@/providers/types'
4+
import { getProviderExecutor } from '@/providers/registry'
5+
import type { ProviderId, ProviderRequest, ProviderResponse } from '@/providers/types'
56
import {
67
calculateCost,
78
generateStructuredOutputInstructions,
8-
getProvider,
99
shouldBillModelUsage,
1010
supportsTemperature,
1111
} from '@/providers/utils'
@@ -40,7 +40,7 @@ export async function executeProviderRequest(
4040
providerId: string,
4141
request: ProviderRequest
4242
): Promise<ProviderResponse | ReadableStream | StreamingExecution> {
43-
const provider = getProvider(providerId)
43+
const provider = await getProviderExecutor(providerId as ProviderId)
4444
if (!provider) {
4545
throw new Error(`Provider not found: ${providerId}`)
4646
}

apps/sim/providers/registry.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* Server-only provider registry
3+
*
4+
* This module contains the actual provider implementations with executeRequest functions.
5+
* It should ONLY be imported from server-side code (API routes, executor handlers, etc.)
6+
*
7+
* Client-side code should use @/providers/utils for model lists and metadata.
8+
*/
9+
10+
import { createLogger } from '@/lib/logs/console/logger'
11+
import { anthropicProvider } from '@/providers/anthropic'
12+
import { azureOpenAIProvider } from '@/providers/azure-openai'
13+
import { cerebrasProvider } from '@/providers/cerebras'
14+
import { deepseekProvider } from '@/providers/deepseek'
15+
import { googleProvider } from '@/providers/google'
16+
import { groqProvider } from '@/providers/groq'
17+
import { mistralProvider } from '@/providers/mistral'
18+
import { ollamaProvider } from '@/providers/ollama'
19+
import { openaiProvider } from '@/providers/openai'
20+
import { openRouterProvider } from '@/providers/openrouter'
21+
import type { ProviderConfig, ProviderId } from '@/providers/types'
22+
import { vertexProvider } from '@/providers/vertex'
23+
import { vllmProvider } from '@/providers/vllm'
24+
import { xAIProvider } from '@/providers/xai'
25+
26+
const logger = createLogger('ProviderRegistry')
27+
28+
/**
29+
* Server-side provider registry with full implementations.
30+
* This includes executeRequest functions that use server-only dependencies.
31+
*/
32+
const providerRegistry: Record<ProviderId, ProviderConfig> = {
33+
openai: openaiProvider,
34+
anthropic: anthropicProvider,
35+
google: googleProvider,
36+
vertex: vertexProvider,
37+
deepseek: deepseekProvider,
38+
xai: xAIProvider,
39+
cerebras: cerebrasProvider,
40+
groq: groqProvider,
41+
vllm: vllmProvider,
42+
mistral: mistralProvider,
43+
'azure-openai': azureOpenAIProvider,
44+
openrouter: openRouterProvider,
45+
ollama: ollamaProvider,
46+
}
47+
48+
/**
49+
* Get a provider implementation for execution.
50+
* This returns the full provider config including executeRequest.
51+
*
52+
* @param providerId - The provider ID
53+
* @returns The provider config or undefined if not found
54+
*/
55+
export async function getProviderExecutor(
56+
providerId: ProviderId
57+
): Promise<ProviderConfig | undefined> {
58+
const provider = providerRegistry[providerId]
59+
if (!provider) {
60+
logger.error(`Provider not found: ${providerId}`)
61+
return undefined
62+
}
63+
return provider
64+
}
65+
66+
/**
67+
* Initialize all providers that have an initialize function.
68+
* Called at server startup.
69+
*/
70+
export async function initializeProviders(): Promise<void> {
71+
for (const [id, provider] of Object.entries(providerRegistry)) {
72+
if (provider.initialize) {
73+
try {
74+
await provider.initialize()
75+
logger.info(`Initialized provider: ${id}`)
76+
} catch (error) {
77+
logger.error(`Failed to initialize ${id} provider`, {
78+
error: error instanceof Error ? error.message : 'Unknown error',
79+
})
80+
}
81+
}
82+
}
83+
}

apps/sim/providers/utils.ts

Lines changed: 50 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,6 @@ import type { CompletionUsage } from 'openai/resources/completions'
33
import { getEnv, isTruthy } from '@/lib/core/config/env'
44
import { isHosted } from '@/lib/core/config/feature-flags'
55
import { createLogger, type Logger } from '@/lib/logs/console/logger'
6-
import { anthropicProvider } from '@/providers/anthropic'
7-
import { azureOpenAIProvider } from '@/providers/azure-openai'
8-
import { cerebrasProvider } from '@/providers/cerebras'
9-
import { deepseekProvider } from '@/providers/deepseek'
10-
import { googleProvider } from '@/providers/google'
11-
import { groqProvider } from '@/providers/groq'
12-
import { mistralProvider } from '@/providers/mistral'
136
import {
147
getComputerUseModels,
158
getEmbeddingModelPricing,
@@ -22,6 +15,7 @@ import {
2215
getModelsWithTempRange02,
2316
getModelsWithThinking,
2417
getModelsWithVerbosity,
18+
getProviderDefaultModel as getProviderDefaultModelFromDefinitions,
2519
getProviderModels as getProviderModelsFromDefinitions,
2620
getProvidersWithToolUsageControl,
2721
getReasoningEffortValuesForModel as getReasoningEffortValuesForModelFromDefinitions,
@@ -32,107 +26,69 @@ import {
3226
supportsToolUsageControl as supportsToolUsageControlFromDefinitions,
3327
updateOllamaModels as updateOllamaModelsInDefinitions,
3428
} from '@/providers/models'
35-
import { ollamaProvider } from '@/providers/ollama'
36-
import { openaiProvider } from '@/providers/openai'
37-
import { openRouterProvider } from '@/providers/openrouter'
38-
import type { ProviderConfig, ProviderId, ProviderToolConfig } from '@/providers/types'
39-
import { vertexProvider } from '@/providers/vertex'
40-
import { vllmProvider } from '@/providers/vllm'
41-
import { xAIProvider } from '@/providers/xai'
29+
import type { ProviderId, ProviderToolConfig } from '@/providers/types'
4230
import { useCustomToolsStore } from '@/stores/custom-tools/store'
4331
import { useProvidersStore } from '@/stores/providers/store'
4432

4533
const logger = createLogger('ProviderUtils')
4634

47-
export const providers: Record<
48-
ProviderId,
49-
ProviderConfig & {
50-
models: string[]
51-
computerUseModels?: string[]
52-
modelPatterns?: RegExp[]
35+
/**
36+
* Client-safe provider metadata.
37+
* This object contains only model lists and patterns - no executeRequest implementations.
38+
* For server-side execution, use @/providers/registry.
39+
*/
40+
export interface ProviderMetadata {
41+
id: string
42+
name: string
43+
description: string
44+
version: string
45+
models: string[]
46+
defaultModel: string
47+
computerUseModels?: string[]
48+
modelPatterns?: RegExp[]
49+
}
50+
51+
/**
52+
* Build provider metadata from PROVIDER_DEFINITIONS.
53+
* This is client-safe as it doesn't import any provider implementations.
54+
*/
55+
function buildProviderMetadata(providerId: ProviderId): ProviderMetadata {
56+
const def = PROVIDER_DEFINITIONS[providerId]
57+
return {
58+
id: providerId,
59+
name: def?.name || providerId,
60+
description: def?.description || '',
61+
version: '1.0.0',
62+
models: getProviderModelsFromDefinitions(providerId),
63+
defaultModel: getProviderDefaultModelFromDefinitions(providerId),
64+
modelPatterns: def?.modelPatterns,
5365
}
54-
> = {
66+
}
67+
68+
export const providers: Record<ProviderId, ProviderMetadata> = {
5569
openai: {
56-
...openaiProvider,
57-
models: getProviderModelsFromDefinitions('openai'),
70+
...buildProviderMetadata('openai'),
5871
computerUseModels: ['computer-use-preview'],
59-
modelPatterns: PROVIDER_DEFINITIONS.openai.modelPatterns,
6072
},
6173
anthropic: {
62-
...anthropicProvider,
63-
models: getProviderModelsFromDefinitions('anthropic'),
74+
...buildProviderMetadata('anthropic'),
6475
computerUseModels: getComputerUseModels().filter((model) =>
6576
getProviderModelsFromDefinitions('anthropic').includes(model)
6677
),
67-
modelPatterns: PROVIDER_DEFINITIONS.anthropic.modelPatterns,
68-
},
69-
google: {
70-
...googleProvider,
71-
models: getProviderModelsFromDefinitions('google'),
72-
modelPatterns: PROVIDER_DEFINITIONS.google.modelPatterns,
73-
},
74-
vertex: {
75-
...vertexProvider,
76-
models: getProviderModelsFromDefinitions('vertex'),
77-
modelPatterns: PROVIDER_DEFINITIONS.vertex.modelPatterns,
78-
},
79-
deepseek: {
80-
...deepseekProvider,
81-
models: getProviderModelsFromDefinitions('deepseek'),
82-
modelPatterns: PROVIDER_DEFINITIONS.deepseek.modelPatterns,
83-
},
84-
xai: {
85-
...xAIProvider,
86-
models: getProviderModelsFromDefinitions('xai'),
87-
modelPatterns: PROVIDER_DEFINITIONS.xai.modelPatterns,
88-
},
89-
cerebras: {
90-
...cerebrasProvider,
91-
models: getProviderModelsFromDefinitions('cerebras'),
92-
modelPatterns: PROVIDER_DEFINITIONS.cerebras.modelPatterns,
93-
},
94-
groq: {
95-
...groqProvider,
96-
models: getProviderModelsFromDefinitions('groq'),
97-
modelPatterns: PROVIDER_DEFINITIONS.groq.modelPatterns,
98-
},
99-
vllm: {
100-
...vllmProvider,
101-
models: getProviderModelsFromDefinitions('vllm'),
102-
modelPatterns: PROVIDER_DEFINITIONS.vllm.modelPatterns,
103-
},
104-
mistral: {
105-
...mistralProvider,
106-
models: getProviderModelsFromDefinitions('mistral'),
107-
modelPatterns: PROVIDER_DEFINITIONS.mistral.modelPatterns,
108-
},
109-
'azure-openai': {
110-
...azureOpenAIProvider,
111-
models: getProviderModelsFromDefinitions('azure-openai'),
112-
modelPatterns: PROVIDER_DEFINITIONS['azure-openai'].modelPatterns,
113-
},
114-
openrouter: {
115-
...openRouterProvider,
116-
models: getProviderModelsFromDefinitions('openrouter'),
117-
modelPatterns: PROVIDER_DEFINITIONS.openrouter.modelPatterns,
118-
},
119-
ollama: {
120-
...ollamaProvider,
121-
models: getProviderModelsFromDefinitions('ollama'),
122-
modelPatterns: PROVIDER_DEFINITIONS.ollama.modelPatterns,
12378
},
79+
google: buildProviderMetadata('google'),
80+
vertex: buildProviderMetadata('vertex'),
81+
deepseek: buildProviderMetadata('deepseek'),
82+
xai: buildProviderMetadata('xai'),
83+
cerebras: buildProviderMetadata('cerebras'),
84+
groq: buildProviderMetadata('groq'),
85+
vllm: buildProviderMetadata('vllm'),
86+
mistral: buildProviderMetadata('mistral'),
87+
'azure-openai': buildProviderMetadata('azure-openai'),
88+
openrouter: buildProviderMetadata('openrouter'),
89+
ollama: buildProviderMetadata('ollama'),
12490
}
12591

126-
Object.entries(providers).forEach(([id, provider]) => {
127-
if (provider.initialize) {
128-
provider.initialize().catch((error) => {
129-
logger.error(`Failed to initialize ${id} provider`, {
130-
error: error instanceof Error ? error.message : 'Unknown error',
131-
})
132-
})
133-
}
134-
})
135-
13692
export function updateOllamaProviderModels(models: string[]): void {
13793
updateOllamaModelsInDefinitions(models)
13894
providers.ollama.models = getProviderModelsFromDefinitions('ollama')
@@ -213,12 +169,12 @@ export function getProviderFromModel(model: string): ProviderId {
213169
return 'ollama'
214170
}
215171

216-
export function getProvider(id: string): ProviderConfig | undefined {
172+
export function getProvider(id: string): ProviderMetadata | undefined {
217173
const providerId = id.split('/')[0] as ProviderId
218174
return providers[providerId]
219175
}
220176

221-
export function getProviderConfigFromModel(model: string): ProviderConfig | undefined {
177+
export function getProviderConfigFromModel(model: string): ProviderMetadata | undefined {
222178
const providerId = getProviderFromModel(model)
223179
return providers[providerId]
224180
}

0 commit comments

Comments
 (0)