feat(feishu): support stream output (cardkit) (#2382)
* feat(feishu): add streaming support via CardKit PATCH API Implement send_delta() for Feishu channel using interactive card progressive editing: - First delta creates a card with markdown content and typing cursor - Subsequent deltas throttled at 0.5s to respect 5 QPS PATCH limit - stream_end finalizes with full formatted card (tables, rich markdown) Also refactors _send_message_sync to return message_id (str | None) and adds _patch_card_sync for card updates. Includes 17 new unit tests covering streaming lifecycle, config, card building, and edge cases. Made-with: Cursor * feat(feishu): close CardKit streaming_mode on stream end Call cardkit card.settings after final content update so chat preview leaves default [生成中...] summary (Feishu streaming docs). Made-with: Cursor * style: polish Feishu streaming (PEP8 spacing, drop unused test imports) Made-with: Cursor * docs(feishu): document cardkit:card:write for streaming - README: permissions, upgrade note for existing apps, streaming toggle - CHANNEL_PLUGIN_GUIDE: Feishu CardKit scope and when to disable streaming Made-with: Cursor * docs: address PR 2382 review (test path, plugin guide, README, English docstrings) - Move Feishu streaming tests to tests/channels/ - Remove Feishu CardKit scope from CHANNEL_PLUGIN_GUIDE (plugin-dev doc only) - README Feishu permissions: consistent English - feishu.py: replace Chinese in streaming docstrings/comments Made-with: Cursor
This commit is contained in:
@@ -505,14 +505,17 @@ nanobot gateway
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Feishu (飞书)</b></summary>
|
||||
<summary><b>Feishu</b></summary>
|
||||
|
||||
Uses **WebSocket** long connection — no public IP required.
|
||||
|
||||
**1. Create a Feishu bot**
|
||||
- Visit [Feishu Open Platform](https://open.feishu.cn/app)
|
||||
- Create a new app → Enable **Bot** capability
|
||||
- **Permissions**: Add `im:message` (send messages) and `im:message.p2p_msg:readonly` (receive messages)
|
||||
- **Permissions**:
|
||||
- `im:message` (send messages) and `im:message.p2p_msg:readonly` (receive messages)
|
||||
- **Streaming replies** (default in nanobot): add **`cardkit:card:write`** (often labeled **Create and update cards** in the Feishu developer console). Required for CardKit entities and streamed assistant text. Older apps may not have it yet — open **Permission management**, enable the scope, then **publish** a new app version if the console requires it.
|
||||
- If you **cannot** add `cardkit:card:write`, set `"streaming": false` under `channels.feishu` (see below). The bot still works; replies use normal interactive cards without token-by-token streaming.
|
||||
- **Events**: Add `im.message.receive_v1` (receive messages)
|
||||
- Select **Long Connection** mode (requires running nanobot first to establish connection)
|
||||
- Get **App ID** and **App Secret** from "Credentials & Basic Info"
|
||||
@@ -530,12 +533,14 @@ Uses **WebSocket** long connection — no public IP required.
|
||||
"encryptKey": "",
|
||||
"verificationToken": "",
|
||||
"allowFrom": ["ou_YOUR_OPEN_ID"],
|
||||
"groupPolicy": "mention"
|
||||
"groupPolicy": "mention",
|
||||
"streaming": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> `streaming` defaults to `true`. Use `false` if your app does not have **`cardkit:card:write`** (see permissions above).
|
||||
> `encryptKey` and `verificationToken` are optional for Long Connection mode.
|
||||
> `allowFrom`: Add your open_id (find it in nanobot logs when you message the bot). Use `["*"]` to allow all users.
|
||||
> `groupPolicy`: `"mention"` (default — respond only when @mentioned), `"open"` (respond to all group messages). Private chats always respond.
|
||||
|
||||
Reference in New Issue
Block a user