diff --git a/frontend/src/components/NormalizedConversation/RetryEditorInline.tsx b/frontend/src/components/NormalizedConversation/RetryEditorInline.tsx index 0df866b3..c9cfb3db 100644 --- a/frontend/src/components/NormalizedConversation/RetryEditorInline.tsx +++ b/frontend/src/components/NormalizedConversation/RetryEditorInline.tsx @@ -14,7 +14,7 @@ import { useUserSystem } from '@/components/ConfigProvider'; import { useBranchStatus } from '@/hooks/useBranchStatus'; import { useVariant } from '@/hooks/useVariant'; import { useRetryProcess } from '@/hooks/useRetryProcess'; -import type { ExecutorAction, ExecutorProfileId } from 'shared/types'; +import { extractProfileFromAction } from '@/utils/executor'; export function RetryEditorInline({ attempt, @@ -46,26 +46,7 @@ export function RetryEditorInline({ (p) => p.id === executionProcessId ); if (!process?.executor_action) return null; - - const extractProfile = ( - action: ExecutorAction | null - ): ExecutorProfileId | null => { - let curr: ExecutorAction | null = action; - while (curr) { - const typ = curr.typ; - switch (typ.type) { - case 'CodingAgentInitialRequest': - case 'CodingAgentFollowUpRequest': - return typ.executor_profile_id; - case 'ScriptRequest': - curr = curr.next_action; - continue; - } - } - return null; - }; - - return extractProfile(process.executor_action)?.variant ?? null; + return extractProfileFromAction(process.executor_action)?.variant ?? null; }, [attemptData.processes, executionProcessId]); const { selectedVariant, setSelectedVariant } = useVariant({ diff --git a/frontend/src/components/tasks/TaskFollowUpSection.tsx b/frontend/src/components/tasks/TaskFollowUpSection.tsx index c35f6420..64f90b35 100644 --- a/frontend/src/components/tasks/TaskFollowUpSection.tsx +++ b/frontend/src/components/tasks/TaskFollowUpSection.tsx @@ -47,11 +47,8 @@ import WYSIWYGEditor from '@/components/ui/wysiwyg'; import { useRetryUi } from '@/contexts/RetryUiContext'; import { useFollowUpSend } from '@/hooks/useFollowUpSend'; import { useVariant } from '@/hooks/useVariant'; -import type { - DraftFollowUpData, - ExecutorAction, - ExecutorProfileId, -} from 'shared/types'; +import type { DraftFollowUpData, ExecutorProfileId } from 'shared/types'; +import { extractProfileFromAction } from '@/utils/executor'; import { buildResolveConflictsInstructions } from '@/lib/conflicts'; import { useTranslation } from 'react-i18next'; import { useScratch } from '@/hooks/useScratch'; @@ -152,29 +149,11 @@ export function TaskFollowUpSection({ // Variant selection - derive default from latest process const latestProfileId = useMemo(() => { if (!processes?.length) return null; - - const extractProfile = ( - action: ExecutorAction | null - ): ExecutorProfileId | null => { - let curr: ExecutorAction | null = action; - while (curr) { - const typ = curr.typ; - switch (typ.type) { - case 'CodingAgentInitialRequest': - case 'CodingAgentFollowUpRequest': - return typ.executor_profile_id; - case 'ScriptRequest': - curr = curr.next_action; - continue; - } - } - return null; - }; return ( processes .slice() .reverse() - .map((p) => extractProfile(p.executor_action ?? null)) + .map((p) => extractProfileFromAction(p.executor_action ?? null)) .find((pid) => pid !== null) ?? null ); }, [processes]); diff --git a/frontend/src/utils/executor.ts b/frontend/src/utils/executor.ts index 9382a84b..b83ae1cf 100644 --- a/frontend/src/utils/executor.ts +++ b/frontend/src/utils/executor.ts @@ -57,6 +57,7 @@ export function extractProfileFromAction( case 'CodingAgentFollowUpRequest': return typ.executor_profile_id; case 'ScriptRequest': + default: curr = curr.next_action; continue; }