Install
openclaw skills install @doashoi/openclaw-feishu-reasoning-uxImprove OpenClaw's Feishu reply experience by customizing streaming cards, raw reasoning visibility, card 2.0 layouts, collapsible panels, titles, colors, and fallback send paths. Use this whenever a user wants a better Feishu reply UX for OpenClaw, especially when raw reasoning disappeared, only Thinking shows, titles/styles regressed, cards feel too black-box, or the user wants Feishu replies to become more observable, layered, and customizable.
openclaw skills install @doashoi/openclaw-feishu-reasoning-uxUse this skill when the task is specifically about how OpenClaw messages appear inside Feishu.
This skill is for:
This skill is not for generic Feishu app setup, permissions, or bot connectivity unless those directly block card delivery.
Before making any change, read:
Do not skip it.
That document contains:
Only after reading it should you decide whether the current case is:
This is not a "silently fix everything" skill.
Treat it as:
The user keeps control of the risky steps.
That means:
When in doubt:
This skill was validated on a specific real deployment shape, but do not treat every detail of that environment as a hard prerequisite.
Proven reference case:
minimax-cn/MiniMax-M2.7minimax-portal/*Use this case as a comparison point, not as a rigid gate.
The details that matter most are usually:
src/ vs dist/)Treat OpenClaw version/build as a compatibility factor, not a rigid gate by itself. The question is not "is the version identical to the reference case?" The question is "does this installed build still expose compatible runtime contracts?"
Do not overfocus on WSL vs non-WSL unless logs show environment differences are actually relevant.
Assume many users do not know Feishu card internals, provider runtime details, or OpenClaw file layout.
So when using this skill:
Good examples:
我检测到当前模型不支持可见 raw reasoning,但我们还能把回复卡片做成 2.0 风格、带颜色标题和折叠面板。你想先改这个吗?我检测到现在标题已经能改。你想让标题显示什么文案?直接告诉我文字就行。当前模型只能流正式回答,不能流 raw 思考。我可以帮你切到支持的模型,或者保留当前模型只优化卡片样式。你想走哪条?Do not dump only low-level findings if the user clearly wants a working outcome.
A correct Feishu customization usually has to satisfy all of these:
Do not optimize appearance first if delivery or runtime lane selection is broken.
Default to phased customization, not all-at-once modification.
The safest order is:
/newIf the user only wants a better Feishu card experience, stop after phase 1 or phase 2. Do not pull them into high-risk reasoning/runtime changes unnecessarily.
Prefer language like:
我们先做风险最小的部分:标题、颜色和卡片 2.0 容器。普通回复流式先确认稳定,再决定要不要动 raw reasoning。raw reasoning 这层要先看模型支不支持,支持再继续。Do not jump straight into runtime surgery unless the user clearly wants visible raw reasoning.
Before any non-trivial Feishu customization, create a recovery trail first.
This is not optional.
Always do all three before risky changes:
If the user environment is fragile, prefer incremental backup points instead of one large backup.
Before claiming a risky change is ready to test, the agent must be able to tell the user:
If you cannot explain rollback clearly, the change is not ready.
Separate hard requirements from things that only increase risk. Do not treat every difference from the reference case as a blocker.
These are the conditions that actually have to be true before you try to modify the raw reasoning lane:
~/.openclaw/logs/raw-stream.jsonl.assistant_thinking_stream.reasoningMode = "stream" is honoredonReasoningStream / onReasoningEnd can reach the final replyOptionsThese are important to inspect, but they are not automatic reasons to stop:
src/ vs dist/)They matter because they may change how you implement the fix. They do not automatically mean the fix is impossible.
1.5. The current Feishu path is truly the intended channel implementation.
reasoningMode = "stream".thinkingLevel = low alone is not enough.onReasoningStream / onReasoningEnd are attached to the final replyOptions.Thinking..., check this first./new or next-day sessions lose raw reasoning, fix session initialization so new Feishu direct sessions default to:
reasoningLevel = "stream"thinkingLevel = "low"minimax-cn/MiniMax-M2.7 is a known trap: the provider may support it while the local model registry still silently falls back to M2.5.If the necessary conditions are not met, do not attempt raw reasoning customization. If only compatibility factors differ, adapt the implementation instead of stopping by reflex.
Before editing anything, classify the issue into one of these layers:
reasoningLevel=streamonReasoningStream is wired incorrectlyDo not assume a visual symptom is a card-layer problem. A "Thinking..." only state is often a runtime or session-state problem. Also do not assume all "Feishu plugins" are the same execution path.
Do not modify high-risk layers if any of these are still unclear:
If any of those are unknown, stop at one of these safe outcomes:
Do not continue into:
dist/ patchingunless the above preconditions are verified.
Do not stop only because the installed OpenClaw version/build differs from the reference case. Stop only when the build's actual runtime contracts are unknown or incompatible.
If the current failure mode, runtime behavior, or channel behavior is not covered by the documented patterns in this skill, do not improvise silently.
In that case:
Required style in those cases:
If the user still wants to continue, proceed incrementally and verify after each step.
Locate the installed OpenClaw package root first. In many environments it will be something like:
npm root -g
Then inspect these Feishu files first:
extensions/feishu/src/reply-dispatcher.tsextensions/feishu/src/streaming-card.tsextensions/feishu/src/send.tsextensions/feishu/src/outbound.tsextensions/feishu/src/channel.tsextensions/feishu/src/config-schema.tsAlso inspect current runtime/session state:
~/.openclaw/openclaw.json~/.openclaw/agents/main/sessions/sessions.json~/.openclaw/logs/raw-stream.jsonlIf symptoms do not match source edits, inspect the actual loaded runtime too:
dist/ files, not src/Follow this order.
Check all three, not just one:
Do not trust the agent saying "I switched models". Verify it in session files.
Look for evidence in:
raw-stream.jsonlDistinguish these cases:
If the model does not produce readable live reasoning, Feishu cannot truly display raw reasoning no matter how good the card layer is.
Do not assume the current model supports visible raw reasoning.
Explicitly determine which of these four cases you are in:
For every model under investigation, verify all three:
raw-stream.jsonl shows live thinking eventsthinkingOnly after this check may you decide whether the task is:
Important:
A snapshot-only result means:
After capability detection, always convert the result into one of these user-facing outcomes:
2.5. Model supports only snapshot/transcript reasoning
Do not just say "not supported" and stop. Turn it into the next actionable user choice.
For Feishu direct sessions that should show raw reasoning, check:
reasoningLevel = streamthinkingLevel = low or intended levelIf new sessions keep dropping reasoning visibility, fix session initialization, not just the current session entry.
Also verify that the failure is not just a stale or wrong model override:
providerOverridemodelOverrideauthProfileOverrideFor raw reasoning to display, the Feishu dispatcher must receive reasoning callbacks through the final reply options that runtime actually uses.
Do not attach onReasoningStream to the wrong layer.
If provider logs show thinking stream but Feishu only shows a static placeholder, inspect how onReasoningStream and onReasoningEnd are passed into the runtime.
Also verify that the runtime path is really in reasoning stream mode. If the runtime is only in plain "thinking enabled" mode, Feishu may still get final transcript thinking without ever receiving live reasoning callbacks.
Keep reasoning and answer as separate lanes.
Typical correct structure:
Do not keep placeholder text in the answer lane.
Raw reasoning and final answer should not share the same mutable text buffer.
Maintain separate state for:
This avoids:
Many runtimes emit cumulative reasoning snapshots, not pure deltas.
If each new reasoning frame includes all prior text, normalize it before streaming:
Also normalize provider-added wrappers before diffing:
Reasoning:\n_..._For card 2.0 reasoning UX:
collapsible_panelDo not collapse immediately on onReasoningEnd if more reasoning or late answer frames may still arrive. Prefer delaying collapse until answer streaming actually begins.
All message paths should share the same title/header strategy:
If titles regress in only one path, inspect outbound.ts and fallback card builders.
Do not treat these as equivalent without evidence:
official Feishu channelsame minimax-cn providersame model name on screenThese can still differ in the real failure points:
Always prove the real path with logs and transcripts.
Do not let the agent do any of these:
src/ files when runtime behavior suggests the loaded code is from dist/If cron, new sessions, or fallback sends lose the behavior, repair the shared runtime/session/delivery logic. Do not hardcode per-task fixes.
Once delivery and runtime behavior are stable, invite the user to customize:
Keep those questions simple and direct. For example:
主标题你想显示什么?思考面板标题你想写成“烟花在想”还是别的?颜色你想随机,还是固定一组偏好色?Do not restart openclaw-gateway on your own without telling the user.
If a restart is required:
Use language like:
这个改动需要重启 gateway 才会生效。你来执行,还是我在你确认后替你执行?This rule exists because Feishu session behavior, active runs, and user expectations can all be disrupted by an unexpected restart.
When implementing raw reasoning plus card 2.0 behavior, use this architecture:
reasoningStream config gateonReasoningStreamonReasoningEndcollapsible_panel for reasoningAvoid these anti-patterns:
src/ when runtime actually loads dist/Before claiming success, verify all of these:
Every meaningful Feishu card customization must update the project’s Feishu card guide or create one if absent.
Document at minimum:
When you finish, report in this order:
If the issue is only partially solvable because of model/provider limits, also include: 6. What still can be customized anyway 7. What user-facing choices are available next
Example 1:
帮我把 OpenClaw 的飞书回复卡片改得更像一个完整 UI,不要只有一块 markdown。
Example 2:
之前飞书里能流 raw reasoning,今天又只剩 Thinking... 了,你帮我恢复。
Example 3:
把飞书思考过程做成折叠面板,思考完自动折叠,再开始流正式回复。
Example 4:
为什么飞书里只有部分路径的标题还是旧的“烟花想法”,帮我统一掉。
Example 5:
帮我看看这个模型到底支不支持在飞书里流 raw reasoning,不要先默认是卡片代码的问题。
Use these as practical calibration examples. They are not heavy formal evals; they exist to keep the skill usable and consistent.
Prompt:
昨天还能看到飞书里流 raw reasoning,今天又只剩 Thinking... 了,帮我查一下。
Expected behavior:
reasoningLevel=streamPrompt:
我想把飞书卡片标题改成别的文案,再加一点颜色。
Expected behavior:
Prompt:
为什么这个模型只有回答流,没有 raw reasoning?还能做点什么?
Expected behavior:
Prompt:
你直接帮我把飞书卡片改掉。
Expected behavior:
Prompt:
每次 /new 之后 raw reasoning 就没了。
Expected behavior: