Skip to content

feat: streaming-on by default, structured default, agent-style hotword block middle#442

Merged
appergb merged 1 commit into
betafrom
fix/streaming-default-prompt-restructure
May 15, 2026
Merged

feat: streaming-on by default, structured default, agent-style hotword block middle#442
appergb merged 1 commit into
betafrom
fix/streaming-default-prompt-restructure

Conversation

@appergb
Copy link
Copy Markdown
Collaborator

@appergb appergb commented May 15, 2026

User description

Summary

围绕用户测试反馈做 4 项调整(A-D):

  • A `streaming_insert` 默认 `false → true`:流式落字感知延迟低,所有 fallback case 已经接好(CJK IME / Codex / Gemini 自动回落到一次性路径)
  • B `default_mode`: `Light → Structured`:新装用户开箱默认走清晰结构 mode
  • C 热词模块从 prompt 末尾移到「ROLE_BLOCK 之后、task 之前」:
    • 新增 `types.rs::HOTWORDS_PLACEHOLDER = "{{HOTWORDS}}"`
    • default mode prompt 拼接顺序:`ROLE_BLOCK + {{HOTWORDS}} + task + COMMON_RULES + OUTPUT_BLOCK`
    • `polish.rs::build_hotword_block` 统一生成 agent-style 错别字纠正 + 热词列表文本,明确告诉模型「转写来自 ASR 可能含错别字」
    • preview 跟 system prompt 用同一段文本(消除不一致)
  • D Style Pack 新建预填示例 prompt:`Style.tsx::NEW_PACK_PROMPT_TEMPLATE` 含 4 段标准结构 + `{{HOTWORDS}}` 占位符

Test plan

代码层:

  • `cargo test --lib` → 263 全过
  • `tsc --noEmit` → 0 error

手工验证(维护者本地测试 1.3.2-2 构建装到 /Applications):

  • 默认 streaming 落字:录一段长话,字逐字落到光标 ✓
  • 默认风格 = Structured ✓
  • 「ZIP」识别为 VIP 时 polished 改回 ZIP ✓
  • Style Pack 新建编辑器看到预填示例 prompt ✓
  • 无明显回归,UX 流畅

兼容性

  • 用户自定义 prompt(无 `{{HOTWORDS}}` 占位符)+ 热词非空 → fallback 拼到末尾(兼容历史)
  • 空热词 + 自定义 prompt → 原 prompt 不变(保留旧测试断言)
  • `compose_system_prompt_uses_user_style_system_prompt_as_base` 等 263 个单测全过

不发 tag

按 hotfix 计划,merge 到 beta 后发 tag。等下一个 PR(polish retry 修复)一起出 1.3.2-3。


PR Type

Enhancement, Tests


Description

  • Enable streaming and structured defaults

  • Rework hotword prompt injection

  • Keep preview and runtime prompts aligned

  • Update mocks, fixtures, and template


Diagram Walkthrough

flowchart LR
  T["types.rs defaults and placeholder"]
  P["polish.rs prompt composition"]
  S["Style.tsx new pack template"]
  M["ipc.ts and test fixtures"]

  T -- "feeds default prompt structure" --> P
  T -- "provides placeholder for UI template" --> S
  T -- "updates mocked preferences" --> M
  S -- "matches runtime hotword block" --> P
Loading

File Walkthrough

Relevant files

…otword block in middle

围绕 user 反馈(用户主动测试后给的迭代清单)做 4 项调整:

A. streaming_insert 默认 false → true
   - 流式落字感知延迟低,所有 fallback case 都已经接好
   - CJK IME / Codex / Gemini provider 自动回落到一次性路径,对存量用户无感
   - 影响 mock + test fixture 一并更新

B. default_mode: PolishMode::Light → PolishMode::Structured
   - 新装用户开箱默认走清晰结构 mode,对多事项口述场景更合适

C. 热词与纠错模块从「prompt 末尾」移到「ROLE_BLOCK 之后」
   - 新增 types.rs::HOTWORDS_PLACEHOLDER = "{{HOTWORDS}}"
   - default_style_system_prompt_for_mode 拼接顺序:
     ROLE_BLOCK + {{HOTWORDS}} + task_and_example + COMMON_RULES + OUTPUT_BLOCK
   - polish.rs::build_hotword_block 统一生成 agent-style 错别字纠正 + 热词列表文本
     (明确告诉模型「转写来自 ASR 可能含错别字」,比旧的「热词:...」措辞更强)
   - polish.rs::compose_system_prompt 找占位符替换;用户自定义 prompt 无占位符 + 热词
     非空 → 末尾追加(兼容历史);空热词 → 原 prompt 不变(保留旧测试断言)
   - preview 跟 system prompt 用同一段文本,消除「设置看一段,发给 LLM 是另一段」不一致

D. Style Pack 新建预填示例 prompt
   - Style.tsx 新增 NEW_PACK_PROMPT_TEMPLATE 含 # 角色 / {{HOTWORDS}} / # 任务 /
     # 通用规则 / # 输出 4 段结构,用户照着改即可
   - 让用户看到 placeholder 怎么用,决定是否保留/移动/删除

cargo test 263 全过;tsc 0 error。

测试反馈:本地构建 1.3.2-2 装到 /Applications 跑通 A-D 全部功能,无回归。
@github-actions
Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ No major issues detected

@appergb appergb merged commit 1f5051d into beta May 15, 2026
4 checks passed
@appergb appergb deleted the fix/streaming-default-prompt-restructure branch May 15, 2026 03:41
appergb pushed a commit that referenced this pull request May 15, 2026
…443 round 2)

pr_agent #443 review 指出 Duplicate Request 风险:

> Retrying after send() fails can submit the same LLM request twice if the
> first attempt already reached the provider but the connection dropped
> before a response was returned. For non-idempotent completion calls, that
> can mean duplicate billing and two completions for one user action.

事实分析 reqwest::Error 各 variant:
- is_connect()  → TCP 握手没建立,server 不可能收到 → 安全 retry
- is_request()  → HTTP 请求层错误(构造问题),server 没收到完整请求 → 安全 retry
- is_timeout()  → client 设置的 timeout 到了,server 可能已经收到并在处理
                  (非幂等 completion 调用)→ 不安全 retry,会重复 billing

修法:从 retry 触发条件移除 `|| e.is_timeout()`。timeout 直接返回
LLMError::Timeout,不再重试。

user 实际看到的失败模式是 "error sending request"(reqwest::is_connect),不在
被移除范围内,覆盖率不变。

注:pr_agent 同轮提的 "Ticket compliance ❌ Not compliant 442" 是 false positive
—— pr_agent 把 PR description 里提到的 #442 当成本 PR 的 ticket id;#442 是另一
个独立 PR(A-D 默认值 / 提示词重构),已 merge。

cargo test 263 全过。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant