import { useState } from 'react'; import { AlertCircle } from 'lucide-react'; import { toast } from 'sonner'; import { api } from '@/api/client'; import type { Message } from '@/api/types'; import { Button } from '@/components/ui/button'; interface Props { message: Message; // 1-indexed position among cap-hit sentinels in this chat. The first // cap-hit is 1, second is 2, third is 3 (hard ceiling). capHitPosition: number; // Only the most recent sentinel shows the Continue button. Older ones // render text-only — they've already been continued past. isLatest: boolean; } // Hard ceiling = 3 cap-hits per chat ⇒ 2 continues max. Lives here in sync // with insertCapHitSentinel's `canContinue = priorCount < 2` rule in // services/inference.ts. const MAX_CONTINUES = 2; export function CapHitSentinel({ message, capHitPosition, isLatest }: Props) { const meta = message.metadata; // Defensive parse — if the row is somehow missing metadata we still render // the bare text rather than crashing the chat. const isCapHit = meta !== null && typeof meta === 'object' && meta.kind === 'cap_hit'; const limit = isCapHit ? meta.limit : null; const canContinue = isCapHit ? meta.can_continue : false; const agentName = isCapHit ? meta.agent_name : null; // `capHitPosition` is 1-indexed; `MAX_CONTINUES - (position - 1)` is the // number of continues remaining including this one. Clamped to ≥0. const remaining = Math.max(0, MAX_CONTINUES - (capHitPosition - 1)); const [continuing, setContinuing] = useState(false); async function handleContinue() { if (continuing || !canContinue || !isLatest) return; setContinuing(true); try { await api.chats.continue(message.chat_id, message.id); } catch (err) { toast.error(err instanceof Error ? err.message : 'continue failed'); } finally { setContinuing(false); } } // Tooltip wording from the v1.8.2 spec. Disabled state takes precedence — // the spec text "Hard limit reached — start a new chat" matches what the // server returns when canContinue is false. const enabledTooltip = limit ? `Resumes with a fresh budget of ${limit} tool calls. ${remaining} continue${remaining === 1 ? '' : 's'} remaining on this chat.` : undefined; const disabledTooltip = 'Hard limit reached — start a new chat'; return (