Skip to content

fix(gemini): restore context after stopping a reply#1932

Merged
piorpua merged 1 commit intoiOfficeAI:mainfrom
cdxiaodong:fix/810-gemini-stop-context
Mar 30, 2026
Merged

fix(gemini): restore context after stopping a reply#1932
piorpua merged 1 commit intoiOfficeAI:mainfrom
cdxiaodong:fix/810-gemini-stop-context

Conversation

@cdxiaodong
Copy link
Copy Markdown
Member

Summary

  • rebuild Gemini conversation state from persisted history after the user stops a reply
  • reset the in-memory Gemini chat before reinjecting recent history so aborted partial turns do not poison the next request
  • add a regression test for stop-time history recovery

Root Cause

Stopping a Gemini reply aborted the active stream, but the worker kept its in-memory chat state. If the stop happened mid-turn, the next send could reuse a malformed chat history and lose prior context.

Testing

  • bun run format
  • bun run lint
  • bunx tsc --noEmit
  • bun run test

Closes #810

@sentry
Copy link
Copy Markdown

sentry bot commented Mar 30, 2026

Codecov Report

❌ Patch coverage is 80.00000% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/process/agent/gemini/index.ts 66.66% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@piorpua piorpua added the bot:reviewing Review in progress (mutex) label Mar 30, 2026
@piorpua
Copy link
Copy Markdown
Contributor

piorpua commented Mar 30, 2026

Code Review:fix(gemini): restore context after stopping a reply (#1932)

变更概述

本 PR 修复了 Gemini 对话在用户中途停止回复后丢失上下文的问题。通过在 GeminiAgentManager.stop() 中重写父类方法,在中断流后重新从数据库注入历史记录;同时在 GeminiAgent.injectConversationHistory() 中先 resetChat() 清空内存状态,再重注历史,防止污染下一次请求。新增了回归测试 geminiAbortRecovery.test.ts


方案评估

结论:✅ 方案合理

方案准确定位了 bug 根源:中途停止流时内存中的 Gemini chat 状态可能残留不完整 turn,导致下一次请求使用了污染状态。通过先 resetChat() 再重注历史,从设计上隔离了停止与重建两个阶段,与已有 injectHistoryFromDatabase 路径完全一致。skillsIndexPrependedOnce = false 的重置也正确处理了技能索引需要重新插入的场景。


问题清单

🔵 LOW — geminiClient 为 null 的分支未被测试覆盖

文件src/process/agent/gemini/index.ts,第 929–931 行

问题代码

if (this.geminiClient) {
  await this.geminiClient.resetChat();
}

问题说明:Codecov 报告此处有 1 个 partial line(patch 覆盖率 66.67%)。geminiClientnull 时的分支(即跳过 resetChat 直接继续)没有对应测试。该分支逻辑本身正确,仅覆盖率不足。

修复建议:在测试中增加一个 geminiClientnull/undefined 的用例:

it('skips resetChat when geminiClient is null', async () => {
  const setUserMemory = vi.fn();
  const fakeAgent = {
    config: { setUserMemory },
    workspace: '/tmp/workspace',
    settings: {},
    geminiClient: null,  // no client
    historyPrefix: null,
    historyUsedOnce: true,
    skillsIndexPrependedOnce: true,
  } as unknown as GeminiAgent;

  await GeminiAgent.prototype.injectConversationHistory.call(fakeAgent, 'User: hi\nAssistant: hello');

  expect(setUserMemory).toHaveBeenCalled(); // should still proceed
});

汇总

# 严重级别 文件 问题
1 🔵 LOW src/process/agent/gemini/index.ts:929 geminiClient 为 null 分支未覆盖测试

结论

批准合并 — 无阻塞性问题,修复方案正确,测试质量良好,仅有一处 LOW 级别覆盖率不足,不影响合并。


本报告由本地 pr-review skill 生成,包含完整项目上下文,无截断限制。

@piorpua
Copy link
Copy Markdown
Contributor

piorpua commented Mar 30, 2026

✅ 已自动 review,无阻塞性问题,正在触发自动合并。

@piorpua piorpua merged commit acfc544 into iOfficeAI:main Mar 30, 2026
14 checks passed
@piorpua piorpua added bot:done Auto-merged by bot and removed bot:reviewing Review in progress (mutex) labels Mar 30, 2026
wuhao1477 added a commit to wuhao1477/AionUi that referenced this pull request Mar 30, 2026
* 'main' of github.com:wuhao1477/AionUi: (40 commits)
  fix(agents): prevent unhandled promise rejection in bootstrap initialization (iOfficeAI#1933)
  fix(gemini): restore context after stopping a reply (iOfficeAI#1932)
  fix(codex): reject start promise immediately on process exit during startup (iOfficeAI#1929)
  fix(conversation): sync renamed titles with detail view (iOfficeAI#1927)
  fix(paste): deduplicate filenames when pasting multiple images simultaneously
  fix(mobile): add SafeArea support and update app icon (iOfficeAI#1926)
  fix(database): guard against undefined params in databaseBridge providers (iOfficeAI#1924)
  fix(conversation): validate type field before creating conversation (iOfficeAI#1921)
  fix(docs): restore wechat_group_5.png reference to wx-5.png in readme
  fix(snapshot): add maxBuffer to git add/commit exec calls (iOfficeAI#1914)
  refactor(acp): consolidate AGENT_SKILLS_DIRS into ACP_BACKENDS_ALL (iOfficeAI#1913)
  fix(gemini): guard against EACCES in workspace realpath during init (ELECTRON-BM) (iOfficeAI#1912)
  fix(channels): send raw QR ticket instead of page URL in WeChat WebUI login SSE (iOfficeAI#1910)
  .md format
  chore(pr-automation): fix missed sleep 5 in comment to sleep 10
  chore(pr-automation): increase auto-merge retry delay to 10s
  chore(pr-automation): add 5s retry for transient GitHub mergeStateStatus UNKNOWN
  fix(docs): remove trailing whitespace in OfficeCLI readmes
  chore(pr-automation): verify auto-merge success before labeling bot:done
  fix(snapshot): guard against non-existent workspace in WorkspaceSnapshotService.init (iOfficeAI#1906)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:done Auto-merged by bot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: AI loses conversation context after stop (regression)

2 participants