@co0ontty/wand 4.77.0 → 4.78.0-beta.ga1e4f59

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 (54) hide show
  1. package/README.md +21 -46
  2. package/dist/agent-dispatch.js +3 -2
  3. package/dist/ai-team-live.d.ts +25 -0
  4. package/dist/ai-team-live.js +135 -0
  5. package/dist/ai-team-prompts.d.ts +10 -6
  6. package/dist/ai-team-prompts.js +74 -41
  7. package/dist/ai-team-runner.d.ts +85 -3
  8. package/dist/ai-team-runner.js +336 -33
  9. package/dist/ai-team-types.d.ts +57 -2
  10. package/dist/ai-team-types.js +4 -0
  11. package/dist/build-info.json +4 -4
  12. package/dist/commit-task-archive.js +14 -18
  13. package/dist/config.js +14 -6
  14. package/dist/git-quick-commit.js +1 -1
  15. package/dist/middleware/rate-limit.d.ts +18 -4
  16. package/dist/middleware/rate-limit.js +55 -23
  17. package/dist/missions.js +0 -3
  18. package/dist/models.d.ts +6 -1
  19. package/dist/models.js +35 -0
  20. package/dist/path-repair.d.ts +6 -5
  21. package/dist/path-repair.js +3 -3
  22. package/dist/render-protocol.d.ts +1 -1
  23. package/dist/render-protocol.js +1 -1
  24. package/dist/server-ai-team-routes.d.ts +1 -0
  25. package/dist/server-ai-team-routes.js +28 -14
  26. package/dist/server-local-preview-routes.js +1 -1
  27. package/dist/server-session-routes.js +0 -3
  28. package/dist/server-settings-routes.d.ts +1 -1
  29. package/dist/server-settings-routes.js +3 -2
  30. package/dist/server-task-routes.js +16 -32
  31. package/dist/server-workspace-routes.js +31 -24
  32. package/dist/server.js +60 -21
  33. package/dist/storage.d.ts +54 -21
  34. package/dist/storage.js +485 -122
  35. package/dist/types.d.ts +7 -0
  36. package/dist/upload-routes.d.ts +2 -2
  37. package/dist/upload-routes.js +10 -3
  38. package/dist/wand-task-sync.d.ts +2 -34
  39. package/dist/wand-task-sync.js +0 -206
  40. package/dist/web-ui/asset-version.d.ts +5 -0
  41. package/dist/web-ui/asset-version.js +5 -0
  42. package/dist/web-ui/content/ai-teams.js +17 -8
  43. package/dist/web-ui/content/scripts.js +67 -66
  44. package/dist/web-ui/content/styles.css +1 -1
  45. package/dist/web-ui/content/tailwind.css +0 -21
  46. package/dist/web-ui/embedded-assets.js +8 -7
  47. package/dist/web-ui/index.js +9 -17
  48. package/dist/web-ui/scripts.d.ts +3 -1
  49. package/dist/web-ui/scripts.js +52 -25
  50. package/dist/web-ui/styles.d.ts +2 -0
  51. package/dist/web-ui/styles.js +12 -0
  52. package/package.json +13 -12
  53. package/scripts/install-render-binary.js +2 -2
  54. package/scripts/stage-render-binaries.js +1 -1
@@ -1,6 +1,6 @@
1
1
  import { type AgentDispatchDeps } from "./agent-dispatch.js";
2
2
  import { type ModelCatalogView } from "./ai-team-availability.js";
3
- import { type AiTeamRun, type AiTeamRunDetail, type AiTeamRunSummary } from "./ai-team-types.js";
3
+ import { type AiTeam, type AiTeamLiveStep, type AiTeamLiveUpdate, type AiTeamRun, type AiTeamRunDetail, type AiTeamRunSummary, type AiTeamStep } from "./ai-team-types.js";
4
4
  import type { SessionRegistry } from "./session-registry.js";
5
5
  import type { WandStorage } from "./storage.js";
6
6
  import type { WandTask, WandTaskAgent } from "./task-types.js";
