Skip to content

fix(gemini): stabilize ask reply state handling#735

Merged
jackwener merged 3 commits intojackwener:mainfrom
Astro-Han:fix/gemini-send
Apr 4, 2026
Merged

fix(gemini): stabilize ask reply state handling#735
jackwener merged 3 commits intojackwener:mainfrom
Astro-Han:fix/gemini-send

Conversation

@Astro-Han
Copy link
Copy Markdown
Contributor

@Astro-Han Astro-Han commented Apr 3, 2026

Description

Stabilize gemini ask by replacing the old reply detection path with a conservative reply-state model.

This change tightens three parts of the Gemini adapter:

  • confirms message submission before reading a reply
  • assigns reply ownership from the submitted user turn instead of stale indices or assistant counts
  • keeps transcript parsing as a low-trust fallback instead of the primary path

Related issue:
#390

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 🌐 New site adapter
  • 📝 Documentation
  • ♻️ Refactor
  • 🔧 CI / build / tooling

Checklist

  • I ran the checks relevant to this PR
  • I updated tests or docs if needed
  • I included output or screenshots when useful

Documentation (if adding/modifying an adapter)

  • Added doc page under docs/adapters/ (if new adapter)
  • Updated docs/adapters/index.md table (if new adapter)
  • Updated sidebar in docs/.vitepress/config.mts (if new adapter)
  • Updated README.md / README.zh-CN.md when command discoverability changed
  • Used positional args for the command's primary subject unless a named flag is clearly better
  • Normalized expected adapter failures to CliError subclasses instead of raw Error

Screenshots / Output

Checks:

  • npm test
  • npm run typecheck
  • npm run test:adapter -- src/clis/gemini/utils.test.ts src/clis/gemini/reply-state.test.ts src/clis/gemini/ask.test.ts

Manual verification:

  • npm run dev -- gemini ask "请只回复:RV1" --timeout 20 -f plain -> 💬 RV1
  • npm run dev -- gemini ask "请只回复:RV1" --timeout 20 -f plain -> 💬 RV1
  • npm run dev -- gemini ask "请只回复:RV3" --timeout 20 --new true -f plain -> 💬 RV3

@Astro-Han Astro-Han changed the title fix(gemini): stabilize ask response handling fix(gemini): stabilize ask reply state handling Apr 3, 2026
@Astro-Han
Copy link
Copy Markdown
Contributor Author

Astro-Han commented Apr 4, 2026

A quick follow-up on what this revision improves.

This version does not keep layering more heuristics onto the old path. Instead, it tightens gemini ask around a more conservative submission and reply-state model, with three main changes:

  1. Confirm submission before waiting for a reply
    After sending the prompt, the command no longer treats the latest visible text as the answer immediately. It first confirms that Gemini has actually accepted the message.

  2. Assign reply ownership from the current-round user turn
    Instead of relying on stale indices or assistant counts to guess which round a reply belongs to, it captures the current-round user anchor at submission time and only accepts assistant content that belongs after that anchor.

  3. Demote transcript parsing to a true fallback path
    Transcript parsing is now a low-trust fallback instead of the primary source of truth, which greatly reduces cases where welcome text, page chrome, or partial streamed text gets mistaken for the final answer.

This revision also adds state-driven tests and command-level verification for the main edge cases, especially:

  • running the same prompt twice in a row
  • the --new true path
  • cases where older history is loaded later and must not be mistaken for the current-round reply

In one sentence: this revision makes gemini ask much more reliable at distinguishing between “the message was actually submitted” and “the visible reply really belongs to this round.”

…matting

- Replace raw Error with CommandExecutionError for Node-side composer
  failures (prepareComposer, insertText) to match adapter error conventions
- Remove extra blank lines after __test__ export
Copy link
Copy Markdown
Owner

@jackwener jackwener left a comment

Choose a reason for hiding this comment

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

Review

Well-designed reply-state model that properly separates submission confirmation from response detection. The two-phase approach (waitForGeminiSubmission → waitForGeminiResponse) with user anchor turn ownership is a significant reliability improvement over the old transcript-diff approach.

Fixed: Node-side throw new Error(...)throw new CommandExecutionError(...) for composer failures (2 instances), matching the PR's stated goal of normalizing to CliError subclasses. Also cleaned up extra blank lines.

Minor note (non-blocking): createPageMock() is duplicated across 3 test files — could be extracted to a shared helper later.

35 tests pass, typecheck clean. LGTM.

- Remove unused areGeminiTurnsEqual and areGeminiLinesEqual functions
- Add Chinese sign-in label (登录) to sign-in detection for consistency
  with other Chinese labels already added in this PR
@jackwener jackwener merged commit 2c5066d into jackwener:main Apr 4, 2026
11 checks passed
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.

2 participants