Skip to content

Commit 78751c7

Browse files
committed
Fix greptile
1 parent a88d5f6 commit 78751c7

File tree

2 files changed

+81
-11
lines changed
  • apps/sim
    • app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/user-input/components/model-selector
    • stores/panel/copilot

2 files changed

+81
-11
lines changed

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/user-input/components/model-selector/model-selector.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,21 @@ export function ModelSelector({ selectedModel, isNearTop, onModelSelect }: Model
6767
*/
6868
const getProviderForModel = (compositeKey: string): string | undefined => {
6969
const slashIdx = compositeKey.indexOf('/')
70-
if (slashIdx === -1) return undefined
71-
return compositeKey.slice(0, slashIdx)
70+
if (slashIdx !== -1) return compositeKey.slice(0, slashIdx)
71+
72+
// Legacy migration path: allow old raw IDs (without provider prefix)
73+
// by resolving against current available model options.
74+
const exact = modelOptions.find((m) => m.value === compositeKey)
75+
if (exact?.provider) return exact.provider
76+
77+
const byRawSuffix = modelOptions.find((m) => m.value.endsWith(`/${compositeKey}`))
78+
return byRawSuffix?.provider
7279
}
7380

7481
const getCollapsedModeLabel = () => {
75-
const model = modelOptions.find((m) => m.value === selectedModel)
82+
const model =
83+
modelOptions.find((m) => m.value === selectedModel) ??
84+
modelOptions.find((m) => m.value.endsWith(`/${selectedModel}`))
7685
return model?.label || selectedModel || 'No models available'
7786
}
7887

apps/sim/stores/panel/copilot/store.ts

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,58 @@ function parseModelKey(compositeKey: string): { provider: string; modelId: strin
310310
return { provider: compositeKey.slice(0, slashIdx), modelId: compositeKey.slice(slashIdx + 1) }
311311
}
312312

313+
const MODEL_PROVIDER_PRIORITY = [
314+
'anthropic',
315+
'bedrock',
316+
'azure-anthropic',
317+
'openai',
318+
'azure-openai',
319+
'gemini',
320+
'google',
321+
'azure',
322+
'unknown',
323+
] as const
324+
325+
const KNOWN_COPILOT_PROVIDERS = new Set<string>(MODEL_PROVIDER_PRIORITY)
326+
327+
function isCompositeModelId(modelId: string): boolean {
328+
const slashIdx = modelId.indexOf('/')
329+
if (slashIdx <= 0 || slashIdx === modelId.length - 1) return false
330+
const provider = modelId.slice(0, slashIdx)
331+
return KNOWN_COPILOT_PROVIDERS.has(provider)
332+
}
333+
334+
function toCompositeModelId(modelId: string, provider: string): string {
335+
if (!modelId) return modelId
336+
return isCompositeModelId(modelId) ? modelId : `${provider}/${modelId}`
337+
}
338+
339+
function pickPreferredProviderModel(matches: AvailableModel[]): AvailableModel | undefined {
340+
for (const provider of MODEL_PROVIDER_PRIORITY) {
341+
const found = matches.find((m) => m.provider === provider)
342+
if (found) return found
343+
}
344+
return matches[0]
345+
}
346+
347+
function normalizeSelectedModelKey(selectedModel: string, models: AvailableModel[]): string {
348+
if (!selectedModel || models.length === 0) return selectedModel
349+
if (models.some((m) => m.id === selectedModel)) return selectedModel
350+
351+
const { provider, modelId } = parseModelKey(selectedModel)
352+
const targetModelId = modelId || selectedModel
353+
354+
const matches = models.filter((m) => m.id.endsWith(`/${targetModelId}`))
355+
if (matches.length === 0) return selectedModel
356+
357+
if (provider) {
358+
const sameProvider = matches.find((m) => m.provider === provider)
359+
if (sameProvider) return sameProvider.id
360+
}
361+
362+
return (pickPreferredProviderModel(matches) ?? matches[0]).id
363+
}
364+
313365
/** Look up the provider for the currently selected model from the composite key. */
314366
function getSelectedProvider(get: CopilotGet): string | undefined {
315367
const { provider } = parseModelKey(get().selectedModel)
@@ -2230,6 +2282,7 @@ export const useCopilotStore = create<CopilotStore>()(
22302282
const data = await response.json()
22312283
const models: unknown[] = Array.isArray(data?.models) ? data.models : []
22322284

2285+
const seenModelIds = new Set<string>()
22332286
const normalizedModels: AvailableModel[] = models
22342287
.filter((model: unknown): model is AvailableModel => {
22352288
return (
@@ -2240,27 +2293,35 @@ export const useCopilotStore = create<CopilotStore>()(
22402293
)
22412294
})
22422295
.map((model: AvailableModel) => {
2243-
const provider = model.provider || 'unknown'
2244-
// Use composite provider/modelId keys (matching agent block pattern in providers/models.ts)
2245-
// so models with the same raw ID from different providers are uniquely identified.
2246-
const compositeId = `${provider}/${model.id}`
2296+
const idProvider = isCompositeModelId(model.id) ? parseModelKey(model.id).provider : ''
2297+
const provider = model.provider || idProvider || 'unknown'
2298+
// Use stable composite provider/modelId keys so same model IDs from different
2299+
// providers remain uniquely addressable.
2300+
const compositeId = toCompositeModelId(model.id, provider)
22472301
return {
22482302
id: compositeId,
22492303
friendlyName: model.friendlyName || model.id,
22502304
provider,
22512305
}
22522306
})
2307+
.filter((model) => {
2308+
if (seenModelIds.has(model.id)) return false
2309+
seenModelIds.add(model.id)
2310+
return true
2311+
})
22532312

22542313
const { selectedModel } = get()
2255-
const selectedModelExists = normalizedModels.some((model) => model.id === selectedModel)
2314+
const normalizedSelectedModel = normalizeSelectedModelKey(selectedModel, normalizedModels)
2315+
const selectedModelExists = normalizedModels.some(
2316+
(model) => model.id === normalizedSelectedModel
2317+
)
22562318

22572319
// Pick the best default: prefer claude-opus-4-6 with provider priority:
22582320
// direct anthropic > bedrock > azure-anthropic > any other.
2259-
let nextSelectedModel = selectedModel
2321+
let nextSelectedModel = normalizedSelectedModel
22602322
if (!selectedModelExists && normalizedModels.length > 0) {
2261-
const providerPriority = ['anthropic', 'bedrock', 'azure-anthropic']
22622323
let opus46: AvailableModel | undefined
2263-
for (const prov of providerPriority) {
2324+
for (const prov of MODEL_PROVIDER_PRIORITY) {
22642325
opus46 = normalizedModels.find((m) => m.id === `${prov}/claude-opus-4-6`)
22652326
if (opus46) break
22662327
}

0 commit comments

Comments
 (0)