haoyuan 0.0.0-stage → 1.0.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 (180) hide show
  1. package/AGENTS.md +29 -0
  2. package/README.md +585 -3
  3. package/api/adapters/__init__.py +0 -0
  4. package/api/adapters/providers/__init__.py +0 -0
  5. package/api/adapters/providers/deepseek.py +153 -0
  6. package/api/adapters/providers/mock.py +134 -0
  7. package/api/assets/web/app.js +21 -0
  8. package/api/assets/web/style.css +111 -0
  9. package/api/configs/__init__.py +0 -0
  10. package/api/configs/configs.py +183 -0
  11. package/api/configs/models.py +140 -0
  12. package/api/configs/runtime.py +60 -0
  13. package/api/configs/secrets.py +58 -0
  14. package/api/configs/secrets_example.py +9 -0
  15. package/api/core/__init__.py +0 -0
  16. package/api/core/agents.py +27 -0
  17. package/api/core/context.py +299 -0
  18. package/api/core/contracts.py +114 -0
  19. package/api/core/events.py +196 -0
  20. package/api/core/gateway.py +128 -0
  21. package/api/core/harness.py +171 -0
  22. package/api/core/plugin.py +288 -0
  23. package/api/core/policy.py +50 -0
  24. package/api/core/runtime.py +1544 -0
  25. package/api/core/session_manager.py +278 -0
  26. package/api/core/storage.py +798 -0
  27. package/api/core/telemetry.py +127 -0
  28. package/api/core/tools.py +129 -0
  29. package/api/data/.gitkeep +0 -0
  30. package/api/extensions/__init__.py +0 -0
  31. package/api/extensions/approvals.py +33 -0
  32. package/api/extensions/common.py +11 -0
  33. package/api/extensions/fs.py +181 -0
  34. package/api/extensions/marketplace.py +303 -0
  35. package/api/extensions/plugins.py +70 -0
  36. package/api/extensions/sessions.py +610 -0
  37. package/api/extensions/settings.py +80 -0
  38. package/api/extensions/skills.py +64 -0
  39. package/api/extensions/supervisor.py +301 -0
  40. package/api/extensions/system.py +69 -0
  41. package/api/extensions/usage.py +70 -0
  42. package/api/extensions/ws.py +72 -0
  43. package/api/gitignore_plugins/README.md +10 -0
  44. package/api/harness/__init__.py +0 -0
  45. package/api/harness/durability.py +66 -0
  46. package/api/harness/orchestrator.py +357 -0
  47. package/api/harness/reference.py +369 -0
  48. package/api/harness/repair.py +156 -0
  49. package/api/harness/repoindex.py +371 -0
  50. package/api/harness/sandbox.py +155 -0
  51. package/api/harness/skills.py +271 -0
  52. package/api/harness/supervisor.py +254 -0
  53. package/api/harness/sysinfo.py +224 -0
  54. package/api/main.py +84 -0
  55. package/api/plugins/coding/plugin.json +27 -0
  56. package/api/plugins/coding/plugin.py +43 -0
  57. package/api/plugins/coding/skills/debug-loop.md +23 -0
  58. package/api/plugins/coding/skills/dev-loop.md +26 -0
  59. package/api/plugins/coding/skills/document-delivery.md +20 -0
  60. package/api/plugins/coding/skills/web-delivery.md +42 -0
  61. package/api/plugins/notes/plugin.json +13 -0
  62. package/api/plugins/notes/plugin.py +19 -0
  63. package/api/plugins/notes/routes.py +174 -0
  64. package/api/plugins/orchestrator/plugin.json +17 -0
  65. package/api/plugins/orchestrator/plugin.py +10 -0
  66. package/api/plugins/orchestrator/routes.py +72 -0
  67. package/api/plugins/plans/plugin.json +18 -0
  68. package/api/plugins/plans/plugin.py +33 -0
  69. package/api/plugins/plans/skills/plan-writing.md +23 -0
  70. package/api/plugins/user-account/README.md +37 -0
  71. package/api/plugins/user-account/plugin.json +24 -0
  72. package/api/plugins/user-account/plugin.py +552 -0
  73. package/api/plugins/video/plugin.json +18 -0
  74. package/api/plugins/video/plugin.py +24 -0
  75. package/api/plugins/video/skills/video-storyboard.md +20 -0
  76. package/api/requirements.txt +8 -0
  77. package/api/skills/core-method.md +29 -0
  78. package/api/tests/conftest.py +28 -0
  79. package/api/tests/test_api.py +297 -0
  80. package/api/tests/test_intent.py +115 -0
  81. package/api/tests/test_notes.py +86 -0
  82. package/api/tests/test_orchestrator.py +58 -0
  83. package/api/tests/test_reference.py +115 -0
  84. package/api/tests/test_runtime.py +39 -0
  85. package/api/tests/test_supervisor_resume.py +144 -0
  86. package/api/tests/test_tools.py +231 -0
  87. package/api/tests/test_user_account.py +58 -0
  88. package/api/tests/test_user_account_lock.py +95 -0
  89. package/api/tools/__init__.py +0 -0
  90. package/api/tools/builtin.py +103 -0
  91. package/api/tools/dev.py +1017 -0
  92. package/api/tools/plan.py +282 -0
  93. package/bin/haoyuan.js +246 -0
  94. package/desktop/app.manifest +28 -0
  95. package/desktop/build.bat +16 -0
  96. package/desktop/desktop.cs +1187 -0
  97. package/dev.bat +24 -0
  98. package/docs/screenshots/collapsed.png +0 -0
  99. package/docs/screenshots/console.png +0 -0
  100. package/docs/screenshots/mobile-panel.png +0 -0
  101. package/docs/screenshots/plugins.png +0 -0
  102. package/docs/screenshots/settings-tw.png +0 -0
  103. package/docs/screenshots/settings.png +0 -0
  104. package/docs/screenshots/skills.png +0 -0
  105. package/docs/screenshots/workbench-dark.png +0 -0
  106. package/docs/screenshots/workbench-en.png +0 -0
  107. package/docs/screenshots/workbench-light.png +0 -0
  108. package/docs/screenshots/workbench-tw.png +0 -0
  109. package/package.json +44 -6
  110. package/start.bat +30 -0
  111. package/start.sh +43 -0
  112. package/stop.bat +12 -0
  113. package/stop.sh +20 -0
  114. package/web/dist/assets/Console-BkDQWIPl.js +2 -0
  115. package/web/dist/assets/Console-DaFz3MyH.css +1 -0
  116. package/web/dist/assets/Orchestrator-CdN5AwCa.js +2 -0
  117. package/web/dist/assets/Orchestrator-DVz53JZI.css +1 -0
  118. package/web/dist/assets/Plugins-DYg5J3N0.css +1 -0
  119. package/web/dist/assets/Plugins-DkPPZbp4.js +1 -0
  120. package/web/dist/assets/Settings-7vNKapFv.css +1 -0
  121. package/web/dist/assets/Settings-B1DUGF6E.js +1 -0
  122. package/web/dist/assets/Skills-C-92tibt.css +1 -0
  123. package/web/dist/assets/Skills-yDmH38xn.js +2 -0
  124. package/web/dist/assets/StatusPill-BTy4yEZr.js +1 -0
  125. package/web/dist/assets/StatusPill-N-1m9qg8.css +1 -0
  126. package/web/dist/assets/Usage-B0UdIv7c.css +1 -0
  127. package/web/dist/assets/Usage-DZ-gRjE6.js +1 -0
  128. package/web/dist/assets/Workbench-DGulMNB3.css +1 -0
  129. package/web/dist/assets/Workbench-Tiad5Hin.js +9 -0
  130. package/web/dist/assets/index-BkQRgtUv.css +1 -0
  131. package/web/dist/assets/index-lqDQMESI.js +92 -0
  132. package/web/dist/favicon.svg +10 -0
  133. package/web/dist/index.html +16 -0
  134. package/web/index.html +15 -0
  135. package/web/package-lock.json +1434 -0
  136. package/web/package.json +21 -0
  137. package/web/public/favicon.svg +10 -0
  138. package/web/src/App.vue +536 -0
  139. package/web/src/api/client.js +256 -0
  140. package/web/src/api/sse.js +76 -0
  141. package/web/src/api/ws.js +87 -0
  142. package/web/src/components/AccountMenu.vue +71 -0
  143. package/web/src/components/AppTopbar.vue +177 -0
  144. package/web/src/components/ApprovalCard.vue +200 -0
  145. package/web/src/components/AuthGate.vue +269 -0
  146. package/web/src/components/ChatTimeline.vue +790 -0
  147. package/web/src/components/CommandPalette.vue +162 -0
  148. package/web/src/components/Composer.vue +203 -0
  149. package/web/src/components/DiffView.vue +77 -0
  150. package/web/src/components/DirPicker.vue +93 -0
  151. package/web/src/components/FileTree.vue +131 -0
  152. package/web/src/components/FileViewer.vue +73 -0
  153. package/web/src/components/Icon.vue +94 -0
  154. package/web/src/components/LanguageSelect.vue +94 -0
  155. package/web/src/components/Markdown.vue +72 -0
  156. package/web/src/components/Modal.vue +39 -0
  157. package/web/src/components/NewTaskModal.vue +256 -0
  158. package/web/src/components/NotesDrawer.vue +1141 -0
  159. package/web/src/components/PlanPanel.vue +98 -0
  160. package/web/src/components/RightPanel.vue +207 -0
  161. package/web/src/components/SessionList.vue +144 -0
  162. package/web/src/components/StatusPill.vue +43 -0
  163. package/web/src/components/SupervisorDock.vue +709 -0
  164. package/web/src/components/ToastStack.vue +20 -0
  165. package/web/src/components/ToolCard.vue +188 -0
  166. package/web/src/components/UserAccountModal.vue +227 -0
  167. package/web/src/components/WorkspaceSetupModal.vue +66 -0
  168. package/web/src/i18n.js +2540 -0
  169. package/web/src/main.js +6 -0
  170. package/web/src/router/index.js +29 -0
  171. package/web/src/stores/app.js +1443 -0
  172. package/web/src/styles/theme.css +367 -0
  173. package/web/src/views/Console.vue +173 -0
  174. package/web/src/views/Orchestrator.vue +257 -0
  175. package/web/src/views/Plugins.vue +801 -0
  176. package/web/src/views/Settings.vue +278 -0
  177. package/web/src/views/Skills.vue +200 -0
  178. package/web/src/views/Usage.vue +140 -0
  179. package/web/src/views/Workbench.vue +390 -0
  180. package/web/vite.config.js +65 -0
