diff --git a/packages/dashboard/app/components/InlineCreateCard.tsx b/packages/dashboard/app/components/InlineCreateCard.tsx index c37923066c..e42ac4bbe4 100644 --- a/packages/dashboard/app/components/InlineCreateCard.tsx +++ b/packages/dashboard/app/components/InlineCreateCard.tsx @@ -108,6 +108,8 @@ export function InlineCreateCard({ const [executorModelId, setExecutorModelId] = useState(undefined); const [validatorProvider, setValidatorProvider] = useState(undefined); const [validatorModelId, setValidatorModelId] = useState(undefined); + const [planningProvider, setPlanningProvider] = useState(undefined); + const [planningModelId, setPlanningModelId] = useState(undefined); const [browserVerification, setBrowserVerification] = useState(false); const [priority, setPriority] = useState(DEFAULT_TASK_PRIORITY); const [modelsLoading, setModelsLoading] = useState(false); @@ -254,12 +256,14 @@ export function InlineCreateCard({ const executorSelectionValue = getModelSelectionValue(executorProvider, executorModelId); const validatorSelectionValue = getModelSelectionValue(validatorProvider, validatorModelId); + const planningSelectionValue = getModelSelectionValue(planningProvider, planningModelId); const availablePresets = settings?.modelPresets || []; const selectedPreset = availablePresets.find((preset) => preset.id === selectedPresetId); const hasExecutorOverride = Boolean(executorProvider && executorModelId); const hasValidatorOverride = Boolean(validatorProvider && validatorModelId); - const selectedModelCount = Number(hasExecutorOverride) + Number(hasValidatorOverride); + const hasPlanningOverride = Boolean(planningProvider && planningModelId); + const selectedModelCount = Number(hasExecutorOverride) + Number(hasValidatorOverride) + Number(hasPlanningOverride); // Track focus-out for conditional cancel behavior and justResetRef cleanup. useEffect(() => { @@ -383,6 +387,8 @@ export function InlineCreateCard({ setExecutorModelId(undefined); setValidatorProvider(undefined); setValidatorModelId(undefined); + setPlanningProvider(undefined); + setPlanningModelId(undefined); setBrowserVerification(false); setPriority(DEFAULT_TASK_PRIORITY); setDependencies([]); @@ -434,6 +440,8 @@ export function InlineCreateCard({ modelId: hasExecutorOverride ? executorModelId : undefined, validatorModelProvider: hasValidatorOverride ? validatorProvider : undefined, validatorModelId: hasValidatorOverride ? validatorModelId : undefined, + planningModelProvider: hasPlanningOverride ? planningProvider : undefined, + planningModelId: hasPlanningOverride ? planningModelId : undefined, enabledWorkflowSteps: browserVerification ? ["browser-verification"] : undefined, priority, nodeId, @@ -451,7 +459,7 @@ export function InlineCreateCard({ } await submitTask(input); - }, [description, submitting, dependencies, selectedAgentId, selectedPresetId, hasExecutorOverride, executorProvider, executorModelId, hasValidatorOverride, validatorProvider, validatorModelId, browserVerification, priority, nodeId, projectId, addToast, submitTask]); + }, [description, submitting, dependencies, selectedAgentId, selectedPresetId, hasExecutorOverride, executorProvider, executorModelId, hasValidatorOverride, validatorProvider, validatorModelId, hasPlanningOverride, planningProvider, planningModelId, browserVerification, priority, nodeId, projectId, addToast, submitTask]); const handleDuplicateProceed = useCallback(async () => { const matches = duplicateMatches; @@ -595,6 +603,12 @@ export function InlineCreateCard({ setValidatorModelId(next.modelId); }, []); + const handlePlanningModelChange = useCallback((value: string) => { + const next = parseModelSelection(value); + setPlanningProvider(next.provider); + setPlanningModelId(next.modelId); + }, []); + const handleToggleFavorite = useCallback(async (provider: string) => { const currentFavorites = favoriteProviders; const isFavorite = currentFavorites.includes(provider); @@ -655,6 +669,8 @@ export function InlineCreateCard({ setExecutorModelId(undefined); setValidatorProvider(undefined); setValidatorModelId(undefined); + setPlanningProvider(undefined); + setPlanningModelId(undefined); setBrowserVerification(false); setSelectedPresetId(undefined); setSelectedAgentId(null); @@ -681,6 +697,8 @@ export function InlineCreateCard({ setExecutorModelId(undefined); setValidatorProvider(undefined); setValidatorModelId(undefined); + setPlanningProvider(undefined); + setPlanningModelId(undefined); setBrowserVerification(false); setSelectedPresetId(undefined); setSelectedAgentId(null); @@ -1088,6 +1106,8 @@ export function InlineCreateCard({ setExecutorModelId(undefined); setValidatorProvider(undefined); setValidatorModelId(undefined); + setPlanningProvider(undefined); + setPlanningModelId(undefined); setShowPresets(false); }} > @@ -1163,8 +1183,10 @@ export function InlineCreateCard({ models={loadedModels} executorValue={executorSelectionValue} validatorValue={validatorSelectionValue} + planningValue={planningSelectionValue} onExecutorChange={handleExecutorChange} onValidatorChange={handleValidatorChange} + onPlanningChange={handlePlanningModelChange} modelsLoading={modelsLoading} modelsError={modelsError} onRetry={loadModels} diff --git a/packages/dashboard/app/components/ModelSelectionModal.tsx b/packages/dashboard/app/components/ModelSelectionModal.tsx index b1f18954c6..8a8a931686 100644 --- a/packages/dashboard/app/components/ModelSelectionModal.tsx +++ b/packages/dashboard/app/components/ModelSelectionModal.tsx @@ -13,8 +13,10 @@ interface ModelSelectionModalProps { models: ModelInfo[]; executorValue: string; validatorValue: string; + planningValue?: string; onExecutorChange: (value: string) => void; onValidatorChange: (value: string) => void; + onPlanningChange?: (value: string) => void; modelsLoading: boolean; modelsError: string | null; onRetry: () => void; @@ -46,8 +48,10 @@ export function ModelSelectionModal({ models, executorValue, validatorValue, + planningValue = "", onExecutorChange, onValidatorChange, + onPlanningChange, modelsLoading, modelsError, onRetry, @@ -95,6 +99,7 @@ export function ModelSelectionModal({ onPresetChange(undefined); onExecutorChange(""); onValidatorChange(""); + onPlanningChange?.(""); return; } if (value === "custom") { @@ -134,10 +139,22 @@ export function ModelSelectionModal({ [onPresetChange, selectedPresetId, onValidatorChange], ); + const handlePlanningChange = useCallback( + (value: string) => { + // Manual model selection clears preset mode + if (onPresetChange && selectedPresetId) { + onPresetChange(undefined); + } + onPlanningChange?.(value); + }, + [onPresetChange, selectedPresetId, onPlanningChange], + ); + if (!isOpen) return null; const hasExecutorOverride = Boolean(executorValue); const hasValidatorOverride = Boolean(validatorValue); + const hasPlanningOverride = Boolean(planningValue); return (
@@ -211,6 +228,34 @@ export function ModelSelectionModal({
)} + {onPlanningChange ? ( +
+
+ + + {getModelBadgeLabel(models, planningValue, t)} + + +
+
+ ) : null} +