From aa318099dcbbfc22396a568212918f00c9fa0aff Mon Sep 17 00:00:00 2001 From: Kacper Date: Thu, 1 Jan 2026 18:20:45 +0100 Subject: [PATCH] feat(ui): add model override trigger to backlog plan dialog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added ModelOverrideTrigger component to the "Plan Backlog Changes" dialog, allowing users to override the global backlog planning model on a per-request basis, consistent with other dialogs in the application. Changes: - Added model override state management to backlog-plan-dialog - Integrated ModelOverrideTrigger component in dialog header (input mode only) - Pass model override (or global default) to backlogPlan.generate API call - UI shows override indicator when model is overridden from global default The feature uses the existing backlogPlanningModel phase setting as the default and allows temporary overrides without changing global settings. Server already supports optional model parameter in the generate endpoint, so no backend changes were required. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- .../dialogs/backlog-plan-dialog.tsx | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/apps/ui/src/components/views/board-view/dialogs/backlog-plan-dialog.tsx b/apps/ui/src/components/views/board-view/dialogs/backlog-plan-dialog.tsx index 6bdf3fef..eb8f6061 100644 --- a/apps/ui/src/components/views/board-view/dialogs/backlog-plan-dialog.tsx +++ b/apps/ui/src/components/views/board-view/dialogs/backlog-plan-dialog.tsx @@ -23,7 +23,9 @@ import { import { getElectronAPI } from '@/lib/electron'; import { toast } from 'sonner'; import { cn } from '@/lib/utils'; -import type { BacklogPlanResult, BacklogChange } from '@automaker/types'; +import type { BacklogPlanResult, BacklogChange, ModelAlias, CursorModelId } from '@automaker/types'; +import { ModelOverrideTrigger } from '@/components/shared/model-override-trigger'; +import { useAppStore } from '@/store/app-store'; interface BacklogPlanDialogProps { open: boolean; @@ -53,6 +55,9 @@ export function BacklogPlanDialog({ const [prompt, setPrompt] = useState(''); const [expandedChanges, setExpandedChanges] = useState>(new Set()); const [selectedChanges, setSelectedChanges] = useState>(new Set()); + const [modelOverride, setModelOverride] = useState(null); + + const { phaseModels } = useAppStore(); // Set mode based on whether we have a pending result useEffect(() => { @@ -83,7 +88,9 @@ export function BacklogPlanDialog({ // Start generation in background setIsGeneratingPlan(true); - const result = await api.backlogPlan.generate(projectPath, prompt); + // Use model override if set, otherwise use global default + const effectiveModel = modelOverride || phaseModels.backlogPlanningModel; + const result = await api.backlogPlan.generate(projectPath, prompt, effectiveModel); if (!result.success) { setIsGeneratingPlan(false); toast.error(result.error || 'Failed to start plan generation'); @@ -96,7 +103,7 @@ export function BacklogPlanDialog({ }); setPrompt(''); onClose(); - }, [projectPath, prompt, setIsGeneratingPlan, onClose]); + }, [projectPath, prompt, modelOverride, phaseModels, setIsGeneratingPlan, onClose]); const handleApply = useCallback(async () => { if (!pendingPlanResult) return; @@ -358,13 +365,28 @@ export function BacklogPlanDialog({ } }; + // Get effective model (override or global default) + const effectiveModel = modelOverride || phaseModels.backlogPlanningModel; + return ( !isOpen && onClose()}> - - - {mode === 'review' ? 'Review Plan' : 'Plan Backlog Changes'} + +
+ + {mode === 'review' ? 'Review Plan' : 'Plan Backlog Changes'} +
+ {mode === 'input' && ( + + )}
{mode === 'review'