From e01eac1892e386ba68667fdd11d2638f14d2a3e3 Mon Sep 17 00:00:00 2001 From: Marco Beretta <81851188+berry-13@users.noreply.github.com> Date: Sat, 8 Aug 2026 02:23:09 +0200 Subject: [PATCH] Fix ask answer handoff and OAuth warnings --- .../Chat/Messages/Content/ToolCallGroup.tsx | 11 ++++------- .../Content/__tests__/ToolCallGroup.test.tsx | 11 +++++++++++ client/src/hooks/Input/useAskAnswerMode.spec.ts | 13 ++++++++++++- client/src/hooks/Input/useAskAnswerMode.ts | 5 ++++- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/client/src/components/Chat/Messages/Content/ToolCallGroup.tsx b/client/src/components/Chat/Messages/Content/ToolCallGroup.tsx index 3952d92db5..880f379282 100644 --- a/client/src/components/Chat/Messages/Content/ToolCallGroup.tsx +++ b/client/src/components/Chat/Messages/Content/ToolCallGroup.tsx @@ -38,7 +38,7 @@ function hasFailedOutput(output: unknown): boolean { return typeof output === 'string' && isError(output); } -function hasPendingAuth(part: TMessageContentParts, isSubmitting: boolean): boolean { +function hasPendingAuth(part: TMessageContentParts): boolean { if (part.type !== ContentTypes.TOOL_CALL) { return false; } @@ -50,10 +50,7 @@ function hasPendingAuth(part: TMessageContentParts, isSubmitting: boolean): bool const progress = standardToolCall.progress ?? 0.1; return ( - typeof standardToolCall.auth === 'string' && - standardToolCall.auth.length > 0 && - progress < 1 && - (isSubmitting || hasFailedOutput(standardToolCall.output)) + typeof standardToolCall.auth === 'string' && standardToolCall.auth.length > 0 && progress < 1 ); } @@ -442,8 +439,8 @@ export default function ToolCallGroup({ [toolMetadata, isSubmitting], ); const hasPendingAuthRequest = useMemo( - () => parts.some(({ part }) => hasPendingAuth(part, isSubmitting)), - [parts, isSubmitting], + () => parts.some(({ part }) => hasPendingAuth(part)), + [parts], ); useEffect(() => { diff --git a/client/src/components/Chat/Messages/Content/__tests__/ToolCallGroup.test.tsx b/client/src/components/Chat/Messages/Content/__tests__/ToolCallGroup.test.tsx index 28f2aba69f..408b180ac2 100644 --- a/client/src/components/Chat/Messages/Content/__tests__/ToolCallGroup.test.tsx +++ b/client/src/components/Chat/Messages/Content/__tests__/ToolCallGroup.test.tsx @@ -310,6 +310,17 @@ describe('ToolCallGroup image hoisting', () => { expect(screen.getAllByText('Only allow sites you trust')).toHaveLength(1); }); + it('keeps the trust warning for a persisted incomplete authentication call', () => { + renderGroup({ + ...baseProps, + parts: [{ part: makeAuthPart('auth-persisted', 'zapier'), idx: 0 }], + lastContentIdx: 0, + renderPart: () => , + }); + + expect(screen.getByText('Only allow sites you trust')).toBeInTheDocument(); + }); + it('does not render a shared trust warning for completed authentication calls', () => { renderGroup({ ...baseProps, diff --git a/client/src/hooks/Input/useAskAnswerMode.spec.ts b/client/src/hooks/Input/useAskAnswerMode.spec.ts index 30d44f7a45..5fcc286e2b 100644 --- a/client/src/hooks/Input/useAskAnswerMode.spec.ts +++ b/client/src/hooks/Input/useAskAnswerMode.spec.ts @@ -141,7 +141,7 @@ describe('useAskAnswerMode', () => { expect(result.current.liveAsk).toBeNull(); }); - it('carries the composer answer into shared card state when collapsed', () => { + it('moves the composer answer into the card and clears it when drafts are disabled', () => { mockUseGetMessages.mockReturnValue({ data: liveAsk }); const { result } = renderHook(() => useAskAnswerMode('conversation-1')); @@ -151,6 +151,17 @@ describe('useAskAnswerMode', () => { actionId: 'a1', text: 'answer from A', }); + expect(mockResetComposer).toHaveBeenCalledTimes(1); + }); + + it('lets draft handoff restore the conversation composer when drafts are enabled', () => { + mockSaveDrafts = true; + mockUseGetMessages.mockReturnValue({ data: liveAsk }); + const { result } = renderHook(() => useAskAnswerMode('conversation-1')); + + act(() => result.current.collapse()); + + expect(mockResetComposer).not.toHaveBeenCalled(); }); it('restores the card answer into the composer when drafts are disabled', () => { diff --git a/client/src/hooks/Input/useAskAnswerMode.ts b/client/src/hooks/Input/useAskAnswerMode.ts index 27457e0f5b..a7dc59d6e3 100644 --- a/client/src/hooks/Input/useAskAnswerMode.ts +++ b/client/src/hooks/Input/useAskAnswerMode.ts @@ -187,12 +187,15 @@ export default function useAskAnswerMode(conversationId?: string | null) { const composerAnswer = formContext?.getValues('text') ?? answerText; morphTransition(() => { setAnswerDraft({ actionId: liveAsk.actionId, text: composerAnswer }); + if (!saveDrafts) { + formContext?.reset(); + } setCollapsedIds((prev) => prev.includes(liveAsk.actionId) ? prev : [...prev, liveAsk.actionId], ); }); } - }, [liveAsk, formContext, answerText, setAnswerDraft, setCollapsedIds]); + }, [liveAsk, formContext, answerText, saveDrafts, setAnswerDraft, setCollapsedIds]); const expand = useCallback(() => { if (liveAsk) {