@dobby.ai/dobby 0.1.0

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.
Files changed (174) hide show
  1. package/.env.example +9 -0
  2. package/AGENTS.md +267 -0
  3. package/README.md +382 -0
  4. package/ROADMAP.md +34 -0
  5. package/config/cron.example.json +9 -0
  6. package/config/gateway.example.json +128 -0
  7. package/config/models.custom.example.json +27 -0
  8. package/dist/src/agent/event-forwarder.js +341 -0
  9. package/dist/src/agent/tests/event-forwarder.test.js +113 -0
  10. package/dist/src/cli/commands/config.js +243 -0
  11. package/dist/src/cli/commands/configure.js +61 -0
  12. package/dist/src/cli/commands/cron.js +288 -0
  13. package/dist/src/cli/commands/doctor.js +189 -0
  14. package/dist/src/cli/commands/extension.js +151 -0
  15. package/dist/src/cli/commands/init.js +286 -0
  16. package/dist/src/cli/commands/start.js +177 -0
  17. package/dist/src/cli/commands/topology.js +254 -0
  18. package/dist/src/cli/index.js +8 -0
  19. package/dist/src/cli/program.js +386 -0
  20. package/dist/src/cli/shared/config-io.js +223 -0
  21. package/dist/src/cli/shared/config-mutators.js +345 -0
  22. package/dist/src/cli/shared/config-path.js +207 -0
  23. package/dist/src/cli/shared/config-schema.js +159 -0
  24. package/dist/src/cli/shared/config-types.js +1 -0
  25. package/dist/src/cli/shared/configure-sections.js +429 -0
  26. package/dist/src/cli/shared/discord-config.js +12 -0
  27. package/dist/src/cli/shared/init-catalog.js +115 -0
  28. package/dist/src/cli/shared/init-models-file.js +65 -0
  29. package/dist/src/cli/shared/presets.js +86 -0
  30. package/dist/src/cli/shared/runtime.js +29 -0
  31. package/dist/src/cli/shared/schema-prompts.js +325 -0
  32. package/dist/src/cli/tests/config-command.test.js +42 -0
  33. package/dist/src/cli/tests/config-io.test.js +64 -0
  34. package/dist/src/cli/tests/config-mutators.test.js +47 -0
  35. package/dist/src/cli/tests/config-path.test.js +21 -0
  36. package/dist/src/cli/tests/discord-config.test.js +23 -0
  37. package/dist/src/cli/tests/doctor.test.js +107 -0
  38. package/dist/src/cli/tests/init-catalog.test.js +87 -0
  39. package/dist/src/cli/tests/presets.test.js +41 -0
  40. package/dist/src/cli/tests/program-options.test.js +92 -0
  41. package/dist/src/cli/tests/routing-config.test.js +199 -0
  42. package/dist/src/cli/tests/routing-legacy.test.js +191 -0
  43. package/dist/src/core/control-command.js +12 -0
  44. package/dist/src/core/dedup-store.js +92 -0
  45. package/dist/src/core/gateway.js +432 -0
  46. package/dist/src/core/routing.js +306 -0
  47. package/dist/src/core/runtime-registry.js +119 -0
  48. package/dist/src/core/tests/control-command.test.js +17 -0
  49. package/dist/src/core/tests/gateway-update-strategy.test.js +167 -0
  50. package/dist/src/core/tests/runtime-registry.test.js +116 -0
  51. package/dist/src/core/tests/typing-controller.test.js +103 -0
  52. package/dist/src/core/types.js +1 -0
  53. package/dist/src/core/typing-controller.js +88 -0
  54. package/dist/src/cron/config.js +114 -0
  55. package/dist/src/cron/schedule.js +49 -0
  56. package/dist/src/cron/service.js +196 -0
  57. package/dist/src/cron/store.js +142 -0
  58. package/dist/src/cron/types.js +1 -0
  59. package/dist/src/extension/loader.js +97 -0
  60. package/dist/src/extension/manager.js +269 -0
  61. package/dist/src/extension/manifest.js +21 -0
  62. package/dist/src/extension/registry.js +137 -0
  63. package/dist/src/main.js +6 -0
  64. package/dist/src/sandbox/executor.js +1 -0
  65. package/dist/src/sandbox/host-executor.js +111 -0
  66. package/docs/BOXLITE_SANDBOX_FEASIBILITY.md +175 -0
  67. package/docs/CRON_SCHEDULER_DESIGN.md +374 -0
  68. package/docs/DOCKER_SANDBOX_vs_BOXLITE.md +77 -0
  69. package/docs/EXTENSION_SYSTEM_ARCHITECTURE.md +119 -0
  70. package/docs/MVP.md +135 -0
  71. package/docs/RUNBOOK.md +242 -0
  72. package/docs/TEAMWORK_HANDOFF_DESIGN.md +440 -0
  73. package/package.json +43 -0
  74. package/plugins/connector-discord/dobby.manifest.json +18 -0
  75. package/plugins/connector-discord/index.js +1 -0
  76. package/plugins/connector-discord/package-lock.json +360 -0
  77. package/plugins/connector-discord/package.json +38 -0
  78. package/plugins/connector-discord/src/connector.ts +350 -0
  79. package/plugins/connector-discord/src/contribution.ts +21 -0
  80. package/plugins/connector-discord/src/mapper.ts +102 -0
  81. package/plugins/connector-discord/tsconfig.json +19 -0
  82. package/plugins/connector-feishu/dobby.manifest.json +18 -0
  83. package/plugins/connector-feishu/index.js +1 -0
  84. package/plugins/connector-feishu/package-lock.json +618 -0
  85. package/plugins/connector-feishu/package.json +38 -0
  86. package/plugins/connector-feishu/src/connector.ts +343 -0
  87. package/plugins/connector-feishu/src/contribution.ts +26 -0
  88. package/plugins/connector-feishu/src/mapper.ts +401 -0
  89. package/plugins/connector-feishu/tsconfig.json +19 -0
  90. package/plugins/plugin-sdk/index.d.ts +261 -0
  91. package/plugins/plugin-sdk/index.js +1 -0
  92. package/plugins/plugin-sdk/package-lock.json +12 -0
  93. package/plugins/plugin-sdk/package.json +22 -0
  94. package/plugins/provider-claude/dobby.manifest.json +17 -0
  95. package/plugins/provider-claude/index.js +1 -0
  96. package/plugins/provider-claude/package-lock.json +3398 -0
  97. package/plugins/provider-claude/package.json +39 -0
  98. package/plugins/provider-claude/src/contribution.ts +1018 -0
  99. package/plugins/provider-claude/tsconfig.json +19 -0
  100. package/plugins/provider-claude-cli/dobby.manifest.json +17 -0
  101. package/plugins/provider-claude-cli/index.js +1 -0
  102. package/plugins/provider-claude-cli/package-lock.json +2898 -0
  103. package/plugins/provider-claude-cli/package.json +38 -0
  104. package/plugins/provider-claude-cli/src/contribution.ts +1673 -0
  105. package/plugins/provider-claude-cli/tsconfig.json +19 -0
  106. package/plugins/provider-pi/dobby.manifest.json +17 -0
  107. package/plugins/provider-pi/index.js +1 -0
  108. package/plugins/provider-pi/package-lock.json +3877 -0
  109. package/plugins/provider-pi/package.json +40 -0
  110. package/plugins/provider-pi/src/contribution.ts +476 -0
  111. package/plugins/provider-pi/tsconfig.json +19 -0
  112. package/plugins/sandbox-core/boxlite.js +1 -0
  113. package/plugins/sandbox-core/dobby.manifest.json +17 -0
  114. package/plugins/sandbox-core/docker.js +1 -0
  115. package/plugins/sandbox-core/package-lock.json +136 -0
  116. package/plugins/sandbox-core/package.json +39 -0
  117. package/plugins/sandbox-core/src/boxlite-context.ts +2 -0
  118. package/plugins/sandbox-core/src/boxlite-contribution.ts +53 -0
  119. package/plugins/sandbox-core/src/boxlite-executor.ts +911 -0
  120. package/plugins/sandbox-core/src/docker-contribution.ts +43 -0
  121. package/plugins/sandbox-core/src/docker-executor.ts +217 -0
  122. package/plugins/sandbox-core/tsconfig.json +19 -0
  123. package/scripts/local-extensions.mjs +168 -0
  124. package/src/agent/event-forwarder.ts +414 -0
  125. package/src/cli/commands/config.ts +328 -0
  126. package/src/cli/commands/configure.ts +92 -0
  127. package/src/cli/commands/cron.ts +410 -0
  128. package/src/cli/commands/doctor.ts +230 -0
  129. package/src/cli/commands/extension.ts +205 -0
  130. package/src/cli/commands/init.ts +396 -0
  131. package/src/cli/commands/start.ts +223 -0
  132. package/src/cli/commands/topology.ts +383 -0
  133. package/src/cli/index.ts +9 -0
  134. package/src/cli/program.ts +465 -0
  135. package/src/cli/shared/config-io.ts +277 -0
  136. package/src/cli/shared/config-mutators.ts +440 -0
  137. package/src/cli/shared/config-schema.ts +228 -0
  138. package/src/cli/shared/config-types.ts +121 -0
  139. package/src/cli/shared/configure-sections.ts +551 -0
  140. package/src/cli/shared/discord-config.ts +14 -0
  141. package/src/cli/shared/init-catalog.ts +189 -0
  142. package/src/cli/shared/init-models-file.ts +77 -0
  143. package/src/cli/shared/runtime.ts +33 -0
  144. package/src/cli/shared/schema-prompts.ts +414 -0
  145. package/src/cli/tests/config-command.test.ts +56 -0
  146. package/src/cli/tests/config-io.test.ts +92 -0
  147. package/src/cli/tests/config-mutators.test.ts +59 -0
  148. package/src/cli/tests/doctor.test.ts +120 -0
  149. package/src/cli/tests/init-catalog.test.ts +96 -0
  150. package/src/cli/tests/program-options.test.ts +113 -0
  151. package/src/cli/tests/routing-config.test.ts +209 -0
  152. package/src/core/control-command.ts +12 -0
  153. package/src/core/dedup-store.ts +103 -0
  154. package/src/core/gateway.ts +607 -0
  155. package/src/core/routing.ts +379 -0
  156. package/src/core/runtime-registry.ts +141 -0
  157. package/src/core/tests/control-command.test.ts +20 -0
  158. package/src/core/tests/runtime-registry.test.ts +140 -0
  159. package/src/core/tests/typing-controller.test.ts +129 -0
  160. package/src/core/types.ts +318 -0
  161. package/src/core/typing-controller.ts +119 -0
  162. package/src/cron/config.ts +154 -0
  163. package/src/cron/schedule.ts +61 -0
  164. package/src/cron/service.ts +249 -0
  165. package/src/cron/store.ts +155 -0
  166. package/src/cron/types.ts +60 -0
  167. package/src/extension/loader.ts +145 -0
  168. package/src/extension/manager.ts +355 -0
  169. package/src/extension/manifest.ts +26 -0
  170. package/src/extension/registry.ts +229 -0
  171. package/src/main.ts +8 -0
  172. package/src/sandbox/executor.ts +44 -0
  173. package/src/sandbox/host-executor.ts +118 -0
  174. package/tsconfig.json +18 -0