@@ -41,12 +41,19 @@ export interface AiTeamRunnerOptions {
41
41
  resolveCwd: (task: WandTask) => string;
42
42
  ops: AiTeamSessionOps;
43
43
  notify?: (run: AiTeamRun) => void;
44
+ /** 运行中步骤的 live 文本推送(§4.9):去抖后每 500ms 至多一次,stepId+text+omittedChars+state 全同不重复推。 */
45
+ notifyLive?: (update: AiTeamLiveUpdate) => void;
44
46
  now?: () => number;
45
47
  /**
46
48
  * 某 provider 已发现的模型清单(§3.4 model-unknown 事前比对)。目录未就绪 / 清单为空时
47
49
  * 返回空值即可,判定方向是「拿不准就放行」。
48
50
  */
49
51
  models?: (provider: WandTaskAgent["provider"]) => ModelCatalogView;
52
+ /**
53
+ * 该 provider 服务端配置的默认模型(拿不到返回空串)。只用于提示词里的成员名单:
54
+ * `default` 哨兵不是模型名,写真正会用的那个。
55
+ */
56
+ defaultModelOf?: (provider: WandTaskAgent["provider"]) => string;
50
57
  }
51
58
  export declare function createAiTeamSessionOps(deps: AgentDispatchDeps & {
52
59
  sessions: SessionRegistry;
@@ -55,8 +62,16 @@ export declare function createAiTeamChatOps(deps: AgentDispatchDeps): AiTeamChat
55
62
  export declare function createAiTeamRunner(deps: AgentDispatchDeps & {
56
63
  sessions: SessionRegistry;
57
64
  notify?: (run: AiTeamRun) => void;
65
+ notifyLive?: (update: AiTeamLiveUpdate) => void;
58
66
  models?: (provider: WandTaskAgent["provider"]) => ModelCatalogView;
67
+ defaultModelOf?: (provider: WandTaskAgent["provider"]) => string;
59
68
  }): AiTeamRunner;
69
+ /**
70
+ * 群聊里的发言人。上传的头像是 data URL,每条消息都带一份太重,改用按 id 取的像素猫。
71
+ * `agent` 传该步**实际使用候选**(§3.6/B15,降级换候选后跟着变),model / thinkingEffort 与
72
+ * provider 同源;Leader 或没有步骤的场景回退首选候选。只填真值,展示文案归客户端。
73
+ */
74
+ export declare function displayAiTeam(snapshot: AiTeam, current: AiTeam | null): AiTeam;
60
75
  /** 遮蔽参照目录:家目录与激活配置目录(含 `/tmp/wand-dev` 这类隔离路径,按传入处理)。 */
61
76
  export interface RedactionDirs {
62
77
  homeDir?: string;
@@ -69,6 +84,35 @@ export interface RedactionDirs {
69
84
  * 方向是宁多勿漏:认不准的超长串一律隐藏,代价只是文案少一段可调试信息。
70
85
  */
71
86
  export declare function redactAiTeamErrorText(text: string, dirs?: RedactionDirs): string;
87
+ /** 每行邀请名单上限(S2/S3):`邀请 @a、@b、@c、@d 加入群聊`。 */
88
+ export declare const CHAT_INVITE_PER_LINE = 4;
89
+ /**
90
+ * 首次建群的入群序列(S1–S3):负责人先入群,再按 `team.members` 原顺序邀请其余成员。
91
+ * 每行最多 [CHAT_INVITE_PER_LINE] 人,第二行起用 `继续邀请 …`;除负责人外没人时给
92
+ * `还没有邀请其他成员入群`(仍两条,不伪造成员)。
93
+ */
94
+ export declare function chatIntroLines(team: Pick<AiTeam, "name" | "members">): string[];
95
+ /** 开工发言里的一条依据(来自 `step.dependsOn` 解析出的上游步骤)。 */
96
+ export interface AiTeamStepBasis {
97
+ seq: number;
98
+ title: string;
99
+ memberName: string;
100
+ reportPath: string;
101
+ }
102
+ /**
103
+ * 开工发言正文(S4):
104
+ * - 第 1 行 `我正在开始工作:第 N 步「标题」`;
105
+ * - 有依赖时第 2 行 `依据 @上游成员 第 M 步「上游标题」的产物 <reportPath>`,超过两条
106
+ * 只列前两条并在尾上 `等 N 步`(N = 依赖总数);
107
+ * - 依赖解析不到(旧数据/步骤被删)→ `依据上游步骤的产物继续`。
108
+ */
109
+ export declare function stepStartText(step: Pick<AiTeamStep, "seq" | "title">, upstream?: ReadonlyArray<AiTeamStepBasis>, dependencyCount?: number): string;
110
+ /**
111
+ * 派工行的依据括注(S5):`(依据:第 1 步「设计规格」的产物)`,多个依赖用 `、` 连接。
112
+ * 位置 `at` 是**本批 steps 内**的 0-based 下标(展示成第 at+1 步);没有依赖就是空串(首步无依据)。
113
+ * 它**取代**旧的 `(等第 N 项完成后)`:同一个依赖关系不写两遍。
114
+ */
115
+ export declare function assignmentBasisNote(after: readonly number[], titles: readonly string[]): string;
72
116
  /**
73
117
  * AI 团队调度器。状态全部在数据库里,会话事件驱动推进;同一运行的所有操作串行执行。
74
118
  * 成员会话是普通 Wand 会话,服务端只负责传话:Leader 决定派谁做什么,成员交报告。
@@ -79,10 +123,16 @@ export declare class AiTeamRunner {
79
123
  private readonly chat?;
80
124
  private readonly resolveCwd;
81
125
  private readonly notifyListener?;
126
+ private readonly notifyLiveListener?;
82
127
  private readonly modelsOf?;
128
+ private readonly defaultModelOf?;
83
129
  private readonly now;
84
130
  private readonly chains;
85
131
  private readonly outputTimers;
132
+ /** live 推送的去抖计时器,按 runId 计(§4.9)。 */
133
+ private readonly liveTimers;
134
+ /** 上次推出去的 live 列表指纹(§4.9):stepId + text + omittedChars + state 全同就不重复推。 */
135
+ private readonly lastLiveKey;
86
136
  private readonly recheckTimers;
87
137
  /** 已经确定「不降级、按既有路径记 failed」的步骤,防止 finishStep 再判一次形成回环。 */
88
138
  private readonly noDegrade;
@@ -90,6 +140,8 @@ export declare class AiTeamRunner {
90
140
  /** 脱敏参照目录只算一次:os.homedir() 读 env,configDir 随 storage 定,运行期不变。 */
91
141
  private redactionDirsValue;
92
142
  constructor(options: AiTeamRunnerOptions);
143
+ /** 提示词里的模型名解析器:`default` 哨兵交给服务端配置的默认模型。 */
144
+ private readonly defaultModelName;
93
145
  /** 本 runner 的遮蔽参照目录(§4.5)。 */
94
146
  private get redactionDirs();
95
147
  /** 只脱敏、不改长度语义(用于本来就不截断的文案)。 */
@@ -112,6 +164,8 @@ export declare class AiTeamRunner {
112
164
  echo?: boolean;
113
165
  }): Promise<AiTeamRunDetail>;
114
166
  continueRun(runId: string, extraSteps: number): Promise<AiTeamRunDetail>;
167
+ /** 已有运行的上限独立持久化;修改团队定义后,下次续跑至少采用新的团队上限。 */
168
+ private extendStepLimit;
115
169
  completeStep(runId: string, stepId: string, report: string): Promise<AiTeamRunDetail>;
116
170
  stop(runId: string): Promise<AiTeamRunDetail>;
117
171
  /**
@@ -121,6 +175,17 @@ export declare class AiTeamRunner {
121
175
  chatInput(sessionId: string, text: string): Promise<void>;
122
176
  detail(runId: string): AiTeamRunDetail;
123
177
  listForTask(taskId: string): AiTeamRun[];
178
+ /**
179
+ * 此刻正在干活的步骤的实时文本(§4.9)。只覆盖 running 且有会话的步骤,按 seq 升序;
180
+ * 快照拿不到的步骤跳过而不抛。run 不存在时与 detail() 同口径抛错。
181
+ */
182
+ live(runId: string): AiTeamLiveStep[];
183
+ private liveSteps;
184
+ private liveStep;
185
+ /** 挂一次 run 级 live 去抖:同一 run 每 500ms 至多算一遍、推一次,与 evaluate 的计时器互不干扰。 */
186
+ private scheduleLivePush;
187
+ /** 推一次 live 列表(§4.9);指纹(stepId + text + omittedChars + state)没变就不重复推,推送失败只忽略。 */
188
+ private pushLive;
124
189
  /** 团队页的运行记录;teamId 为空时列出所有团队(侧边栏计数用)。 */
125
190
  listRuns(filter: {
126
191
  teamId?: string;
@@ -131,7 +196,12 @@ export declare class AiTeamRunner {
131
196
  ingest(event: ProcessEvent): void;
132
197
  /** 服务启动时调用:把重启前未结束的运行接回来,并开始兜底巡检。 */
133
198
  reconcile(): void;
134
- /** 兜底巡检:PTY 成员写完报告后可能不再产生事件。 */
199
+ /**
200
+ * 兜底巡检:PTY 成员写完报告后可能不再产生事件。
201
+ * 顺带对每个 run 强制对账一次 live(§4.9):registry 内部状态静默翻转时一条事件都不会进来,
202
+ * 状态芯片只能等客户端下一次重拉;这里在同一串里重算列表走 pushLive,指纹变了才推,
203
+ * 没变就什么都不发。巡检间隔与 evaluate 行为都不动。
204
+ */
135
205
  startSweep(): void;
136
206
  dispose(): void;
137
207
  /** 等当前排队的所有操作跑完(测试用)。 */
@@ -142,8 +212,10 @@ export declare class AiTeamRunner {
142
212
  private evaluate;
143
213
  private scheduleRecheck;
144
214
  private stepOutcome;
145
- /** proceed=false 时只记结果不推进,由调用方在记完一批之后统一 advance。 */
215
+ /** 步骤落地后补推一次 live(§4.9):让卡片收尾,列表可能已空。内部抛错时不推。 */
146
216
  private finishStep;
217
+ /** proceed=false 时只记结果不推进,由调用方在记完一批之后统一 advance。 */
218
+ private finishStepCore;
147
219
  /**
148
220
  * 派出所有已就绪的成员步骤:依赖都已完成、且该成员手上没有活。不同成员并行,同一成员串行。
149
221
  * 有成员失败、队列清空或依赖再也满足不了时,等在跑的都结束后交回 Leader。
@@ -157,6 +229,16 @@ export declare class AiTeamRunner {
157
229
  * 成员步骤的上游交接:把依赖步骤的报告写成一个交接文件,提示词只给路径。
158
230
  * 没有依赖、或写文件失败时返回 null(提示词仍逐行列出上游报告文件)。
159
231
  */
232
+ /**
233
+ * 开工发言(S4):成员**自己发的真实发言**(头像 + 名字 + 气泡),不是居中 notice;
234
+ * 文案由 [stepStartText] 拼(依据只来自 `step.dependsOn`,不引 `decision.message` / 报告正文 / 提示词文本)。
235
+ */
236
+ private postStepStart;
237
+ /**
238
+ * 开工发言的依据:只看 `step.dependsOn`,按依赖顺序解析出上游步骤(没有依赖返回空数组)。
239
+ * 不调 `memberUpstream`:那个会顺手写交接文件,而这里只要读数据(设计 v2.1 强调不引 LLM 文本)。
240
+ */
241
+ private upstreamBasis;
160
242
  private memberUpstream;
161
243
  /**
162
244
  * 同一个群聊里接着开新运行时的续跑交接(§4.4 同一套文件交接):把之前几轮的步骤摘要