mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-30 06:12:03 +00:00
Revert "Wire provider model enablement into selectors"
This reverts commit 8f1740c0f5.
This commit is contained in:
@@ -4,6 +4,7 @@ import { Badge } from '@/components/ui/badge';
|
||||
import { Brain, AlertTriangle } from 'lucide-react';
|
||||
import { AnthropicIcon, CursorIcon, OpenAIIcon } from '@/components/ui/provider-icon';
|
||||
import { cn } from '@/lib/utils';
|
||||
import type { ModelAlias } from '@/store/app-store';
|
||||
import { useAppStore } from '@/store/app-store';
|
||||
import { useSetupStore } from '@/store/setup-store';
|
||||
import { getModelProvider, PROVIDER_PREFIXES, stripProviderPrefix } from '@automaker/types';
|
||||
@@ -18,10 +19,6 @@ interface ModelSelectorProps {
|
||||
testIdPrefix?: string;
|
||||
}
|
||||
|
||||
const CODEX_EMPTY_AVAILABLE_MESSAGE = 'No Codex models available';
|
||||
const CODEX_EMPTY_ENABLED_MESSAGE =
|
||||
'No Codex models enabled. Enable models in Settings → AI Providers.';
|
||||
|
||||
export function ModelSelector({
|
||||
selectedModel,
|
||||
onModelSelect,
|
||||
@@ -30,8 +27,6 @@ export function ModelSelector({
|
||||
const {
|
||||
enabledCursorModels,
|
||||
cursorDefaultModel,
|
||||
enabledCodexModels,
|
||||
codexDefaultModel,
|
||||
codexModels,
|
||||
codexModelsLoading,
|
||||
codexModelsError,
|
||||
@@ -54,10 +49,8 @@ export function ModelSelector({
|
||||
}
|
||||
}, [isCodexAvailable, codexModels.length, codexModelsLoading, fetchCodexModels]);
|
||||
|
||||
const enabledCodexModelIds = new Set(enabledCodexModels);
|
||||
|
||||
// Transform codex models from store to ModelOption format
|
||||
const codexModelOptions: ModelOption[] = codexModels.map((model) => {
|
||||
const dynamicCodexModels: ModelOption[] = codexModels.map((model) => {
|
||||
// Infer badge based on tier
|
||||
let badge: string | undefined;
|
||||
if (model.tier === 'premium') badge = 'Premium';
|
||||
@@ -74,10 +67,6 @@ export function ModelSelector({
|
||||
};
|
||||
});
|
||||
|
||||
const enabledCodexModelOptions = codexModelOptions.filter((model) =>
|
||||
enabledCodexModelIds.has(model.id)
|
||||
);
|
||||
|
||||
// Filter Cursor models based on enabled models from global settings
|
||||
const filteredCursorModels = CURSOR_MODELS.filter((model) => {
|
||||
// Extract the cursor model ID from the prefixed ID (e.g., "cursor-auto" -> "auto")
|
||||
@@ -85,36 +74,21 @@ export function ModelSelector({
|
||||
return enabledCursorModels.includes(cursorModelId as any);
|
||||
});
|
||||
|
||||
const hasEnabledCodexModels = enabledCodexModelOptions.length > 0;
|
||||
const codexDefaultSelection =
|
||||
codexModelOptions.find((model) => model.id === codexDefaultModel)?.id ||
|
||||
enabledCodexModelOptions[0]?.id ||
|
||||
codexModelOptions[0]?.id;
|
||||
|
||||
const handleProviderChange = (provider: ModelProvider) => {
|
||||
if (provider === 'cursor' && selectedProvider !== 'cursor') {
|
||||
// Switch to Cursor's default model (from global settings)
|
||||
onModelSelect(`${PROVIDER_PREFIXES.cursor}${cursorDefaultModel}`);
|
||||
} else if (provider === 'codex' && selectedProvider !== 'codex') {
|
||||
// Switch to Codex's default model (from global settings)
|
||||
if (codexDefaultSelection) {
|
||||
onModelSelect(codexDefaultSelection);
|
||||
}
|
||||
// Switch to Codex's default model (use isDefault flag from dynamic models)
|
||||
const defaultModel = codexModels.find((m) => m.isDefault);
|
||||
const defaultModelId = defaultModel?.id || codexModels[0]?.id || 'codex-gpt-5.2-codex';
|
||||
onModelSelect(defaultModelId);
|
||||
} else if (provider === 'claude' && selectedProvider !== 'claude') {
|
||||
// Switch to Claude's default model
|
||||
onModelSelect('sonnet');
|
||||
}
|
||||
};
|
||||
|
||||
const showCodexAvailableEmpty =
|
||||
!codexModelsLoading && !codexModelsError && codexModelOptions.length === 0;
|
||||
const showCodexEnabledEmpty =
|
||||
!codexModelsLoading &&
|
||||
!codexModelsError &&
|
||||
codexModelOptions.length > 0 &&
|
||||
!hasEnabledCodexModels;
|
||||
const showCodexList = !codexModelsLoading && !codexModelsError && hasEnabledCodexModels;
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{/* Provider Selection */}
|
||||
@@ -298,7 +272,7 @@ export function ModelSelector({
|
||||
</div>
|
||||
|
||||
{/* Loading state */}
|
||||
{codexModelsLoading && codexModelOptions.length === 0 && (
|
||||
{codexModelsLoading && dynamicCodexModels.length === 0 && (
|
||||
<div className="flex items-center justify-center gap-2 p-6 text-sm text-muted-foreground">
|
||||
<RefreshCw className="w-4 h-4 animate-spin" />
|
||||
Loading models...
|
||||
@@ -323,21 +297,15 @@ export function ModelSelector({
|
||||
)}
|
||||
|
||||
{/* Model list */}
|
||||
{showCodexAvailableEmpty && (
|
||||
{!codexModelsLoading && !codexModelsError && dynamicCodexModels.length === 0 && (
|
||||
<div className="text-sm text-muted-foreground p-3 border border-dashed rounded-md text-center">
|
||||
{CODEX_EMPTY_AVAILABLE_MESSAGE}
|
||||
No Codex models available
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showCodexEnabledEmpty && (
|
||||
<div className="text-sm text-muted-foreground p-3 border border-dashed rounded-md text-center">
|
||||
{CODEX_EMPTY_ENABLED_MESSAGE}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showCodexList && (
|
||||
{!codexModelsLoading && dynamicCodexModels.length > 0 && (
|
||||
<div className="flex flex-col gap-2">
|
||||
{enabledCodexModelOptions.map((option) => {
|
||||
{dynamicCodexModels.map((option) => {
|
||||
const isSelected = selectedModel === option.id;
|
||||
return (
|
||||
<button
|
||||
|
||||
@@ -159,9 +159,6 @@ export function PhaseModelSelector({
|
||||
const expandedCodexTriggerRef = useRef<HTMLDivElement>(null);
|
||||
const {
|
||||
enabledCursorModels,
|
||||
enabledCodexModels,
|
||||
enabledOpencodeModels,
|
||||
enabledDynamicModelIds,
|
||||
favoriteModels,
|
||||
toggleFavoriteModel,
|
||||
codexModels,
|
||||
@@ -264,14 +261,6 @@ export function PhaseModelSelector({
|
||||
}));
|
||||
}, [codexModels]);
|
||||
|
||||
const availableCodexModels = useMemo(
|
||||
() =>
|
||||
transformedCodexModels.filter((model) =>
|
||||
enabledCodexModels.includes(model.id as CodexModelId)
|
||||
),
|
||||
[transformedCodexModels, enabledCodexModels]
|
||||
);
|
||||
|
||||
// Filter Cursor models to only show enabled ones
|
||||
const availableCursorModels = CURSOR_MODELS.filter((model) => {
|
||||
const cursorId = stripProviderPrefix(model.id) as CursorModelId;
|
||||
@@ -377,20 +366,16 @@ export function PhaseModelSelector({
|
||||
// Combine static and dynamic OpenCode models
|
||||
const allOpencodeModels: ModelOption[] = useMemo(() => {
|
||||
// Start with static models
|
||||
const staticModels = OPENCODE_MODELS.filter((model) =>
|
||||
enabledOpencodeModels.includes(model.id)
|
||||
);
|
||||
const staticModels = [...OPENCODE_MODELS];
|
||||
|
||||
// Add dynamic models (convert ModelDefinition to ModelOption)
|
||||
const dynamicModelOptions: ModelOption[] = dynamicOpencodeModels
|
||||
.filter((model) => enabledDynamicModelIds.includes(model.id))
|
||||
.map((model) => ({
|
||||
id: model.id,
|
||||
label: model.name,
|
||||
description: model.description,
|
||||
badge: model.tier === 'premium' ? 'Premium' : model.tier === 'basic' ? 'Free' : undefined,
|
||||
provider: 'opencode' as const,
|
||||
}));
|
||||
const dynamicModelOptions: ModelOption[] = dynamicOpencodeModels.map((model) => ({
|
||||
id: model.id,
|
||||
label: model.name,
|
||||
description: model.description,
|
||||
badge: model.tier === 'premium' ? 'Premium' : model.tier === 'basic' ? 'Free' : undefined,
|
||||
provider: 'opencode' as const,
|
||||
}));
|
||||
|
||||
// Merge, avoiding duplicates (static models take precedence for same ID)
|
||||
// In practice, static and dynamic IDs don't overlap
|
||||
@@ -398,14 +383,14 @@ export function PhaseModelSelector({
|
||||
const uniqueDynamic = dynamicModelOptions.filter((m) => !staticIds.has(m.id));
|
||||
|
||||
return [...staticModels, ...uniqueDynamic];
|
||||
}, [dynamicOpencodeModels, enabledOpencodeModels, enabledDynamicModelIds]);
|
||||
}, [dynamicOpencodeModels]);
|
||||
|
||||
// Group models
|
||||
const { favorites, claude, cursor, codex, opencode } = useMemo(() => {
|
||||
const favs: typeof CLAUDE_MODELS = [];
|
||||
const cModels: typeof CLAUDE_MODELS = [];
|
||||
const curModels: typeof CURSOR_MODELS = [];
|
||||
const codModels: typeof availableCodexModels = [];
|
||||
const codModels: typeof transformedCodexModels = [];
|
||||
const ocModels: ModelOption[] = [];
|
||||
|
||||
// Process Claude Models
|
||||
@@ -427,7 +412,7 @@ export function PhaseModelSelector({
|
||||
});
|
||||
|
||||
// Process Codex Models
|
||||
availableCodexModels.forEach((model) => {
|
||||
transformedCodexModels.forEach((model) => {
|
||||
if (favoriteModels.includes(model.id)) {
|
||||
favs.push(model);
|
||||
} else {
|
||||
@@ -451,7 +436,7 @@ export function PhaseModelSelector({
|
||||
codex: codModels,
|
||||
opencode: ocModels,
|
||||
};
|
||||
}, [favoriteModels, availableCursorModels, availableCodexModels, allOpencodeModels]);
|
||||
}, [favoriteModels, availableCursorModels, transformedCodexModels, allOpencodeModels]);
|
||||
|
||||
// Group OpenCode models by model type for better organization
|
||||
const opencodeSections = useMemo(() => {
|
||||
@@ -468,11 +453,8 @@ export function PhaseModelSelector({
|
||||
free: {},
|
||||
dynamic: {},
|
||||
};
|
||||
const enabledDynamicProviders = dynamicOpencodeModels.filter((model) =>
|
||||
enabledDynamicModelIds.includes(model.id)
|
||||
);
|
||||
const dynamicProviderById = new Map(
|
||||
enabledDynamicProviders.map((model) => [model.id, model.provider])
|
||||
dynamicOpencodeModels.map((model) => [model.id, model.provider])
|
||||
);
|
||||
|
||||
const resolveProviderKey = (modelId: string): string => {
|
||||
@@ -542,10 +524,10 @@ export function PhaseModelSelector({
|
||||
}).filter(Boolean) as OpencodeSection[];
|
||||
|
||||
return builtSections;
|
||||
}, [opencode, dynamicOpencodeModels, enabledDynamicModelIds]);
|
||||
}, [opencode, dynamicOpencodeModels]);
|
||||
|
||||
// Render Codex model item with secondary popover for reasoning effort (only for models that support it)
|
||||
const renderCodexModelItem = (model: (typeof availableCodexModels)[0]) => {
|
||||
const renderCodexModelItem = (model: (typeof transformedCodexModels)[0]) => {
|
||||
const isSelected = selectedModel === model.id;
|
||||
const isFavorite = favoriteModels.includes(model.id);
|
||||
const hasReasoning = codexModelHasThinking(model.id as CodexModelId);
|
||||
@@ -726,7 +708,7 @@ export function PhaseModelSelector({
|
||||
};
|
||||
|
||||
// Render OpenCode model item (simple selector, no thinking/reasoning options)
|
||||
const renderOpencodeModelItem = (model: ModelOption) => {
|
||||
const renderOpencodeModelItem = (model: (typeof OPENCODE_MODELS)[0]) => {
|
||||
const isSelected = selectedModel === model.id;
|
||||
const isFavorite = favoriteModels.includes(model.id);
|
||||
|
||||
@@ -1172,7 +1154,7 @@ export function PhaseModelSelector({
|
||||
}
|
||||
// Codex model
|
||||
if (model.provider === 'codex') {
|
||||
return renderCodexModelItem(model as (typeof availableCodexModels)[0]);
|
||||
return renderCodexModelItem(model as (typeof transformedCodexModels)[0]);
|
||||
}
|
||||
// OpenCode model
|
||||
if (model.provider === 'opencode') {
|
||||
|
||||
Reference in New Issue
Block a user