@co0ontty/wand 4.89.4 → 4.89.5-beta.344.1.g4dbc0b7
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/README.md +17 -4
- package/dist/ai-team-employee-binding.js +2 -1
- package/dist/ai-team-runner.d.ts +2 -1
- package/dist/ai-team-runner.js +38 -2
- package/dist/ai-team-types.js +3 -2
- package/dist/ai-text-runner.d.ts +61 -0
- package/dist/ai-text-runner.js +653 -0
- package/dist/archive-policy.d.ts +17 -0
- package/dist/archive-policy.js +8 -0
- package/dist/bounded-process-output.d.ts +5 -0
- package/dist/bounded-process-output.js +9 -0
- package/dist/build-info.json +4 -4
- package/dist/command-error.d.ts +6 -0
- package/dist/command-error.js +8 -0
- package/dist/config.js +11 -42
- package/dist/conversation-service.d.ts +7 -1
- package/dist/conversation-service.js +35 -10
- package/dist/conversation-session-preview.d.ts +2 -0
- package/dist/conversation-session-preview.js +4 -0
- package/dist/decision-client.js +22 -6
- package/dist/decision-expert-employee.js +2 -2
- package/dist/decision-expert-identity.d.ts +1 -1
- package/dist/decision-expert-identity.js +1 -1
- package/dist/decision-expert-service.d.ts +1 -0
- package/dist/decision-expert-service.js +82 -76
- package/dist/decision-hardware.js +4 -3
- package/dist/decision-types.d.ts +4 -0
- package/dist/decision-types.js +4 -0
- package/dist/deployment-lock.d.ts +13 -0
- package/dist/deployment-lock.js +189 -0
- package/dist/employee-text.js +1 -1
- package/dist/fixed-employee-avatar.d.ts +6 -0
- package/dist/fixed-employee-avatar.js +4 -0
- package/dist/git-quick-commit.d.ts +5 -40
- package/dist/git-quick-commit.js +7 -635
- package/dist/hr-employee-identity.d.ts +5 -0
- package/dist/hr-employee-identity.js +5 -0
- package/dist/hr-employee.d.ts +5 -0
- package/dist/hr-employee.js +21 -0
- package/dist/middleware/path-safety.js +1 -1
- package/dist/milestone-scope.js +1 -1
- package/dist/model-auto-assign.d.ts +1 -1
- package/dist/model-auto-assign.js +1 -1
- package/dist/models.d.ts +4 -0
- package/dist/models.js +21 -1
- package/dist/npm-update-utils.js +18 -55
- package/dist/pi-auto-resources.js +6 -3
- package/dist/plush-avatar.d.ts +12 -2
- package/dist/plush-avatar.js +16 -2
- package/dist/plush-cat-appearance.d.ts +97 -0
- package/dist/plush-cat-appearance.js +118 -0
- package/dist/plush-cat-whiskers.d.ts +6 -0
- package/dist/plush-cat-whiskers.js +42 -0
- package/dist/process-manager.d.ts +22 -21
- package/dist/process-manager.js +49 -83
- package/dist/prompt-optimizer.d.ts +1 -1
- package/dist/prompt-optimizer.js +1 -1
- package/dist/render-host.js +1 -19
- package/dist/retention.js +8 -10
- package/dist/scheduled-task-service.d.ts +41 -0
- package/dist/scheduled-task-service.js +320 -0
- package/dist/scheduled-task-state.d.ts +6 -0
- package/dist/scheduled-task-state.js +28 -0
- package/dist/scheduled-task-time.d.ts +4 -0
- package/dist/scheduled-task-time.js +82 -0
- package/dist/scheduled-task-types.d.ts +71 -0
- package/dist/scheduled-task-types.js +1 -0
- package/dist/server-employee-routes.d.ts +3 -0
- package/dist/server-employee-routes.js +28 -18
- package/dist/server-file-routes.js +44 -1
- package/dist/server-pi-recommendation-routes.js +13 -4
- package/dist/server-resume-routes.js +1 -1
- package/dist/server-scheduled-task-routes.d.ts +4 -0
- package/dist/server-scheduled-task-routes.js +34 -0
- package/dist/server-session-routes.d.ts +2 -10
- package/dist/server-session-routes.js +40 -69
- package/dist/server-task-routes.d.ts +2 -17
- package/dist/server-task-routes.js +23 -109
- package/dist/server-team-dispatch-routes.js +12 -2
- package/dist/server-update-routes.js +12 -3
- package/dist/server-workspace-routes.d.ts +1 -1
- package/dist/server-workspace-routes.js +40 -74
- package/dist/server.js +56 -17
- package/dist/session-registry.d.ts +4 -0
- package/dist/session-registry.js +27 -11
- package/dist/session-request.d.ts +9 -0
- package/dist/session-request.js +27 -0
- package/dist/session-topic.d.ts +1 -1
- package/dist/session-topic.js +1 -1
- package/dist/silicon-employee-draft.d.ts +2 -2
- package/dist/silicon-employee-draft.js +3 -3
- package/dist/socket-probe.d.ts +2 -0
- package/dist/socket-probe.js +20 -0
- package/dist/storage-schedules.d.ts +20 -0
- package/dist/storage-schedules.js +78 -0
- package/dist/storage-schema.d.ts +3 -0
- package/dist/storage-schema.js +702 -0
- package/dist/storage.d.ts +29 -2
- package/dist/storage.js +148 -698
- package/dist/structured-exec-pump.js +79 -38
- package/dist/structured-session-manager.d.ts +8 -17
- package/dist/structured-session-manager.js +85 -501
- package/dist/system-employee.d.ts +1 -1
- package/dist/system-employee.js +1 -1
- package/dist/task-archive-policy.d.ts +4 -0
- package/dist/task-archive-policy.js +16 -0
- package/dist/task-read-model.d.ts +27 -0
- package/dist/task-read-model.js +47 -0
- package/dist/task-retention.d.ts +1 -1
- package/dist/task-retention.js +1 -1
- package/dist/task-title-service.d.ts +30 -0
- package/dist/task-title-service.js +122 -0
- package/dist/task-title.d.ts +1 -1
- package/dist/task-title.js +1 -1
- package/dist/terminal-daemon-client.js +1 -18
- package/dist/tui/commands.d.ts +1 -1
- package/dist/tui/commands.js +6 -3
- package/dist/user-memory.js +1 -1
- package/dist/web-ui/asset-runtime.d.ts +12 -0
- package/dist/web-ui/asset-runtime.js +6 -0
- package/dist/web-ui/chat-message-meta.d.ts +3 -1
- package/dist/web-ui/chat-message-meta.js +21 -1
- package/dist/web-ui/composer-avatar-activity.d.ts +6 -0
- package/dist/web-ui/composer-avatar-activity.js +29 -0
- package/dist/web-ui/content/ai-teams.js +13 -13
- package/dist/web-ui/content/module-manifest.json +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/chat-render-SEND5BPU.js +24 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/chunk-2YZLCGYN.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/chunk-42SHIKAP.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/chunk-6XQEBIEX.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/chunk-DDSO7OX7.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/chunk-G3CXNMA2.js +20 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/chunk-N6DK4I6R.js +111 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/chunk-NURCNMRU.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/chunk-TF2CXDA5.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/chunk-TMRPHNJO.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/chunk-WC7RK7LP.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/chunk-YNCSBEGK.js +36 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/chunk-YOXXNXOX.js +2 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/chunk-YX475LXO.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/employee-card-RDXHBUIQ.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/host-4QETSHC5.js +69 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/host-56WPSON2.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/host-5QOHKHNC.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/host-CVTNA7YL.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/host-EZV22Q7Y.js +4 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/host-IW43Z5ZF.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/host-JT7NIUQL.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/host-JWEIDB55.js +3 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/host-OU5TRYH6.js +2 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/host-PRSTCPVE.js +5 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/host-TWPJI3HE.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/host-WZGJSNML.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/host-X6KQVFD6.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/host-YKCQFMQR.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/host-bridge-P3TCCPPI.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/library-bridge-MQFJGTGY.js +4 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/page-4BPVZIC2.js +3 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/panel-ZMZRP7EF.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/runtime.js +848 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/sha256-ANXV72UC.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/task-board-host-6P2YMGBL.js +2 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/workspace-agent-picker-SHJ3F4KZ.js +1 -0
- package/dist/web-ui/content/modules/935d59f357b389bc/workspace-window-TUY5Q3OO.js +1 -0
- package/dist/web-ui/content/plush-avatar.js +177 -177
- package/dist/web-ui/content/scripts.js +1 -1090
- package/dist/web-ui/content/styles.css +1 -1
- package/dist/web-ui/content/tailwind.css +1 -1
- package/dist/web-ui/embedded-assets.d.ts +32 -0
- package/dist/web-ui/embedded-assets.js +10 -8
- package/dist/web-ui/markdown.d.ts +3 -2
- package/dist/web-ui/markdown.js +61 -46
- package/dist/web-ui/message-file-target.d.ts +13 -0
- package/dist/web-ui/message-file-target.js +85 -0
- package/dist/web-ui/react/local-preview/controller.d.ts +2 -0
- package/dist/web-ui/react/local-preview/controller.js +12 -0
- package/dist/web-ui/scripts.d.ts +10 -0
- package/dist/web-ui/scripts.js +42 -5
- package/package.json +6 -3
- package/browser-extension/icons/wand-128.png +0 -0
- package/browser-extension/icons/wand-16.png +0 -0
- package/browser-extension/icons/wand-32.png +0 -0
- package/browser-extension/icons/wand-48.png +0 -0
- package/dist/commit-task-archive.d.ts +0 -8
- package/dist/commit-task-archive.js +0 -65
package/README.md
CHANGED
|
@@ -59,6 +59,7 @@ wand config:password
|
|
|
59
59
|
- **Message queueing** — keep typing while the AI is working; messages are queued automatically
|
|
60
60
|
- **File browser** — built-in path browsing and search
|
|
61
61
|
- **Quick commits** — review Git changes and generate a commit message from the web UI
|
|
62
|
+
- **Scheduled tasks** — choose an employee, workspace directory and prompt, run once or repeat daily/weekly, and review execution history. See [scheduling behavior](docs/scheduled-tasks.md).
|
|
62
63
|
|
|
63
64
|
#### Deployment
|
|
64
65
|
|
|
@@ -135,7 +136,7 @@ npm run check # TypeScript type check
|
|
|
135
136
|
npm run build # Compile and copy static assets to dist/
|
|
136
137
|
```
|
|
137
138
|
|
|
138
|
-
On this configured development machine, use `~/start.sh` to build/install the working tree and restart, `~/start.sh --restart` to restart without rebuilding, or `~/start.sh --status` to check status. This user-home helper enters the project and handles sudo locally; do not prefix it with `sudo`. It is not included in a fresh clone, and credentials stay outside the repository. Restart safety rules remain in [AGENTS.md](AGENTS.md).
|
|
139
|
+
On this configured development machine, use `~/start.sh` to build/install the working tree and restart, `~/start.sh --restart` to restart without rebuilding, or `~/start.sh --status` to check status. This user-home helper enters the project and handles sudo locally; do not prefix it with `sudo`. It is not included in a fresh clone, and credentials stay outside the repository. Restart safety rules remain in [AGENTS.md](AGENTS.md). Build/check commands share a project lock; local deployment and npm updates share the global installation lock. A busy lock fails before package or service changes. Local Beta versions are written only to build metadata and a private package snapshot, never to the working tree's package manifests. The `build:body` / `check:body` scripts are internal steps for the locked entry points.
|
|
139
140
|
|
|
140
141
|
Use an isolated config for testing:
|
|
141
142
|
|
|
@@ -233,18 +234,30 @@ npm install -g @google/gemini-cli@latest
|
|
|
233
234
|
|
|
234
235
|
#### 交互体验
|
|
235
236
|
|
|
236
|
-
- **结构化对话** —
|
|
237
|
+
- **结构化对话** — 代码块语法高亮、工具调用折叠/展开、多问题分组渲染、输入区展示最近一轮 Token 用量与费用
|
|
237
238
|
- **个性化角色** — 像素风猫咪头像(赛博虎妞 / 勤劳初二),支持自定义对话角色名称
|
|
238
239
|
- **消息排队** — 在 AI 思考时可继续输入,消息自动排队发送
|
|
239
240
|
- **文件浏览器** — 内置路径浏览和搜索功能
|
|
240
241
|
- **本地预览** — 消息和终端里的本机链接可点击预览;顶栏也可手动打开本机 HTTP 端口或 HTML 目录
|
|
241
242
|
- **快捷提交** — Git 变动快速提交入口,一键生成 commit message
|
|
243
|
+
- **定时任务** — 选择员工、工作区目录和提示词,单次或每天/每周自动执行,并查看执行记录;详见 [使用说明](docs/scheduled-tasks.md)。
|
|
242
244
|
|
|
243
245
|
#### 部署与访问
|
|
244
246
|
|
|
245
247
|
- **多平台客户端** — Android / iOS / macOS 原生客户端,支持加密连接码分发、自动更新检查
|
|
246
248
|
- **HTTPS** — 可选自签证书,适合远程或移动端访问
|
|
247
249
|
- **版本管理** — 内置更新检查与升级提示,支持 stable/beta 双通道
|
|
250
|
+
|
|
251
|
+
Web 设置中的「Beta 通道」决定服务端 npm 更新来源:关闭时仅检查
|
|
252
|
+
`@co0ontty/wand@latest`,开启时检查 `@co0ontty/wand@beta`;「自动更新 Web 服务」
|
|
253
|
+
独立决定是否自动安装。检查后安装锁定具体版本,避免 dist-tag 在安装期间移动。
|
|
254
|
+
关闭 Beta 不会自动降级;需要立即返回较旧正式版时,点击「更新或重新安装」。
|
|
255
|
+
|
|
256
|
+
正式 npm 发布由 `vX.Y.Z` Git tag 触发,只写入 `latest`,拒绝预发布版本。
|
|
257
|
+
master 的 Beta 发布只写入 `beta`,版本为下一补丁号加
|
|
258
|
+
`-beta.<构建序号>.<重试序号>.g<提交>`,例如 `4.89.5-beta.100.1.gabcdef0`。
|
|
259
|
+
版本基数同时检查正式 Git tags 和 npm latest,兼容未推送 Git 的本地正式发布。
|
|
260
|
+
Beta 尚未发布、通道版本无效或 npm 暂不可达时,不自动安装其他通道。
|
|
248
261
|
- **CLI 更新** — 在服务端设置中检查并快速更新 Claude Code、Codex、OpenCode、Qoder CLI、Pi 和 Gemini CLI,也可开启自动更新
|
|
249
262
|
|
|
250
263
|
### 配置
|
|
@@ -271,7 +284,7 @@ wand config:set port 9443
|
|
|
271
284
|
|
|
272
285
|
### 语音识别
|
|
273
286
|
|
|
274
|
-
Web、Android、iOS 可在语音输入设置中选择「服务端识别」或「客户端本地识别」。服务端使用按需安装的 whisper.cpp 多语言模型,支持无 GPU CPU 服务器、Mac mini Metal 与可选 CUDA;模型不随普通构建下载。部署、模型大小、鉴权和隐私边界见 [服务端语音识别](docs/server-speech.md)。设置内下载/初始化 LAYA
|
|
287
|
+
Web、Android、iOS 可在语音输入设置中选择「服务端识别」或「客户端本地识别」。服务端使用按需安装的 whisper.cpp 多语言模型,支持无 GPU CPU 服务器、Mac mini Metal 与可选 CUDA;模型不随普通构建下载。部署、模型大小、鉴权和隐私边界见 [服务端语音识别](docs/server-speech.md)。设置内下载/初始化 LAYA 与语音模型,以及「石一」(决策专家)的本机性能检查和默认本地/免费调用链,见 [本地模型管理](docs/local-model-setup.md)。
|
|
275
288
|
|
|
276
289
|
### 可选本地决策(实验性)
|
|
277
290
|
|
|
@@ -322,7 +335,7 @@ npm run check # TypeScript 类型检查
|
|
|
322
335
|
npm run build # 编译 + 复制静态资源到 dist/
|
|
323
336
|
```
|
|
324
337
|
|
|
325
|
-
本机开发环境统一调用用户主目录入口:`~/start.sh` 构建/安装当前代码并重启,`~/start.sh --restart` 仅重启、不重新构建,`~/start.sh --status` 查状态。入口自动进入项目并在本地处理 sudo,外层不要再加 sudo;它是本机配置,不随新克隆提供,凭据不入仓库。重启安全约束仍以 [AGENTS.md](AGENTS.md)
|
|
338
|
+
本机开发环境统一调用用户主目录入口:`~/start.sh` 构建/安装当前代码并重启,`~/start.sh --restart` 仅重启、不重新构建,`~/start.sh --status` 查状态。入口自动进入项目并在本地处理 sudo,外层不要再加 sudo;它是本机配置,不随新克隆提供,凭据不入仓库。重启安全约束仍以 [AGENTS.md](AGENTS.md) 为准。构建/检查共用项目锁,本地部署与 npm 更新共用全局安装锁;锁忙时在包或服务修改前拒绝执行。本地 Beta 版本仅写入构建信息和私有打包快照,不改共享工作树的包版本文件。`build:body` / `check:body` 是加锁入口的内部步骤,不直接调用。
|
|
326
339
|
|
|
327
340
|
隔离测试环境(不影响生产实例):
|
|
328
341
|
|
|
@@ -31,7 +31,8 @@ export function requireTeamEmployee(source, id) {
|
|
|
31
31
|
}
|
|
32
32
|
// The default partner's read projection includes short-term habits; they are not team snapshot data.
|
|
33
33
|
return isDefaultSiliconEmployee(employee)
|
|
34
|
-
? defaultEmployeeDefinition(employee.agents, employee.updatedAt, source.getSiliconEmployeeDefinition?.(id) ?? employee, null)
|
|
34
|
+
? { ...defaultEmployeeDefinition(employee.agents, employee.updatedAt, source.getSiliconEmployeeDefinition?.(id) ?? employee, null),
|
|
35
|
+
avatar: employee.avatar }
|
|
35
36
|
: employee;
|
|
36
37
|
}
|
|
37
38
|
/** Resolve once per new run. Team duty/role/leadership remain local; no knowledge is read. */
|
package/dist/ai-team-runner.d.ts
CHANGED
|
@@ -178,6 +178,7 @@ export declare class AiTeamRunner {
|
|
|
178
178
|
private readonly noDegrade;
|
|
179
179
|
private readonly teamRequestIds;
|
|
180
180
|
private sweepTimer;
|
|
181
|
+
private disposed;
|
|
181
182
|
/** 脱敏参照目录只算一次:os.homedir() 读 env,configDir 随 storage 定,运行期不变。 */
|
|
182
183
|
private redactionDirsValue;
|
|
183
184
|
constructor(options: AiTeamRunnerOptions);
|
|
@@ -284,7 +285,7 @@ export declare class AiTeamRunner {
|
|
|
284
285
|
* 没变就什么都不发。巡检间隔与 evaluate 行为都不动。
|
|
285
286
|
*/
|
|
286
287
|
startSweep(): void;
|
|
287
|
-
dispose(): void
|
|
288
|
+
dispose(): Promise<void>;
|
|
288
289
|
/** 等当前排队的所有操作跑完(测试用)。 */
|
|
289
290
|
idle(): Promise<void>;
|
|
290
291
|
private enqueue;
|
package/dist/ai-team-runner.js
CHANGED
|
@@ -381,6 +381,7 @@ export class AiTeamRunner {
|
|
|
381
381
|
noDegrade = new Set();
|
|
382
382
|
teamRequestIds = new Map();
|
|
383
383
|
sweepTimer = null;
|
|
384
|
+
disposed = false;
|
|
384
385
|
/** 脱敏参照目录只算一次:os.homedir() 读 env,configDir 随 storage 定,运行期不变。 */
|
|
385
386
|
redactionDirsValue = null;
|
|
386
387
|
constructor(options) {
|
|
@@ -423,6 +424,8 @@ export class AiTeamRunner {
|
|
|
423
424
|
}
|
|
424
425
|
// ── 公开操作 ──
|
|
425
426
|
async start(input) {
|
|
427
|
+
if (this.disposed)
|
|
428
|
+
throw new AiTeamConflictError("AiTeamRunner has been disposed.");
|
|
426
429
|
const definition = input.team ?? this.storage.getAiTeam(input.teamId ?? "");
|
|
427
430
|
if (!definition)
|
|
428
431
|
throw new Error("团队不存在。");
|
|
@@ -791,6 +794,8 @@ export class AiTeamRunner {
|
|
|
791
794
|
}
|
|
792
795
|
/** 挂一次 run 级 live 去抖:同一 run 每 500ms 至多算一遍、推一次,与 evaluate 的计时器互不干扰。 */
|
|
793
796
|
scheduleLivePush(runId) {
|
|
797
|
+
if (this.disposed)
|
|
798
|
+
return;
|
|
794
799
|
if (!this.notifyLiveListener || this.liveTimers.has(runId))
|
|
795
800
|
return;
|
|
796
801
|
const timer = setTimeout(() => {
|
|
@@ -807,6 +812,8 @@ export class AiTeamRunner {
|
|
|
807
812
|
* 放行不松开去抖:推完照样记指纹并重排心跳,所以静默期最多每 heartbeatMs 一次,不是无界重推。
|
|
808
813
|
*/
|
|
809
814
|
pushLive(runId, heartbeat = false) {
|
|
815
|
+
if (this.disposed)
|
|
816
|
+
return;
|
|
810
817
|
if (!this.notifyLiveListener)
|
|
811
818
|
return;
|
|
812
819
|
const run = this.storage.getAiTeamRun(runId);
|
|
@@ -858,6 +865,8 @@ export class AiTeamRunner {
|
|
|
858
865
|
* 同一 run 至多一个计时器;run 不在 running、被删除或 dispose 时 cancel,不泄漏。
|
|
859
866
|
*/
|
|
860
867
|
scheduleHeartbeat(runId) {
|
|
868
|
+
if (this.disposed)
|
|
869
|
+
return;
|
|
861
870
|
if (this.heartbeatTimers.has(runId))
|
|
862
871
|
return;
|
|
863
872
|
if (!this.notifyLiveListener && !this.notifyListener)
|
|
@@ -921,6 +930,8 @@ export class AiTeamRunner {
|
|
|
921
930
|
// ── 事件驱动 ──
|
|
922
931
|
/** 与 missions.ingest 并列调用。绝大多数事件与团队无关,必须廉价返回。 */
|
|
923
932
|
ingest(event) {
|
|
933
|
+
if (this.disposed)
|
|
934
|
+
return;
|
|
924
935
|
if (!event.sessionId || event.sessionId === "__system__")
|
|
925
936
|
return;
|
|
926
937
|
if (event.type !== "status" && event.type !== "ended" && event.type !== "task" && event.type !== "output")
|
|
@@ -972,6 +983,8 @@ export class AiTeamRunner {
|
|
|
972
983
|
* 没变就什么都不发。巡检间隔与 evaluate 行为都不动。
|
|
973
984
|
*/
|
|
974
985
|
startSweep() {
|
|
986
|
+
if (this.disposed)
|
|
987
|
+
return;
|
|
975
988
|
if (this.sweepTimer)
|
|
976
989
|
return;
|
|
977
990
|
this.sweepTimer = setInterval(() => {
|
|
@@ -984,7 +997,8 @@ export class AiTeamRunner {
|
|
|
984
997
|
}, SWEEP_INTERVAL_MS);
|
|
985
998
|
this.sweepTimer.unref?.();
|
|
986
999
|
}
|
|
987
|
-
dispose() {
|
|
1000
|
+
async dispose() {
|
|
1001
|
+
this.disposed = true;
|
|
988
1002
|
if (this.sweepTimer)
|
|
989
1003
|
clearInterval(this.sweepTimer);
|
|
990
1004
|
this.sweepTimer = null;
|
|
@@ -1006,6 +1020,8 @@ export class AiTeamRunner {
|
|
|
1006
1020
|
this.lastLiveKey.clear();
|
|
1007
1021
|
this.noDegrade.clear();
|
|
1008
1022
|
this.teamRequestIds.clear();
|
|
1023
|
+
// Settle accepted host handshakes before the server closes storage.
|
|
1024
|
+
await this.idle();
|
|
1009
1025
|
}
|
|
1010
1026
|
/** 等当前排队的所有操作跑完(测试用)。 */
|
|
1011
1027
|
async idle() {
|
|
@@ -1016,7 +1032,11 @@ export class AiTeamRunner {
|
|
|
1016
1032
|
// ── 内部:串行化 ──
|
|
1017
1033
|
enqueue(runId, task) {
|
|
1018
1034
|
const previous = this.chains.get(runId) ?? Promise.resolve();
|
|
1019
|
-
const next = previous.catch(() => undefined).then(
|
|
1035
|
+
const next = previous.catch(() => undefined).then(() => {
|
|
1036
|
+
if (this.disposed)
|
|
1037
|
+
throw new AiTeamConflictError("AiTeamRunner has been disposed.");
|
|
1038
|
+
return task();
|
|
1039
|
+
});
|
|
1020
1040
|
const tracked = next.catch((error) => {
|
|
1021
1041
|
if (!(error instanceof AiTeamConflictError)) {
|
|
1022
1042
|
console.error(`[AiTeam] run ${runId}:`, getErrorMessage(error));
|
|
@@ -1044,6 +1064,8 @@ export class AiTeamRunner {
|
|
|
1044
1064
|
}
|
|
1045
1065
|
// ── 内部:推进 ──
|
|
1046
1066
|
async evaluate(runId) {
|
|
1067
|
+
if (this.disposed)
|
|
1068
|
+
return;
|
|
1047
1069
|
const run = this.storage.getAiTeamRun(runId);
|
|
1048
1070
|
if (!run || run.status !== "running")
|
|
1049
1071
|
return;
|
|
@@ -1066,6 +1088,8 @@ export class AiTeamRunner {
|
|
|
1066
1088
|
await this.advance(run);
|
|
1067
1089
|
}
|
|
1068
1090
|
scheduleRecheck(runId, delayMs) {
|
|
1091
|
+
if (this.disposed)
|
|
1092
|
+
return;
|
|
1069
1093
|
if (this.recheckTimers.has(runId))
|
|
1070
1094
|
return;
|
|
1071
1095
|
const timer = setTimeout(() => {
|
|
@@ -1250,6 +1274,8 @@ export class AiTeamRunner {
|
|
|
1250
1274
|
* 有成员失败、队列清空或依赖再也满足不了时,等在跑的都结束后交回 Leader。
|
|
1251
1275
|
*/
|
|
1252
1276
|
async advance(run) {
|
|
1277
|
+
if (this.disposed)
|
|
1278
|
+
return;
|
|
1253
1279
|
if (run.status !== "running")
|
|
1254
1280
|
return;
|
|
1255
1281
|
const steps = this.storage.listAiTeamSteps(run.id);
|
|
@@ -1294,6 +1320,8 @@ export class AiTeamRunner {
|
|
|
1294
1320
|
}
|
|
1295
1321
|
/** 开一轮 Leader:把上一轮 Leader 之后结束的成员报告交给他。 */
|
|
1296
1322
|
async startLeaderRound(run, userNote) {
|
|
1323
|
+
if (this.disposed)
|
|
1324
|
+
return;
|
|
1297
1325
|
if (!this.hasBudget(run))
|
|
1298
1326
|
return;
|
|
1299
1327
|
// 成员干活时用户在群里说的话,这一轮一起交给负责人。
|
|
@@ -1482,6 +1510,8 @@ export class AiTeamRunner {
|
|
|
1482
1510
|
* 提示词分两段:`system`(角色与规则)只在新建会话时交给系统提示通道,`message` 是本轮用户消息。
|
|
1483
1511
|
*/
|
|
1484
1512
|
async dispatchStep(run, step, buildPrompt, proceed = true) {
|
|
1513
|
+
if (this.disposed)
|
|
1514
|
+
return;
|
|
1485
1515
|
const member = this.member(run.team, step.memberId);
|
|
1486
1516
|
const candidates = member ? memberAgents(member) : [];
|
|
1487
1517
|
const info = this.infoOf(step);
|
|
@@ -1550,6 +1580,8 @@ export class AiTeamRunner {
|
|
|
1550
1580
|
}
|
|
1551
1581
|
}
|
|
1552
1582
|
catch (error) {
|
|
1583
|
+
if (this.disposed)
|
|
1584
|
+
return;
|
|
1553
1585
|
const message = getErrorMessage(error);
|
|
1554
1586
|
const rejected = error instanceof AgentDispatchPreflightError && error.failure.retryable;
|
|
1555
1587
|
const kind = rejected ? "input-rejected" : classifyCandidateFailure(message);
|
|
@@ -1939,6 +1971,8 @@ export class AiTeamRunner {
|
|
|
1939
1971
|
}
|
|
1940
1972
|
}
|
|
1941
1973
|
postTurn(run, turn) {
|
|
1974
|
+
if (this.disposed)
|
|
1975
|
+
return;
|
|
1942
1976
|
if (!this.chat || !run.chatSessionId)
|
|
1943
1977
|
return;
|
|
1944
1978
|
try {
|
|
@@ -2046,6 +2080,8 @@ export class AiTeamRunner {
|
|
|
2046
2080
|
this.storage.saveAiTeamStep(step);
|
|
2047
2081
|
}
|
|
2048
2082
|
notify(run) {
|
|
2083
|
+
if (this.disposed)
|
|
2084
|
+
return;
|
|
2049
2085
|
// 记下 run 通道的活动基线并排上静默心跳:长任务只等一次状态写入是不够的,
|
|
2050
2086
|
// 用户在十几分钟没有新消息时需要「仍在运行」的证据,见 beat()。
|
|
2051
2087
|
this.lastRunNotifyAt.set(run.id, this.now());
|
package/dist/ai-team-types.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DECISION_EXPERT_KEY } from "./decision-expert-identity.js";
|
|
2
2
|
import { SPEECH_POLISHER_KEY } from "./speech-polisher-identity.js";
|
|
3
|
+
import { HR_EMPLOYEE_KEY } from "./hr-employee-identity.js";
|
|
3
4
|
export const AI_TEAM_MIN_MEMBERS = 2;
|
|
4
5
|
export const AI_TEAM_MAX_MEMBERS = 8;
|
|
5
6
|
export const AI_TEAM_DEFAULT_MAX_STEPS = 30;
|
|
@@ -53,13 +54,13 @@ export function isDecisionExpertSiliconEmployee(employee) {
|
|
|
53
54
|
return employee?.systemKey === DECISION_EXPERT_KEY;
|
|
54
55
|
}
|
|
55
56
|
export function isBuiltinSiliconEmployee(employee) {
|
|
56
|
-
return isSystemSiliconEmployee(employee) || isDefaultSiliconEmployee(employee) || isDecisionExpertSiliconEmployee(employee) || employee?.systemKey === SPEECH_POLISHER_KEY;
|
|
57
|
+
return isSystemSiliconEmployee(employee) || isDefaultSiliconEmployee(employee) || isDecisionExpertSiliconEmployee(employee) || employee?.systemKey === SPEECH_POLISHER_KEY || employee?.systemKey === HR_EMPLOYEE_KEY;
|
|
57
58
|
}
|
|
58
59
|
export const SILICON_EMPLOYEE_MAX_TAGS = 8;
|
|
59
60
|
export const SILICON_EMPLOYEE_TAG_MAX_CHARS = 20;
|
|
60
61
|
/** 内置标识只由真实员工身份投影,不能用自定义标签冒充。 */
|
|
61
62
|
export function siliconEmployeeTags(employee) {
|
|
62
|
-
if (isSystemSiliconEmployee(employee) || isDecisionExpertSiliconEmployee(employee) || employee.systemKey === SPEECH_POLISHER_KEY)
|
|
63
|
+
if (isSystemSiliconEmployee(employee) || isDecisionExpertSiliconEmployee(employee) || employee.systemKey === SPEECH_POLISHER_KEY || employee.systemKey === HR_EMPLOYEE_KEY)
|
|
63
64
|
return [SYSTEM_EMPLOYEE_TAG];
|
|
64
65
|
if (isDefaultSiliconEmployee(employee))
|
|
65
66
|
return [DEFAULT_EMPLOYEE_TAG];
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type EmployeeTextDeps } from "./employee-text.js";
|
|
2
|
+
import type { AiTextRequest, SessionProvider, SessionSnapshot } from "./types.js";
|
|
3
|
+
export { QuickCommitError } from "./command-error.js";
|
|
4
|
+
/** Neutral one-shot text execution. Tool-running Git fallback never uses the retry chain. */
|
|
5
|
+
export declare function defaultProvider(provider: SessionProvider | undefined): SessionProvider;
|
|
6
|
+
export interface QuickCommitAiOptions {
|
|
7
|
+
modelGroups?: import("./model-groups.js").ModelGroup[];
|
|
8
|
+
provider?: SessionProvider;
|
|
9
|
+
model?: string | null;
|
|
10
|
+
thinkingEffort?: SessionSnapshot["thinkingEffort"];
|
|
11
|
+
inheritEnv?: boolean;
|
|
12
|
+
/** 内置「系统运维」员工的角色设定:作为系统提示前缀注入。 */
|
|
13
|
+
opsPersona?: string;
|
|
14
|
+
/** 员工候选链(按顺序);未设置时只用 provider/model 这一次调用。 */
|
|
15
|
+
cliCandidates?: import("./types.js").AiCliCandidate[];
|
|
16
|
+
/** SDK 使用当前实例配置与现有免费分组服务,不创建其他执行渠道。 */
|
|
17
|
+
employeeText?: EmployeeTextDeps;
|
|
18
|
+
/** 系统应用必须经员工渠道;没有可用候选时直接失败,不退回默认 provider。 */
|
|
19
|
+
employeeChannelOnly?: boolean;
|
|
20
|
+
/** 整条候选链的时间上限;默认 CLI_CHAIN_BUDGET_MS。第一条消息里的调用要短得多。 */
|
|
21
|
+
budgetMs?: number;
|
|
22
|
+
signal?: AbortSignal;
|
|
23
|
+
}
|
|
24
|
+
type CliAiTextOptions = QuickCommitAiOptions & {
|
|
25
|
+
deadline?: number;
|
|
26
|
+
};
|
|
27
|
+
export declare function normalizeAiText(raw: string): string;
|
|
28
|
+
export declare function buildPiTextArgs(request: AiTextRequest, opts: QuickCommitAiOptions, allowTools?: boolean): string[];
|
|
29
|
+
export declare function buildGrokTextArgs(request: AiTextRequest, opts: QuickCommitAiOptions, allowTools?: boolean): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Gemini CLI 没有 `--append-system-prompt`,规则走 `contentWithSystemPrompt` 并进内容;
|
|
32
|
+
* headless 下必须带 `--skip-trust`,否则未信任的工作目录会直接以 55 退出。
|
|
33
|
+
*
|
|
34
|
+
* `-p ""` 只把 CLI 钉在 headless 模式,真正的 prompt 走 stdin:commit diff 可能很大,
|
|
35
|
+
* 塞进 argv 会撞 ARG_MAX。Gemini 没有 Codex `--ephemeral` 那样的临时会话开关,
|
|
36
|
+
* 一次性调用会留在它自己的聊天记录里(Wand 不扫描 Gemini 历史,不会误当可恢复会话)。
|
|
37
|
+
*/
|
|
38
|
+
export declare function buildGeminiTextArgs(opts: QuickCommitAiOptions, allowTools?: boolean): string[];
|
|
39
|
+
export declare function buildQoderTextArgs(request: AiTextRequest, opts: QuickCommitAiOptions, allowTools?: boolean): string[];
|
|
40
|
+
/** provider 自己的系统提示开关 + 规则文本;没有开关的 provider 返回空。 */
|
|
41
|
+
export declare function systemPromptArgsFrom(provider: SessionProvider, system: string): string[];
|
|
42
|
+
/** 没有系统提示开关的 provider(codex / opencode):规则只能并进内容前面。 */
|
|
43
|
+
export declare function contentWithSystemPrompt(provider: SessionProvider, request: AiTextRequest): string;
|
|
44
|
+
export declare function runCliText(command: string, args: string[], prompt: string, opts: {
|
|
45
|
+
cwd: string;
|
|
46
|
+
timeoutMs: number;
|
|
47
|
+
inheritEnv?: boolean;
|
|
48
|
+
signal?: AbortSignal;
|
|
49
|
+
env?: (base: NodeJS.ProcessEnv) => NodeJS.ProcessEnv;
|
|
50
|
+
}): Promise<string>;
|
|
51
|
+
export declare function assertGeminiTextCapability(): void;
|
|
52
|
+
export declare function callCliAiText(request: AiTextRequest, cwd: string, language: string, opts: CliAiTextOptions): Promise<string>;
|
|
53
|
+
/** 角色设定走系统提示前缀;任务自己的输出格式与约束必须排在后面。 */
|
|
54
|
+
export declare function withOpsPersona(request: AiTextRequest, persona?: string): AiTextRequest;
|
|
55
|
+
/**
|
|
56
|
+
* Run a lightweight AI request through the system employee's configured chain.
|
|
57
|
+
* provider 与引擎由候选决定;SDK 与 CLI 均保留各自适配和身份。
|
|
58
|
+
* parseOutput 在候选链内解析/校验结果;失败后继续下一条,而非提前宣布成功。
|
|
59
|
+
*/
|
|
60
|
+
export declare function callConfiguredAiText(request: AiTextRequest, cwd: string, language: string, opts: QuickCommitAiOptions): Promise<string>;
|
|
61
|
+
export declare function callConfiguredAiText<T>(request: AiTextRequest, cwd: string, language: string, opts: QuickCommitAiOptions, parseOutput: (raw: string) => T): Promise<T>;
|