package/.env.example ADDED
@@ -0,0 +1,9 @@
1
+ DISCORD_BOT_TOKEN=replace_me
2
+ ANTHROPIC_AUTH_TOKEN=replace_me
3
+ ANTHROPIC_API_KEY=replace_me
4
+ ANTHROPIC_BASE_URL=
5
+ ANTHROPIC_MODEL=
6
+ API_TIMEOUT_MS=600000
7
+ CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
8
+ CUSTOM_PROVIDER_AUTH_TOKEN=replace_me
9
+ LOG_LEVEL=info
package/AGENTS.md ADDED
@@ -0,0 +1,267 @@
1
+ # AGENTS Guide (dobby)
2
+
3
+ 本文件给在本仓库内工作的 AI / 自动化代理使用。目标是让文档、代码和配置改动都以当前实现为准,而不是沿用已经过时的假设。
4
+
5
+ ## 1. 项目定位
6
+
7
+ - 项目名:`dobby`
8
+ - 形态:Discord-first 本地 Agent Gateway,宿主负责 CLI、网关主流程、扩展加载、计划任务调度
9
+ - 扩展模型:Provider / Connector / Sandbox 全部通过扩展 contribution 接入
10
+ - 运行时扩展目录固定:`<data.rootDir>/extensions`
11
+ - 启用模型:`extensions.allowList` 只声明“允许加载”,安装与卸载由 `dobby extension *` 管理
12
+ - 当前仓库内维护的扩展包 scope 是 `@dobby.ai/*`
13
+ - 代码事实优先级:
14
+ - 第一优先级:`src/*`
15
+ - 第二优先级:`config/gateway.example.json`、`config/cron.example.json`
16
+ - 第三优先级:`docs/*`
17
+ - 不要把仓库中的 `config/gateway.json` 当作通用示例,它可能包含本地机器路径、私有包名或敏感 token
18
+
19
+ ## 2. 技术栈与常用命令
20
+
21
+ - Node.js `>=20`
22
+ - TypeScript + ESM(`module: NodeNext`,`strict: true`)
23
+ - 宿主核心依赖:`commander`、`pino`、`zod`、`ajv`、`@mariozechner/pi-ai`、`cron-parser`
24
+
25
+ 仓库根目录常用命令:
26
+
27
+ ```bash
28
+ npm install
29
+ npm run check
30
+ npm run build
31
+ npm run test:cli
32
+ npm run start --
33
+ npm run start -- doctor
34
+ DOBBY_CONFIG_PATH=./config/gateway.json npm run start --
35
+ ```
36
+
37
+ 本地开发辅助命令:
38
+
39
+ ```bash
40
+ npm run dev
41
+ npm run dev:local
42
+ npm run start:local
43
+ ```
44
+
45
+ 插件开发命令(由 `scripts/local-extensions.mjs` 驱动):
46
+
47
+ ```bash
48
+ npm run plugins:install
49
+ npm run plugins:check
50
+ npm run plugins:build
51
+ npm run extensions:install:local
52
+ npm run extensions:list:local
53
+ npm run plugins:setup:local
54
+ ```
55
+
56
+ 注意:
57
+
58
+ - 普通运行路径不会自动读取 `.env`
59
+ - 只有 `npm run dev:local` 和 `npm run start:local` 使用 `--env-file-if-exists=.env`
60
+ - Discord connector 仍以显式 `botToken` 配置为主
61
+
62
+ ## 3. 代码结构与职责
63
+
64
+ - `src/main.ts`
65
+ - CLI 入口,仅调用 `runCli`
66
+ - `src/cli/program.ts`
67
+ - 注册全部顶层命令:`start`、`init`、`configure`、`config`、`bot`、`channel`、`route`、`extension`、`doctor`、`cron`
68
+ - `src/cli/commands/start.ts`
69
+ - 启动网关、创建数据目录、加载扩展、实例化 provider / connector / sandbox、启动 cron 服务、接管优雅退出
70
+ - `src/cli/commands/init.ts`
71
+ - 首次初始化向导;会先安装所需扩展,再根据扩展 `configSchema` 交互生成配置
72
+ - `src/cli/commands/config*.ts`
73
+ - `config show|list|edit|schema *` 与 `configure`
74
+ - `src/cli/commands/topology.ts`
75
+ - `bot/channel/route` 管理命令
76
+ - `src/cli/commands/extension.ts`
77
+ - 运行时扩展 store 的安装、卸载、列举,以及 `--enable` 自动写入 allowList / 模板实例
78
+ - `src/cli/commands/cron.ts`
79
+ - 计划任务 CRUD、状态查看、手动触发
80
+ - `src/core/gateway.ts`
81
+ - 入站消息与计划任务的统一执行入口:去重、控制命令、路由解析、mention 策略、runtime 获取、事件转发、错误回写
82
+ - `src/core/runtime-registry.ts`
83
+ - conversation 级 runtime 复用、串行队列、取消、reset、closeAll
84
+ - `src/core/control-command.ts`
85
+ - 控制命令解析:`stop` / `/stop` / `/cancel` / `/new` / `/reset`
86
+ - `src/core/routing.ts`
87
+ - `gateway.json` 的 zod 校验、相对路径归一化、legacy 字段拒绝、引用关系校验
88
+ - `src/core/dedup-store.ts`
89
+ - 去重 TTL 持久化,文件位置:`data/state/dedup.json`
90
+ - `src/agent/event-forwarder.ts`
91
+ - 统一处理流式增量、tool 事件、不同 connector `updateStrategy`
92
+ - `src/extension/manager.ts`
93
+ - 初始化扩展 store、调用 npm 安装 / 卸载、列出已安装扩展
94
+ - `src/extension/loader.ts`
95
+ - 只从 `<data.rootDir>/extensions/node_modules` 解析 allowList 包并加载 contribution
96
+ - `src/extension/registry.ts`
97
+ - 注册 contribution,暴露实例创建与 `configSchema` catalog
98
+ - `src/cron/*`
99
+ - cron 配置解析、状态存储、调度与失败退避
100
+ - `src/sandbox/*`
101
+ - 宿主执行器接口和内置 `HostExecutor`
102
+ - `plugins/*`
103
+ - 本地维护的扩展源码:`connector-discord`、`provider-pi`、`provider-claude-cli`、`provider-claude`、`sandbox-core`、`plugin-sdk`
104
+ - 运行时不会从这里 fallback 加载
105
+
106
+ ## 4. 配置模型不变量
107
+
108
+ 配置入口是 `gateway.json`,结构以 `src/core/routing.ts` 为准。
109
+
110
+ 必须保持以下事实成立:
111
+
112
+ - `providers.default` 必须存在于 `providers.items`
113
+ - `sandboxes.default` 若存在且不是 `host.builtin`,必须存在于 `sandboxes.items`
114
+ - `routes.defaults.provider` 若未设置,运行时回落到 `providers.default`
115
+ - `routes.defaults.sandbox` 若未设置,运行时回落到 `sandboxes.default ?? host.builtin`
116
+ - 每条 route 在加载后都会补全 `provider`、`sandbox`、`tools`、`mentions`
117
+ - `bindings.items[*].connector` 必须指向存在的 `connectors.items`
118
+ - `bindings.items[*].route` 必须指向存在的 `routes.items`
119
+ - 同一个 `(connector, source.type, source.id)` 只能出现一次
120
+ - `providers/connectors/sandboxes.items[*].type` 必须能在“已安装且已启用的扩展 contribution”里找到
121
+ - `data.rootDir`、`projectRoot`、`systemPromptFile` 都会在加载时转成绝对路径
122
+ - `data.rootDir` 的相对路径有一条特殊规则:
123
+ - 如果配置文件位于 `.../config/gateway.json` 且父目录是 dobby 仓库根目录,则相对仓库根目录解析
124
+ - 否则相对配置文件所在目录解析
125
+ - `projectRoot`、`systemPromptFile` 等其他相对路径统一相对配置文件所在目录解析
126
+ - connector 私有 config 不能再承载入口映射;入口绑定统一写在 `bindings.items`
127
+
128
+ ## 5. 运行时行为不变量
129
+
130
+ - 会话串行粒度:
131
+ - `connectorId + platform + accountId + chatId + threadId(root)`
132
+ - 去重键:
133
+ - `connectorId + platform + accountId + chatId + messageId`
134
+ - 线程路由规则:
135
+ - Discord 线程消息使用父频道 ID 查 `bindings.items`
136
+ - Discord connector 当前只处理已绑定的 guild channel
137
+ - DM 在 connector 侧被直接忽略,虽然核心类型保留了 `isDirectMessage`
138
+ - mention 策略:
139
+ - `mentions="required"` 时,群聊消息必须 @bot 才会进入 runtime
140
+ - 控制命令:
141
+ - `stop`、`/stop`、`/cancel` 会取消当前与排队中的该会话任务
142
+ - `/new`、`/reset` 会 reset runtime,并在 provider 支持时归档历史 session
143
+ - 附件处理:
144
+ - Discord / Feishu 附件优先下载到 `data/attachments/<connectorId>/<source.id>/<messageId>/...`
145
+ - 图片转为 `session.prompt(..., { images })`
146
+ - 非图片附件路径或远程 URL 以 `<attachments>...</attachments>` 注入 prompt
147
+ - 流式输出:
148
+ - 行为受 connector `updateStrategy` 控制,当前 Discord 是 `edit`
149
+ - 错误策略:
150
+ - 主流程异常会向 connector 写回 `Error: ...`
151
+ - 流式更新、typing、tool 状态发送失败只记 warning,不应打崩进程
152
+
153
+ ## 6. 扩展系统约束
154
+
155
+ - 扩展包必须包含 `dobby.manifest.json`
156
+ - `manifest.contributions[*].entry` 必须指向包内已构建的 `.js/.mjs/.cjs`
157
+ - entry 必须位于包根目录内部,禁止路径越界
158
+ - 模块导出必须提供有效 contribution,对应 `kind` 必须和 manifest 一致
159
+ - 运行时加载来源只有 `<data.rootDir>/extensions/node_modules`
160
+ - 宿主不会从自身依赖树、`plugins/*` 源码目录或 `dist` 外路径 fallback
161
+ - `configSchema` 是可选的
162
+ - `init`、`configure`、`config edit` 会优先按 schema 交互提问
163
+ - `applyAndValidateContributionSchemas` 会用 Ajv 套默认值并验证实例配置
164
+
165
+ 当前仓库内的扩展源码与 contribution:
166
+
167
+ - `@dobby.ai/connector-discord` -> `connector.discord`
168
+ - `@dobby.ai/provider-pi` -> `provider.pi`
169
+ - `@dobby.ai/provider-claude-cli` -> `provider.claude-cli`
170
+ - `@dobby.ai/provider-claude` -> `provider.claude`
171
+ - `@dobby.ai/sandbox-core` -> `sandbox.boxlite`、`sandbox.docker`
172
+
173
+ 注意:
174
+
175
+ - `dobby init` 当前只内建选择 `provider.pi`、`provider.claude-cli` 和 `connector.discord`
176
+ - `provider.claude` 与 sandbox 扩展需要手工安装 / 启用 / 配置
177
+
178
+ ## 7. Cron / 计划任务约束
179
+
180
+ - 启动时总会加载 cron 配置,并在缺失时自动创建默认文件
181
+ - cron 配置路径优先级:
182
+ - `--cron-config`
183
+ - `DOBBY_CRON_CONFIG_PATH`
184
+ - 与 gateway 配置同目录下的 `cron.json`
185
+ - fallback 到 `<data.rootDir>/state/cron.config.json`
186
+ - job 支持三种 schedule:
187
+ - `at`
188
+ - `every`
189
+ - `cron`
190
+ - 状态存储:
191
+ - job store:`cron-jobs.json`
192
+ - run log:`cron-runs.jsonl`
193
+ - 调度器支持:
194
+ - `maxConcurrentRuns`
195
+ - 启动时补跑 `runMissedOnStartup`
196
+ - 连续失败退避重试
197
+ - 当前真实运行语义:
198
+ - 所有 scheduled run 都走 `Gateway.handleScheduled`
199
+ - conversation key 固定为 `cron:<runId>`
200
+ - runtime 始终按 `stateless + ephemeral` 执行
201
+ - `cron` CLI / store 虽然有 `sessionPolicy` 字段,但当前调度路径没有把它传到运行时
202
+
203
+ ## 8. 文档和代码改动建议
204
+
205
+ - 改配置模型时,同步检查:
206
+ - `src/core/types.ts`
207
+ - `src/core/routing.ts`
208
+ - `src/cli/shared/config-types.ts`
209
+ - `src/cli/shared/config-mutators.ts`
210
+ - `src/cli/shared/configure-sections.ts`
211
+ - `config/gateway.example.json`
212
+ - `README.md`
213
+ - 改 CLI 时,同步检查:
214
+ - `src/cli/program.ts`
215
+ - 对应 `src/cli/commands/*.ts`
216
+ - `README.md`
217
+ - 改扩展加载链路时,同步检查:
218
+ - `src/extension/manager.ts`
219
+ - `src/extension/loader.ts`
220
+ - `src/extension/registry.ts`
221
+ - `docs/EXTENSION_SYSTEM_ARCHITECTURE.md`
222
+ - 改计划任务时,同步检查:
223
+ - `src/cron/config.ts`
224
+ - `src/cron/store.ts`
225
+ - `src/cron/service.ts`
226
+ - `src/cli/commands/cron.ts`
227
+ - `config/cron.example.json`
228
+ - `docs/CRON_SCHEDULER_DESIGN.md`
229
+ - 涉及执行器和路径边界时优先保守,避免放宽 `projectRoot` / `workspaceRoot` 约束
230
+
231
+ ## 9. 提交前最小校验
232
+
233
+ 默认最小校验:
234
+
235
+ ```bash
236
+ npm run check
237
+ npm run build
238
+ npm run test:cli
239
+ ```
240
+
241
+ 如果改了插件实现,额外执行:
242
+
243
+ ```bash
244
+ npm run plugins:check
245
+ npm run plugins:build
246
+ ```
247
+
248
+ 如果改了扩展安装 / 加载链路,建议再执行:
249
+
250
+ ```bash
251
+ npm run extensions:list:local
252
+ ```
253
+
254
+ 手工冒烟建议:
255
+
256
+ 1. 启动后确认日志包含 `Extension packages loaded`、`Discord connector ready`、`Cron scheduler started`(若启用)以及 `Gateway started`
257
+ 2. 在映射频道 @bot 发消息,确认流式更新与 typing
258
+ 3. 发送 `stop` 或 `/cancel`,确认能取消当前会话
259
+ 4. 发送 `/new` 或 `/reset`,确认会话被重置且 provider 归档成功
260
+ 5. 若启用 cron,执行 `dobby cron run <jobId>` 并确认正在运行的 gateway 会在下一次 scheduler tick 执行任务
261
+
262
+ ## 10. 当前已知边界
263
+
264
+ - 有一批 focused tests,但仍缺少端到端自动化测试
265
+ - cron job 的 `sessionPolicy` 目前是 schema / CLI 字段,调度执行时未生效
266
+ - Discord connector 仍不处理 DM
267
+ - `extension uninstall` 不会自动清理 `gateway.json` 中的 allowList 和实例引用
package/README.md ADDED
@@ -0,0 +1,382 @@
1
+ # dobby
2
+
3
+ Discord-first 本地 Agent Gateway。宿主只负责 CLI、网关主流程、扩展加载和计划任务调度;Provider / Connector / Sandbox 通过扩展 contribution 接入。
4
+
5
+ 当前仓库内维护的扩展包:
6
+
7
+ - `@dobby.ai/connector-discord`
8
+ - `@dobby.ai/connector-feishu`
9
+ - `@dobby.ai/provider-pi`
10
+ - `@dobby.ai/provider-claude-cli`
11
+ - `@dobby.ai/provider-claude`
12
+ - `@dobby.ai/sandbox-core`
13
+
14
+ 文档默认以 `@dobby.ai/*` 为准,不再把旧 `@dobby/*` 作为推荐配置。
15
+
16
+ ## 核心能力
17
+
18
+ - connector source -> binding -> route -> provider / sandbox
19
+ - Discord 频道 / 线程接入;线程消息继续按父频道命中 binding
20
+ - Feishu 长连接消息接入(self-built app,手工安装/配置)
21
+ - Feishu 出站支持普通文本和 Markdown 卡片;默认群内直发,不走 reply thread
22
+ - conversation 级 runtime 复用与串行化
23
+ - 扩展 store 安装、启用、列举与 schema 驱动配置
24
+ - Discord 流式回复、typing、附件下载与图片输入
25
+ - cron 调度:一次性、固定间隔、cron expression
26
+ - 交互式初始化:`dobby init`
27
+ - 交互式配置:`dobby configure` / `dobby config edit`
28
+ - 诊断与保守修复:`dobby doctor [--fix]`
29
+
30
+ ## 架构概览
31
+
32
+ ```text
33
+ Discord / Cron
34
+ -> Connector
35
+ -> Gateway
36
+ -> Dedup / Control Commands / Binding Resolver / Route Resolver
37
+ -> Runtime Registry
38
+ -> Provider Runtime
39
+ -> Sandbox Executor
40
+ -> Event Forwarder
41
+ -> Connector Reply
42
+ ```
43
+
44
+ 主要目录:
45
+
46
+ - `src/cli`:CLI 程序和各子命令
47
+ - `src/core`:gateway 主流程、路由、去重、runtime registry
48
+ - `src/extension`:扩展 store、manifest 解析、扩展加载与实例化
49
+ - `src/cron`:计划任务配置、持久化与调度
50
+ - `src/sandbox`:宿主执行器接口与 `HostExecutor`
51
+ - `plugins/*`:本地维护的扩展源码
52
+ - `config/*.example.json`:示例配置
53
+
54
+ 注意:运行时只从 `<data.rootDir>/extensions/node_modules` 加载扩展,不会从 `plugins/*` 源码目录 fallback。
55
+
56
+ ## 环境要求
57
+
58
+ - Node.js `>=20`
59
+ - npm
60
+ - 对应 provider / connector 的外部运行条件
61
+ - 例如 Discord bot token
62
+ - Claude CLI 或 Claude Agent SDK 所需认证
63
+ - 可选的 Docker / Boxlite 运行环境
64
+
65
+ ## 快速开始
66
+
67
+ 1. 安装依赖
68
+
69
+ ```bash
70
+ npm install
71
+ ```
72
+
73
+ 2. 构建
74
+
75
+ ```bash
76
+ npm run build
77
+ ```
78
+
79
+ 3. 初始化最小可运行配置
80
+
81
+ ```bash
82
+ npm run start -- init
83
+ ```
84
+
85
+ `init` 会做这些事情:
86
+
87
+ - 交互选择 provider 和 connector
88
+ - 自动安装所选扩展到运行时 extension store
89
+ - 优先使用扩展暴露的 `configSchema` 生成配置
90
+ - 生成 `gateway.json`
91
+ - 选择 `provider.pi` 且缺少 `models.custom.json` 时,自动创建该文件
92
+
93
+ 说明:当前 `init` 仍只内建 Discord connector。Feishu connector 需要通过 `extension install` + `config edit/configure` 手工启用。
94
+
95
+ 4. 运行诊断
96
+
97
+ ```bash
98
+ npm run start -- doctor
99
+ ```
100
+
101
+ 5. 启动网关
102
+
103
+ ```bash
104
+ npm run start --
105
+ ```
106
+
107
+ 说明:
108
+
109
+ - `dobby` 无子命令时,默认等价于 `dobby start`
110
+ - 在仓库内直接运行时,CLI 会自动使用 `./config/gateway.json`
111
+ - 也可以通过环境变量覆盖配置路径:
112
+
113
+ ```bash
114
+ DOBBY_CONFIG_PATH=./config/gateway.json npm run start --
115
+ ```
116
+
117
+ ## 配置文件路径
118
+
119
+ gateway 配置路径优先级:
120
+
121
+ 1. `DOBBY_CONFIG_PATH`
122
+ 2. 当前目录向上查找 dobby 仓库时的 `./config/gateway.json`
123
+ 3. 默认 `~/.dobby/gateway.json`
124
+
125
+ cron 配置路径优先级:
126
+
127
+ 1. `--cron-config`
128
+ 2. `DOBBY_CRON_CONFIG_PATH`
129
+ 3. 与 gateway 配置同目录的 `cron.json`
130
+ 4. `<data.rootDir>/state/cron.config.json`
131
+
132
+ 如果 cron 配置文件不存在,启动时会自动生成默认文件。
133
+
134
+ ## 运行时目录
135
+
136
+ `data.rootDir` 默认是 `./data`。如果配置文件是仓库内的 `./config/gateway.json`,它会相对仓库根目录解析;否则相对配置文件所在目录解析。加载后会生成这些目录:
137
+
138
+ - `sessions/`
139
+ - `attachments/`
140
+ - `logs/`
141
+ - `state/`
142
+ - `extensions/`
143
+
144
+ 扩展 store 实际路径是:
145
+
146
+ ```text
147
+ <data.rootDir>/extensions/node_modules/*
148
+ ```
149
+
150
+ ## CLI 概览
151
+
152
+ 顶层命令:
153
+
154
+ ```bash
155
+ dobby start
156
+ dobby init
157
+ dobby configure
158
+ dobby doctor [--fix]
159
+ ```
160
+
161
+ 配置与拓扑:
162
+
163
+ ```bash
164
+ dobby config show [section] [--json]
165
+ dobby config list [section] [--json]
166
+ dobby config edit [--section provider|connector|route|binding]
167
+ dobby config schema list [--json]
168
+ dobby config schema show <contributionId> [--json]
169
+
170
+ dobby bot list [--json]
171
+ dobby bot set <connectorId> [--name <name>] [--token <token>]
172
+
173
+ dobby binding list [--connector <id>] [--json]
174
+ dobby binding set <bindingId> --connector <id> --source-type channel|chat --source-id <id> --route <id>
175
+ dobby binding remove <bindingId>
176
+
177
+ dobby route list [--json]
178
+ dobby route set <routeId> [--project-root <path>] [--tools full|readonly] [--provider <id>] [--sandbox <id>] [--mentions required|optional]
179
+ dobby route remove <routeId> [--cascade-bindings]
180
+ ```
181
+
182
+ 扩展管理:
183
+
184
+ ```bash
185
+ dobby extension install <packageSpec>
186
+ dobby extension install <packageSpec> --enable
187
+ dobby extension uninstall <packageName>
188
+ dobby extension list [--json]
189
+ ```
190
+
191
+ 计划任务:
192
+
193
+ ```bash
194
+ dobby cron add <name> --prompt <text> --connector <id> --route <id> --channel <id> [--thread <id>] [--at <iso> | --every-ms <ms> | --cron <expr>] [--tz <tz>]
195
+ dobby cron list [--json]
196
+ dobby cron status [jobId] [--json]
197
+ dobby cron run <jobId>
198
+ dobby cron update <jobId> ...
199
+ dobby cron pause <jobId>
200
+ dobby cron resume <jobId>
201
+ dobby cron remove <jobId>
202
+ ```
203
+
204
+ ## Gateway 配置模型
205
+
206
+ 顶层结构:
207
+
208
+ - `extensions`
209
+ - `providers`
210
+ - `connectors`
211
+ - `sandboxes`
212
+ - `routes`
213
+ - `bindings`
214
+ - `data`
215
+
216
+ 关键语义:
217
+
218
+ - `extensions.allowList`
219
+ - 只声明启用状态,不负责安装
220
+ - `providers.default`
221
+ - 默认 provider instance ID
222
+ - `providers.items[*].type` / `connectors.items[*].type` / `sandboxes.items[*].type`
223
+ - 指向某个 contribution,实例配置直接内联在对象里
224
+ - `routes.defaults`
225
+ - 统一提供 route 默认的 `provider`、`sandbox`、`tools`、`mentions`
226
+ - `routes.items[*]`
227
+ - route 是可复用的执行 profile,定义 `projectRoot`,并按需覆盖 `provider`、`sandbox`、`tools`、`mentions`、`systemPromptFile`
228
+ - `bindings.items[*]`
229
+ - `(connector, source.type, source.id) -> route` 的入口绑定
230
+ - `sandboxes.default`
231
+ - 未指定时默认使用 `host.builtin`
232
+ - 未匹配 binding 的入站消息会被直接忽略,不存在 default route fallback
233
+
234
+ 当前代码还保留但未真正生效的字段:
235
+
236
+ - cron job 的 `sessionPolicy`
237
+
238
+ 示例配置:
239
+
240
+ - gateway:[`config/gateway.example.json`](config/gateway.example.json)
241
+ - cron:[`config/cron.example.json`](config/cron.example.json)
242
+ - provider.pi 自定义模型:[`config/models.custom.example.json`](config/models.custom.example.json)
243
+
244
+ ## 扩展包与 contribution
245
+
246
+ 仓库内现有 contribution:
247
+
248
+ - `connector.discord`
249
+ - `provider.pi`
250
+ - `provider.claude-cli`
251
+ - `provider.claude`
252
+ - `sandbox.boxlite`
253
+ - `sandbox.docker`
254
+
255
+ `dobby init` 当前只内建这些 starter 选择:
256
+
257
+ - provider:`provider.pi`、`provider.claude-cli`
258
+ - connector:`connector.discord`
259
+
260
+ `provider.claude` 与 sandbox 相关扩展需要手工安装和配置,例如:
261
+
262
+ ```bash
263
+ npm run start -- extension install @dobby.ai/provider-claude --enable
264
+ npm run start -- extension install @dobby.ai/sandbox-core --enable
265
+ ```
266
+
267
+ `--enable` 的行为:
268
+
269
+ - 把包写入 `extensions.allowList`
270
+ - 按 manifest contribution 生成默认实例模板
271
+ - 在需要时补默认 provider
272
+
273
+ ## 计划任务 / Cron
274
+
275
+ job 支持三种调度方式:
276
+
277
+ - `--at <ISO timestamp>`
278
+ - `--every-ms <ms>`
279
+ - `--cron "<expr>" [--tz <timezone>]`
280
+
281
+ 示例:
282
+
283
+ ```bash
284
+ npm run start -- cron add daily-report \
285
+ --prompt "Summarize open issues in this repo" \
286
+ --connector discord.main \
287
+ --route projectA \
288
+ --channel 1234567890 \
289
+ --cron "0 9 * * 1-5" \
290
+ --tz "Asia/Shanghai"
291
+ ```
292
+
293
+ 说明:
294
+
295
+ - `cron run <jobId>` 只是把 job 标记为“下一次 scheduler tick 执行”
296
+ - 需要已有一个正在运行的 `dobby start`
297
+ - 当前 scheduled run 一律按 stateless / ephemeral 执行
298
+
299
+ ## Discord 连接器的当前行为
300
+
301
+ - 只处理已绑定的 guild channel,DM 目前禁用
302
+ - 线程消息使用父频道 ID 做 binding 查找
303
+ - 会自动下载附件到本地
304
+ - 图片会作为 image input 传给 provider
305
+ - 非图片附件会把路径注入 prompt
306
+ - 内置 reconnect watchdog
307
+ - `reconnectStaleMs` 默认 `60000`
308
+ - `reconnectCheckIntervalMs` 默认 `10000`
309
+
310
+ ## 会话控制命令
311
+
312
+ 在 Discord 频道内可用:
313
+
314
+ - `stop`
315
+ - `/stop`
316
+ - `/cancel`
317
+ - `/new`
318
+ - `/reset`
319
+
320
+ 当前语义:
321
+
322
+ - `stop` / `/cancel`:取消该会话当前和排队中的任务
323
+ - `/new` / `/reset`:重置当前会话,并在 provider 支持时归档旧 session
324
+
325
+ ## 本地插件开发
326
+
327
+ 开发流程:
328
+
329
+ ```bash
330
+ npm run plugins:install
331
+ npm run plugins:check
332
+ npm run plugins:build
333
+ npm run extensions:install:local
334
+ ```
335
+
336
+ 或一步完成:
337
+
338
+ ```bash
339
+ npm run plugins:setup:local
340
+ ```
341
+
342
+ 补充说明:
343
+
344
+ - `plugins/*` 是扩展源码,不是运行时加载入口
345
+ - 本地扩展安装到 extension store 后,才会被宿主识别
346
+ - `@dobby.ai/plugin-sdk` 在插件里按 `peerDependencies` 暴露,开发期通过 `file:../plugin-sdk` 提供
347
+
348
+ ## 检查与测试
349
+
350
+ 最小校验:
351
+
352
+ ```bash
353
+ npm run check
354
+ npm run build
355
+ npm run test:cli
356
+ ```
357
+
358
+ 如果改了插件代码,建议再执行:
359
+
360
+ ```bash
361
+ npm run plugins:check
362
+ npm run plugins:build
363
+ ```
364
+
365
+ 当前测试现状:
366
+
367
+ - 已有 CLI / core 的 focused tests
368
+ - 暂无完整的 e2e 自动化
369
+ - 仍建议做一次手工 Discord 冒烟
370
+
371
+ ## 本地运行小提示
372
+
373
+ - `npm run dev:local` 与 `npm run start:local` 会尝试读取 `.env`
374
+ - 普通 `npm run start -- ...` 不会自动载入 `.env`
375
+ - 配置编辑流优先使用扩展 `configSchema`,无 schema 时退回 JSON 输入
376
+
377
+ ## 相关文档
378
+
379
+ - 扩展系统:[`docs/EXTENSION_SYSTEM_ARCHITECTURE.md`](docs/EXTENSION_SYSTEM_ARCHITECTURE.md)
380
+ - cron 设计:[`docs/CRON_SCHEDULER_DESIGN.md`](docs/CRON_SCHEDULER_DESIGN.md)
381
+ - 运行与排障:[`docs/RUNBOOK.md`](docs/RUNBOOK.md)
382
+ - Teamwork handoff:[`docs/TEAMWORK_HANDOFF_DESIGN.md`](docs/TEAMWORK_HANDOFF_DESIGN.md)
package/ROADMAP.md ADDED
@@ -0,0 +1,34 @@
1
+ # ROADMAP
2
+
3
+ Work In Progress
4
+
5
+ 下面列出一些个人觉得比较有意思的功能
6
+
7
+ ## session 管理
8
+
9
+ 如何手动结束当前会话,场景:会话轮数太多,用户想要手动结束会话,开启新话题
10
+
11
+ “用户打断”时怎么处理当前运行,非常贴近真实聊天场景
12
+
13
+ ## 配置功能
14
+
15
+ 如何让用户配置的更加简便
16
+
17
+ ## skills
18
+
19
+ 这个好像直接用 claude code 和 pi-mono 就可以实现,需要找到一些比较好用的 skills
20
+
21
+ - X 上的热点追踪 social listening 功能
22
+ - 机票价格助手 trip Google Flights
23
+
24
+ ## agents 协同
25
+
26
+ 如何让多个 agent 协同工作,handoff 等等
27
+
28
+ ## 调度
29
+
30
+ 如何让 agent 定时工作
31
+
32
+ ## 插件
33
+
34
+ - codex cli
@@ -0,0 +1,9 @@
1
+ {
2
+ "enabled": true,
3
+ "storeFile": "./data/state/cron-jobs.json",
4
+ "runLogFile": "./data/state/cron-runs.jsonl",
5
+ "pollIntervalMs": 10000,
6
+ "maxConcurrentRuns": 1,
7
+ "runMissedOnStartup": true,
8
+ "jobTimeoutMs": 600000
9
+ }