package/AGENTS.md ADDED
@@ -0,0 +1,29 @@
1
+ # AGENTS.md
2
+
3
+ ## Project commands
4
+
5
+ - Backend tests: `cd api && python -m pytest -q`
6
+ - Backend run: `cd api && python main.py` (base port 8030, env `HAOYUAN_PORT`; auto +1 when busy, actual port written to `api/data/runtime.json`)
7
+ - Frontend dev: `cd web && npm run dev` (base port 8130, env `HAOYUAN_WEB_PORT`; auto +1 when busy, proxies `/api`, `/docs` and `/ws` to `HAOYUAN_API_PORT` or `runtime.json` `api_port`)
8
+ - Frontend build: `cd web && npm run build`
9
+ - Production: build the frontend, then run the API; the API serves `web/dist` at `/`.
10
+ - Plugin center (separate repo `../hao-yuan-plugin-center`): `cd ../hao-yuan-plugin-center && python main.py` (base port 8180, env `PLUGIN_CENTER_PORT`). The API connects to it via `HAOYUAN_PLUGIN_CENTER_URL` (default `http://127.0.0.1:8180`).
11
+ - `desktop.exe` (source `desktop/desktop.cs`, build `desktop\build.bat`): can override base ports via `api_port_config` / `web_port_config` in `api/data/runtime.json` and restart services.
12
+
13
+ ## Architecture invariants
14
+
15
+ - `core/` is the kernel. It must not import from `plugins/`.
16
+ - Business capabilities belong in `plugins/<name>/` and register through `register(ctx)`.
17
+ - Plugins may add routers, tools, agents, skills and middlewares through `PluginContext` (`add_router`, `add_middleware`, `on`). Toggle hooks receive `(name, enabled)`.
18
+ - Tool handlers receive `(ctx: ToolContext, args: dict)` and must respect `ctx.workspace`.
19
+ - Every state-changing tool that touches the filesystem or executes commands must be `confirm=True` and high risk.
20
+ - Events are append-only in SQLite and broadcast over WebSocket. Do not log secrets into event payloads.
21
+ - The API envelope is `{ code, data, message }`; `code` is 200 on success.
22
+ - Frontend state lives in `web/src/stores/app.js`; API calls go through `web/src/api/client.js`.
23
+
24
+ ## Verification discipline
25
+
26
+ - After backend changes: run `python -m pytest -q` in `api/`.
27
+ - After frontend changes: run `npm run build` in `web/`.
28
+ - For UI changes, take Playwright screenshots at 1440x900 and 430x900 with the local Chrome executable, and verify there are no console errors or 404 resources.
29
+ - Never claim live-model verification without a configured API key; use mock-mode tests and state that limitation explicitly.
package/README.md CHANGED
@@ -1,3 +1,585 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
1
+ # 豪源 · HaoYuan
2
+
3
+ > 个人指挥 AI 实现多个 AI 员工异步并行工作的 AI 工作室。
4
+ > 一个内核,一组可安装插件,一套可验证的长程任务闭环。
5
+
6
+ 豪源以 **agent-harness** 为后端参考底座重写,保留并强化了 AI 助理的编程专长,同时用插件化架构重新组织了会话、工具、Agent、路由、技能、监督与编排。前端完全重写,目标是把「AI 协作」从聊天窗口升级为可指挥、可观察、可干预的工作台。
7
+
8
+ ![Workbench](docs/screenshots/workbench-dark.png)
9
+
10
+ ---
11
+
12
+ ## 1. 核心特性
13
+
14
+ ### 1.1 真正可用的编码闭环
15
+
16
+ | 能力 | 实现 |
17
+ |---|---|
18
+ | 仓库感知 | `project_scan`、`repo_map`、符号索引、`search_symbol` |
19
+ | 精准读取 | `read_file`、`read_range`、行号定位 |
20
+ | 最小编辑 | `apply_patch`(unified diff / SEARCH-REPLACE)、`edit_file`、`multi_edit` |
21
+ | 文件操作 | `write_file`、`glob`、`grep`、`list_dir`、`delete_path`、`move_path` |
22
+ | 命令验证 | `run_shell`(UTF-8、超时、结构化错误摘要)、`git` 封装 |
23
+ | 验证门禁 | 代码写完后强制要求跑测试/lint/build,避免「只改不验」 |
24
+ | 测试修复环 | pytest 失败结构化解析 → 定位行 → 最小修复 → 失败指纹升级策略 |
25
+ | 子代理 | `task` 在独立上下文侦察,只回填结论,避免污染主上下文 |
26
+ | 上下文治理 | 工具结果老化、结构化摘要、轮内压缩、硬预算裁剪 |
27
+ | 上下文预装 | 需求感知 `repo_map` 排序 + 复杂题相关源码 `context_pack`(最多约 30KB),减少重复整读 |
28
+ | 长程任务 | 步数预算、自动续跑、检查点、幂等副作用登记(写操作不重复施加) |
29
+ | 人机协同 | 高风险写操作/命令弹出 diff 预览,批准或拒绝后才执行 |
30
+
31
+ 会话意图分层:寒暄、闲聊与通用问答直接回答,不扫描工作区、不触发工具或写入;只有编码、改文件、跑命令等明确任务才进入编码闭环。
32
+
33
+ ### 1.2 多会话异步并行
34
+
35
+ - 一个会话 = 一个后台 `asyncio.Task`,切窗、关页、断线都不会停止任务。
36
+ - 全局并发闸 + FIFO 排队;等待人工审批时自动让出并发槽。
37
+ - 会话状态机:`idle → queued → running ⇄ waiting_input → done / error`。
38
+ - 工作台顶部会话标签栏:新建或打开会话自动生成标签,点击即可横向切换,`×` 仅关闭视图不删除会话,刷新后保留。
39
+ - 新会话的首条消息会由模型按当前界面语言生成短标题;旧会话若仍是默认标题,则按首条消息自动显示摘要。
40
+ - 每个会话拥有独立地址 `/#/s/<session-id>`,可直接复制、刷新、分享或直接在地址栏切换。
41
+ - 刷新页面后从 SQLite 恢复消息、事件、计划、审批与产物。
42
+ - 前端实时事件主通道使用 SSE(断线重连、游标续传、无需 WebSocket 也能流式输出);WebSocket 端点保留用于兼容;REST 支持事件回放。
43
+
44
+ ### 1.3 AI 总管与多智能体编排
45
+
46
+ - **Supervisor**:跨会话健康巡检、卡死告警、自动中断、控制台对话与调度动作。
47
+ - **Orchestrator**:目标 → 任务 DAG → 每个员工独立 git worktree → 并行执行 → 合并验收。
48
+ - 员工会话共享契约文件与共享黑板,失败不阻塞同层其它任务。
49
+
50
+ ### 1.4 技能库(Skills)
51
+
52
+ - Markdown + front-matter,声明 `name / title / description / kinds / triggers`。
53
+ - 按任务类型与关键词自动匹配;技能多了自动切 BM25 排序。
54
+ - 内置:核心方法论、仓库工程闭环、Debug 闭环、网页交付、方案写作、视频分镜。
55
+ - 支持在 UI 中新建、编辑、删除技能,保存即生效。
56
+
57
+ ### 1.5 方案 / 分镜文档
58
+
59
+ - `make_plan`:生成独立 HTML 方案/计划书,含 KPI、章节、表格、风险、里程碑。
60
+ - `make_storyboard`:生成视频分镜脚本(镜头、时长、画面、口播)。
61
+ - 产物登记到 `api/data/artifacts/`,工作台右侧可直接预览/下载。
62
+
63
+ ### 1.6 插件化架构
64
+
65
+ 豪源不是「一个巨大的单体」,而是:
66
+
67
+ ```
68
+ Kernel(会话 / 事件 / 工具注册 / 策略 / 模型网关 / 审批)
69
+ │
70
+ ├── coding 编码 Agent + 工程工具 + 技能
71
+ ├── plans 方案工具 + Planner Agent
72
+ ├── video 分镜工具 + Video Agent
73
+ ├── supervisor 巡检 + 控制台路由
74
+ ├── orchestrator 任务 DAG + worktree + 合并
75
+ └── embodied 具身 Agent Harness(默认关闭,可安装启用)
76
+ ```
77
+
78
+ 插件可以贡献:工具、Agent、HTTP 路由、技能目录、事件订阅、生命周期钩子、前端导航/命令元数据。单个插件加载失败不会拖垮内核。
79
+
80
+ ![Plugins](docs/screenshots/plugins.png)
81
+
82
+ ### 1.7 三语言、浅色默认与可收起侧栏
83
+
84
+ - 默认 **浅色(白色)主题**,可在设置页或侧栏底部切换为深色。
85
+ - 默认 **简体中文**,可在 **简体中文 / 繁體中文 / English** 之间切换。
86
+ - 语言入口放在三个显眼位置:工作台顶栏、侧栏底部(所有页面可用)、设置页「外观」。
87
+ - 选择持久化到 `localStorage`,刷新和重启后保持;同时更新 `document.lang` 与页面标题。
88
+ - 侧栏可收起为 76px 图标栏;收起后顶部保留明确的「展开侧栏」按钮,会话列表自动隐藏,恢复后完整还原。
89
+ - 右侧洞察面板默认收起,给对话区留出更多空间;点击右上角按钮打开,用户选择会持久化。
90
+ - 内置技能标题、描述,插件标题、描述,状态、按钮、提示、审批、计划、用量、编排等 UI 文案均已完成三语言覆盖。
91
+
92
+ ---
93
+
94
+ ## 2. 快速开始
95
+
96
+ ### 匿名使用统计(透明声明)
97
+
98
+ 豪源内置一个**完全匿名**的使用统计心跳,用于统计在线设备数与版本分布:
99
+
100
+ - **上报内容**:本地随机生成的 `install_id`(UUID)、客户端版本号、操作系统类型(如 `Windows 11`)。不含用户名、邮箱、文件内容、工作区路径、对话内容等任何个人数据。
101
+ - **上报频率**:启动后及运行期间每 5 分钟一次(仅一次轻量 POST 请求)。
102
+ - **完全可关闭**:启动前设置环境变量 `HAOYUAN_TELEMETRY=0` 即永久关闭,所有功能不受影响。
103
+ - **隐私保障**:服务端只记录 IP 的单向哈希,不存明文 IP;数据保留 90 天。
104
+ - **完整声明**:见插件中心隐私接口 `GET {插件中心地址}/api/plugin-center/privacy`,或源码 `api/core/telemetry.py`(约 100 行,可自行审计)。
105
+
106
+ ### 环境要求
107
+
108
+ - Python 3.10+
109
+ - Node.js 18+
110
+ - Windows / Linux / macOS
111
+
112
+ ### Windows 一键启动
113
+
114
+ ```bat
115
+ start.bat
116
+ ```
117
+
118
+ 脚本会自动:停止 8030 上的旧进程 → 创建 `api/env1` → 安装 Python 依赖 → 安装前端依赖 → 每次重新构建前端 → 启动 API,并自动打开产品网页。这样不会因为旧进程或旧静态资源导致流式事件异常。
119
+
120
+ **端口自动顺延**:后端默认 `8030`、前端默认 `8130`;启动时若端口被占用会自动 +1(8031、8032…)直到绑定成功。实际端口写入 `api/data/runtime.json`,启动脚本会读取后直接打开正确地址。也可用环境变量 `HAOYUAN_PORT` / `HAOYUAN_WEB_PORT`(前端)、`HAOYUAN_API_PORT`(前端代理目标)显式指定基准端口。
121
+
122
+ 停止:
123
+
124
+ ```bat
125
+ stop.bat
126
+ ```
127
+
128
+ ### 桌面控制台(desktop.exe)
129
+
130
+ 双击根目录的 `desktop.exe` 打开图形化控制台(约 20 KB,仅依赖 Windows 自带的 .NET Framework 4.x):
131
+
132
+ - **全部启动 / 全部关闭**:一键管理后端与前端开发服务,启动后自动打开产品网页
133
+ - **启动 / 停止后端**(默认 8030)、**启动 / 停止前端**(默认 8130)
134
+ - **端口设置**:可直接修改后端 / 前端端口,点击「应用端口并重启」保存配置并自动重启两个服务;端口被占用时服务仍会自动 +1 顺延
135
+ - **打开产品网页**:自动打开后端实际端口(`api/data/runtime.json`),仅前端运行时回退前端端口
136
+ - **构建前端**、**打开项目目录**、每秒刷新的服务状态与实时运行日志
137
+
138
+ 关闭控制台窗口不会停止服务,如需停止请点击「全部关闭」或对应的停止按钮。源码位于 `desktop/`,修改后运行 `desktop\build.bat` 可重新编译。
139
+
140
+ ### Linux / macOS
141
+
142
+ ```bash
143
+ bash start.sh
144
+ bash stop.sh
145
+ ```
146
+
147
+ ### 手动启动
148
+
149
+ ```bash
150
+ # 后端
151
+ cd api
152
+ python -m venv env1
153
+ env1\Scripts\activate # Linux: source env1/bin/activate
154
+ pip install -r requirements.txt
155
+ python main.py # http://127.0.0.1:8030,被占用时自动 +1
156
+
157
+ # 前端开发模式(热更新,可选)
158
+ cd web
159
+ npm install
160
+ npm run dev # http://localhost:8130,被占用时自动 +1;/api 与 /ws 代理到后端实际端口
161
+ ```
162
+
163
+ 生产模式由后端直接托管 `web/dist`,只需要访问后端实际端口。端口可通过环境变量覆盖:`HAOYUAN_PORT`(后端,默认 8030)、`HAOYUAN_WEB_PORT`(前端,默认 8130)、`HAOYUAN_API_PORT`(前端代理目标,默认读取 `api/data/runtime.json`)。
164
+
165
+ ### 配置模型
166
+
167
+ ```bash
168
+ copy api\configs\secrets_example.py api\configs\secrets_local.py
169
+ ```
170
+
171
+ 编辑 `api/configs/secrets_local.py`:
172
+
173
+ ```python
174
+ DEEPSEEK_API_KEY = "sk-..."
175
+ DEEPSEEK_BASE_URL = "https://api.deepseek.com"
176
+ DEEPSEEK_MODEL = "deepseek-flash"
177
+
178
+ # 可选:智谱
179
+ ZHIPU_API_KEY = ""
180
+
181
+ # 可选:小米 MiMo(公平评测使用的模型)
182
+ MIMO_API_KEY = "tp-..."
183
+ MIMO_BASE_URL = "https://token-plan-cn.xiaomimimo.com/v1"
184
+ MIMO_MODEL = "mimo-v2.6-flash"
185
+ ```
186
+
187
+ 也可以使用环境变量(优先级高于文件):
188
+
189
+ ```powershell
190
+ $env:DEEPSEEK_API_KEY="sk-..."
191
+ ```
192
+
193
+ **未配置任何 Key 时自动使用本地 `mock` 模型**,完整跑通会话、工具调用、审批、事件与前端。
194
+
195
+ ---
196
+
197
+ ## 3. 界面
198
+
199
+ | 工作台(浅色,默认) | 工作台(英文) |
200
+ |---|---|
201
+ | ![](docs/screenshots/workbench-light.png) | ![](docs/screenshots/workbench-en.png) |
202
+
203
+ | 工作台(繁體中文) | 工作台(深色) |
204
+ |---|---|
205
+ | ![](docs/screenshots/workbench-tw.png) | ![](docs/screenshots/workbench-dark.png) |
206
+
207
+ | 总管控制台 | 技能库 |
208
+ |---|---|
209
+ | ![](docs/screenshots/console.png) | ![](docs/screenshots/skills.png) |
210
+
211
+ | 设置与语言入口 | 侧栏收起后的展开按钮 |
212
+ |---|---|
213
+ | ![](docs/screenshots/settings.png) | ![](docs/screenshots/collapsed.png) |
214
+
215
+ 移动端右侧洞察面板:
216
+ ![](docs/screenshots/mobile-panel.png)
217
+
218
+ 主要交互:
219
+
220
+ - 顶部会话标签:点击切换对话框,`×` 关闭标签(不影响会话数据)
221
+ - 新建任务不再提供预设问题,直接在输入框描述即可;会话标题会自动摘要
222
+ - 地址栏路由:`/#/s/<session-id>` 对应具体会话,可直接复制、刷新或在新窗口打开
223
+ - `Ctrl / Cmd + K`:命令面板(导航、会话、动作)
224
+ - `Ctrl / Cmd + N`:新建任务
225
+ - `Ctrl / Cmd + B`:折叠 / 展开侧栏
226
+ - `Enter`:发送;`Shift + Enter`:换行(`Ctrl / Cmd + Enter` 同样发送)
227
+ - 审批卡片:`A` 批准、`R` 拒绝
228
+ - 语言切换:工作台右上角、任意页面侧栏底部、设置页「外观」
229
+ - 会话运行中继续输入:作为「追加指令」合并进当前执行,不打断任务
230
+ - 右侧面板默认收起;点击右上角按钮展开,包含概览 / 计划 / 文件 / 变更 / 产物,支持拖拽调整宽度
231
+ - 文件与 diff 使用大尺寸预览弹层,避免窄栏阅读代码
232
+
233
+ ---
234
+
235
+ ## 4. 架构
236
+
237
+ ```text
238
+ hao-yuan/
239
+ ├── api/
240
+ │ ├── main.py FastAPI 入口(扩展路由 + 插件路由 + 静态前端)
241
+ │ ├── configs/ 配置、模型注册、密钥
242
+ │ ├── core/
243
+ │ │ ├── contracts.py Tool / Agent / Policy / ToolContext
244
+ │ │ ├── storage.py SQLite (WAL) 存储层
245
+ │ │ ├── events.py 事件总线(广播 + 批量落库 + 回放)
246
+ │ │ ├── gateway.py 模型网关(流式 + 降级 + fallback)
247
+ │ │ ├── context.py 上下文压缩 / 老化 / 硬预算
248
+ │ │ ├── runtime.py Agent 主循环
249
+ │ │ ├── session_manager.py 并发闸 / 排队 / 审批 / 续跑
250
+ │ │ ├── policy.py 权限门禁
251
+ │ │ ├── tools.py 工具注册与执行
252
+ │ │ ├── agents.py Agent 注册
253
+ │ │ └── plugin.py 插件发现 / 依赖 / 生命周期
254
+ │ ├── harness/ 沙箱 / 技能 / 符号索引 / 修复环 / 监督 / 编排 / 具身
255
+ │ ├── tools/ builtin / dev / plan
256
+ │ ├── adapters/providers/ deepseek / mimo / mock
257
+ │ ├── plugins/ coding / plans / video / supervisor / orchestrator / embodied
258
+ │ ├── extensions/ 系统 / 会话 / 技能 / 设置 / 文件 / 用量 / 插件 / 审批 / 实时事件(SSE / WebSocket)
259
+ │ ├── skills/ 核心技能
260
+ │ ├── tests/ 28 个后端测试
261
+ │ └── data/ 运行时数据(gitignore)
262
+ ├── web/ Vue 3 + Vite
263
+ ├── docs/screenshots/ 界面截图
264
+ ├── start.bat / stop.bat
265
+ ├── start.sh / stop.sh
266
+ ├── dev.bat
267
+ ├── desktop.exe 图形化桌面控制台(启停服务 / 打开网页)
268
+ └── desktop/ desktop.exe 源码与构建脚本
269
+ ```
270
+
271
+ ### 数据与边界
272
+
273
+ - 数据库:`api/data/haoyuan.db`(WAL)
274
+ - 产物:`api/data/artifacts/<session_id>/`
275
+ - 运行时端口:`api/data/runtime.json`(后端写 `api_port`、前端写 `web_port`、桌面控制台写 `api_port_config` / `web_port_config`)
276
+ - 所有文件工具都受会话工作区白名单约束,拒绝 `../` 与绝对路径越界。
277
+ - 高风险工具(写文件、patch、删除、移动、shell、git、机器人运动)必须经审批。
278
+ - `run_shell` 对灾难性命令做硬阻断(如 `rm -rf /`、磁盘格式化、关机)。
279
+ - 产物 HTML 通过带沙箱 CSP 的接口预览,避免模型生成页面读取本地凭据。
280
+ - 密钥只从环境变量或 `secrets_local.py` 读取,不入库、不返回明文。
281
+ - 真实 Key 存放在 `api/configs/secrets_local.py`,已被 `.gitignore` 忽略;`git add --dry-run` 验证不会进入仓库。
282
+
283
+ ---
284
+
285
+ ## 5. 插件开发
286
+
287
+ 在 `api/plugins/` 下新建目录:
288
+
289
+ ```
290
+ api/plugins/my-plugin/
291
+ ├── plugin.json
292
+ ├── plugin.py
293
+ ├── routes.py # 可选
294
+ └── skills/ # 可选
295
+ └── my-skill.md
296
+ ```
297
+
298
+ `plugin.json`:
299
+
300
+ ```json
301
+ {
302
+ "name": "my-plugin",
303
+ "title": "My Plugin",
304
+ "version": "1.0.0",
305
+ "description": "What this plugin adds",
306
+ "author": "you",
307
+ "requires": ["coding"],
308
+ "default_enabled": true,
309
+ "backend": "plugin.py",
310
+ "routes": "routes.py",
311
+ "contributes": {
312
+ "tools": ["my_tool"],
313
+ "agents": ["my_agent"],
314
+ "skills": true
315
+ },
316
+ "frontend": {
317
+ "nav": [{ "label": "My Plugin", "path": "/my-plugin", "icon": "puzzle" }],
318
+ "commands": [{ "id": "my-plugin.run", "title": "Run my plugin" }]
319
+ }
320
+ }
321
+ ```
322
+
323
+ `plugin.py`:
324
+
325
+ ```python
326
+ from core.contracts import AgentSpec, ToolSpec
327
+
328
+
329
+ async def my_tool(ctx, args):
330
+ return {"echo": args.get("text", "")}
331
+
332
+
333
+ def register(ctx):
334
+ ctx.register_tool(
335
+ ToolSpec(
336
+ name="my_tool",
337
+ description="Echo text",
338
+ input_schema={
339
+ "type": "object",
340
+ "properties": {"text": {"type": "string"}},
341
+ "required": ["text"],
342
+ },
343
+ ),
344
+ my_tool,
345
+ )
346
+ ctx.register_agent(
347
+ AgentSpec(
348
+ name="my_agent",
349
+ title="My Agent",
350
+ instructions="You are ...",
351
+ tools=["my_tool"],
352
+ kind="dev",
353
+ )
354
+ )
355
+ ctx.add_skill_dir("skills")
356
+
357
+
358
+ async def startup(ctx):
359
+ ...
360
+
361
+
362
+ async def shutdown(ctx):
363
+ ...
364
+ ```
365
+
366
+ 插件能力:
367
+
368
+ - `requires` 依赖排序;缺失依赖会被隔离并记录错误。
369
+ - `startup / shutdown` 生命周期。
370
+ - `ctx.events.subscribe(sink)` 订阅全局事件(编排器就是这样接收员工完成事件的)。
371
+ - 启用/禁用状态持久化在 SQLite;启用/禁用后需重启 API 以加载/卸载路由。
372
+ - 前端通过 `/api/plugins` 获取 `contributes` 与 `frontend` 元数据。
373
+
374
+ ### 为什么这样设计
375
+
376
+ 参考了 WordPress 的「小内核 + 可安装插件」:内核只负责会话、事件、策略、模型与工具协议;业务能力全部下沉为插件。
377
+ 也吸收了 DeepSeek Harness 的「harness 本身可插拔」思路:具身 Agent 就是一个独立 harness 插件,可以继续安装小车、机械臂、人形机器人等不同 harness,而不改内核。
378
+
379
+ ---
380
+
381
+ ## 6. 自测结果
382
+
383
+ 在本次交付环境中已执行:
384
+
385
+ ```bash
386
+ cd api
387
+ python -m pytest -q
388
+ # 28 passed, 1 warning
389
+
390
+ cd ../web
391
+ npm run build
392
+ # ✓ built, 83 modules transformed
393
+ ```
394
+
395
+ 测试覆盖:
396
+
397
+ - 健康检查、模型、技能、插件、审批列表
398
+ - mock 模型完整会话(消息 → 事件 → done)
399
+ - 编码会话写文件 → 工具事件 → artifact → 工作区树读取
400
+ - 人工审批流程:pending → 批准 → 工具执行 → 文件落盘
401
+ - 会话改名 / 隐藏 / 恢复 / 清空 / 彻底删除
402
+ - 全局门禁与默认工作区设置、用量与 CSV 导出
403
+ - 插件启用状态持久化
404
+ - Orchestrator git worktree 端到端(创建 → 派发 → 完成 → 合并)
405
+ - 工具级:沙箱越界、读写/编辑/patch/multi_edit、glob/grep/符号、shell、删除/移动
406
+ - 危险 shell 命令硬阻断
407
+ - 符号索引、repo map、pytest 解析、修复指引
408
+ - 方案 HTML 与分镜 HTML 产物生成
409
+ - 意图分流:寒暄、闲聊与通用问答(如「你好吗」「今天天气不错」「什么是依赖注入」)直接回复,不扫描工作区、不触发工具或写入(含真实 deepseek-flash 验证)
410
+ - 首条消息自动生成会话标题(跟随界面语言;mock 覆盖回退与真实模型验证)
411
+ - 会话独立路由:`/#/s/<session-id>` 深链、标签切换、地址栏编辑、刷新恢复与关闭回退
412
+
413
+ 另外用 Playwright + 本机 Chrome 对生产构建做了真实浏览器巡检:
414
+
415
+ - 工作台 / 控制台 / 技能 / 插件 / 设置 / 用量 / 编排页全部加载
416
+ - 顶部会话标签与独立路由:打开、切换、关闭、地址栏深链、刷新恢复
417
+ - 默认标题自动摘要、右上角语言菜单(English / 简体中文切换)与无预设问题的空状态
418
+ - 简体中文、繁體中文、English 三语言切换正常,刷新后语言保持
419
+ - 语言入口覆盖工作台顶栏、侧栏底部、设置页三处
420
+ - 侧栏 286px ↔ 76px 收起/展开正常,收起后会话列表隐藏且展开按钮可见
421
+ - 右侧洞察面板默认收起,展开/收起状态持久化
422
+ - 输入框 `Enter` 提交、`Shift + Enter` 换行正常,中文输入法组合态不会误提交
423
+ - 深色 / 浅色主题正常
424
+ - 430px 移动端布局、侧栏抽屉、右侧洞察抽屉正常
425
+ - SSE 实时流:真实 DeepSeek 的思考过程与正文增量在 `done` 之前可见
426
+ - 控制台无 JS 错误、无资源 404、无 WebSocket 404(前端实时流主通道已改为 SSE)
427
+
428
+ > 本次已使用 AI 助理参考的 DeepSeek Key 完成真实在线验证:`deepseek-flash` 返回 `OK`,usage provider/model = `deepseek/deepseek-flash`。Key 仅存放在 `api/configs/secrets_local.py`,已被 `.gitignore` 忽略;仓库只提交 `secrets_example.py` 模板。Mock 回归测试仍保留,断网或无 Key 时可自动降级。
429
+
430
+ ---
431
+
432
+ ## 7. Harness 公平评测结果
433
+
434
+ > 最新报告:[test/testing/index-2026-10-27.html](test/testing/index-2026-10-27.html)(2026-10-27,mimo-v2.6-flash)
435
+ > 历史报告:[test/testing/index-2026-10-25.html](test/testing/index-2026-10-25.html)(2026-10-25,deepseek-flash)
436
+
437
+ ### 7.1 MiMo 公平评测(最新)
438
+
439
+ **方法**:5 个可自动判分的任务(基础自适应 1 + 定位 / 性能 / 长程 / 并发 4)× 3 个工具;统一 `mimo-v2.6-flash`、提示词、种子仓库与预算。运行结束后注入隐藏测试,并对 `tests/`、`pyproject.toml` 做 SHA-256 校验,篡改即 0 分。t1/d1/d3 使用 official-r1 交错批次,d4/d6 使用冻结代码后的独立复跑批次。
440
+
441
+ | 排名 | 工具 | 综合(产品加权) | 正确率 | 速度 | 成本 | 工程纪律 | 等权 |
442
+ |---|---|---|---|---|---|---|---|
443
+ | 1 | **豪源 HaoYuan** | **98.8** | 100.0 | 94.4 | 96.9 | 100.0 | **98.3(第 1)** |
444
+ | 2 | OpenCode | 90.5 | 100.0 | 67.8 | 53.5 | 100.0 | 84.3(第 2) |
445
+ | 3 | Claude Code | 88.9 | 100.0 | 65.1 | 40.9 | 100.0 | 81.2(第 3) |
446
+
447
+ 综合 = 0.65 × 正确率 + 0.15 × 速度 + 0.10 × 成本 + 0.10 × 工程纪律;等权口径为 0.40 / 0.20 / 0.20 / 0.20。
448
+
449
+ - 三者正确率均为 100%;豪源产品加权 **98.8**、等权 **98.3**,两种口径均为第一。
450
+ - 分任务:豪源在 t1(63.8s)、d3(220.6s)、d4(469.6s)最快;OpenCode 拿下 d1(111.3s),Claude Code 拿下 d6(254.5s)。
451
+ - 成本:5 题总成本豪源 **$3.33**、OpenCode $6.56、Claude Code $9.04;单任务成本分别为 $0.666 / $1.313 / $1.809。
452
+ - 自适应强度:t1 简单题 63.8s / 11 次调用,未启动计划或子代理;d4 长程题通过预装相关源码减少重复探索(从 1200s 超时降到 469.6s)。
453
+ - 关键修复:补齐 MiMo provider(此前 `resolve("mimo", ...)` 会静默回退 deepseek)、需求感知 repo map、复杂题 30KB context pack、进程树回收、严格 provider + 单次调用上限 + 同模型重试、简单题 lite 路由。
454
+ - 局限:正式对照每题 1 轮;d4/d6 为独立复跑批次;模型延迟方差较大(Claude d3 先前 623s、本次 884s);d5 区分度不足未入榜;自建任务,不能替代 SWE-bench 等公开基准。
455
+
456
+ 复现:
457
+
458
+ ```bash
459
+ cd test/bench
460
+ python harness_bench.py run --batch official-r1 --tools haoyuan,claude,opencode --tasks t1_multisite_bugfix,d1_needle_regress,d3_perf_cliff --resume
461
+ python harness_bench.py run --batch official-r1 --tools haoyuan,claude,opencode --tasks d4_multilayer_feature,d6_concurrency_fix --resume
462
+ python make_report_mimo_final.py
463
+ ```
464
+
465
+ ### 7.2 deepseek-flash 深度评测(历史)
466
+
467
+ **方法**:8 个可自动判分的编码任务(5 基础 + 3 困难)× 每任务 3 轮 × 3 个工具;统一 deepseek-flash、提示词、种子仓库与预算;运行结束后注入隐藏测试,并对 `tests/`、`pyproject.toml` 做 SHA-256 校验,篡改即 0 分。
468
+
469
+ | 排名 | 工具 | 综合得分(产品加权) | 正确率 | 典型速度 | 尾延迟 | 成本 | 等权得分 |
470
+ |---|---|---|---|---|---|---|---|
471
+ | 1 | **豪源 HaoYuan** | **96.6** | 100.0 | 100.0(中位 30.3s) | 67.6(P90 159.4s) | 82.2($0.364) | 95.0(第 2) |
472
+ | 2 | OpenCode | 95.1 | 100.0 | 67.6(中位 44.8s) | 100.0(P90 107.7s) | 100.0($0.299) | 96.8(第 1) |
473
+ | 3 | Claude Code | 90.7 | 100.0 | 70.6(中位 42.9s) | 90.7(P90 118.7s) | 55.4($0.540) | 91.7(第 3) |
474
+
475
+ 综合 = 0.70 × 正确率 + 0.15 × 典型速度 + 0.05 × 尾延迟 + 0.10 × 成本;等权口径将后两项改为 0.10 / 0.10。
476
+
477
+ - 三者正确率均为 100%,差异集中在速度、尾延迟与 token 成本;豪源产品加权第一,OpenCode 等权反超。
478
+ - 豪源任务中位耗时 30.3s 最短,T1/T2/T3/H1 四题中位最快;24 次运行完整性 100%。OpenCode 尾延迟与单任务成本最优;Claude Code token 成本最高。
479
+ - 短板:H2 版本迁移中位 159.4s(OpenCode 101.1s),H3 出现过 260s 长尾;后续继续压缩迁移审计与自测回合。
480
+ - 局限:仅覆盖 deepseek-flash、每任务 3 轮,任务为自建,不能替代 SWE-bench 等公开基准。
481
+ - 自迭代:评测期间修复 Windows 管道适配、空回复/未写入保护、迁移验收审计、轻量 git diff 审计、完成态顺序,并回滚一次「过度自测」的负优化。
482
+
483
+ 复现:
484
+
485
+ ```bash
486
+ cd test/bench
487
+ python harness_bench.py run --batch final-r1 --tools haoyuan,claude,opencode --tasks all
488
+ python aggregate.py
489
+ python make_report.py
490
+ ```
491
+
492
+ ---
493
+
494
+ ## 8. 与 AI 助理的功能对齐
495
+
496
+ | 能力 | 豪源 | 说明 |
497
+ |---|---|---|
498
+ | 编码工具链 | ✅ | 定位、最小 patch、验证、修复环、子代理 |
499
+ | 上下文压缩 / 长程 | ✅ | 轮内压缩、老化、硬预算、检查点、幂等续跑 |
500
+ | 多会话并行 | ✅ | 并发闸、FIFO、后台任务与前端解耦 |
501
+ | 权限门禁 / diff 审批 | ✅ | 审批卡片、预览、超时、并发槽让出 |
502
+ | 技能库 | ✅ | front-matter + 规则/BM25 + UI 编辑 |
503
+ | 方案计划书 | ✅ | 独立 HTML 产物 |
504
+ | 视频分镜 | ✅ | HTML 分镜脚本;不包含 ffmpeg 成片渲染 |
505
+ | AI 总管 | ✅ | 快照、告警、控制台对话、调度动作 |
506
+ | 多智能体编排 | ✅ | 任务 DAG + git worktree + 合并指标 |
507
+ | Token / 成本统计 | ✅ | 日聚合、按模型、CSV 导出 |
508
+ | 插件机制 | ✅ 增强 | 清单、依赖、生命周期、工具/Agent/路由/技能/前端元数据 |
509
+ | 飞书远程指挥 | ⏳ 未纳入本版 | 接口层已解耦,可作为插件补充 |
510
+ | ASR / TTS / 视频渲染 | ⏳ 未纳入本版 | 当前聚焦 AI 编程主链路 |
511
+ | 权威 Benchmark | ⏳ 公开基准未跑 | 已完成自建评测:5 任务 MiMo 公平评测 + 8 任务 deepseek 深度评测(见第 7 节);SWE-bench 等公开基准未重跑 |
512
+
513
+ ---
514
+
515
+ ## 9. 后续路线(已预留架构)
516
+
517
+ ### 9.1 面向 16GB 显存本地训练的 Skills 库
518
+
519
+ 计划内置:
520
+
521
+ - Qwen3.5-0.8B 的 SFT 数据构造与训练脚本
522
+ - RL(偏好优化 / 可验证奖励)训练脚本
523
+ - 显存友好配置:LoRA / QLoRA、梯度累积、小 batch、序列长度控制
524
+ - 以「技能」为单位组织:数据模板、训练配置、评估用例、部署说明
525
+
526
+ 豪源当前的 Skill 机制已经是文件级、可版本化的,后续可直接把训练方法论文档作为 Skill 注入 Agent。
527
+
528
+ ### 9.2 插件化具身 Harness
529
+
530
+ `plugins/embodied` 已演示:
531
+
532
+ - 机器人状态 / 传感器 / 移动 / 转向 / 急停工具
533
+ - 高风险动作审批
534
+ - HTTP 演示桥
535
+
536
+ 后续可以在不改内核的前提下增加:
537
+
538
+ - `embodied-ros2`(ROS2 话题 / 服务)
539
+ - `embodied-serial`(Arduino / ESP32)
540
+ - `embodied-smolvla`(视觉语言动作模型)
541
+ - 小车、机械臂、人形机器人各自的 harness 插件
542
+
543
+ ---
544
+
545
+ ## 10. API 速览
546
+
547
+ 统一前缀 `/api`,响应格式 `{ code, data, message }`。
548
+
549
+ | 分组 | 主要端点 |
550
+ |---|---|
551
+ | 系统 | `GET /health`、`GET /info`、`GET /models`、`GET /agents`、`GET /tools` |
552
+ | 会话 | `POST /sessions`、`GET /sessions`、`GET /sessions/{id}`、`PATCH /sessions/{id}` |
553
+ | 消息 | `POST /sessions/{id}/messages`、`GET /sessions/{id}/messages` |
554
+ | 事件 | `GET /sessions/{id}/events?after_id=`、`GET /sessions/{id}/stream`、`WS /ws` |
555
+ | 审批 | `GET /approvals`、`POST /approvals/{id}/resolve`、`POST /sessions/{id}/confirm` |
556
+ | 技能 | `GET/POST /skills`、`GET/PUT/DELETE /skills/{name}` |
557
+ | 文件 | `GET /workspace/tree`、`GET /workspace/file`、`GET /workspace/changes`、`GET /workspace/diff` |
558
+ | 设置 | `GET/PUT /settings`、`PUT /settings/gate`、`PUT /settings/workspace` |
559
+ | 用量 | `GET /usage/today`、`GET /usage/daily`、`GET /usage/by-model`、`GET /usage/export.csv` |
560
+ | 插件 | `GET /plugins`、`POST /plugins/{name}/toggle` |
561
+ | 总管 | `GET /supervisor/overview`、`GET /supervisor/console`、`POST /supervisor/act`、`POST /supervisor/chat` |
562
+ | 编排 | `POST /orchestrations`、`GET /orchestrations`、`GET /orchestrations/{id}` |
563
+
564
+ 交互式文档:<http://127.0.0.1:8030/docs>(端口顺延后以后端日志或 `api/data/runtime.json` 为准)
565
+
566
+ ---
567
+
568
+ ## 11. 开发与测试
569
+
570
+ ```bash
571
+ cd api
572
+ python -m pytest -q
573
+
574
+ cd ../web
575
+ npm run build
576
+ npm run dev # 开发模式,/api 与 /ws 自动代理到后端实际端口
577
+ ```
578
+
579
+ 建议在 `AGENTS.md` 中记录团队的 lint / test / build 命令,豪源会自动把项目记忆注入上下文。
580
+
581
+ ---
582
+
583
+ ## License
584
+
585
+ Private project. All rights reserved.
File without changes
File without changes