import React from 'react'; import type { AIResponse } from '../../types'; import { SESSION_ASK_ERROR_CODES } from '../../utils/aiProvider'; /** What the reviewer chose on an "Ask this session" answer that could not run. */ export type SessionAskAction = 'wait' | 'interrupt'; /** * In-progress line for a question waiting on a busy session. Renders nothing * for any other response, so providers without a bridge are unaffected. */ export const SessionAskStatus: React.FC<{ response: AIResponse }> = ({ response }) => { if (!response.status) return null; return ( {' '} {response.status === 'waiting' ? 'Waiting for the session to finish its current turn…' : 'Interrupting the session…'} ); }; /** * Colour for an answer's error line: a busy session is a choice, not a * failure, so it reads muted; every other error keeps the destructive tone. */ export function sessionAskErrorTone(response: Pick): string { return response.errorCode === SESSION_ASK_ERROR_CODES.agentBusy ? 'text-muted-foreground' : 'text-destructive'; } const buttonClass = 'px-2 py-1 rounded-md text-[10px] font-medium transition-colors'; /** * Follow-up under an "Ask this session" error: * - the session is busy: ask when it finishes, or interrupt it and ask now; * - the session is gone or blocked: a plain note. Ask AI has no other provider * while a session is attached, so there is nothing to switch to. * Busy actions render only when the host passes a handler. */ export const SessionAskActions: React.FC<{ response: AIResponse; onAction?: (action: SessionAskAction) => void; canInterrupt?: boolean; }> = ({ response, onAction, canInterrupt = true }) => { if (!response.errorCode) return null; if (response.errorCode === SESSION_ASK_ERROR_CODES.agentBusy) { if (!onAction) return null; return (
{canInterrupt && }
); } if (response.errorCode === SESSION_ASK_ERROR_CODES.gone || response.errorCode === SESSION_ASK_ERROR_CODES.blocked) { const gone = response.errorCode === SESSION_ASK_ERROR_CODES.gone; return (

{gone ? 'Ask AI answers only from the session that opened Plannotator, and that session is gone, so Ask AI can\'t reach it.' : 'Ask AI answers only from the session that opened Plannotator, and that session is waiting on this decision, so Ask AI can\'t reach it until you decide.'}

); } return null; }; /** * A muted note under an "Ask this session" answer that stopped early because * the person typed into the session while it answered (the rest of that turn * went to their prompt). The partial answer above it stands. Renders nothing * for any other response. */ export const SessionAskNote: React.FC<{ response: Pick }> = ({ response }) => { if (!response.notice) return null; return (

{response.notice}

); };