@co0ontty/wand 4.89.5 → 4.90.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.
- package/README.md +5 -3
- package/dist/agent-dispatch.js +4 -9
- package/dist/ai-team-employee-binding.js +10 -9
- 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/avatar-input.d.ts +2 -0
- package/dist/avatar-input.js +19 -0
- package/dist/bounded-process-output.d.ts +5 -0
- package/dist/bounded-process-output.js +9 -0
- package/dist/build-info.json +3 -3
- 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 +12 -2
- package/dist/conversation-service.js +104 -25
- 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 +7 -0
- package/dist/fixed-employee-avatar.js +13 -0
- package/dist/git-quick-commit.d.ts +5 -40
- package/dist/git-quick-commit.js +8 -636
- 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 +5 -44
- package/dist/pi-auto-resources.js +6 -3
- package/dist/plush-avatar.d.ts +10 -1
- package/dist/plush-avatar.js +13 -1
- 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/scheduled-task-service.d.ts +41 -0
- package/dist/scheduled-task-service.js +294 -0
- package/dist/scheduled-task-state.d.ts +11 -0
- package/dist/scheduled-task-state.js +65 -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-ai-team-routes.js +3 -17
- package/dist/server-employee-routes.d.ts +3 -0
- package/dist/server-employee-routes.js +20 -38
- package/dist/server-file-routes.js +44 -1
- package/dist/server-pi-recommendation-routes.js +13 -4
- package/dist/server-request.d.ts +2 -0
- package/dist/server-request.js +9 -0
- 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 +5 -13
- package/dist/server-session-routes.js +35 -70
- package/dist/server-task-routes.d.ts +6 -21
- package/dist/server-task-routes.js +25 -120
- package/dist/server-team-dispatch-routes.js +12 -2
- package/dist/server-workspace-routes.d.ts +1 -1
- package/dist/server-workspace-routes.js +33 -78
- package/dist/server.js +55 -20
- package/dist/session-model.d.ts +15 -0
- package/dist/session-model.js +23 -0
- package/dist/session-registry.d.ts +5 -1
- package/dist/session-registry.js +20 -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/session-transport.d.ts +3 -1
- package/dist/session-transport.js +11 -5
- 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 +42 -8
- package/dist/storage.js +182 -715
- package/dist/structured-claude-adapter.js +12 -0
- package/dist/structured-claude-protocol.d.ts +4 -0
- package/dist/structured-claude-protocol.js +18 -4
- package/dist/structured-codex-adapter.js +11 -0
- package/dist/structured-exec-pump.js +79 -38
- package/dist/structured-failure.d.ts +21 -0
- package/dist/structured-failure.js +14 -0
- package/dist/structured-gemini-adapter.js +12 -2
- package/dist/structured-grok-adapter.js +12 -2
- package/dist/structured-opencode-adapter.js +8 -1
- package/dist/structured-qoder-adapter.js +14 -0
- package/dist/structured-session-manager.d.ts +13 -18
- package/dist/structured-session-manager.js +147 -517
- package/dist/system-employee.d.ts +1 -1
- package/dist/system-employee.js +1 -1
- package/dist/task-archive-policy.js +1 -1
- 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/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/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/5478be410b112154/chat-render-PY6DIXNZ.js +24 -0
- package/dist/web-ui/content/modules/5478be410b112154/chunk-2YZLCGYN.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/chunk-6CFHW3FA.js +111 -0
- package/dist/web-ui/content/modules/5478be410b112154/chunk-6XQEBIEX.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/chunk-DDSO7OX7.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/chunk-G3CXNMA2.js +20 -0
- package/dist/web-ui/content/modules/5478be410b112154/chunk-LGVAPHRS.js +36 -0
- package/dist/web-ui/content/modules/5478be410b112154/chunk-NURCNMRU.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/chunk-PCMFGZKX.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/chunk-QRNA4D7E.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/chunk-TMRPHNJO.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/chunk-WC7RK7LP.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/chunk-YOXXNXOX.js +2 -0
- package/dist/web-ui/content/modules/5478be410b112154/chunk-YX475LXO.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/employee-card-MDWKU4V3.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/host-56WPSON2.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/host-5QOHKHNC.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/host-AWIJ5L2K.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/host-BOZLGIT5.js +69 -0
- package/dist/web-ui/content/modules/5478be410b112154/host-EZV22Q7Y.js +4 -0
- package/dist/web-ui/content/modules/5478be410b112154/host-IW43Z5ZF.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/host-JT7NIUQL.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/host-JWEIDB55.js +3 -0
- package/dist/web-ui/content/modules/5478be410b112154/host-OU5TRYH6.js +2 -0
- package/dist/web-ui/content/modules/5478be410b112154/host-PRSTCPVE.js +5 -0
- package/dist/web-ui/content/modules/5478be410b112154/host-TWPJI3HE.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/host-WZGJSNML.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/host-X6KQVFD6.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/host-YKCQFMQR.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/host-bridge-2LZX6UUZ.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/library-bridge-MQFJGTGY.js +4 -0
- package/dist/web-ui/content/modules/5478be410b112154/page-T3VUCU2W.js +3 -0
- package/dist/web-ui/content/modules/5478be410b112154/panel-HJBGBBPY.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/runtime.js +920 -0
- package/dist/web-ui/content/modules/5478be410b112154/sha256-ANXV72UC.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/task-board-host-AVMDIHIV.js +2 -0
- package/dist/web-ui/content/modules/5478be410b112154/workspace-agent-picker-KI7QVSK3.js +1 -0
- package/dist/web-ui/content/modules/5478be410b112154/workspace-window-L542FGP2.js +1 -0
- package/dist/web-ui/content/plush-avatar.js +177 -177
- package/dist/web-ui/content/scripts.js +1 -994
- 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 -48
- 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/provider-identity.d.ts +1 -1
- package/dist/web-ui/provider-identity.js +3 -4
- 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/web-ui/content/licenses/codex-LICENSE.txt +0 -21
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
|
|
|
@@ -239,6 +240,7 @@ npm install -g @google/gemini-cli@latest
|
|
|
239
240
|
- **文件浏览器** — 内置路径浏览和搜索功能
|
|
240
241
|
- **本地预览** — 消息和终端里的本机链接可点击预览;顶栏也可手动打开本机 HTTP 端口或 HTML 目录
|
|
241
242
|
- **快捷提交** — Git 变动快速提交入口,一键生成 commit message
|
|
243
|
+
- **定时任务** — 选择员工、工作区目录和提示词,单次或每天/每周自动执行,并查看执行记录;详见 [使用说明](docs/scheduled-tasks.md)。
|
|
242
244
|
|
|
243
245
|
#### 部署与访问
|
|
244
246
|
|
|
@@ -282,7 +284,7 @@ wand config:set port 9443
|
|
|
282
284
|
|
|
283
285
|
### 语音识别
|
|
284
286
|
|
|
285
|
-
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)。
|
|
286
288
|
|
|
287
289
|
### 可选本地决策(实验性)
|
|
288
290
|
|
|
@@ -333,7 +335,7 @@ npm run check # TypeScript 类型检查
|
|
|
333
335
|
npm run build # 编译 + 复制静态资源到 dist/
|
|
334
336
|
```
|
|
335
337
|
|
|
336
|
-
本机开发环境统一调用用户主目录入口:`~/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` 是加锁入口的内部步骤,不直接调用。
|
|
337
339
|
|
|
338
340
|
隔离测试环境(不影响生产实例):
|
|
339
341
|
|
package/dist/agent-dispatch.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { getDefaultModelForProvider } from "./config.js";
|
|
2
1
|
import { isLocalDecisionModel } from "./decision-expert-identity.js";
|
|
3
|
-
import {
|
|
2
|
+
import { fallbackProviderModel, sessionEmployeeFields } from "./session-model.js";
|
|
4
3
|
import { defaultRoleForCli } from "./default-employee.js";
|
|
5
4
|
import { providerCliCommand } from "./session-provider.js";
|
|
6
5
|
import { agentKey } from "./ai-team-types.js";
|
|
@@ -46,7 +45,7 @@ export async function dispatchAgentForTask(deps, input) {
|
|
|
46
45
|
const cwd = group.cwd;
|
|
47
46
|
const provider = agent.provider;
|
|
48
47
|
const model = agent.model === "default" ? "" : agent.model;
|
|
49
|
-
const resolvedModel = model ||
|
|
48
|
+
const resolvedModel = model || fallbackProviderModel(config, provider);
|
|
50
49
|
if (isLocalDecisionModel(resolvedModel)) {
|
|
51
50
|
throw new AgentDispatchPreflightError("LAYA 仅支持有界决策,不能执行聊天或任务;该候选尚未接受输入。");
|
|
52
51
|
}
|
|
@@ -58,9 +57,7 @@ export async function dispatchAgentForTask(deps, input) {
|
|
|
58
57
|
sessionSource: "automation",
|
|
59
58
|
automationId: input.automationId,
|
|
60
59
|
systemPrompt,
|
|
61
|
-
|
|
62
|
-
employeeName: role?.name,
|
|
63
|
-
employeeAvatar: role?.avatar,
|
|
60
|
+
...sessionEmployeeFields(role),
|
|
64
61
|
workspaceId: group.workspaceId,
|
|
65
62
|
workspaceTaskId: group.workspaceTaskId,
|
|
66
63
|
})
|
|
@@ -79,9 +76,7 @@ export async function dispatchAgentForTask(deps, input) {
|
|
|
79
76
|
sessionSource: "automation",
|
|
80
77
|
automationId: input.automationId,
|
|
81
78
|
systemPrompt,
|
|
82
|
-
|
|
83
|
-
employeeName: role?.name,
|
|
84
|
-
employeeAvatar: role?.avatar,
|
|
79
|
+
...sessionEmployeeFields(role),
|
|
85
80
|
employeeCandidates: input.employee?.agents,
|
|
86
81
|
employeeCandidateIndex: input.employeeCandidateIndex,
|
|
87
82
|
workspaceId: group.workspaceId,
|
|
@@ -61,18 +61,19 @@ export function serializeExecutionTeam(team) {
|
|
|
61
61
|
...member, _employeeSnapshot: snapshots.get(member),
|
|
62
62
|
})) });
|
|
63
63
|
}
|
|
64
|
+
function projectBoundMember(member, source, includeAgents) {
|
|
65
|
+
const employee = member.employeeId ? source.getSiliconEmployee(member.employeeId) : null;
|
|
66
|
+
if (!employee)
|
|
67
|
+
return member;
|
|
68
|
+
return includeAgents
|
|
69
|
+
? { ...member, name: employee.name, avatar: employee.avatar, agents: employee.agents, agent: employee.agents[0] }
|
|
70
|
+
: { ...member, name: employee.name, avatar: employee.avatar };
|
|
71
|
+
}
|
|
64
72
|
/** Team definitions expose current employee-owned fields without storing another copy of the role. */
|
|
65
73
|
export function projectTeamDefinition(team, source) {
|
|
66
|
-
return { ...team, members: team.members.map((member) =>
|
|
67
|
-
const employee = member.employeeId ? source.getSiliconEmployee(member.employeeId) : null;
|
|
68
|
-
return employee ? { ...member, name: employee.name, avatar: employee.avatar,
|
|
69
|
-
agents: employee.agents, agent: employee.agents[0] } : member;
|
|
70
|
-
}) };
|
|
74
|
+
return { ...team, members: team.members.map((member) => projectBoundMember(member, source, true)) };
|
|
71
75
|
}
|
|
72
76
|
/** Read-only names/avatars follow the same employee, never a replacement at the same member id. */
|
|
73
77
|
export function projectTeamEmployees(team, source) {
|
|
74
|
-
return { ...team, members: team.members.map((member) =>
|
|
75
|
-
const employee = member.employeeId ? source.getSiliconEmployee(member.employeeId) : null;
|
|
76
|
-
return employee ? { ...member, name: employee.name, avatar: employee.avatar } : member;
|
|
77
|
-
}) };
|
|
78
|
+
return { ...team, members: team.members.map((member) => projectBoundMember(member, source, false)) };
|
|
78
79
|
}
|
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>;
|