import React, { useCallback, useEffect, useRef } from 'react'; import { Box, Text } from '@anthropic/ink'; import { isMaxSubscriber, isProSubscriber, isTeamSubscriber } from '../utils/auth.js'; import { getGlobalConfig, saveGlobalConfig } from '../utils/config.js'; import type { EffortLevel } from '../utils/effort.js'; import { convertEffortValueToLevel, getDefaultEffortForModel, getOpusDefaultEffortConfig, toPersistableEffort, } from '../utils/effort.js'; import { parseUserSpecifiedModel } from '../utils/model/model.js'; import { updateSettingsForSource } from '../utils/settings/settings.js'; import type { OptionWithDescription } from './CustomSelect/select.js'; import { Select } from './CustomSelect/select.js'; import { effortLevelToSymbol } from './EffortIndicator.js'; import { PermissionDialog } from './permissions/PermissionDialog.js'; type EffortCalloutSelection = EffortLevel | undefined | 'dismiss'; type Props = { model: string; onDone: (selection: EffortCalloutSelection) => void; }; const AUTO_DISMISS_MS = 30_000; export function EffortCallout({ model, onDone }: Props): React.ReactNode { const defaultEffortConfig = getOpusDefaultEffortConfig(); // Latest-ref pattern — write via effect so React Compiler can memoize. const onDoneRef = useRef(onDone); useEffect(() => { onDoneRef.current = onDone; }); const handleCancel = useCallback((): void => { onDoneRef.current('dismiss'); }, []); // Permanently dismiss on mount so it only shows once useEffect(() => { markV2Dismissed(); }, []); // 30-second auto-dismiss timer useEffect(() => { const timeoutId = setTimeout(handleCancel, AUTO_DISMISS_MS); return () => clearTimeout(timeoutId); }, [handleCancel]); const defaultEffort = getDefaultEffortForModel(model); const defaultLevel = defaultEffort ? convertEffortValueToLevel(defaultEffort) : 'high'; const handleSelect = useCallback( (value: EffortLevel): void => { const effortLevel = value === defaultLevel ? undefined : value; updateSettingsForSource('userSettings', { effortLevel: toPersistableEffort(effortLevel), }); onDoneRef.current(value); }, [defaultLevel], ); const options: OptionWithDescription[] = [ { label: , value: 'medium', }, { label: , value: 'high' }, { label: , value: 'low' }, ]; return ( {defaultEffortConfig.dialogDescription} low {'·'} medium {'·'}{' '} high