import { useMemo, type ReactNode } from "react" import { useTranslations } from "next-intl" import type { AgentType, ConnectionStatus, PromptCapabilitiesInfo, PromptDraft, SessionConfigOptionInfo, SessionModeInfo, AvailableCommandInfo, } from "@/lib/types" import type { PendingPermission, PendingQuestion, ClaudeApiRetryState, } from "@/contexts/acp-connections-context" import type { QueuedMessage } from "@/hooks/use-message-queue" import { Loader2 } from "lucide-react" import { ChatInput } from "@/components/chat/chat-input" import { PermissionDialog } from "@/components/chat/permission-dialog" import { QuestionDialog } from "@/components/chat/question-dialog" interface ConversationShellProps { status: ConnectionStatus | null promptCapabilities: PromptCapabilitiesInfo defaultPath?: string agentName?: string error: string | null claudeApiRetry: ClaudeApiRetryState | null pendingPermission: PendingPermission | null pendingQuestion: PendingQuestion | null onFocus: () => void onSend: (draft: PromptDraft, modeId?: string | null) => void onCancel: () => void onRespondPermission: (requestId: string, optionId: string) => void onAnswerQuestion: (answer: string) => void children: ReactNode modes?: SessionModeInfo[] configOptions?: SessionConfigOptionInfo[] modeLoading?: boolean configOptionsLoading?: boolean selectorsLoading?: boolean selectedModeId?: string | null onModeChange?: (modeId: string) => void onConfigOptionChange?: (configId: string, valueId: string) => void agentType?: AgentType | null availableCommands?: AvailableCommandInfo[] | null attachmentTabId?: string | null draftStorageKey?: string | null hideInput?: boolean isActive?: boolean queue?: QueuedMessage[] onEnqueue?: (draft: PromptDraft, modeId: string | null) => void onQueueReorder?: (items: QueuedMessage[]) => void onQueueEdit?: (id: string) => void onQueueDelete?: (id: string) => void editingItemId?: string | null editingDraftText?: string | null isEditingQueueItem?: boolean onSaveQueueEdit?: (draft: PromptDraft) => void onCancelQueueEdit?: () => void onForkSend?: (draft: PromptDraft, modeId?: string | null) => void } export function ConversationShell({ status, promptCapabilities, defaultPath, agentName, error, claudeApiRetry, pendingPermission, pendingQuestion, onFocus, onSend, onCancel, onRespondPermission, onAnswerQuestion, children, modes, configOptions, modeLoading = false, configOptionsLoading = false, selectorsLoading = false, selectedModeId, onModeChange, onConfigOptionChange, agentType, availableCommands, attachmentTabId, draftStorageKey, hideInput = false, isActive, queue, onEnqueue, onQueueReorder, onQueueEdit, onQueueDelete, editingItemId, editingDraftText, isEditingQueueItem, onSaveQueueEdit, onCancelQueueEdit, onForkSend, }: ConversationShellProps) { const tAcp = useTranslations("Folder.chat.acpConnections") const retryLineText = useMemo(() => { const retry = claudeApiRetry if (!retry) return null const retryAttempt = retry.attempt !== null && retry.attempt !== undefined ? Math.trunc(retry.attempt) : null const retryMax = retry.maxRetries !== null && retry.maxRetries !== undefined ? Math.trunc(retry.maxRetries) : null const retryDelaySeconds = retry.retryDelayMs !== null && retry.retryDelayMs !== undefined ? (retry.retryDelayMs / 1000).toFixed(1) : null const errorLabel = retry.error ?? tAcp("claudeApiRetry.fallbackError") const statusLabel = retry.errorStatus !== null && retry.errorStatus !== undefined ? tAcp("claudeApiRetry.httpStatus", { status: Math.trunc(retry.errorStatus), }) : "" const retryLabel = retryAttempt !== null && retryMax !== null ? tAcp("claudeApiRetry.retryingWithMax", { attempt: retryAttempt, max: retryMax, }) : retryAttempt !== null ? tAcp("claudeApiRetry.retryingAttempt", { attempt: retryAttempt, }) : tAcp("claudeApiRetry.retrying") const delayLabel = retryDelaySeconds !== null ? tAcp("claudeApiRetry.nextRetryIn", { seconds: retryDelaySeconds, }) : null return delayLabel !== null ? tAcp("claudeApiRetry.lineWithDelay", { error: errorLabel, status: statusLabel, retry: retryLabel, delay: delayLabel, }) : tAcp("claudeApiRetry.line", { error: errorLabel, status: statusLabel, retry: retryLabel, }) }, [claudeApiRetry, tAcp]) return (