( lastMessage: AssistantMessage, toolUseContext?: ToolUseContext, timeoutMs: number = TOOL_HOOK_EXECUTION_TIMEOUT_MS, )
| 3736 | } |
| 3737 | |
| 3738 | export async function executeStopFailureHooks( |
| 3739 | lastMessage: AssistantMessage, |
| 3740 | toolUseContext?: ToolUseContext, |
| 3741 | timeoutMs: number = TOOL_HOOK_EXECUTION_TIMEOUT_MS, |
| 3742 | ): Promise<void> { |
| 3743 | const appState = toolUseContext?.getAppState() |
| 3744 | // executeHooksOutsideREPL hardcodes main sessionId (:2738). Agent frontmatter |
| 3745 | // hooks (registerFrontmatterHooks) key by agentId; gating with agentId here |
| 3746 | // would pass the gate but fail execution. Align gate with execution. |
| 3747 | const sessionId = getSessionId() |
| 3748 | if (!hasHookForEvent('StopFailure', appState, sessionId)) return |
| 3749 | |
| 3750 | const rawContent = lastMessage.message?.content |
| 3751 | const lastAssistantText = |
| 3752 | (Array.isArray(rawContent) |
| 3753 | ? extractTextContent( |
| 3754 | rawContent as readonly { readonly type: string }[], |
| 3755 | '\n', |
| 3756 | ).trim() |
| 3757 | : typeof rawContent === 'string' |
| 3758 | ? rawContent.trim() |
| 3759 | : '') || undefined |
| 3760 | |
| 3761 | // Some createAssistantAPIErrorMessage call sites omit `error` (e.g. |
| 3762 | // image-size at errors.ts:431). Default to 'unknown' so matcher filtering |
| 3763 | // at getMatchingHooks:1525 always applies. |
| 3764 | const error = (lastMessage.error as string | undefined) ?? 'unknown' |
| 3765 | const hookInput: StopFailureHookInput = { |
| 3766 | ...createBaseHookInput(undefined, undefined, toolUseContext), |
| 3767 | hook_event_name: 'StopFailure', |
| 3768 | error, |
| 3769 | error_details: lastMessage.errorDetails, |
| 3770 | last_assistant_message: lastAssistantText, |
| 3771 | } |
| 3772 | |
| 3773 | await executeHooksOutsideREPL({ |
| 3774 | getAppState: toolUseContext?.getAppState, |
| 3775 | hookInput, |
| 3776 | timeoutMs, |
| 3777 | matchQuery: error, |
| 3778 | }) |
| 3779 | } |
| 3780 | |
| 3781 | /** |
| 3782 | * Execute stop hooks if configured |
no test coverage detected