Keep Feishu card reasoning payloads#498
Conversation
evandance
left a comment
There was a problem hiding this comment.
Thanks — the underlying issue is real (the dispatcher's isReasoning === true ? '' : ... filter was silently dropping reasoning payloads). The fix works for the test's payload shape: splitReasoningText (src/card/builder.ts:80-103) recognizes the 'Reasoning:\n' prefix and controller.onDeliver (streaming-card-controller.ts:465-473) routes through the pure-reasoning branch, so content lands in the reasoning panel as expected.
The concern is that the controller decides reasoning vs answer by text format (the prefix or <think> tags), not by payload.isReasoning. If a payload arrives with isReasoning: true but bare reasoning text — no prefix, no tags, possible from a future model variant or a different streaming format — splitReasoningText falls to its default branch and returns {answerText: text}. That gets appended to text.completedText and renders as the visible answer.
Two ways to harden:
- Route on the flag in the dispatcher: when
payload.isReasoning === true, callcontroller.onReasoningStream(payload)instead ofcontroller.onDeliver(...).onReasoningStream(line 494) already handles bare-text reasoning, and the dispatcher already exposes it on line 422. - Make
controller.onDelivertreatpayload.isReasoning === trueas pure reasoning up front, before falling through tosplitReasoningText.
Either way, add a regression test for the bare format — { text: 'checking context', isReasoning: true } should still land in the reasoning area, not the answer body.
If you can also paste the trigger scenario (what SDK version / model / config causes reasoning to reach deliver instead of onReasoningStream) into the PR description, that'll tell us whether the fix belongs here or upstream.
|
Thanks, agreed. The current patch preserves the reasoning payload, but it still leaves reasoning-vs-answer classification to the text shape, which is fragile for bare reasoning chunks. I will harden this by routing Trigger scenario: this came from the Feishu CardKit streaming path where reasoning chunks reached the dispatcher deliver branch, so the previous |
evandance
left a comment
There was a problem hiding this comment.
Thanks for the rework — this is exactly the right shape. The dispatcher now routes reasoning payloads by the isReasoning flag rather than by text classification, and the two new tests pin both the prefix format and the bare-text case (checking context) to the reasoning lane with explicit onDeliver not called assertions. The trigger scenario from the Feishu CardKit streaming path is documented in the thread too. All concerns from the prior review are addressed.
LGTM, approving.
Summary
isReasoning: truethrough the reasoning stream path instead of the visible answer delivery path.Trigger scenario
This came from the Feishu CardKit streaming path where reasoning chunks reached the dispatcher deliver branch. The previous
isReasoning ? "" : ...filter dropped those chunks before the streaming card controller could render the reasoning panel.Validation