pi-channels-streaming-card
Pi messaging channels (Feishu/Lark, DingTalk, WeCom, webhooks) with native streaming cards: CardKit typewriter output, collapsible thinking/tools timeline, and context-window footer. Fork of @amaster.ai/pi-channels.
Package details
Install pi-channels-streaming-card from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-channels-streaming-card- Package
pi-channels-streaming-card- Version
0.2.0- Published
- Aug 9, 2026
- Downloads
- 140/mo · 14/wk
- Author
- davidhe607
- License
- Apache-2.0
- Types
- extension
- Size
- 296.4 KB
- Dependencies
- 4 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./dist/index.js"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-channels-streaming-card
Pi 消息通道插件(飞书/Lark、DingTalk、企微、webhook),内置原生流式卡片能力,并针对飞书深度增强:图片自动识别、重启自愈、答案兜底。
Fork 自 @amaster.ai/pi-channels(Apache-2.0),新增飞书流式卡片 + 视觉识别 + 自愈能力。
✨ 特性
- 飞书打字机流式输出:基于飞书 CardKit
cardElement.content接口,文字逐字蹦出(动画跟随生成速度,不拖慢输出) - 思考与工具折叠面板:思考过程、工具调用收进原生
collapsible_panel(默认收起,点击展开);上一轮答案归档为「过程 N」同样收纳 - 上下文底栏:
已完成 · 耗时 · 模型 · ↑输入 · ↓输出 · ctx 用量/窗口 百分比 - 🖼 飞书图片自动识别(无需切换模型):
- 图片消息到达后自动通过
im.messageResource.get拉取字节,纯内存处理(零磁盘写入) - 自动调用视觉模型(qwen-vl-plus 等,从
models.json读取)生成描述,前置注入主模型提示词 - 主模型保持 deepseek-v4-flash 等文本模型即可「看懂」图片
- 图片消息到达后自动通过
- 🛟 重启自愈:
- 流式卡片状态持久化到
card-state.json(创建即存、流式中节流保存、完成即删) - 启动时自动把上次中断的卡片标记为
⚠️ 已中断(重启),不再永久卡在「思考中」 - 孤儿集合只在启动时捕获一次,重试窗口绝不误伤新创建的流式卡片
- 流式卡片状态持久化到
- 📨 答案兜底:若卡片中途死亡(更新全部失败),自动转纯文本消息补发,答案永不丢失
- 🖼 图片消息卡片独立发送:回复图片消息时卡片以新消息发送,规避飞书引用缩略图的兼容问题
- 其他通道(DingTalk/企微/webhook)保持原 pi-channels 行为不变
📦 安装
先卸载原版 pi-channels(避免冲突),再安装本插件:
pi remove npm:@amaster.ai/pi-channels
pi install npm:pi-channels-streaming-card # 发布到 npm 后
# 或从 GitHub 安装:
pi install git:github.com/<你的用户名>/pi-channels-streaming-card
重启 pi 生效:
# 交互模式下 /reload,或重启进程
⚙️ 配置
配置方式和 pi-channels 完全一致(~/.pi/agent/settings.json):
{
"pi-channels": {
"adapters": {
"feishu": {
"type": "feishu",
"appId": "cli_xxx",
"appSecret": "xxx",
"eventMode": "websocket",
"respondToMentionsOnly": true
}
},
"bridge": {
"enabled": true,
"provider": "opencode-go",
"model": "deepseek-v4-flash",
"streamingCards": true
}
}
}
bridge.streamingCards: true 开启飞书流式卡片(CardKit 打字机)。
🖼 图片识别配置(可选)
在 ~/.pi/agent/models.json 配置任意 OpenAI 兼容的视觉模型即可(插件自动探测含 vl/vision/image 的模型 id):
{
"providers": {
"qwen-vl": {
"baseUrl": "https://<你的百炼网关>/compatible-mode/v1",
"apiKey": "sk-xxx",
"api": "openai-completions",
"models": [{ "id": "qwen-vl-plus", "name": "通义千问 VL Plus(识图)" }]
}
}
}
未配置视觉模型时,图片消息降级为纯文本 [图片],不影响其他功能。
🎴 卡片效果
┌─────────────────────────────────┐
│ π pi ✅ 已完成 │ ← 头部状态(蓝=进行中/绿=完成/红=失败/橙=中断)
│ │
│ 答案内容(打字机逐字输出) │ ← 主内容(仅最终答案)
│ │
│ ▸ 思考与工具 · 6 次工具调用 │ ← 原生折叠面板(默认收起)
│ - 思考 1 · completed │
│ - ✓ bash │
│ - ✕ edit · 失败 │
│─────────────────────────────────│
│ 已完成 · 28s · deepseek-v4-flash │ ← 底栏
│ · ↑129k · ↓379 · ctx 129k/1m 13%│
└─────────────────────────────────┘
🛠 实现说明
- 创建卡片实体:
POST /cardkit/v1/cards(streaming_mode: true) - 发送卡片:
im.message.create+content: {type:"card", data:{card_id}}(图片消息改为独立新消息,不 reply) - 流式文本:
PUT /cardkit/v1/cards/{id}/elements/{element_id}/content(打字机动效,print_strategy: "fast"保证不落后于生成速度) - 结构更新:
PUT /cardkit/v1/cards/{id}全量更新(头部状态、折叠面板、底栏) - 完成时:
card.settings关闭streaming_mode(移除打字光标) - CardKit 失败时自动回退到
im.message.patch全卡更新(功能不中断) - 图片识别:
im.messageResource.get(params: {type:'image'})→ 内存字节 → base64 data URL → OpenAI 兼容/chat/completions视觉请求 - 自愈:卡片快照持久化 → 启动时
healOrphanedCards(仅处理启动时存在的孤儿,3s 延迟 + 指数退避重试,序列号大跳步规避 sequence 冲突)
📄 许可
Apache-2.0(与上游 pi-channels 一致)