Skip to content

fix: ask 工具终端渲染清理与宽度自适应换行 - #454

Merged
liuqihonggit merged 3 commits into
mainfrom
w4
Oct 22, 2026
Merged

liuqihonggit merged 3 commits into
mainfrom
w4

Conversation

@liuqihonggit

Copy link
Copy Markdown
Owner

Summary

  • 根因一:AI 生成文本混入 CR 段(\r\r\n 病态行尾)直接写终端导致超长换行错乱;根因二:长问题/选项裸写靠终端原生 wrap(ANSI 转义序列在任意列截断、中文宽字符不计数)
  • 新建 QuestionTextSanitizer:Sanitize(CR 段贪吃折叠单换行、\n\r 防双换行、ESC/NUL 剥除、TAB 转空格)+ Wrap(显示宽度词边界折行、CJK 宽字符 2 列计、悬挂缩进、超宽词硬切)
  • TerminalInteractiveService 全渲染点接入:question/header 折行、选项标签悬挂对齐、描述缩进折行、ANSI 按行独立包夹

Test plan

  • QuestionTextSanitizerTests 18 用例(含 \x00 变长转义陷阱改 \u 定长)
  • host.tests 全量 1433 绿(含 AskClarify 既有回归)

@liuqihonggit
liuqihonggit enabled auto-merge (squash) October 22, 2026 14:55
根因: AI 生成文本混入 CR 段(\r\r\n 病态行尾)直接写终端导致超长换行错乱;长问题/选项裸写靠终端原生 wrap(ANSI 转义序列在任意列截断、中文宽字符不计数)

修复:
- 新建 QuestionTextSanitizer 纯函数类:Sanitize(CR 段贪吃折叠单换行、\n\r 防双换行、ESC/NUL 剥除防终端二次解释、TAB 转空格)+ Wrap(显示宽度词边界折行、CJK 宽字符 2 列计、悬挂缩进对齐、超宽词硬切、段落保留)
- TerminalInteractiveService 全渲染点接入:question/header 按终端宽折行、选项标签悬挂对齐标签内容列、描述 5 列缩进折行;ANSI 样式改为按行独立包夹(折行后转义不被截断)
- 18 单测锁定清理与折行语义(含 \x00 变长转义陷阱用 \u 定长改写)

验证: host.tests 1433 全绿(含既有 AskClarify 命令测试回归)
根因: 测试用 new ObjectId(type) 构造 10 个连续 ID,而 SequenceId 是进程级静态原子计数器(按 ObjectType 全局共享)— xUnit 并行时其他测试同类型 new 交错插入序号断链,LongRangeSet 压缩出 2 个区间(CI Linux 并行度高才暴露,本地单跑 9/9 过)

修复:
- 测试改用 internal 查找键构造 ObjectId(type, seq) 指定连续 seq(1000-1009,确定性、与全局计数器零耦合)
- Abstractions.csproj 增 InternalsVisibleTo JoinCode.Plugins.Tests(先例 Integration.Tests/Plugins.Infrastructure/Abs.Tests 同款)

验证: 修改域 20/20 + 全量并行 3×189 全绿(过滤本地环境差异 E2E 五项 — NativePluginHost 进程类,CI Linux 全过)
根因一(async_primitives 假红): RetryWriteBack_Failed_TriggersSendFailed 与 SendFailed_Multicast 依赖单条占位塞满重试队列,但 RunLoop await foreach 取出条目后卡 Task.Delay(200ms) — 取出即队列空,CI 慢机断言前被抢跑消费则 TryWrite 成功假阳(本地 16/16 过、CI Linux 偶发;占位改 2 条后本地稳定复现可调试)
修复: 占位 2 条 + ReceiveBackpressureSignal(10s) 拉长 RunLoop 首条消费延迟(串行循环卡 Delay 期间第二条稳占队列,满判定确定性成立;10s Delay 由 Dispose 取消令牌打断不拖慢测试)

根因二(MCP+Sync 超时元凶): E2eSettingsJsonHelper 生成的 vendor 模型条目缺 contextWindow 字段,引擎 ValidateOrThrow 每回合抛 ConfigurationException 并被 CrashStore 反复快照(重 IO)— Sync 2m11s 增至 6m27s、job 顶到 timeout-minutes 10 被强杀
修复: 六个模型条目补真实 contextWindow(gpt-4o 128k / claude-sonnet-4 200k / deepseek 128k / agnes 128k / sensenova 128k)

验证: async_lock.tests 全量 5×600 全绿(每轮 31s — 10s Delay 取消传播正常);E2E 本地缺 MockServer 构件无法跑,CI 验证
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.

1 participant