Skip to content

fix(feishu): gate reasoning previews to stream sessions#61271

Merged
vincentkoc merged 1 commit intoopenclaw:mainfrom
vincentkoc:fix/feishu-reasoning-preview-stream-only
Apr 5, 2026
Merged

fix(feishu): gate reasoning previews to stream sessions#61271
vincentkoc merged 1 commit intoopenclaw:mainfrom
vincentkoc:fix/feishu-reasoning-preview-stream-only

Conversation

@vincentkoc
Copy link
Copy Markdown
Member

Summary

  • Problem: Feishu still exposed streamed reasoning previews on any streaming session, even when the persisted session reasoning level was not stream.
  • Why it matters: hidden reasoning traces can leak into normal Feishu chat cards while other channels already suppress or status-only this path.
  • What changed: gate Feishu reasoning previews on persisted reasoning:stream, thread that permission into the reply dispatcher, and add regression coverage plus a changelog entry.
  • What did NOT change (scope boundary): this does not change normal answer streaming, comment-thread replies, or other channels that already suppress/status-only reasoning previews.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause (if applicable)

  • Root cause: Feishu reply dispatch treated streaming: true as permission to expose onReasoningStream, without checking the session's persisted reasoning mode.
  • Missing detection / guardrail: Feishu had streaming-card reasoning tests, but no guard that tied those callbacks to reasoningLevel === "stream".
  • Contributing context (if known): Telegram had already needed the same narrowing, and Feishu kept the older broader behavior.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: extensions/feishu/src/reasoning-preview.test.ts, extensions/feishu/src/reply-dispatcher.test.ts, extensions/feishu/src/bot.test.ts
  • Scenario the test should lock in: Feishu only exposes reasoning preview callbacks when the session is explicitly reasoning:stream.
  • Why this is the smallest reliable guardrail: the leak boundary is a session-state + dispatcher wiring decision, so helper and dispatcher tests are the tightest checks.
  • Existing test that already covers this (if any): None.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • Feishu no longer shows streamed reasoning previews in normal streaming sessions unless the session is explicitly reasoning:stream.

Diagram (if applicable)

Before:
[Feishu streaming session] -> [reasoning callback exposed] -> [thinking text can render in card]

After:
[Feishu streaming session] -> [check persisted reasoningLevel]
  -> [stream] -> [reasoning callback exposed]
  -> [off/on/unknown] -> [reasoning callback suppressed]

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: local worktree
  • Model/provider: N/A
  • Integration/channel (if any): Feishu
  • Relevant config (redacted): Feishu account with streaming: true; session store entry toggled between reasoningLevel: stream and reasoningLevel: on

Steps

  1. Start a Feishu streaming session whose persisted session entry is not reasoning:stream.
  2. Send a prompt that produces streamed reasoning tokens.
  3. Observe whether the dispatcher exposes a visible reasoning preview lane.

Expected

  • Feishu only exposes streamed reasoning previews when the session is explicitly reasoning:stream.

Actual

  • Before this patch, Feishu exposed reasoning previews for any streaming session.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios: direct Bun sanity check covering persisted reasoningLevel lookup and dispatcher callback gating; git diff --check after rebase.
  • Edge cases checked: missing session key, non-stream reasoning level, and load failures all disable previews.
  • What you did not verify: pnpm test:serial -- ... for the touched Feishu tests kept hanging in this workspace after startup, so I did not get a clean local Vitest result to claim.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: sessions intentionally using reasoning:stream could stop showing previews if the store lookup path regresses.
    • Mitigation: helper regression test plus bot wiring assertion.

@vincentkoc vincentkoc self-assigned this Apr 5, 2026
@openclaw-barnacle openclaw-barnacle Bot added channel: feishu Channel integration: feishu size: S maintainer Maintainer-authored PR labels Apr 5, 2026
@vincentkoc vincentkoc marked this pull request as ready for review April 5, 2026 09:40
@vincentkoc vincentkoc merged commit d609f71 into openclaw:main Apr 5, 2026
30 of 32 checks passed
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 5, 2026

Greptile Summary

This PR correctly gates Feishu reasoning preview callbacks to sessions with reasoningLevel === "stream", matching the behaviour already in place for Telegram. The fix is threaded cleanly through the helper (resolveFeishuReasoningPreviewEnabled), the reply dispatcher (allowReasoningPreview parameter), and both single-agent and broadcast dispatch paths in bot.ts, with regression tests at each layer.

Confidence Score: 5/5

Safe to merge; the fix is logically correct and all remaining findings are P2.

The core gate (reasoningPreviewEnabled = streamingEnabled && params.allowReasoningPreview === true) is correct, session-store reads match the existing skipCache: true pattern used elsewhere in the codebase, and test coverage spans the helper, dispatcher, and bot wiring layers. The single inline comment is a minor efficiency nit that does not affect correctness.

No files require special attention; the minor efficiency concern in the broadcast observer path of extensions/feishu/src/bot.ts is non-blocking.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/feishu/src/bot.ts
Line: 1115-1119

Comment:
**Unnecessary disk read for observer agents**

`resolveFeishuReasoningPreviewEnabled` is called for every agent in the broadcast loop — including observer agents — but `allowReasoningPreview` is only consumed inside the `if (agentId === activeAgentId)` branch. Each observer agent pays a `skipCache: true` disk read whose result is immediately discarded. Moving the call inside the active-agent branch eliminates these wasted reads.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(feishu): gate reasoning previews to ..." | Re-trigger Greptile

Comment on lines 1115 to +1119
const agentSessionKey = buildBroadcastSessionKey(route.sessionKey, route.agentId, agentId);
const allowReasoningPreview = resolveFeishuReasoningPreviewEnabled({
storePath: core.channel.session.resolveStorePath(cfg.session?.store, { agentId }),
sessionKey: agentSessionKey,
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Unnecessary disk read for observer agents

resolveFeishuReasoningPreviewEnabled is called for every agent in the broadcast loop — including observer agents — but allowReasoningPreview is only consumed inside the if (agentId === activeAgentId) branch. Each observer agent pays a skipCache: true disk read whose result is immediately discarded. Moving the call inside the active-agent branch eliminates these wasted reads.

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/feishu/src/bot.ts
Line: 1115-1119

Comment:
**Unnecessary disk read for observer agents**

`resolveFeishuReasoningPreviewEnabled` is called for every agent in the broadcast loop — including observer agents — but `allowReasoningPreview` is only consumed inside the `if (agentId === activeAgentId)` branch. Each observer agent pays a `skipCache: true` disk read whose result is immediately discarded. Moving the call inside the active-agent branch eliminates these wasted reads.

How can I resolve this? If you propose a fix, please make it concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: feishu Channel integration: feishu maintainer Maintainer-authored PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant