import { useRef } from 'react' import { AiPanelComposer, AiPanelContextBar, AiPanelHeader, AiPanelMessageHistory, } from './AiPanelChrome' import { DEFAULT_AI_AGENT, getAiAgentDefinition, type AiAgentId } from '../lib/aiAgents' import { type NoteListItem } from '../utils/ai-context' import type { VaultEntry } from '../types' import { useAiPanelController, type AiPanelController } from './useAiPanelController' import { useAiPanelPromptQueue } from './useAiPanelPromptQueue' import { useAiPanelFocus } from './useAiPanelFocus' export type { AiAgentMessage } from '../hooks/useCliAiAgent' interface AiPanelProps { onClose: () => void onOpenNote?: (path: string) => void onUnsupportedAiPaste?: (message: string) => void defaultAiAgent?: AiAgentId defaultAiAgentReady?: boolean onFileCreated?: (relativePath: string) => void onFileModified?: (relativePath: string) => void onVaultChanged?: () => void vaultPath: string activeEntry?: VaultEntry | null /** Direct content of the active note from the editor tab. */ activeNoteContent?: string | null entries?: VaultEntry[] openTabs?: VaultEntry[] noteList?: NoteListItem[] noteListFilter?: { type: string | null; query: string } } interface AiPanelViewProps { controller: AiPanelController onClose: () => void onOpenNote?: (path: string) => void onUnsupportedAiPaste?: (message: string) => void defaultAiAgent?: AiAgentId defaultAiAgentReady?: boolean activeEntry?: VaultEntry | null entries?: VaultEntry[] } export function AiPanelView({ controller, onClose, onOpenNote, onUnsupportedAiPaste, defaultAiAgent: providedDefaultAiAgent, defaultAiAgentReady: providedDefaultAiAgentReady, activeEntry, entries, }: AiPanelViewProps) { const defaultAiAgent = providedDefaultAiAgent ?? DEFAULT_AI_AGENT const defaultAiAgentReady = providedDefaultAiAgentReady ?? true const useLegacyAiExperience = providedDefaultAiAgent === undefined && providedDefaultAiAgentReady === undefined const inputRef = useRef(null) const panelRef = useRef(null) const agentLabel = getAiAgentDefinition(defaultAiAgent).label const { agent, input, setInput, linkedEntries, hasContext, isActive, handleSend, handleNavigateWikilink, handleNewChat, } = controller useAiPanelPromptQueue({ agent, input, isActive, setInput }) useAiPanelFocus({ inputRef, panelRef, hasMessages: agent.messages.length > 0, isActive, onClose, }) return ( ) } export function AiPanel({ onClose, onOpenNote, onUnsupportedAiPaste, defaultAiAgent: providedDefaultAiAgent, defaultAiAgentReady: providedDefaultAiAgentReady, onFileCreated, onFileModified, onVaultChanged, vaultPath, activeEntry, activeNoteContent, entries, openTabs, noteList, noteListFilter, }: AiPanelProps) { const controller = useAiPanelController({ vaultPath, defaultAiAgent: providedDefaultAiAgent ?? DEFAULT_AI_AGENT, defaultAiAgentReady: providedDefaultAiAgentReady ?? true, activeEntry, activeNoteContent, entries, openTabs, noteList, noteListFilter, onOpenNote, onFileCreated, onFileModified, onVaultChanged, }) return ( ) }