feat(card): add cardStreamingMode and stabilize card timeline ordering#494
Conversation
Add card-side reasoning/answer text splitting for `/reasoning on` flows so thinking blocks render in quoted format while answer text stays as plain markdown. Introduce two new config options: - `cardStreamReasoning` (bool, default false): when true, reasoning text streams in-place to the card throttled by `cardStreamInterval`; when false, only one `streamAICard` call per completed block to conserve API quota. - `cardStreamInterval` (int ≥ 200, default 1000ms): throttle interval for live reasoning stream updates. Includes card-draft-controller `sealActiveThinking` for turn-boundary sealing, split helper with comprehensive tests, and cross-repo handoff documentation for the upstream `fix/reasoning-block-reply-answer-loss` branch. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile Summary此 PR 引入 cardStreamingMode: off | answer | all 统一枚举,替代语义模糊的 cardRealTimeStream 布尔开关,并加固了 AI Card 的 open to final_seen to sealed 生命周期,修复了 late tool/reasoning/answer block 的时间线排序竞态。所有先前 PR 评论均已落实:__ 推理行误判已修正,legacy throttle 兼容路径已保留 300ms 默认值,warnedLegacyConfigs 意图已在代码中注释说明。 Confidence Score: 5/5此 PR 可安全合并,所有先前 P0/P1 评论均已落实,仅存一个 P2 边界情况 代码逻辑清晰、测试覆盖全面、生命周期状态机设计严谨,所有先前评审关注点均已修复。唯一未覆盖的是多次 final 携带 mediaUrls 的极端场景,属 P2 style 层面,不影响合并 src/reply-strategy-card.ts 中 deliver(final) 的媒体投递未限制在首次 final,其余文件无需特别关注 Important Files Changed
Sequence DiagramsequenceDiagram
participant Runtime
participant CardReplyStrategy
participant CardDraftController
participant DingTalkAPI
Runtime->>CardReplyStrategy: onPartialReply(text)
CardReplyStrategy->>CardDraftController: updateAnswer(text)
CardDraftController-->>DingTalkAPI: streamAICard throttled
Runtime->>CardReplyStrategy: onReasoningStream(text)
CardReplyStrategy->>CardDraftController: updateReasoning or appendThinkingBlock
Runtime->>CardReplyStrategy: deliver kind=final
note over CardReplyStrategy: lifecycleState = final_seen
Runtime-->>CardReplyStrategy: deliver kind=tool or block late
CardReplyStrategy->>CardDraftController: appendToolBeforeCurrentAnswer
Runtime->>CardReplyStrategy: finalize
CardReplyStrategy->>CardDraftController: flush and waitForInFlight
CardReplyStrategy->>DingTalkAPI: finishAICard with overrideAnswer
note over CardReplyStrategy: lifecycleState = sealed
Greploops — Automatically fix all review issues by running Reviews (2): Last reviewed commit: "fix(card): align streaming mode behavior..." | Re-trigger Greptile |
|
对抗性审查意见与修复进展简报 本轮基于
主要发现
修复进展
验证结果
这轮修复后,前述 4 个对抗性审查问题都已完成收口,当前分支状态适合继续走合并前复核。 |
AI-assisted: 是
背景
cardRealTimeStream与cardStreamReasoning,语义重叠且不易解释。/reasoning on、/reasoning stream、tool tail 与 final answer 的时间线顺序在 card 模式下还存在边界情况,容易出现 API 调用偏多或答案顺序不稳定。目标
cardStreamingMode: off | answer | all配置语义,并兼容旧的cardRealTimeStream。streamAICard调用并修复相关竞态。final_seen生命周期,允许 late thinking/tool tail 补齐,同时忽略 late partial answer,但仍可吸收 late answer block/final。实现
cardStreamingMode与解析 helper。cardRealTimeStream作为兼容项,并在未显式设置新枚举时回退到all。cardStreamReasoning,仅通过内部兼容路径保留旧运行时行为直到新策略接管。off作为生效默认值落在解析层,避免破坏 control-ui schema 与 legacy fallback 语义。reply-strategy-card.ts改为按cardStreamingMode驱动off | answer | all。open -> final_seen -> sealed生命周期。final_seen后允许 late reasoning/tool 进入时间线;late partial answer 仍忽略,但 late answer block/final 会更新冻结中的最终答案。cardStreamingMode选择。cardStreamingMode语义。cardStreamInterval的作用,以及cardRealTimeStream的弃用兼容行为。实现 TODO
cardStreamingMode配置兼容层final_seen生命周期、late tail 排序,并允许 late answer block/final 更新冻结答案cardStreamingMode验证 TODO
pnpm exec vitest run tests/unit/card-streaming-mode.test.ts tests/unit/config-schema.test.ts tests/unit/config-advanced.test.ts tests/unit/types.test.ts tests/unit/card-draft-controller.test.ts tests/unit/reply-strategy-card.test.ts tests/unit/inbound-handler.test.tspnpm exec vitest run tests/unit/reasoning-answer-split.test.ts tests/unit/reply-strategy-card.test.ts tests/unit/session-peer-store.test.ts tests/unit/inbound-handler.test.tsnpm run lint(通过;存在仓库内既有 warnings,无 lint error)npm run type-checkpnpm testopenclaw gateway restartcardStreamingMode=off下/reasoning on的思考块与最终答案顺序cardStreamingMode=answer下 late thinking/tool tail after final 不会覆盖最终答案,且 late answer block/final 可更新冻结答案cardStreamingMode=all下思考与答案实时流式更新,以及cardStreamInterval节流效果