feat: cross-platform streaming polish output (Win/Linux/macOS)#412
Merged
Conversation
PR Reviewer Guide 🔍(Review updated until commit ceda94e)Here are some key observations to aid the review process:
|
appergb
pushed a commit
that referenced
this pull request
May 11, 2026
…typed pr-agent #412 反馈两条都修: 1. \"Missing fallback\" —— typer 在第一字就失败(最常见:session 开始时已处 于 macOS Secure Input,或 SendInput / enigo 拒绝),已往返流式但 typed_chars=0。 旧逻辑仍返 already_streamed=true → 上层跳过 inserter → 用户看不到任何内容。 新逻辑:typed_chars=0 且 typer_failure 存在时,回退到一次性 inserter 路径 兜底,让 polish 文本通过正常 insertion 写出。 2. \"Wrong final text\" —— SSE 中途失败但已落字(typed_chars > 0),旧逻辑给 history 写 raw.text 而屏幕显示 partial polish,二者分叉。新逻辑:typer 持续 累积 typed_text(屏幕实际落字内容),history 与屏幕保持一致 —— 写 typed_text, polish_error 注明 \"streaming polish failed mid-stream after N chars\"。 实现:typer 任务返回值由 (typed_chars, first_failure) 变为 (typed_text, first_failure), 顶层用 typed_text.chars().count() 派生 typed_chars,并把 typed_text 在两个分支 都用上。 测试:cargo test --lib 222 passed。
|
Persistent review updated to latest commit 822a0fb |
appergb
pushed a commit
that referenced
this pull request
May 11, 2026
pr-agent #412 二次反馈 \"Clipboard Mismatch\":原来无条件先写 polish 完整 text 到剪贴板,再决定 typer 是否中途失败 → typer 中途失败时屏幕 / history 是 partial typed_text,但剪贴板是完整 polish,Cmd+V 会粘出用户从未见过的内容。 修复:先把 final_text 算出来(typer 失败时 = typed_text,正常时 = 完整 polish), 然后剪贴板、history、返回值统统用同一个 final_text,三处保持一致。 测试:cargo test --lib 222 passed。
|
Persistent review updated to latest commit 4030380 |
added 3 commits
May 12, 2026 01:33
让润色 LLM 的 SSE chunk 边到达边逐字模拟键盘事件落到光标,用户感知到的
处理时延显著降低(第一个 token 即开始落字)。Opt-in,不开等价于历史行为。
后端(src-tauri/src/)
- unicode_keystroke.rs(新):跨平台 Unicode 按键合成
- macOS:CGEvent + 切到 ABC 输入源(规避 CJK/日文 IME 拦截 Unicode 事件)+
Secure Input 探测;TIS 调用强制调度到主线程,规避 macOS 14+ TSM 断言。
- Windows:SendInput(KEYEVENTF_UNICODE),绕过 TSF / IME,不切输入法。
- Linux(实验):enigo Keyboard::text。X11 / XTest 稳定;Wayland 看 compositor
给不给 libei 权限,失败回落由调用方处理。
- polish.rs:OpenAI-compatible provider 新增 polish_streaming + 共用 SSE 解析
skeleton(与 QA streaming 同款);Codex provider 返 not-implemented 让上层降级
- coordinator.rs:StreamingPolishOutcome { Streamed, UnsupportedFallback, Failed }
+ polish_or_passthrough_streaming 分发器
- coordinator/dictation.rs::run_streaming_polish:
· 切到 ABC(macOS)→ spawn_blocking typer 串行读 mpsc → 调流式润色 →
drop tx → typer drain 退出 → 恢复输入源
· 中途取消 / typer 失败 / Secure Input 启用:drain 不爆,已流出去的字保留
· 流式成功:可选写回剪贴板(streaming_insert_save_clipboard,默认 on)
· 流式失败:已流的部分保留,未流时回落到 raw 一次性
· end_session 的 cancel 检查识别 already_streamed=true 走完收尾(撤销不掉)
- types.rs:UserPreferences 新增 streaming_insert(默认 false)+
streaming_insert_save_clipboard(默认 true),Wire/Deserialize/Default 三处同步
- lib.rs:mod unicode_keystroke
前端(src/)
- lib/types.ts + ipc.ts:UserPreferences 同步两字段 + mock 默认值
- lib/stylePrefs.test.ts:测试 fixture previousPrefs 补两字段
- pages/Settings.tsx:AdvancedSection 加流式 Card(Toggle ×2),按平台分发 hint
文案(mac / win / linux 三套)
- i18n/{zh-CN,en,ja,ko,zh-TW}:advanced 新增 8 个 streamingInsert* key,5 个
locale 完全对齐
验证范围
- macOS host:cargo check + cargo test --lib (222 pass) + npm run build (tsc + vite)
- Windows/Linux cfg 分支只走过 cargo check(cross-target 验证依赖 CI runner)
…typed pr-agent #412 反馈两条都修: 1. \"Missing fallback\" —— typer 在第一字就失败(最常见:session 开始时已处 于 macOS Secure Input,或 SendInput / enigo 拒绝),已往返流式但 typed_chars=0。 旧逻辑仍返 already_streamed=true → 上层跳过 inserter → 用户看不到任何内容。 新逻辑:typed_chars=0 且 typer_failure 存在时,回退到一次性 inserter 路径 兜底,让 polish 文本通过正常 insertion 写出。 2. \"Wrong final text\" —— SSE 中途失败但已落字(typed_chars > 0),旧逻辑给 history 写 raw.text 而屏幕显示 partial polish,二者分叉。新逻辑:typer 持续 累积 typed_text(屏幕实际落字内容),history 与屏幕保持一致 —— 写 typed_text, polish_error 注明 \"streaming polish failed mid-stream after N chars\"。 实现:typer 任务返回值由 (typed_chars, first_failure) 变为 (typed_text, first_failure), 顶层用 typed_text.chars().count() 派生 typed_chars,并把 typed_text 在两个分支 都用上。 测试:cargo test --lib 222 passed。
pr-agent #412 二次反馈 \"Clipboard Mismatch\":原来无条件先写 polish 完整 text 到剪贴板,再决定 typer 是否中途失败 → typer 中途失败时屏幕 / history 是 partial typed_text,但剪贴板是完整 polish,Cmd+V 会粘出用户从未见过的内容。 修复:先把 final_text 算出来(typer 失败时 = typed_text,正常时 = 完整 polish), 然后剪贴板、history、返回值统统用同一个 final_text,三处保持一致。 测试:cargo test --lib 222 passed。
4030380 to
ceda94e
Compare
|
Persistent review updated to latest commit ceda94e |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
User description
Summary
主要改动
Test plan
已知限制
PR Type
Enhancement, Bug fix
Description
Add opt-in streaming insertion pipeline
Implement cross-platform Unicode keystrokes
Preserve fallback on unsupported streaming
Add prefs, UI, translations
Diagram Walkthrough
File Walkthrough
6 files
Dispatch streaming polish outcomes and fallbacksStream deltas through keyboard typingAdd streaming polish provider supportImplement cross-platform Unicode typing helpersExtend user preferences TypeScript interfaceAdd streaming settings section to UI1 files
Register Unicode keystroke helper module2 files
Add streaming preference and clipboard fieldsUpdate mock settings for new fields5 files
Add streaming settings English copyAdd streaming settings Japanese copyAdd streaming settings Korean copyAdd streaming settings Simplified Chinese copyAdd streaming settings Traditional Chinese copy1 files
Extend preference fixtures for streaming