@coze-arch/cli 0.0.14-alpha.5e3bce → 0.0.14-alpha.c52ee4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/__templates__/nextjs/scripts/prepare.sh +0 -1
- package/lib/__templates__/nuxt-vue/scripts/prepare.sh +0 -1
- package/lib/__templates__/pi-agent/.coze +10 -0
- package/lib/__templates__/pi-agent/AGENTS.md +150 -0
- package/lib/__templates__/pi-agent/README.md +155 -0
- package/lib/__templates__/pi-agent/_gitignore +3 -0
- package/lib/__templates__/pi-agent/docs/project-overview.md +273 -0
- package/lib/__templates__/pi-agent/docs/user/getting-started.md +46 -0
- package/lib/__templates__/pi-agent/package.json +52 -0
- package/lib/__templates__/pi-agent/pnpm-lock.yaml +7840 -0
- package/lib/__templates__/pi-agent/scripts/dev.sh +14 -0
- package/lib/__templates__/pi-agent/scripts/prepare.sh +2 -0
- package/lib/__templates__/pi-agent/src/agent.ts +367 -0
- package/lib/__templates__/pi-agent/src/channels/feishu/index.ts +760 -0
- package/lib/__templates__/pi-agent/src/channels/feishu/streaming-card.ts +297 -0
- package/lib/__templates__/pi-agent/src/channels/wechat/index.ts +171 -0
- package/lib/__templates__/pi-agent/src/config.ts +596 -0
- package/lib/__templates__/pi-agent/src/core.ts +218 -0
- package/lib/__templates__/pi-agent/src/dashboard/api/channels.ts +148 -0
- package/lib/__templates__/pi-agent/src/dashboard/api/docs.ts +204 -0
- package/lib/__templates__/pi-agent/src/dashboard/api/models.ts +141 -0
- package/lib/__templates__/pi-agent/src/dashboard/api/overview.ts +33 -0
- package/lib/__templates__/pi-agent/src/dashboard/config-store.ts +64 -0
- package/lib/__templates__/pi-agent/src/dashboard/index.ts +39 -0
- package/lib/__templates__/pi-agent/src/dashboard/server.ts +622 -0
- package/lib/__templates__/pi-agent/src/dashboard/types.ts +25 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/index.html +13 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/postcss.config.cjs +7 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/components/app-layout.tsx +186 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/components/page-title.tsx +17 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/alert.tsx +22 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/badge.tsx +25 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/button.tsx +40 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/card.tsx +29 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/input.tsx +18 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/label.tsx +8 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/select.tsx +80 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/components/ui/separator.tsx +23 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/hooks/use-fetch.ts +32 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/hooks/use-local-storage-state.ts +23 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/main.tsx +30 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/pages/channels-page.tsx +188 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/pages/chat-page.tsx +451 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/pages/docs-page.tsx +65 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/pages/models-page.tsx +122 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/pages/overview-page.tsx +134 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/services/chat-ws-service.ts +167 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/styles.css +294 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/src/utils/index.ts +11 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/tsconfig.json +13 -0
- package/lib/__templates__/pi-agent/src/dashboard/web/vite.config.ts +17 -0
- package/lib/__templates__/pi-agent/src/index.ts +123 -0
- package/lib/__templates__/pi-agent/src/session-store.ts +223 -0
- package/lib/__templates__/pi-agent/template.config.js +45 -0
- package/lib/__templates__/pi-agent/tests/config.test.ts +292 -0
- package/lib/__templates__/pi-agent/tests/dashboard-docs-api.test.ts +125 -0
- package/lib/__templates__/pi-agent/tests/dashboard-models-api.test.ts +171 -0
- package/lib/__templates__/pi-agent/tests/feishu-channel.test.ts +149 -0
- package/lib/__templates__/pi-agent/tests/feishu-streaming-card.test.ts +15 -0
- package/lib/__templates__/pi-agent/tests/session-store.test.ts +61 -0
- package/lib/__templates__/pi-agent/tests/smoke/run-smoke.ts +275 -0
- package/lib/__templates__/pi-agent/tsconfig.json +20 -0
- package/lib/__templates__/pi-agent/types/larksuiteoapi-node-sdk.d.ts +113 -0
- package/lib/__templates__/templates.json +24 -0
- package/lib/__templates__/vite/scripts/prepare.sh +0 -1
- package/lib/cli.js +8 -106
- package/package.json +1 -1
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Pi Bot AGENTS Guide
|
|
2
|
+
|
|
3
|
+
## 1. 项目定位
|
|
4
|
+
|
|
5
|
+
- 这是一个已经交付给用户、会继续被迭代的 Pi Bot 项目。
|
|
6
|
+
- 你面对的是“当前用户的项目”,不是一个需要保持通用性的初始化模板。
|
|
7
|
+
- 当新需求和现有行为冲突时,默认优先保护已有功能、配置兼容性、会话数据和可调试性。
|
|
8
|
+
|
|
9
|
+
## 2. 工作区与配置
|
|
10
|
+
|
|
11
|
+
- 用户工作区和运行时配置默认位于相邻目录 `<%= workspaceDir %>/`。
|
|
12
|
+
- 默认配置文件路径是 `<%= workspaceDir %>/config.json`。
|
|
13
|
+
- 运行时配置的代码入口是 `src/config.ts`。不要绕过它再引入新的平行配置源。
|
|
14
|
+
- 如果要修改配置写回逻辑,必须保留无关字段,避免覆盖用户已有配置。
|
|
15
|
+
|
|
16
|
+
## 3. 必读顺序
|
|
17
|
+
|
|
18
|
+
在进行较大修改前,优先按下面顺序理解项目:
|
|
19
|
+
|
|
20
|
+
1. `README.md`
|
|
21
|
+
2. `docs/project-overview.md`
|
|
22
|
+
3. 与需求相关的源码入口
|
|
23
|
+
4. 与改动相关的测试
|
|
24
|
+
|
|
25
|
+
不要依赖当前目录之外的文档。
|
|
26
|
+
|
|
27
|
+
## 4. 核心架构约束
|
|
28
|
+
|
|
29
|
+
### 4.1 消息与分层
|
|
30
|
+
|
|
31
|
+
- 平台消息必须先归一化为 `BotMessage`,再进入 runtime。
|
|
32
|
+
- `channel` 层负责平台协议适配、路由过滤、消息发送。
|
|
33
|
+
- `runtime` 层负责 agent 调用、session 生命周期和流式输出。
|
|
34
|
+
- `dashboard` 负责调试界面、运行态观察和受控配置编辑。
|
|
35
|
+
- 不要把平台逻辑、UI 逻辑、模型逻辑混写在一起。
|
|
36
|
+
|
|
37
|
+
### 4.2 Session 与持久化
|
|
38
|
+
|
|
39
|
+
- 会话归类规则以 `src/core.ts` 中的 `getSessionKey()` 为准,不要随意改动会话 key 规则。
|
|
40
|
+
- `src/session-store.ts` 负责 session 索引、transcript 文件和 reset 归档逻辑。
|
|
41
|
+
- reset session 时必须归档旧 transcript,不能直接覆盖旧会话文件。
|
|
42
|
+
- 不要删除、清空或重置 .pi-bot/ 下的会话数据,除非用户明确要求。
|
|
43
|
+
|
|
44
|
+
### 4.3 配置与兼容性
|
|
45
|
+
|
|
46
|
+
- 用户可编辑配置以 `<%= workspaceDir %>/config.json` 为 source of truth。
|
|
47
|
+
- 新增配置项时,优先采用向后兼容的方式;避免无说明地重命名、删除或改变现有字段语义。
|
|
48
|
+
- Dashboard 的配置写回必须是“局部更新”,不能把不相关配置抹掉。
|
|
49
|
+
- 若变更会影响配置 schema、session 持久化格式、HTTP API shape 或默认行为,先确认再修改。
|
|
50
|
+
|
|
51
|
+
### 4.4 外部平台的降级能力
|
|
52
|
+
|
|
53
|
+
- 飞书、微信、模型 provider、流式卡片等外部能力都可能失败。
|
|
54
|
+
- 外部能力失败时,优先保证主链路可用,并提供合理降级。
|
|
55
|
+
- 例如 reaction、streaming card 或可选增强能力失败时,不应阻断最终回复。
|
|
56
|
+
|
|
57
|
+
### 4.5 Agent 能力扩展方式
|
|
58
|
+
|
|
59
|
+
- 新增“搜索 / 检索 / 信息采集 / 外部知识 / 热点汇总”这类能力时,默认优先使用 `pi-coding-agent` / `pi-mono` 生态已有的扩展方式:
|
|
60
|
+
- `customTools`
|
|
61
|
+
- extensions
|
|
62
|
+
- `ResourceLoader`
|
|
63
|
+
- skills / prompt templates
|
|
64
|
+
- 不要在 `channel` 层、`onMessage()`、`createBotApp()` 或其他 host 侧装配代码里,通过关键词匹配、意图判断或硬编码分支,手动把请求路由到某个 `collector`、`searcher`、`crawler`。
|
|
65
|
+
- `channel` 层只负责平台协议适配、消息归一化、路由过滤和发送回复;不负责“这个问题该不该调用外部信息能力”的业务决策。
|
|
66
|
+
- `runtime` 层负责把能力注册为 agent 可调用的 tool / extension,再由 agent 在对话过程中决定是否使用。
|
|
67
|
+
- 如果需求确实无法通过 tool / extension / skill 方式实现,必须先说明为什么现有扩展点不适用,再考虑增加 host 侧分流逻辑。
|
|
68
|
+
- 反例:
|
|
69
|
+
- 在 `onMessage()` 里判断“如果用户提到 Hacker News / GitHub 就直接调用 collector”
|
|
70
|
+
- 正例:
|
|
71
|
+
- 在 runtime 注册一个“抓取热点内容”的自定义 tool,让 agent 自主决定何时调用
|
|
72
|
+
|
|
73
|
+
## 5. 修改策略
|
|
74
|
+
|
|
75
|
+
- 优先做小步、增量、可验证的修改,避免没有必要的大规模重写。
|
|
76
|
+
- 用户可见行为发生变化时,优先考虑是否应该做成配置项,而不是直接硬编码。
|
|
77
|
+
- 修 bug 或加功能时,同时检查是否需要补测试和文档。
|
|
78
|
+
|
|
79
|
+
## 6. 常见改动的落点
|
|
80
|
+
|
|
81
|
+
- 改运行时配置或模型/provider 解析:
|
|
82
|
+
- `src/config.ts`
|
|
83
|
+
- `tests/config.test.ts`
|
|
84
|
+
- 改 session 行为或 transcript 持久化:
|
|
85
|
+
- `src/core.ts`
|
|
86
|
+
- `src/agent.ts`
|
|
87
|
+
- `src/session-store.ts`
|
|
88
|
+
- `tests/session-store.test.ts`
|
|
89
|
+
- 改飞书/微信 channel:
|
|
90
|
+
- `src/channels/*`
|
|
91
|
+
- 对应 channel tests
|
|
92
|
+
- 改 Dashboard 接口或配置编辑:
|
|
93
|
+
- `src/dashboard/api/*`
|
|
94
|
+
- `src/dashboard/server.ts`
|
|
95
|
+
- 对应 API tests
|
|
96
|
+
- 改 Dashboard 前端:
|
|
97
|
+
- `src/dashboard/web/src/*`
|
|
98
|
+
- 必要时补充前后端联动验证
|
|
99
|
+
|
|
100
|
+
## 7. 验证要求
|
|
101
|
+
|
|
102
|
+
默认情况下:
|
|
103
|
+
|
|
104
|
+
- 代码改动后至少运行:
|
|
105
|
+
- `npm test`
|
|
106
|
+
- `npm run typecheck`
|
|
107
|
+
- 如果修改了 Dashboard 前端或其构建相关内容,再运行:
|
|
108
|
+
- `npm run dashboard:build`
|
|
109
|
+
- 如果修改影响了跨模块主链路,例如 config、channel、runtime、session、dashboard 联动,再运行:
|
|
110
|
+
- `npm run smoke`
|
|
111
|
+
|
|
112
|
+
如果因为环境限制无法完成验证,需要在最终说明中明确指出未验证项和风险,并给出用户手动验证的方式。
|
|
113
|
+
|
|
114
|
+
## 8. 文档同步要求
|
|
115
|
+
|
|
116
|
+
出现以下情况时,同步更新相关文档:
|
|
117
|
+
|
|
118
|
+
- 启动或配置方式变化
|
|
119
|
+
- 用户可见行为变化
|
|
120
|
+
- 目录结构或核心模块职责变化
|
|
121
|
+
- 测试方式或验证要求变化
|
|
122
|
+
|
|
123
|
+
### 8.1 文档落点与命名规范
|
|
124
|
+
|
|
125
|
+
- 除 `README.md`、`AGENTS.md` 这类仓库入口文件外,不要随意在项目根目录新增文档。
|
|
126
|
+
- 架构说明、设计说明、实现说明、迭代记录等开发文档,放在 `docs/` 下。
|
|
127
|
+
- 面向最终用户的使用说明、接入说明、操作指南,放在 `docs/user/` 下。
|
|
128
|
+
- 新增文档文件名使用 kebab-case,例如 `agent-tooling-guide.md`、`dashboard-chat-flow.md`。
|
|
129
|
+
- 不要创建语义含糊的文件名,例如 `new-doc.md`、`notes.md`、`temp.md`、`test.md`。
|
|
130
|
+
- 如果某次改动需要补文档,优先更新已有文档;只有在现有文档承载不合适时,才新增文档文件。
|
|
131
|
+
- 新增文档后,应该让相关入口文档能找到它,避免产生“写了但没人知道在哪”的文档孤岛。
|
|
132
|
+
|
|
133
|
+
## 9. 需要先确认的高风险变更
|
|
134
|
+
|
|
135
|
+
遇到以下改动,先暂停并与用户确认:
|
|
136
|
+
|
|
137
|
+
- 修改 `config.json` schema 或默认值语义
|
|
138
|
+
- 修改 `getSessionKey()` 规则
|
|
139
|
+
- 修改 session 文件格式、索引格式或归档规则
|
|
140
|
+
- 修改默认 channel 行为,导致消息路由或触发条件变化
|
|
141
|
+
- 删除现有 API、页面、配置项或持久化数据
|
|
142
|
+
|
|
143
|
+
## 10. 目标
|
|
144
|
+
|
|
145
|
+
你的目标是在当前项目基础上持续迭代,稳定交付用户需要的能力,同时尽量保持:
|
|
146
|
+
|
|
147
|
+
- 现有行为可预测
|
|
148
|
+
- 配置与数据可兼容
|
|
149
|
+
- 出问题时便于排查
|
|
150
|
+
- 后续继续迭代时容易维护
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Pi Bot
|
|
2
|
+
|
|
3
|
+
这是一个基于 `pi-mono` / `@mariozechner/pi-coding-agent` 的 Bot 项目。
|
|
4
|
+
|
|
5
|
+
## 当前结构
|
|
6
|
+
|
|
7
|
+
- `src/config.ts`
|
|
8
|
+
- 项目唯一配置入口,读取 `config.json` 并装配 `BotAppConfig`
|
|
9
|
+
- `src/index.ts`
|
|
10
|
+
- 应用启动入口
|
|
11
|
+
- `src/agent.ts`
|
|
12
|
+
- agent runtime 封装
|
|
13
|
+
- `src/dashboard/config-store.ts`
|
|
14
|
+
- Dashboard 配置读写抽象,支持文件和内存两种存储
|
|
15
|
+
- `src/core.ts`
|
|
16
|
+
- 通用消息协议、共享类型和 helper
|
|
17
|
+
- `src/channels/feishu`
|
|
18
|
+
- 飞书 channel
|
|
19
|
+
- `src/channels/wechat`
|
|
20
|
+
- 微信 channel
|
|
21
|
+
- `tests/smoke`
|
|
22
|
+
- 基础 smoke test(使用内存配置存储验证 dashboard 配置读写链路)
|
|
23
|
+
- `tests/config.test.ts`
|
|
24
|
+
- config 解析与模型构建测试
|
|
25
|
+
- `types`
|
|
26
|
+
- 本地类型声明补充
|
|
27
|
+
- `docs/project-overview.md`
|
|
28
|
+
- 项目结构与实现介绍
|
|
29
|
+
- `docs/user/getting-started.md`
|
|
30
|
+
- 用户快速开始文档,Dashboard 的 `Docs` 页面会直接展示这份 Markdown
|
|
31
|
+
|
|
32
|
+
## Start
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install
|
|
36
|
+
npm run dev
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`npm run dev` 会先按顺序加载 `.env` 和 `.env.local`,然后启动 `src/index.ts`。
|
|
40
|
+
|
|
41
|
+
## 用户文档
|
|
42
|
+
|
|
43
|
+
启动后,可以在 Dashboard 的 `Docs` 页面查看当前项目的用户指引,默认地址是:
|
|
44
|
+
|
|
45
|
+
```txt
|
|
46
|
+
http://127.0.0.1:5000/docs
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
用户文档的 Markdown 源文件位于 `docs/user/getting-started.md`。如果你修改了接入步骤或调整了用户可见行为,请同步更新这份文档。
|
|
50
|
+
|
|
51
|
+
## 常用命令
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm run dev
|
|
55
|
+
npm test
|
|
56
|
+
npm run smoke
|
|
57
|
+
npm run typecheck
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Agent 模式
|
|
61
|
+
|
|
62
|
+
- `PI_BOT_AGENT_MODE=mock`
|
|
63
|
+
- 使用 mock runtime,适合本地链路验证
|
|
64
|
+
- `PI_BOT_AGENT_MODE=pi`
|
|
65
|
+
- 使用真实 `pi-coding-agent` runtime
|
|
66
|
+
|
|
67
|
+
除 `PI_BOT_AGENT_MODE` 和飞书相关环境变量外,agent 的模型、provider、workspace、thinking level 都从 `<%= workspaceDir %>/config.json` 读取。
|
|
68
|
+
|
|
69
|
+
## Provider 配置
|
|
70
|
+
|
|
71
|
+
provider 不再通过项目内的特化实现硬编码,而是从 `<%= workspaceDir %>/config.json` 的 `models.providers` 读取。
|
|
72
|
+
|
|
73
|
+
如果你已经启动了本地 Dashboard,现在也可以直接在界面里切换默认模型:
|
|
74
|
+
|
|
75
|
+
- `http://127.0.0.1:5000/models`
|
|
76
|
+
- 选择默认模型(选择后会自动保存)
|
|
77
|
+
|
|
78
|
+
默认情况下,Dashboard 会通过文件型 `ConfigStore` 读写 `<%= workspaceDir %>/config.json`,保存后需要重启进程让配置生效。测试或嵌入场景也可以通过 `createBotApp(..., { dashboardConfigStore })` 注入内存型 `ConfigStore`,避免依赖真实配置文件。
|
|
79
|
+
|
|
80
|
+
默认主模型来自:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"agents": {
|
|
85
|
+
"defaults": {
|
|
86
|
+
"thinkingLevel": "medium",
|
|
87
|
+
"model": {
|
|
88
|
+
"primary": "coze/glm-4-7-251222"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
provider 定义示例:
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"models": {
|
|
100
|
+
"providers": {
|
|
101
|
+
"coze": {
|
|
102
|
+
"api": "openai-completions",
|
|
103
|
+
"apiKey": "${COZE_WORKLOAD_IDENTITY_API_KEY}",
|
|
104
|
+
"baseUrl": "${COZE_INTEGRATION_MODEL_BASE_URL}",
|
|
105
|
+
"models": [
|
|
106
|
+
{
|
|
107
|
+
"id": "glm-4-7-251222",
|
|
108
|
+
"name": "GLM 4.7",
|
|
109
|
+
"reasoning": false,
|
|
110
|
+
"input": ["text"],
|
|
111
|
+
"contextWindow": 200000,
|
|
112
|
+
"maxTokens": 8192,
|
|
113
|
+
"cost": {
|
|
114
|
+
"input": 0,
|
|
115
|
+
"output": 0,
|
|
116
|
+
"cacheRead": 0,
|
|
117
|
+
"cacheWrite": 0
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
后续要扩展新的 openai-compatible provider,只需要在 `<%= workspaceDir %>/config.json` 里新增一个 provider 配置和模型定义即可。
|
|
128
|
+
|
|
129
|
+
当前 Dashboard 的模型配置页仅用于切换默认模型,不支持编辑 Provider 或模型参数。如果要扩展或修改 provider/model,仍然建议直接编辑 `<%= workspaceDir %>/config.json`。
|
|
130
|
+
|
|
131
|
+
## Feishu Debug
|
|
132
|
+
|
|
133
|
+
如果你在联调真实飞书机器人,并想排查重复回复或事件重试问题,可开启:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
export PI_BOT_DEBUG_FEISHU=1
|
|
137
|
+
npm run dev
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
飞书 channel 会输出收到事件、过滤原因、去重结果和发送回复等关键日志。
|
|
141
|
+
|
|
142
|
+
默认情况下,飞书 channel 会在 bot 开始处理消息时给原消息加一个 `OneSecond` reaction,并在发送回复前移除它。这里的 `emojiType` 需要填写飞书文档里的 `emoji_type` 枚举值,比如 `OneSecond`、`MUSCLE`。你也可以在 `<%= workspaceDir %>/config.json` 里覆盖这个行为:
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"channels": {
|
|
147
|
+
"feishu": {
|
|
148
|
+
"thinkingReaction": {
|
|
149
|
+
"enabled": true,
|
|
150
|
+
"emojiType": "OneSecond"
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# Pi Bot 项目总览
|
|
2
|
+
|
|
3
|
+
## 1. 项目定位
|
|
4
|
+
|
|
5
|
+
`pi-bot` 是一个基于 `pi-mono` / `@mariozechner/pi-coding-agent` 的 Bot 项目。
|
|
6
|
+
|
|
7
|
+
这个目录直接承载三类能力:
|
|
8
|
+
|
|
9
|
+
- 初始化骨架
|
|
10
|
+
- 平台 channel 接入
|
|
11
|
+
- provider 扩展
|
|
12
|
+
|
|
13
|
+
项目里的关键运行时代码集中在这里,阅读、修改和扩展都会更直接。
|
|
14
|
+
|
|
15
|
+
## 2. 当前目录结构
|
|
16
|
+
|
|
17
|
+
```txt
|
|
18
|
+
.
|
|
19
|
+
├── docs
|
|
20
|
+
│ ├── project-overview.md
|
|
21
|
+
│ └── user
|
|
22
|
+
├── src
|
|
23
|
+
│ ├── agent.ts
|
|
24
|
+
│ ├── config.ts
|
|
25
|
+
│ ├── core.ts
|
|
26
|
+
│ ├── session-store.ts
|
|
27
|
+
│ ├── dashboard
|
|
28
|
+
│ │ ├── config-store.ts
|
|
29
|
+
│ │ ├── api
|
|
30
|
+
│ │ │ ├── channels.ts
|
|
31
|
+
│ │ │ ├── models.ts
|
|
32
|
+
│ │ │ └── overview.ts
|
|
33
|
+
│ │ ├── web
|
|
34
|
+
│ │ │ ├── src
|
|
35
|
+
│ │ │ │ ├── components
|
|
36
|
+
│ │ │ │ │ ├── ui
|
|
37
|
+
│ │ │ │ │ └── app-layout.tsx
|
|
38
|
+
│ │ │ │ ├── pages
|
|
39
|
+
│ │ │ │ ├── utils
|
|
40
|
+
│ │ │ │ ├── main.tsx
|
|
41
|
+
│ │ │ │ └── styles.css
|
|
42
|
+
│ │ │ ├── index.html
|
|
43
|
+
│ │ │ ├── postcss.config.cjs
|
|
44
|
+
│ │ │ ├── tsconfig.json
|
|
45
|
+
│ │ │ └── vite.config.ts
|
|
46
|
+
│ │ ├── index.ts
|
|
47
|
+
│ │ ├── server.ts
|
|
48
|
+
│ │ └── types.ts
|
|
49
|
+
│ ├── index.ts
|
|
50
|
+
│ ├── channels
|
|
51
|
+
│ │ ├── feishu
|
|
52
|
+
│ │ └── wechat
|
|
53
|
+
├── tests
|
|
54
|
+
│ ├── config.test.ts
|
|
55
|
+
│ └── smoke
|
|
56
|
+
└── types
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
各部分职责:
|
|
60
|
+
|
|
61
|
+
- `src/config.ts`
|
|
62
|
+
- 项目唯一配置入口,读取 `config.json` 并装配 agent、channel、routing 等运行配置
|
|
63
|
+
- `src/index.ts`
|
|
64
|
+
- 应用装配层,创建 channel 并把消息交给 runtime
|
|
65
|
+
- `src/agent.ts`
|
|
66
|
+
- `pi-coding-agent` runtime 封装
|
|
67
|
+
- `src/core.ts`
|
|
68
|
+
- 通用消息协议、共享类型和基础 helper
|
|
69
|
+
- `src/session-store.ts`
|
|
70
|
+
- session 持久化索引层
|
|
71
|
+
- 负责维护 `sessionKey -> sessionId/sessionFile` 映射,并管理 transcript header、reset 归档等文件操作
|
|
72
|
+
- `src/channels/feishu`
|
|
73
|
+
- 飞书消息接收、标准化、去重、过滤和回复发送
|
|
74
|
+
- `src/channels/wechat`
|
|
75
|
+
- 微信消息标准化和回复发送
|
|
76
|
+
- `src/dashboard/*`
|
|
77
|
+
- 本地 Dashboard(HTTP + WebSocket),用于查看运行状态、编辑配置、以及以 UI 方式调试聊天会话
|
|
78
|
+
- 同时提供 `Docs` 页面,直接展示项目内的快速开始文档
|
|
79
|
+
- 开发态通过 Vite middleware 提供前端资源;生产态直接托管 `src/dashboard/web/dist`
|
|
80
|
+
- `src/dashboard/config-store.ts`
|
|
81
|
+
- Dashboard 配置存储抽象
|
|
82
|
+
- 默认使用文件存储读写 `workspace/config.json`
|
|
83
|
+
- 也支持内存存储,便于 smoke test 或宿主注入
|
|
84
|
+
- `tests/smoke`
|
|
85
|
+
- 基础链路 smoke test
|
|
86
|
+
- 当前会额外覆盖 dashboard 的 models/channels 配置读写,并使用内存 `ConfigStore` 避免依赖真实配置文件
|
|
87
|
+
- `tests/config.test.ts`
|
|
88
|
+
- config 解析与模型构建测试
|
|
89
|
+
- `types`
|
|
90
|
+
- 第三方 SDK 的类型补充
|
|
91
|
+
|
|
92
|
+
## 3. Dashboard(现状实现)
|
|
93
|
+
|
|
94
|
+
Dashboard 是一个「和 Bot 同进程」启动的本地 HTTP 服务,默认地址:
|
|
95
|
+
|
|
96
|
+
- `http://127.0.0.1:5000`
|
|
97
|
+
- 端口/Host 可通过环境变量覆盖:`PI_BOT_DASHBOARD_PORT`、`PI_BOT_DASHBOARD_HOST`
|
|
98
|
+
|
|
99
|
+
服务端入口:
|
|
100
|
+
|
|
101
|
+
- [`src/dashboard/server.ts`](../src/dashboard/server.ts) 负责 Express 路由、Vite 开发中间件、以及 WebSocket(聊天流式)
|
|
102
|
+
- [`src/dashboard/index.ts`](../src/dashboard/index.ts) 负责把 Bot runtime 信息注入 Dashboard server
|
|
103
|
+
- [`src/dashboard/config-store.ts`](../src/dashboard/config-store.ts) 负责把 Dashboard 的配置读写抽象成 `ConfigStore`
|
|
104
|
+
|
|
105
|
+
### 3.1 前端技术栈
|
|
106
|
+
|
|
107
|
+
- Vite + React + React Router
|
|
108
|
+
- Tailwind CSS v4(`styles.css` 里使用 `@import "tailwindcss"` / `@theme`)
|
|
109
|
+
- shadcn 风格组件(代码内置于 `src/dashboard/web/src/components/ui/*`)
|
|
110
|
+
- 暗黑模式:通过在 `documentElement` 上切换 `dark` class,并在 `styles.css` 提供 `:root` / `.dark` token
|
|
111
|
+
|
|
112
|
+
### 3.2 页面与路由
|
|
113
|
+
|
|
114
|
+
前端路由位于 `src/dashboard/web/src/main.tsx`,当前页面:
|
|
115
|
+
|
|
116
|
+
- `/overview`:运行状态与关键路径(workspace/agent dir 等)
|
|
117
|
+
- `/docs`:项目快速开始文档
|
|
118
|
+
- `/models`:切换默认模型
|
|
119
|
+
- `/channels`:编辑渠道配置
|
|
120
|
+
- `/chat`:调试聊天会话(含历史、reset、WebSocket 流式)
|
|
121
|
+
|
|
122
|
+
### 3.3 HTTP API(服务端)
|
|
123
|
+
|
|
124
|
+
当前主要接口(均在同一进程内,不做鉴权):
|
|
125
|
+
|
|
126
|
+
- `GET /api/overview`:运行状态/路径/启用渠道等
|
|
127
|
+
- `GET /api/docs`:读取 `docs/user/` 下的用户文档并返回当前文档内容
|
|
128
|
+
- `GET /api/models`:通过 `ConfigStore` 读取配置并返回默认模型与可选模型列表(用于下拉选择)
|
|
129
|
+
- `POST /api/models`:仅写回默认模型(请求体只包含 `defaultModel`;服务端会基于当前配置扫描列表做校验)
|
|
130
|
+
- `GET /api/channels`:通过 `ConfigStore` 读取配置并返回可编辑结构
|
|
131
|
+
- `POST /api/channels`:通过 `ConfigStore` 写回配置;默认文件存储会落回 `workspace/config.json`,保存后需要重启进程生效
|
|
132
|
+
- `GET /api/chat/history`:按 session identity 计算 sessionKey,并按需加载持久化 transcript 后返回消息
|
|
133
|
+
- `POST /api/chat/reset`:重置指定 sessionKey 的会话;会切换到新的 `sessionId/sessionFile`,旧 transcript 归档到 `archive/`
|
|
134
|
+
- `WS /api/chat/ws`:聊天流式(推荐的 UI 通道)
|
|
135
|
+
|
|
136
|
+
补充说明:
|
|
137
|
+
|
|
138
|
+
- 生产/日常开发默认使用文件型 `ConfigStore`
|
|
139
|
+
- `createBotApp(..., { dashboardConfigStore })` 可注入自定义存储实现
|
|
140
|
+
- `tests/smoke/run-smoke.ts` 当前使用内存型 `ConfigStore`,直接验证 dashboard 配置的读写 API 行为
|
|
141
|
+
|
|
142
|
+
### 3.4 模型配置页能力边界
|
|
143
|
+
|
|
144
|
+
当前 `/models` 页面的目标,是以 UI 方式快速切换默认模型,降低直接手改 JSON 的成本。当前页面支持:
|
|
145
|
+
|
|
146
|
+
- 修改默认模型(写回 `agents.defaults.model.primary`)
|
|
147
|
+
|
|
148
|
+
当前页面不支持:
|
|
149
|
+
|
|
150
|
+
- 编辑 Provider 配置
|
|
151
|
+
- 编辑模型参数
|
|
152
|
+
- 新增/删除 Provider 或模型条目
|
|
153
|
+
|
|
154
|
+
因此,如果要接入新的 openai-compatible provider、修改模型定义或参数,仍然建议直接编辑默认文件存储对应的 `workspace/config.json`;补充完成后,Dashboard 会自动读取并展示这些新模型供选择。
|
|
155
|
+
|
|
156
|
+
### 3.5 Session 持久化
|
|
157
|
+
|
|
158
|
+
当前 `pi-bot` 已支持 session 持久化,逻辑参考 `openclaw` 的 transcript/sessionFile 模式:
|
|
159
|
+
|
|
160
|
+
- `src/core.ts` 里的 `getSessionKey()` 仍然负责根据 channel / conversation / thread 等信息生成稳定的业务会话键
|
|
161
|
+
- `src/session-store.ts` 负责把这个 `sessionKey` 映射到一个可落盘的 transcript 文件
|
|
162
|
+
- `src/agent.ts` 在创建真实 `pi-coding-agent` session 时,不再只依赖进程内 `Map`,而是通过 `SessionManager.open(sessionFile)` 绑定到固定 transcript
|
|
163
|
+
|
|
164
|
+
默认持久化目录位于:
|
|
165
|
+
|
|
166
|
+
```txt
|
|
167
|
+
<agentDir>/.pi-bot/sessions/
|
|
168
|
+
├── index.json
|
|
169
|
+
├── transcripts/
|
|
170
|
+
└── archive/
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
其中:
|
|
174
|
+
|
|
175
|
+
- `index.json`
|
|
176
|
+
- 保存 `sessionKey -> { sessionId, sessionFile, updatedAt }` 的索引
|
|
177
|
+
- `transcripts/`
|
|
178
|
+
- 保存当前活跃会话的 transcript(`.jsonl`)
|
|
179
|
+
- `archive/`
|
|
180
|
+
- 保存 reset 后被归档的旧 transcript
|
|
181
|
+
|
|
182
|
+
补充说明:
|
|
183
|
+
|
|
184
|
+
- 持久化覆盖全部 channel:`dashboard` / `feishu` / `wechat`
|
|
185
|
+
- transcript 文件名不会直接使用原始 `sessionKey`,而是基于其 hash 生成,避免特殊字符和超长文件名问题
|
|
186
|
+
- Dashboard 重启后仍可通过 `GET /api/chat/history` 恢复已有会话消息
|
|
187
|
+
- Reset 不会直接覆盖旧 transcript,而是新建 session 并归档旧文件,便于排查和追溯
|
|
188
|
+
|
|
189
|
+
### 3.6 构建方式
|
|
190
|
+
|
|
191
|
+
前端生产构建命令:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
npm run dashboard:build
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
该脚本对应 Vite 配置:
|
|
198
|
+
|
|
199
|
+
- [`src/dashboard/web/vite.config.ts`](../src/dashboard/web/vite.config.ts)
|
|
200
|
+
|
|
201
|
+
开发态(`NODE_ENV !== "production"`):
|
|
202
|
+
|
|
203
|
+
- Dashboard server 通过 Vite middleware 直接服务前端(无需单独启动 Vite dev server)
|
|
204
|
+
|
|
205
|
+
生产态(`NODE_ENV=production`):
|
|
206
|
+
|
|
207
|
+
- Dashboard server 托管 `src/dashboard/web/dist` 的静态文件
|
|
208
|
+
- 如果你需要生产态可用,记得先运行 `npm run dashboard:build`
|
|
209
|
+
|
|
210
|
+
## 4. 运行模型
|
|
211
|
+
|
|
212
|
+
当前项目的运行链路如下:
|
|
213
|
+
|
|
214
|
+
1. channel 接收平台事件
|
|
215
|
+
2. channel 把事件转换成 `BotMessage`
|
|
216
|
+
3. `src/index.ts` 调用 `runtime.run(message)`
|
|
217
|
+
4. `src/agent.ts` 根据配置选择 mock 或真实 `pi-coding-agent`
|
|
218
|
+
5. 真实 runtime 会先通过 `getSessionKey()` 确定业务会话,再通过 `src/session-store.ts` 找到或创建对应的持久化 transcript
|
|
219
|
+
6. runtime 基于该 transcript 执行 prompt,新的 user / assistant 消息持续写入 sessionFile
|
|
220
|
+
7. runtime 返回文本
|
|
221
|
+
8. channel 把文本发回原平台
|
|
222
|
+
|
|
223
|
+
## 4.1 飞书卡片与流式输出
|
|
224
|
+
|
|
225
|
+
`pi-bot` 的飞书回复有两种渲染形态:
|
|
226
|
+
|
|
227
|
+
- 普通文本:`msg_type: "text"`
|
|
228
|
+
- Markdown 卡片:`msg_type: "interactive"`(卡片内使用 `tag: "markdown"`)
|
|
229
|
+
|
|
230
|
+
默认情况下会按内容自动选择是否使用卡片(与 `openclaw` 的判断一致):
|
|
231
|
+
|
|
232
|
+
- 命中代码块(```...```,流式阶段也接受仅出现 opening fence)或 Markdown 表格时,使用卡片渲染
|
|
233
|
+
- 其他普通文本/普通 Markdown,使用文本消息
|
|
234
|
+
|
|
235
|
+
当启用流式回复(`onStreamMessage` + `runtime.stream()`)时,如果内容命中“使用卡片”的条件,会尝试使用 CardKit 的 streaming card API 做实时更新:
|
|
236
|
+
|
|
237
|
+
- 创建 streaming card(CardKit `cardkit/v1/cards`)
|
|
238
|
+
- reply 一条 `interactive` 卡片引用到原消息
|
|
239
|
+
- 按增量内容持续更新卡片中的 markdown 元素
|
|
240
|
+
- 最终关闭 streaming 模式并更新 summary
|
|
241
|
+
|
|
242
|
+
注意:流式卡片需要飞书开放平台开通 CardKit 相关权限(例如 `cardkit:card:write`)。如果权限未开通,streaming card 创建/更新会失败并自动回退为“最终一次性回复”。
|
|
243
|
+
|
|
244
|
+
如果 streaming card 创建失败(例如未开通 CardKit 权限、参数/租户不匹配等),会自动回退为“最终一次性回复”,不会影响正常出消息。
|
|
245
|
+
|
|
246
|
+
补充说明:
|
|
247
|
+
|
|
248
|
+
- 进程内仍保留 `Map<string, AgentSession>` 作为热缓存,避免同一 session 在单次运行期间重复创建
|
|
249
|
+
- 但真正的“可恢复会话”依赖的是磁盘上的 transcript,而不是这个内存 `Map`
|
|
250
|
+
- 因此进程重启后,只要 `sessionKey` 不变,就可以重新打开对应 transcript 继续对话
|
|
251
|
+
- 飞书 thinking reaction 默认 emoji 已调整为 `OneSecond`,也可通过 `channels.feishu.thinkingReaction.emojiType` 覆盖
|
|
252
|
+
|
|
253
|
+
## 5. 当前建议的开发顺序
|
|
254
|
+
|
|
255
|
+
如果后续继续扩展,建议按这个顺序理解项目:
|
|
256
|
+
|
|
257
|
+
1. 阅读根目录 `README.md`
|
|
258
|
+
2. 阅读 `docs/project-overview.md`
|
|
259
|
+
3. 阅读 `src/config.ts`
|
|
260
|
+
4. 阅读 `src/index.ts`
|
|
261
|
+
5. 阅读 `src/agent.ts`
|
|
262
|
+
6. 根据需要再进入 `src/channels/*`、`src/dashboard/*` 和相关测试
|
|
263
|
+
|
|
264
|
+
## 6. 关于 docs
|
|
265
|
+
|
|
266
|
+
`docs/` 目录中保留了两类材料:
|
|
267
|
+
|
|
268
|
+
- `docs/project-overview.md`
|
|
269
|
+
- 面向维护者的架构介绍
|
|
270
|
+
- `docs/user/getting-started.md`
|
|
271
|
+
- 面向项目使用者的快速开始文档,Dashboard 的 `Docs` 页面会直接读取并展示
|
|
272
|
+
|
|
273
|
+
最贴近现状的介绍文档是这份 `docs/project-overview.md`。如果其他文档与当前目录结构冲突,应以当前源码、`README.md` 和本文件为准。
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 快速开始
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# 快速开始
|
|
6
|
+
|
|
7
|
+
即使暂时没有打通外部渠道,你也可以先用 Dashboard 的 `聊天` 页面验证 Agent 行为。
|
|
8
|
+
|
|
9
|
+
## 接入飞书机器人
|
|
10
|
+
|
|
11
|
+
1. 打开 [渠道](/channels) 页面。
|
|
12
|
+
2. 填写 `App ID` 和 `App Secret`。
|
|
13
|
+
3. 按需填写 `domain`、`encryptKey`、`verificationToken`。
|
|
14
|
+
4. 点击保存。
|
|
15
|
+
5. 重启应用让配置生效。
|
|
16
|
+
|
|
17
|
+
### 飞书机器人配置
|
|
18
|
+
|
|
19
|
+
1. 在「权限管理」中配置以下权限:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"scopes": {
|
|
24
|
+
"tenant": [
|
|
25
|
+
"cardkit:card:write",
|
|
26
|
+
"docx:document:readonly",
|
|
27
|
+
"im:message.group_at_msg:readonly",
|
|
28
|
+
"im:message.p2p_msg:readonly",
|
|
29
|
+
"im:message.reactions:read",
|
|
30
|
+
"im:message.reactions:write_only",
|
|
31
|
+
"im:message:send_as_bot"
|
|
32
|
+
],
|
|
33
|
+
"user": [
|
|
34
|
+
"docx:document:readonly"
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
2. 在「事件与回调」中添加 `im.message.receive_v1` 事件,并将订阅方式设置为“使用长连接接收事件”。
|
|
41
|
+
|
|
42
|
+
## 发送第一条飞书消息
|
|
43
|
+
|
|
44
|
+
飞书接通后,你可以直接给机器人发私聊消息。
|
|
45
|
+
|
|
46
|
+
如果当前配置开启了群聊提及限制,那么群聊里需要先 `@机器人`,消息才会进入处理链路。
|