import React from 'react'; import { AgentSelector } from '@/components/sections/commands/AgentSelector'; import { ModelSelector } from '@/components/sections/agents/ModelSelector'; import { ThinkingPill } from '@/components/session/ThinkingPill'; import { Checkbox } from '@/components/ui/checkbox'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { isPrimaryMode } from '@/components/chat/mobileControlsUtils'; import { useI18n } from '@/lib/i18n'; import { useConfigStore } from '@/stores/useConfigStore'; import { useAgentsStore } from '@/stores/useAgentsStore'; export type ReviewFlowExecution = { providerID: string; modelID: string; variant: string; agent: string; generateHandoff: boolean; autoReview: boolean; }; type ReviewFlowDialogProps = { open: boolean; onOpenChange: (open: boolean) => void; projectDirectory: string | null; submitting?: boolean; onConfirm: (execution: ReviewFlowExecution) => Promise | void; }; const getInitialExecution = (params: { providerID: string; modelID: string; variant: string; agent: string; }): ReviewFlowExecution => ({ providerID: params.providerID, modelID: params.modelID, variant: params.variant, agent: params.agent, generateHandoff: true, autoReview: false, }); export function ReviewFlowDialog({ open, onOpenChange, projectDirectory, submitting = false, onConfirm, }: ReviewFlowDialogProps) { const { t } = useI18n(); const loadProviders = useConfigStore((state) => state.loadProviders); const loadConfigAgents = useConfigStore((state) => state.loadAgents); const loadAgentsStoreAgents = useAgentsStore((state) => state.loadAgents); const providers = useConfigStore((state) => state.providers); const currentProviderID = useConfigStore((state) => state.currentProviderId); const currentModelID = useConfigStore((state) => state.currentModelId); const currentVariant = useConfigStore((state) => state.currentVariant || ''); const currentAgentName = useConfigStore((state) => state.currentAgentName || ''); const [execution, setExecution] = React.useState(() => getInitialExecution({ providerID: currentProviderID, modelID: currentModelID, variant: currentVariant, agent: currentAgentName, })); React.useEffect(() => { if (!open) return; void loadProviders({ directory: projectDirectory, source: 'reviewFlowDialog' }); void loadConfigAgents({ directory: projectDirectory }); void loadAgentsStoreAgents(); }, [open, loadProviders, loadConfigAgents, loadAgentsStoreAgents, projectDirectory]); React.useEffect(() => { if (!open) return; setExecution(getInitialExecution({ providerID: currentProviderID, modelID: currentModelID, variant: currentVariant, agent: currentAgentName, })); }, [open, currentProviderID, currentModelID, currentVariant, currentAgentName]); React.useEffect(() => { if (!open || providers.length === 0) return; const provider = providers.find((item) => item.id === execution.providerID) ?? providers[0]; const models = Array.isArray(provider?.models) ? provider.models : []; const hasModel = models.some((item) => item.id === execution.modelID); const fallbackModelID = models[0]?.id ?? ''; if (provider?.id === execution.providerID && hasModel) return; setExecution((prev) => ({ ...prev, providerID: provider?.id ?? '', modelID: hasModel ? prev.modelID : fallbackModelID, variant: '', })); }, [open, providers, execution.providerID, execution.modelID]); const agentFilter = React.useCallback((agent: { mode?: string }) => isPrimaryMode(agent.mode), []); const variantOptions = React.useMemo(() => { const provider = providers.find((item) => item.id === execution.providerID); const model = provider?.models?.find((item) => item.id === execution.modelID) as { variants?: Record } | undefined; return model?.variants ? Object.keys(model.variants) : []; }, [providers, execution.providerID, execution.modelID]); const hasVariantOptions = variantOptions.length > 0; React.useEffect(() => { if (hasVariantOptions || !execution.variant) return; setExecution((prev) => ({ ...prev, variant: '' })); }, [hasVariantOptions, execution.variant]); const canConfirm = execution.providerID.trim().length > 0 && execution.modelID.trim().length > 0; const handleSubmit = React.useCallback(() => { if (!canConfirm || submitting) return; void onConfirm(execution); }, [canConfirm, submitting, onConfirm, execution]); React.useEffect(() => { if (!open) return; const onKeyDown = (event: KeyboardEvent) => { if ((event.metaKey || event.ctrlKey) && event.key === 'Enter') { event.preventDefault(); handleSubmit(); } }; window.addEventListener('keydown', onKeyDown); return () => window.removeEventListener('keydown', onKeyDown); }, [open, handleSubmit]); return ( { if (!submitting) onOpenChange(nextOpen); }}> {t('diffView.reviewDialog.title')} {t('diffView.reviewDialog.description')}
{t('diffView.reviewDialog.info')}
{t('chat.modelControls.model')} { setExecution((prev) => ({ ...prev, providerID, modelID, variant: '' })); }} />
{t('sessions.scheduledTasks.editor.thinkingLevel.label')} setExecution((prev) => ({ ...prev, variant }))} />
{t('sessions.scheduledTasks.editor.agent.label')} setExecution((prev) => ({ ...prev, agent }))} />
); }