{"_id":"@aitechmei/dsh-feishu","_rev":"2-53d6704536a86a71162234b4e880bcdc","name":"@aitechmei/dsh-feishu","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@aitechmei/dsh-feishu","version":"0.1.0","keywords":["feishu","lark","dsh","deepseek-harness","bot","channel"],"license":"MIT","_id":"@aitechmei/dsh-feishu@0.1.0","maintainers":[{"name":"aitechmei","email":"aitechmei@163.com"}],"homepage":"https://github.com/AITechMei/dsh-feishu#readme","bugs":{"url":"https://github.com/AITechMei/dsh-feishu/issues"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"e0afe9d013cfe798aa0474efaaf6fb0dd5695cc1","tarball":"https://registry.npmjs.org/@aitechmei/dsh-feishu/-/dsh-feishu-0.1.0.tgz","fileCount":18,"integrity":"sha512-xVqxMHt2HdYd+pECpEkVsAicNoOhG/AI9wjL8KrT3cXG3n+AfLcLs/pgc8kkhN6xfFO0onSWwzXQ/+qRaiFQkw==","signatures":[{"sig":"MEUCIEMRVxhhTzgi44Zihj94QuKW8TRdTRr0HYKS73b2eTU9AiEAzzSTxh9D5g6FWwlIXamqH1WFmuJeY4RgkT+m52dXvak=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42614},"main":"lib/index.js","type":"module","types":"lib/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./lib/index.d.ts","default":"./lib/index.js"},"./invariant":{"types":"./lib/invariant.d.ts","default":"./lib/invariant.js"},"./package.json":"./package.json","./cordis.patch.yml":"./cordis.patch.yml"},"gitHead":"31ec732e7c3fb4dc205f043f2bbcf0c0b94b4173","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json"},"_npmUser":{"name":"aitechmei","email":"aitechmei@163.com"},"repository":{"url":"git+https://github.com/AITechMei/dsh-feishu.git","type":"git"},"_npmVersion":"10.9.3","description":"Feishu/Lark messaging bot channel for deepseek-harness: inbound events, session binding, and text replies","directories":{},"_nodeVersion":"22.19.0","dependencies":{"@larksuiteoapi/node-sdk":"1.73.0","@deepseek-ai/schemastery":"^3.18.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.8","typescript":"^6.0.3","@types/node":"^22.0.0","@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-llm":"^0.1.0-rc.7","@deepseek-ai/dsh-agent":"^0.1.0-rc.7","@deepseek-ai/dsh-session":"^0.1.0-rc.7","@deepseek-ai/dsh-invariants":"^0.1.0-rc.7"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-llm":"^0.1.0-rc.7","@deepseek-ai/dsh-agent":"^0.1.0-rc.7","@deepseek-ai/dsh-session":"^0.1.0-rc.7","@deepseek-ai/dsh-invariants":"^0.1.0-rc.7"},"_npmOperationalInternal":{"tmp":"tmp/dsh-feishu_0.1.0_1787038172111_0.10258379199155199","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aitechmei/dsh-feishu","version":"0.2.0","description":"Feishu/Lark messaging bot channel for deepseek-harness: inbound events, session binding, and text replies","type":"module","main":"lib/index.js","types":"lib/index.d.ts","exports":{".":{"types":"./lib/index.d.ts","default":"./lib/index.js"},"./invariant":{"types":"./lib/invariant.d.ts","default":"./lib/invariant.js"},"./cordis.patch.yml":"./cordis.patch.yml","./package.json":"./package.json"},"scripts":{"build":"tsc -p tsconfig.json","test":"vitest run"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"license":"MIT","dependencies":{"@deepseek-ai/schemastery":"^3.18.1","@larksuiteoapi/node-sdk":"1.73.0","qrcode":"^1.5.4","yaml":"^2.9.0"},"peerDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-agent":"^0.1.0-rc.7","@deepseek-ai/dsh-invariants":"^0.1.0-rc.7","@deepseek-ai/dsh-llm":"^0.1.0-rc.7","@deepseek-ai/dsh-session":"^0.1.0-rc.7"},"devDependencies":{"@deepseek-ai/cordis":"^4.0.1","@deepseek-ai/dsh-agent":"^0.1.0-rc.7","@deepseek-ai/dsh-invariants":"^0.1.0-rc.7","@deepseek-ai/dsh-llm":"^0.1.0-rc.7","@deepseek-ai/dsh-session":"^0.1.0-rc.7","@types/node":"^22.0.0","@types/qrcode":"^1.5.6","typescript":"^6.0.3","vitest":"^4.1.8"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/AITechMei/dsh-feishu.git"},"keywords":["feishu","lark","dsh","deepseek-harness","bot","channel"],"engines":{"node":">=22"},"bin":{"dsh-feishu-setup":"bin/dsh-feishu-setup.mjs"},"_id":"@aitechmei/dsh-feishu@0.2.0","gitHead":"27ca175ab9d59b4e9ca346f34be17c89e7dc36e6","bugs":{"url":"https://github.com/AITechMei/dsh-feishu/issues"},"homepage":"https://github.com/AITechMei/dsh-feishu#readme","_nodeVersion":"22.19.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-OG9bo6hnqIOm/MRQfTf+C3Bu9AmU0Z+gcEyZyNqkv3KdYotCpztGWyDq3Jelp9ApQ3Bq8UbPEmtVmVMg8zP4GQ==","shasum":"0623e9a5f6bde8ebcf2cb67891ea479d36c09af1","tarball":"https://registry.npmjs.org/@aitechmei/dsh-feishu/-/dsh-feishu-0.2.0.tgz","fileCount":31,"unpackedSize":109307,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDUG9naBqpRKNdtI3KmvH0+xvNeeHBAYgRc11z1wFVkcgIhAPUq+J+Mw2b8Ev1egrNg8jSZgs9269GeZ895H1rjtjEH"}]},"_npmUser":{"name":"aitechmei","email":"aitechmei@163.com"},"directories":{},"maintainers":[{"name":"aitechmei","email":"aitechmei@163.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-feishu_0.2.0_1787056261288_0.5580415366937659"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-18T07:29:31.943Z","modified":"2026-08-18T12:31:01.672Z","0.1.0":"2026-08-18T07:29:32.247Z","0.2.0":"2026-08-18T12:31:01.446Z"},"bugs":{"url":"https://github.com/AITechMei/dsh-feishu/issues"},"license":"MIT","homepage":"https://github.com/AITechMei/dsh-feishu#readme","keywords":["feishu","lark","dsh","deepseek-harness","bot","channel"],"repository":{"type":"git","url":"git+https://github.com/AITechMei/dsh-feishu.git"},"description":"Feishu/Lark messaging bot channel for deepseek-harness: inbound events, session binding, and text replies","maintainers":[{"name":"aitechmei","email":"aitechmei@163.com"}],"readme":"# feishu/ — 飞书／Lark 消息机器人渠道\n\n[English](README.md) | 中文\n\n`@aitechmei/dsh-feishu` 将 harness 连接到一个飞书（或国际版 Lark）应用，作为消息机器人运行。一个插件行位通过官方 `@larksuiteoapi/node-sdk` 的 WebSocket 长连接订阅入站消息（无需公网 URL），把每个聊天绑定到一个持久的 harness 会话，并把 agent 的 assistant 回复以飞书原生 Markdown（带可选的 DeepSeek 品牌前缀与“思考中”表情）回传给该聊天。\n\n该流程与 ACP 桥等服务器驱动 agent 的方式一致：入站文本通过 `agent.followup()` 收进每个聊天的 `Agent`，已提交的 `assistant/message` 会话事件再回传出去。范围限定为消息（机器人私聊与群聊，带 @提及门槛），不包含飞书的文档／知识库／云文档工具。\n\n## 安装\n\n作为一个插件 bundle 安装到 dsh profile。profile 目录是 pnpm workspace 根，\n所以 `pnpm add` 需要 `-w` 标志：\n\n```sh\ndsh plugin --profile feishu add -w @aitechmei/dsh-feishu\n```\n\n如果从插件源码目录挂载，用本地路径代替 registry 包名：\n\n```sh\ndsh plugin --profile feishu add -w file:/path/to/dsh-feishu\n```\n\n插件的 `dsh.bundle` patch 会在首次启动时把 `feishu` 行位插入到 `dsh-base`\n之后。把机器人的凭据与访问策略写到 profile 自己的 patch 层\n（`$DSH_HOME/profiles/feishu/cordis.patch.yml`），然后启动：\n\n\n```sh\ndsh --profile feishu\n```\n\n## 配置向导\n\n提供交互式 CLI（`dsh-feishu-setup`，也可 `npx @aitechmei/dsh-feishu setup`），\n带你完成账号接入并写入 profile patch。既可以**扫码自动创建机器人**（飞书设备码\n流程，尽力而为），也可以**手动录入已有的 appId/appSecret**（始终可用）。向导随后\n引导访问策略，并把 `feishu` 行位写入 `$DSH_HOME/profiles/<name>/cordis.patch.yml`，\n保留其它行位不变。\n\n```sh\n# 默认 'feishu' profile 的交互向导\ndsh-feishu-setup\n# 显式 profile / 试运行（打印将写入的 patch，不写盘）/ 脚本化\ndsh-feishu-setup --profile feishu-test --dry-run\ndsh-feishu-setup --profile feishu-test --json --yes\n```\n\n| 参数 | 含义 |\n|---|---|\n| `--profile <name>` | 目标 dsh profile（默认 `feishu`）；须已存在。 |\n| `--region <feishu|lark|auto>` | 预选平台（默认交互选择）。 |\n| `--manual` | 跳过扫码，手动录入凭据。 |\n| `--dry-run` | 只打印将写入的 patch，不写盘。 |\n| `--json` | 向 stdout 输出结构化结果。 |\n| `-y` / `--yes` | 使用推荐默认值并跳过确认。 |\n\n写入后请**重启 dsh** 使改动生效。扫码路径自动创建的是扫码用户所在 tenant 下的\n**个人**应用，无团队后台配额保证，属于尽力而为；手动录入自建应用才是可靠、长期的\n配置方式。\n\n## 配置\n\n将本 bundle 置于 `dsh-base` 之后，并挂载 `feishu` 行位：\n\n```yaml\n- id: feishu\n  name: '@aitechmei/dsh-feishu'\n  config:\n    appId: cli_xxx\n    appSecret: '***'\n    # optional\n    verificationToken: '***'\n    encryptKey: '***'\n    domain: feishu        # feishu | lark\n    dmPolicy: allowlist   # allowlist | open\n    allowFrom: [ou_sender]\n    groupPolicy: allowlist # allowlist | disabled | open\n    groupAllowFrom: [oc_chat]\n    requireMention: true\n    provider: deepseek-official\n    model: deepseek-v4-pro\n    cwd: /path/to/workspace\n    brandHeader: '**🐋 DeepSeek**'   # 可选品牌前缀\n    reactions: true                  # 思考中 Typing/CrossMark 表情\n```\n\n| 键 | 默认 | 含义 |\n|---|---|---|\n| `appId` / `appSecret` | — | 飞书开放平台应用凭据（必须设置）。 |\n| `verificationToken` / `encryptKey` | — | 事件订阅的校验与加密，当应用使用它们时。 |\n| `domain` | `feishu` | `feishu` 对应 `<...>.feishu.cn`，`lark` 对应 `<...>.larksuite.com`。 |\n| `dmPolicy` | `allowlist` | `open` 收下所有私聊；`allowlist` 仅收下 `allowFrom`。 |\n| `allowFrom` | — | 允许私聊该机器人的发送者 open id（`ou_…`）。 |\n| `groupPolicy` | `allowlist` | `disabled` 忽略群聊；`allowlist` 仅收下 `groupAllowFrom`；`open` 收下所有群聊。 |\n| `groupAllowFrom` | — | 在 `allowlist` 下被收下的群聊 id（`oc_…`）。 |\n| `requireMention` | `true` | 在被收下的群聊里要求 @提及机器人才能触发。 |\n| `provider` / `model` | 部署默认 | 为每个聊天创建的 agent 的路由。 |\n| `cwd` | 宿主 cwd | 创建会话的工作目录。 |\n| `brandHeader` | `**🐋 DeepSeek**` | 为富／长回复前置的品牌文本；空字符串表示关闭。 |\n| `reactions` | `true` | 处理中显示“思考中” `Typing` 表情，失败时换成 `CrossMark`。也受 `FEISHU_REACTIONS` 开关控制（关闭值：`false`/`0`/`no`/`off`）。 |\n\n凭据属于部署的 `.env`，通过 `credentials` seam 提供；配置不应内置机密。\n\n## 会话绑定\n\n每个聊天确定性地映射到一个持久的会话 id `feishu:<chat_id>`，因此对话历史在进程重启后仍保留，且机器人跨消息复用一个存活的 agent。一个恢复或新建的 agent 驱动每个聊天；对同一聊天的并发消息按顺序进入该 agent 的收件箱。准入前实施访问控制：忽略机器人自己发出的消息，私聊检查 `dmPolicy`/`allowFrom`，群聊检查 `groupPolicy`/`groupAllowFrom` 以及 @提及门槛。\n\n## 事件与扩展点\n\n该渠道不注册新的会话事件类型。被收下的用户消息在持久的 `user/message` 事件上携带 `feishu` 的 `MessageSource` 标签（`chatId`、`senderOpenId`、`messageId`），因此模型和任何消费方无需依赖实时传输即可归属一条提示。assistant 的回复从常规的 `session/event` → `assistant/message` 流读取，并以原生 Markdown（`msg_type: post` + `md`）发出；内容过长或 API 拒绝 `post` 载荷时降级为纯文本。可选的 `**🐋 DeepSeek**` 品牌前缀会加在富／长回复前。agent 处理时，机器人会在入站消息上加 `Typing` 表情，并在回合结束时移除（失败则换成 `CrossMark`）。\n\n## 模型体验\n\n间接地，通过它收下的用户消息体现。该渠道把每条被收下的聊天消息逐字提交为一条常规的用户角色提示进入 agent 循环，且不添加任何提示词或 schema，因此模型的上下文恰好是部署的组合加上消息文本。\n\n#### KV Cache 效果\n\n独立地，通过 agent 循环体现。该渠道不注册任何锁定或替换请求前缀的内容；每个聊天的会话各自保留自己的历史，适配器的缓存行为不变。\n\n## 模型来源（由宿主决定）\n\n回复模型**不由本包管理**——它取决于宿主 profile 解析出的**默认模型**。本渠道只把入站消息送进 agent 循环，并复用部署合成后的\n`agent-default-model`，因此这里**没有可配置的按渠道模型字段**。\n\n> [!IMPORTANT]\n> 在当前 dsh 布局里，`agent-default-model` 插件的**config 层优先于**全局 `settings.yaml` 的 `agent-default-model` 段。\n> 如果你只在 `settings.yaml` 配了第三方 provider（如 volcengine），新建的 profile 仍可能解析到 dsh-base 默认的\n> `deepseek-official`（在未导出其 key 时会因无凭据无法回复，bot 弹出 `CrossMark` 而非回复）。\n> 要使用你自己的模型，**在 profile 自己的 patch 层覆盖两行**（`$DSH_HOME/profiles/<name>/cordis.patch.yml`）：\n\n```yaml\n- id: llm-pi-ai\n  config:\n    providers:\n      volcengine:\n        displayName: volcengine\n        apiKeyEnv: VOLCENGINE_API_KEY\n        api: openai-responses\n        baseURL: https://ark.cn-beijing.volces.com/api/coding/v3\n        models:\n          - id: ark-code-latest\n            name: ark-code-latest\n- id: agent-default-model\n  config:\n    provider: volcengine\n    model: ark-code-latest\n```\n\n任意 provider（deepseek、openai 等）同理：把 provider 元数据填到 `llm-pi-ai`，再把 `agent-default-model` 指向它。\n这是宿主侧便利性的缺口，已记录；待宿主优先采纳全局 `settings.yaml` 默认后，该覆盖变为可选。\n\n## 已知限制与延后工作\n\n- **Markdown 渲染尽力而为** —— `post` + `md` 渲染标题、加粗、列表和围栏代码；**表格渲染不作承诺**（可能渲染，也可能降级为纯文本，但绝不强制降级）。流式卡片回复、图片、交互式卡片未实现；超长回复作为单条大文本发出，而非流式或分片。\n- **表情尽力而为** —— `Typing`/`CrossMark` 依赖 `im:message.reaction:*` scope 与飞书封闭的静态 emoji 集合；scope 或 emoji 不可用时跳过表情，回复仍正常发送。\n- **缺少 Webhook 传输** —— 仅提供 WebSocket 长连接；公网 URL 的 webhook 模式延后。\n- **机器人身份尽力而为** —— 机器人的 open id 在启动时解析一次，用于 @提及检测；一次瞬时失败会让群聊提及门槛保持保守（不触发群聊），直到重启。\n- **无飞书办公套件工具** —— 文档／知识库／云文档／多维表格工具不在本包范围内。","readmeFilename":"README.zh.md"}