@co0ontty/wand 4.76.0 → 4.77.0-beta.g7fb0b70
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/dist/agent-dispatch.d.ts +46 -0
- package/dist/agent-dispatch.js +84 -0
- package/dist/ai-team-availability.d.ts +69 -0
- package/dist/ai-team-availability.js +100 -0
- package/dist/ai-team-prompts.d.ts +113 -0
- package/dist/ai-team-prompts.js +435 -0
- package/dist/ai-team-runner.d.ts +241 -0
- package/dist/ai-team-runner.js +1370 -0
- package/dist/ai-team-types.d.ts +147 -0
- package/dist/ai-team-types.js +32 -0
- package/dist/attention.d.ts +40 -0
- package/dist/attention.js +86 -0
- package/dist/build-info.json +4 -4
- package/dist/claude-sdk-runner.d.ts +5 -0
- package/dist/claude-sdk-runner.js +2 -1
- package/dist/commit-task-archive.d.ts +3 -0
- package/dist/commit-task-archive.js +43 -0
- package/dist/config.js +0 -2
- package/dist/git-quick-commit.d.ts +2 -1
- package/dist/git-quick-commit.js +72 -60
- package/dist/message-truncator.d.ts +41 -5
- package/dist/message-truncator.js +255 -38
- package/dist/missions.d.ts +4 -2
- package/dist/missions.js +2 -2
- package/dist/process-manager.d.ts +1 -0
- package/dist/process-manager.js +17 -8
- package/dist/prompt-optimizer.js +13 -13
- package/dist/server-ai-team-routes.d.ts +11 -0
- package/dist/server-ai-team-routes.js +283 -0
- package/dist/server-attention-routes.d.ts +9 -0
- package/dist/server-attention-routes.js +26 -0
- package/dist/server-file-routes.js +1 -1
- package/dist/server-session-routes.js +41 -5
- package/dist/server-settings-routes.js +1 -1
- package/dist/server-task-routes.d.ts +2 -0
- package/dist/server-task-routes.js +6 -40
- package/dist/server-workspace-routes.js +13 -5
- package/dist/server.js +43 -0
- package/dist/session-topic.js +13 -13
- package/dist/session-transport.d.ts +3 -0
- package/dist/session-transport.js +1 -0
- package/dist/storage.d.ts +54 -1
- package/dist/storage.js +413 -2
- package/dist/structured-claude-adapter.d.ts +5 -0
- package/dist/structured-claude-adapter.js +13 -2
- package/dist/structured-claude-protocol.d.ts +2 -0
- package/dist/structured-claude-protocol.js +4 -0
- package/dist/structured-codex-adapter.js +2 -2
- package/dist/structured-grok-adapter.js +2 -1
- package/dist/structured-opencode-adapter.js +2 -2
- package/dist/structured-pi-adapter.js +2 -1
- package/dist/structured-provider-common.d.ts +17 -0
- package/dist/structured-provider-common.js +52 -0
- package/dist/structured-qoder-adapter.js +2 -1
- package/dist/structured-session-manager.d.ts +18 -1
- package/dist/structured-session-manager.js +67 -10
- package/dist/system-ai.d.ts +13 -2
- package/dist/system-ai.js +9 -5
- package/dist/task-title.js +10 -10
- package/dist/types.d.ts +25 -2
- package/dist/wand-task-sync.d.ts +1 -0
- package/dist/wand-task-sync.js +1 -0
- package/dist/web-ui/content/ai-teams.js +12 -0
- package/dist/web-ui/content/scripts.js +86 -5301
- package/dist/web-ui/content/styles.css +1 -1
- package/dist/web-ui/embedded-assets.d.ts +1 -0
- package/dist/web-ui/embedded-assets.js +3 -2
- package/dist/web-ui/scripts.d.ts +8 -0
- package/dist/web-ui/scripts.js +28 -2
- package/dist/ws-broadcast.js +52 -19
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -31,6 +31,9 @@ import { registerTaskRoutes } from "./server-task-routes.js";
|
|
|
31
31
|
import { getGithubConnectorStatus } from "./github-connector.js";
|
|
32
32
|
import { registerMissionRoutes } from "./server-mission-routes.js";
|
|
33
33
|
import { Missions } from "./missions.js";
|
|
34
|
+
import { createAiTeamRunner } from "./ai-team-runner.js";
|
|
35
|
+
import { registerAiTeamRoutes } from "./server-ai-team-routes.js";
|
|
36
|
+
import { registerAttentionRoutes } from "./server-attention-routes.js";
|
|
34
37
|
import { refreshProviderCliUpdateState, registerAdminUpdateRoutes, registerPublicUpdateRoutes, ServerUpdateState, } from "./server-update-routes.js";
|
|
35
38
|
import { parseSessionCreationOrigin, registerClaudeHistoryRoutes, registerSessionRoutes } from "./server-session-routes.js";
|
|
36
39
|
import { registerWorkspaceRoutes } from "./server-workspace-routes.js";
|
|
@@ -54,6 +57,7 @@ import { DistributionManager } from "./distribution-manager.js";
|
|
|
54
57
|
import { isLogBusActive, wandTuiLog } from "./tui/log-bus.js";
|
|
55
58
|
import { EMBEDDED_WEB_ASSETS } from "./web-ui/embedded-assets.js";
|
|
56
59
|
import { renderApp } from "./web-ui/index.js";
|
|
60
|
+
import { getAiTeamsChunk } from "./web-ui/scripts.js";
|
|
57
61
|
import { WsBroadcastManager } from "./ws-broadcast.js";
|
|
58
62
|
import { TerminalDaemonClient } from "./terminal-daemon-client.js";
|
|
59
63
|
import { createUpgradeAwareTerminalHost } from "./render-host.js";
|
|
@@ -343,6 +347,26 @@ export async function startServer(config, configPath, options = {}) {
|
|
|
343
347
|
const structuredSessions = new StructuredSessionManager(storage, config, structuredLogger, undefined, {}, structuredHosts.host);
|
|
344
348
|
const sessionRegistry = new SessionRegistry(processes, structuredSessions, storage);
|
|
345
349
|
const missions = new Missions(storage, structuredSessions, sessionRegistry);
|
|
350
|
+
// wsManager 在后面才建:团队运行的变更通知经由这个转发口,接好之前静默丢弃。
|
|
351
|
+
let notifyAiTeamRun = (_data) => { };
|
|
352
|
+
// 团队降级的 model-unknown 事前比对只看这份已发现的清单;没刷新过就是空,判定方向是放行。
|
|
353
|
+
const aiTeamModelIds = (provider) => {
|
|
354
|
+
const cache = modelCatalog.snapshot();
|
|
355
|
+
const key = {
|
|
356
|
+
claude: "models",
|
|
357
|
+
codex: "codexModels",
|
|
358
|
+
opencode: "opencodeModels",
|
|
359
|
+
grok: "grokModels",
|
|
360
|
+
qoder: "qoderModels",
|
|
361
|
+
pi: "piModels",
|
|
362
|
+
}[provider];
|
|
363
|
+
return cache[key].map((entry) => entry.id);
|
|
364
|
+
};
|
|
365
|
+
const aiTeams = createAiTeamRunner({
|
|
366
|
+
storage, config, structured: structuredSessions, processes, sessions: sessionRegistry,
|
|
367
|
+
notify: (run) => notifyAiTeamRun({ kind: "ai-team-run", runId: run.id, taskId: run.taskId }),
|
|
368
|
+
models: aiTeamModelIds,
|
|
369
|
+
});
|
|
346
370
|
const updateState = new ServerUpdateState();
|
|
347
371
|
const getUpdateChannel = () => normalizeUpdateChannel(storage.getConfigValue("updateChannel"));
|
|
348
372
|
let disconnectAuthenticatedSockets = () => { };
|
|
@@ -396,6 +420,14 @@ export async function startServer(config, configPath, options = {}) {
|
|
|
396
420
|
app.get("/vendor/xterm/xterm.bundle.js", (req, res) => sendEmbeddedVendorAsset("/vendor/xterm/xterm.bundle.js", req, res));
|
|
397
421
|
app.get("/vendor/xterm/xterm.css", (req, res) => sendEmbeddedVendorAsset("/vendor/xterm/xterm.css", req, res));
|
|
398
422
|
app.get("/vendor/qrcode/qrcode.bundle.js", (req, res) => sendEmbeddedVendorAsset("/vendor/qrcode/qrcode.bundle.js", req, res));
|
|
423
|
+
// AI 团队页按需脚本:页面 meta 里的地址带内容 hash,hash 对得上才长缓存。
|
|
424
|
+
app.get("/assets/ai-teams.js", (req, res) => {
|
|
425
|
+
const chunk = getAiTeamsChunk();
|
|
426
|
+
res.setHeader("Cache-Control", req.query.v === chunk.hash
|
|
427
|
+
? "public, max-age=604800, immutable"
|
|
428
|
+
: "no-cache");
|
|
429
|
+
res.type("application/javascript").send(chunk.content);
|
|
430
|
+
});
|
|
399
431
|
// ── Web UI endpoints ──
|
|
400
432
|
app.get("/", (_req, res) => {
|
|
401
433
|
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
|
@@ -644,6 +676,8 @@ export async function startServer(config, configPath, options = {}) {
|
|
|
644
676
|
registerGithubRoutes(app, { storage, requireAdmin, sessions: sessionRegistry });
|
|
645
677
|
// 任务管理与 Missions 一样只需登录:原生 connected-app 也要能列/建/派发。
|
|
646
678
|
registerTaskRoutes(app, { storage, sessions: sessionRegistry, structured: structuredSessions, processes, config });
|
|
679
|
+
registerAiTeamRoutes(app, { storage, runner: aiTeams });
|
|
680
|
+
registerAttentionRoutes(app, { sessions: sessionRegistry, runner: aiTeams });
|
|
647
681
|
registerAdminUpdateRoutes(app, {
|
|
648
682
|
storage,
|
|
649
683
|
config,
|
|
@@ -760,6 +794,7 @@ export async function startServer(config, configPath, options = {}) {
|
|
|
760
794
|
cols: reqCols,
|
|
761
795
|
rows: reqRows,
|
|
762
796
|
thinkingEffort: body.thinkingEffort ?? config.defaultThinkingEffort,
|
|
797
|
+
systemPrompt: body.systemPrompt,
|
|
763
798
|
workspaceId,
|
|
764
799
|
workspaceTaskId: body.workspaceTaskId,
|
|
765
800
|
...origin,
|
|
@@ -839,15 +874,21 @@ export async function startServer(config, configPath, options = {}) {
|
|
|
839
874
|
// Wire process events to WebSocket broadcast
|
|
840
875
|
processes.on("process", (event) => {
|
|
841
876
|
missions.ingest(event);
|
|
877
|
+
aiTeams.ingest(event);
|
|
842
878
|
wsManager.emitEvent(event);
|
|
843
879
|
});
|
|
844
880
|
structuredSessions.setEventEmitter((event) => {
|
|
845
881
|
missions.ingest(event);
|
|
882
|
+
aiTeams.ingest(event);
|
|
846
883
|
wsManager.emitEvent(event);
|
|
847
884
|
});
|
|
885
|
+
notifyAiTeamRun = (data) => {
|
|
886
|
+
wsManager.emitEvent({ type: "notification", sessionId: "__system__", data });
|
|
887
|
+
};
|
|
848
888
|
// Re-attach structured CLI runs that kept going inside terminald while the
|
|
849
889
|
// previous web process was down; fire-and-forget, failures are logged inside.
|
|
850
890
|
void structuredSessions.recoverDetachedRuns();
|
|
891
|
+
aiTeams.reconcile();
|
|
851
892
|
// ── Restart endpoint (needs server + wss in scope) ──
|
|
852
893
|
/**
|
|
853
894
|
* 统一的关服 + 重启。重启方式由 computeRelaunch 决定:
|
|
@@ -900,6 +941,7 @@ export async function startServer(config, configPath, options = {}) {
|
|
|
900
941
|
structuredSessions.dispose();
|
|
901
942
|
}
|
|
902
943
|
catch { /* noop */ }
|
|
944
|
+
aiTeams.dispose();
|
|
903
945
|
try {
|
|
904
946
|
structuredHosts.rustClient?.disconnect();
|
|
905
947
|
}
|
|
@@ -1177,6 +1219,7 @@ export async function startServer(config, configPath, options = {}) {
|
|
|
1177
1219
|
structuredSessions.dispose();
|
|
1178
1220
|
}
|
|
1179
1221
|
catch { /* best-effort shutdown */ }
|
|
1222
|
+
aiTeams.dispose();
|
|
1180
1223
|
try {
|
|
1181
1224
|
structuredHosts.rustClient?.disconnect();
|
|
1182
1225
|
}
|
package/dist/session-topic.js
CHANGED
|
@@ -245,19 +245,19 @@ export async function generateSessionTopic(userMessages, cwd, language, ai = {})
|
|
|
245
245
|
if (!input)
|
|
246
246
|
throw new Error("没有可总结的用户消息。");
|
|
247
247
|
const outputLanguage = language?.trim() || "与用户消息相同的语言";
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
"
|
|
258
|
-
input
|
|
259
|
-
|
|
260
|
-
const raw = await callConfiguredAiText(
|
|
248
|
+
const request = {
|
|
249
|
+
system: [
|
|
250
|
+
"请综合总结用户消息里的所有轮次,用于单个终端/会话的列表标题。",
|
|
251
|
+
`使用${outputLanguage}输出。`,
|
|
252
|
+
"只输出一个 JSON 对象,不要 Markdown、解释或额外文字。",
|
|
253
|
+
'格式:{"title":"不超过20个字的具体主题标题","description":"不超过60个字的一句话任务描述"}',
|
|
254
|
+
"标题必须概括该会话用户命令自己的具体工作,不要复述项目名、目录名或上级任务标题,也不要使用“关于”“请求”“任务”等空泛词。",
|
|
255
|
+
"描述保留当前整体目标、关键对象和新增要求。",
|
|
256
|
+
"后续轮次与前面目标有关时必须共同概括;发生目标切换时优先反映最新目标,同时保留仍有效的上下文。",
|
|
257
|
+
].join("\n"),
|
|
258
|
+
prompt: `按发送顺序排列的用户消息:\n${input}`,
|
|
259
|
+
};
|
|
260
|
+
const raw = await callConfiguredAiText(request, cwd ?? process.cwd(), language ?? "", ai);
|
|
261
261
|
const topic = parseTopic(raw);
|
|
262
262
|
if (!topic)
|
|
263
263
|
throw new Error("模型返回的会话主题格式无效。");
|
|
@@ -21,6 +21,8 @@ export interface SessionDetailDTO extends SessionBaseDTO {
|
|
|
21
21
|
messageTotal?: number;
|
|
22
22
|
leadingBlockOffset?: number;
|
|
23
23
|
leadingBlockTotal?: number;
|
|
24
|
+
/** 被切掉的头部里用户可感知的块数(默认收起的工具 / 思考块不计入)。 */
|
|
25
|
+
leadingVisibleCount?: number;
|
|
24
26
|
}
|
|
25
27
|
/** Resolve every client-visible title on the server so all clients show the same value. */
|
|
26
28
|
export declare function resolveSessionDisplayTitle(snapshot: SessionSnapshot, blockedTitles?: readonly string[]): string;
|
|
@@ -32,6 +34,7 @@ export interface SessionDetailDTOOptions {
|
|
|
32
34
|
messageTotal?: number;
|
|
33
35
|
leadingBlockOffset?: number;
|
|
34
36
|
leadingBlockTotal?: number;
|
|
37
|
+
leadingVisibleCount?: number;
|
|
35
38
|
outputLimit?: number;
|
|
36
39
|
}
|
|
37
40
|
export declare function toSessionDetailDTO(snapshot: SessionSnapshot, options?: SessionDetailDTOOptions): SessionDetailDTO;
|
|
@@ -92,6 +92,7 @@ export function toSessionDetailDTO(snapshot, options = {}) {
|
|
|
92
92
|
...(options.messageTotal !== undefined ? { messageTotal: options.messageTotal } : {}),
|
|
93
93
|
...(options.leadingBlockOffset !== undefined ? { leadingBlockOffset: options.leadingBlockOffset } : {}),
|
|
94
94
|
...(options.leadingBlockTotal !== undefined ? { leadingBlockTotal: options.leadingBlockTotal } : {}),
|
|
95
|
+
...(options.leadingVisibleCount !== undefined ? { leadingVisibleCount: options.leadingVisibleCount } : {}),
|
|
95
96
|
};
|
|
96
97
|
}
|
|
97
98
|
/** Bound snapshot-like event payloads before they enter per-client WS queues. */
|
package/dist/storage.d.ts
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
|
-
import { SessionSnapshot, ConversationTurn, StructuredSessionState, Workspace, LayoutNode, TaskWindowLayout, WorkspaceDefaultProvider, WorkspaceKind, WorkspaceTask, WorkspaceTaskWorktree, WorkspaceTaskStatus } from "./types.js";
|
|
1
|
+
import { SessionSnapshot, ConversationTurn, SessionProvider, StructuredSessionState, Workspace, LayoutNode, TaskWindowLayout, WorkspaceDefaultProvider, WorkspaceKind, WorkspaceTask, WorkspaceTaskWorktree, WorkspaceTaskStatus } from "./types.js";
|
|
2
|
+
import type { AiTeam, AiTeamRun, AiTeamRunChatMarker, AiTeamRunStatus, AiTeamStep, CandidateFailureKind, StepDispatchInfo } from "./ai-team-types.js";
|
|
3
|
+
import type { WandTaskAgentKind } from "./task-types.js";
|
|
2
4
|
import type { AgentActivityItem, Mission, MissionAttempt, MissionReviewComment, MissionReviewStatus, MissionStatus } from "./mission-types.js";
|
|
3
5
|
import { type PasswordVault, type PasswordVaultItem, type PasswordVaultItemFilter, type PasswordVaultItemInput } from "./password-manager.js";
|
|
6
|
+
/** `ai_team_runs.run_state_json`:本次运行的候选黑名单(§3.4 修正 B12 两层键值 + host-disabled)。 */
|
|
7
|
+
export interface AiTeamRunState {
|
|
8
|
+
/** spawn-missing:该 provider 的候选全部直接跳过。 */
|
|
9
|
+
providers: SessionProvider[];
|
|
10
|
+
/** 五元组 key → 拉黑它的原因(model-unknown / startup-timeout)。 */
|
|
11
|
+
agents: Array<{
|
|
12
|
+
key: string;
|
|
13
|
+
kind: CandidateFailureKind;
|
|
14
|
+
}>;
|
|
15
|
+
/** 五元组 key → startup-timeout 累计次数(到 2 次进 agents)。 */
|
|
16
|
+
strikes: Record<string, number>;
|
|
17
|
+
/** host-disabled:整个 run 不再尝试该 kind 的候选。 */
|
|
18
|
+
hostDisabled: WandTaskAgentKind[];
|
|
19
|
+
}
|
|
4
20
|
export interface ConnectorMeta {
|
|
5
21
|
provider: string;
|
|
6
22
|
apiUrl: string | null;
|
|
@@ -88,6 +104,8 @@ export declare class WandStorage {
|
|
|
88
104
|
setSessionWorkspaceId(sessionId: string, workspaceId: string | null): void;
|
|
89
105
|
/** Lightweight count of persisted sessions grouped by workspace. */
|
|
90
106
|
countSessionsByWorkspace(): Map<string, number>;
|
|
107
|
+
/** Count user-initiated CLI launches (one per session), including archived sessions. */
|
|
108
|
+
countInteractiveSessionsByProvider(): Record<SessionProvider, number>;
|
|
91
109
|
/** Sessions not yet attached to a project. Omits messages/output. */
|
|
92
110
|
listUnboundSessionBindings(): Array<{
|
|
93
111
|
id: string;
|
|
@@ -265,6 +283,33 @@ export declare class WandStorage {
|
|
|
265
283
|
deleteAuthSession(token: string): void;
|
|
266
284
|
deleteAllAuthSessions(): void;
|
|
267
285
|
deleteExpiredAuthSessions(now: number): void;
|
|
286
|
+
listAiTeams(): AiTeam[];
|
|
287
|
+
getAiTeam(id: string): AiTeam | null;
|
|
288
|
+
saveAiTeam(team: AiTeam): void;
|
|
289
|
+
/** 只删团队定义;已有运行保存了团队快照,不受影响。 */
|
|
290
|
+
deleteAiTeam(id: string): void;
|
|
291
|
+
saveAiTeamRun(run: AiTeamRun): void;
|
|
292
|
+
/** 群聊会话对应的最近一次运行(同一个群聊可以接着开新运行)。 */
|
|
293
|
+
getLatestAiTeamRunByChat(sessionId: string): AiTeamRun | null;
|
|
294
|
+
/**
|
|
295
|
+
* 会话列表用的群聊标记索引:chat_session_id → 最近一次运行的入口信息。
|
|
296
|
+
* 一次查询建整张表,供 /api/tasks 每请求一次构建;不逐会话查询。
|
|
297
|
+
*/
|
|
298
|
+
listAiTeamRunChatMarkers(): Map<string, AiTeamRunChatMarker>;
|
|
299
|
+
getAiTeamRun(id: string): AiTeamRun | null;
|
|
300
|
+
listAiTeamRuns(filter?: {
|
|
301
|
+
taskId?: string;
|
|
302
|
+
teamId?: string;
|
|
303
|
+
statuses?: readonly AiTeamRunStatus[];
|
|
304
|
+
limit?: number;
|
|
305
|
+
}): AiTeamRun[];
|
|
306
|
+
saveAiTeamStep(step: AiTeamStep): void;
|
|
307
|
+
listAiTeamSteps(runId: string): AiTeamStep[];
|
|
308
|
+
getRunningAiTeamStepBySession(sessionId: string): AiTeamStep | null;
|
|
309
|
+
/** `ai_team_runs.run_state_json` 的读侧入口(§3.4);脏值 / 旧行退化成空黑名单。 */
|
|
310
|
+
getAiTeamRunState(runId: string): AiTeamRunState;
|
|
311
|
+
/** 只写 `run_state_json` 一列,不碰 `saveAiTeamRun` 负责的业务字段。 */
|
|
312
|
+
setAiTeamRunState(runId: string, state: AiTeamRunState): void;
|
|
268
313
|
saveMission(mission: Mission): void;
|
|
269
314
|
getMission(id: string): Mission | null;
|
|
270
315
|
listMissions(includeArchived?: boolean): Mission[];
|
|
@@ -301,4 +346,12 @@ export declare class WandStorage {
|
|
|
301
346
|
private mapSessionRow;
|
|
302
347
|
deleteSession(id: string): void;
|
|
303
348
|
}
|
|
349
|
+
/**
|
|
350
|
+
* `ai_team_steps.dispatch_info_json` 的读侧校验(§3.2)。脏值 / 旧行默认 `{}` 一律退化成
|
|
351
|
+
* 「首选、没跳过任何候选」,坏条目逐条丢弃,不整字段作废——降级留痕是可观测性数据,
|
|
352
|
+
* 不能因为一条脏记录把整条链丢掉。
|
|
353
|
+
*/
|
|
354
|
+
export declare function parseStepDispatchInfo(raw: unknown): StepDispatchInfo;
|
|
355
|
+
/** `ai_team_runs.run_state_json` 的读侧校验(§3.4);脏值退化成空黑名单。 */
|
|
356
|
+
export declare function parseAiTeamRunState(raw: unknown): AiTeamRunState;
|
|
304
357
|
export {};
|