Skip to content

fix(gemini): sync waitingResponseRef on stop and add useGeminiMessage tests#1370

Merged
piorpua merged 1 commit intomainfrom
zynx/fix/gemini-reset-state-ref-sync
Mar 17, 2026
Merged

fix(gemini): sync waitingResponseRef on stop and add useGeminiMessage tests#1370
piorpua merged 1 commit intomainfrom
zynx/fix/gemini-reset-state-ref-sync

Conversation

@piorpua
Copy link
Copy Markdown
Contributor

@piorpua piorpua commented Mar 17, 2026

Summary

  • Fix resetState ref sync: adds waitingResponseRef.current = false alongside the existing setWaitingResponse(false) call. Previously the ref could remain stale (true) between the async React state update and the next render cycle. All other write-sites for waitingResponse already perform the double-write; resetState was the only exception.
  • Export useGeminiMessage: makes the hook importable for isolated unit testing.
  • Add regression tests (tests/unit/useGeminiMessage.dom.test.ts): three cases covering resetState() state reset, activeMsgIdRef clearing, and correct event filtering after a new request begins.
  • Update coverage config: include GeminiSendBox.tsx in vitest.config.ts.

Test plan

  • bun run test -- useGeminiMessage — all 3 new tests pass
  • bunx tsc --noEmit — no type errors
  • bun run lint:fix — no errors (pre-existing warnings only)
  • Manual: stop a running Gemini conversation and verify the stop button disappears immediately

Closes #1354

… tests

- Add `waitingResponseRef.current = false` inside `resetState` to keep the
  ref in sync with the state update. Previously only `setWaitingResponse(false)`
  was called (async React update), leaving the ref stale until the next render.
  Every other write-site for waitingResponse already performs the double-write.

- Export `useGeminiMessage` so it can be unit-tested in isolation.

- Add three regression tests in `tests/unit/useGeminiMessage.dom.test.ts`:
  1. resetState() resets `running` to false
  2. resetState() clears activeMsgIdRef so thought events from new messages
     are no longer filtered
  3. Full lifecycle: old request → resetState → new request → correct filtering

- Include GeminiSendBox.tsx in vitest coverage tracking.

Follow-up to #1354
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

HIGH Issues

1. New console.log statements in renderer code (debug hygiene / production noise)

File: src/renderer/pages/conversation/gemini/GeminiSendBox.tsx:140-170

console.log(
  `%c[RequestTrace]%c ✅ FINISH | ${requestTraceRef.current.provider}${requestTraceRef.current.modelId} | ${duration}ms | ${new Date().toISOString()}`,
  'color: #52c41a; font-weight: bold',
  'color: inherit'
);
console.log(
  `%c[RequestTrace]%c ➡️ START | ${requestTraceRef.current.provider}${trace.modelId} | ${new Date().toISOString()}`,
  'color: #1890ff; font-weight: bold',
  'color: inherit',
  trace
);
console.log(
  `%c[RequestTrace]%c ❌ ERROR | ${requestTraceRef.current.provider}${requestTraceRef.current.modelId} | ${duration}ms | ${new Date().toISOString()}`,
  'color: #ff4d4f; font-weight: bold',
  'color: inherit',
  message.data
);

Problem: The PR introduces/keeps console.log in production renderer code. This violates the project’s debug hygiene expectations (no-console: warn) and will add noisy logs for all users during normal usage (every request start/finish/error). Since the PR is already touching this area, it’s a good time to ensure these logs are gated or removed.

Fix: Gate these logs behind a debug flag (e.g., import.meta.env.DEV, process.env.NODE_ENV !== 'production', or a project-specific logger), or replace with the project’s logging facility if one exists.

Example:

const isDev = import.meta.env?.DEV ?? process.env.NODE_ENV !== 'production';

if (isDev) {
  console.log(/* ... */);
}

Or:

logger.debug('[RequestTrace] ...', { trace });

MEDIUM Issues

2. Hook export from a UI module increases coupling; consider extracting to a dedicated hook module

File: src/renderer/pages/conversation/gemini/GeminiSendBox.tsx

The PR changes:

export const useGeminiMessage = (conversation_id: string, onError?: (message: IResponseMessage) => void) => {

Recommendation: Exporting the hook is fine for testing, but exporting it from GeminiSendBox.tsx forces tests (and any future consumers) to import a large UI module with many renderer/UI dependencies. You already had to mock a lot to load the module in the new test file, which is a sign of tight coupling.

Fix: Move useGeminiMessage into a dedicated file (e.g. src/renderer/pages/conversation/gemini/hooks/useGeminiMessage.ts) and keep GeminiSendBox.tsx focused on UI composition. This will:

  • reduce test mocking surface,
  • speed up tests,
  • make the hook reusable and easier to reason about.

Summary

Level Count
CRITICAL 0
HIGH 1
MEDIUM 1

🤖 This review was generated by AI and may contain inaccuracies. Please focus on issues you agree with and feel free to disregard any that seem incorrect. Thank you for your contribution!

@piorpua piorpua merged commit 064b896 into main Mar 17, 2026
23 checks passed
@piorpua piorpua deleted the zynx/fix/gemini-reset-state-ref-sync branch March 17, 2026 11:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants