diff --git a/packages/editor/App.tsx b/packages/editor/App.tsx index 119715010..3d9ca4c2e 100644 --- a/packages/editor/App.tsx +++ b/packages/editor/App.tsx @@ -4655,6 +4655,8 @@ const App: React.FC = () => { isOpen={shouldShowPlanAIAnnouncement} origin={origin} providerName={selectedAIProvider?.name ?? null} + providers={aiProviders} + onSelectProvider={(providerId) => handleAIConfigChange({ providerId })} onOpenAI={handleOpenAIAnnouncement} onDismiss={dismissPlanAIAnnouncement} /> diff --git a/packages/ui/components/PlanAIAnnouncementDialog.tsx b/packages/ui/components/PlanAIAnnouncementDialog.tsx index f27a8dcbd..59c945ee3 100644 --- a/packages/ui/components/PlanAIAnnouncementDialog.tsx +++ b/packages/ui/components/PlanAIAnnouncementDialog.tsx @@ -5,10 +5,18 @@ import { AGENT_CONFIG, getAgentAIProviderTypes, getAgentName } from '@plannotato import { SparklesIcon } from './SparklesIcon'; import { getProviderMeta } from './ProviderIcons'; +interface PlanAIAnnouncementProvider { + id: string; + name: string; +} + interface PlanAIAnnouncementDialogProps { isOpen: boolean; origin?: Origin | null; providerName?: string | null; + /** Actually-detected providers (installed + authenticated). Cards matching one of these are selectable. */ + providers?: PlanAIAnnouncementProvider[]; + onSelectProvider?: (providerId: string) => void; onOpenAI: () => void; onDismiss: () => void; } @@ -27,6 +35,8 @@ export const PlanAIAnnouncementDialog: React.FC = isOpen, origin, providerName, + providers = [], + onSelectProvider, onOpenAI, onDismiss, }) => { @@ -67,25 +77,55 @@ export const PlanAIAnnouncementDialog: React.FC = const meta = getProviderMeta(providerType); const Icon = meta.icon; const isSelected = providerType === providerName; - return ( -
+ // A card is selectable only if the provider is actually detected on this machine. + const detected = providers.find(p => p.name === providerType) ?? null; + const isSelectable = Boolean(detected && onSelectProvider); + + const inner = ( + <>
{meta.label}
- {isSelected && ( + {isSelected ? (
selected
- )} + ) : !detected ? ( +
not installed
+ ) : null}
-
+ + ); + + if (!isSelectable) { + return ( +
+ {inner} +
+ ); + } + + return ( + ); })}