wezard 1.3.19 → 1.3.21
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/daemon/detail.js +10 -0
- package/dist/daemon/detail.js.map +1 -1
- package/dist/daemon/mirror-bridge.js +28 -51
- package/dist/daemon/mirror-bridge.js.map +1 -1
- package/dist/shared/chat-http.js +35 -16
- package/dist/shared/chat-http.js.map +1 -1
- package/dist/shared/chat-view.js +27 -2
- package/dist/shared/chat-view.js.map +1 -1
- package/dist/shared/detail-render.js +36 -4
- package/dist/shared/detail-render.js.map +1 -1
- package/dist/shared/detail-store.js +9 -4
- package/dist/shared/detail-store.js.map +1 -1
- package/dist/svr/index.js +1 -1
- package/dist/svr/index.js.map +1 -1
- package/package.json +1 -1
- package/web/chat.js +7 -7
package/dist/daemon/detail.js
CHANGED
|
@@ -57,6 +57,16 @@ export const recordApprovalDecision = (reqId, decision, decidedBy) => {
|
|
|
57
57
|
if (rec)
|
|
58
58
|
forwardToRemote(rec);
|
|
59
59
|
};
|
|
60
|
+
// 上下文断点标记: 清空/轮换发生的那一刻就落一条独立记录, chat 线程据此画分隔线,
|
|
61
|
+
// 不必等下一轮开口 (那一轮还可能是个被丢弃的空壳)。
|
|
62
|
+
export const recordMark = (rec) => {
|
|
63
|
+
if (!store)
|
|
64
|
+
return;
|
|
65
|
+
store.recordMark(rec);
|
|
66
|
+
const full = store.get(rec.id);
|
|
67
|
+
if (full)
|
|
68
|
+
forwardToRemote(full);
|
|
69
|
+
};
|
|
60
70
|
// Brief 模式聚合详情: 一个 turn 的时间线。startTurn 建空壳,item 增量 append,close 收尾。
|
|
61
71
|
// 每次变更都完整重推整条 record 给 remote svr — svr 侧存的是 last-write-wins 快照。
|
|
62
72
|
export const recordTurnStart = (rec) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detail.js","sourceRoot":"","sources":["../../daemon/detail.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EACL,iBAAiB,
|
|
1
|
+
{"version":3,"file":"detail.js","sourceRoot":"","sources":["../../daemon/detail.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,7 +23,7 @@ import { isAutoWindowActive } from "./session-cache.js";
|
|
|
23
23
|
import { dangerOf } from "./danger.js";
|
|
24
24
|
import { runTmux as runTmuxCmd, spawnTmuxClaude } from "./spawn-tmux.js";
|
|
25
25
|
import { startSubagentWatch } from "./subagent-tail.js";
|
|
26
|
-
import { recordTool, recordToolResult, recordTurnStart, recordTurnItem, recordTurnUsage, recordTurnClose, recordCloseOpenTurns, buildDetailUrl, buildChatUrl } from "./detail.js";
|
|
26
|
+
import { recordTool, recordToolResult, recordMark, recordTurnStart, recordTurnItem, recordTurnUsage, recordTurnClose, recordCloseOpenTurns, buildDetailUrl, buildChatUrl } from "./detail.js";
|
|
27
27
|
import { labelFor, tagOfKey, baseOfKey, keyOf, withTagHeader, parseTagHeader } from "../shared/session-label.js";
|
|
28
28
|
import { splitMarkdown } from "../shared/md-chunk.js";
|
|
29
29
|
import { randomTip } from "./tips.js";
|
|
@@ -1555,6 +1555,7 @@ export const startMirror = (deps) => {
|
|
|
1555
1555
|
};
|
|
1556
1556
|
const TOOL_DETAIL_PREFIX = "TOOL_DETAIL|";
|
|
1557
1557
|
const newTurnId = () => `t${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
|
|
1558
|
+
const newMarkId = () => `m${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
|
|
1558
1559
|
const detailCardFor = (s, target) => {
|
|
1559
1560
|
if (s.tools.length === 0)
|
|
1560
1561
|
return undefined;
|
|
@@ -2034,14 +2035,6 @@ export const startMirror = (deps) => {
|
|
|
2034
2035
|
// `[mirror]` 系统提示 —— 它们都不走这道门。
|
|
2035
2036
|
// 只在 brief 下生效: 抑制的前提是详情页兜得住内容, 而 turn store 只有 brief 在写。
|
|
2036
2037
|
const turnSilent = (a) => cfg.wrc.mirror.brief && cfg.wrc.mirror.chatOriginOnly && a.turnFromChat === false;
|
|
2037
|
-
// 详情页入口一次性告知。CLI 轮全程静默后, 一个从未收到过气泡的会话在群里将没有
|
|
2038
|
-
// 任何链接可点 —— 每个 attachment 发一条 (且仅一条) 带链接的提示解决这个死角。
|
|
2039
|
-
const noticeCliSilent = (a, turnId) => {
|
|
2040
|
-
if (a.cliSilentNoticed)
|
|
2041
|
-
return;
|
|
2042
|
-
a.cliSilentNoticed = true;
|
|
2043
|
-
sendRaw(a, `${briefDetailLink(turnId, a.target)} CLI 侧对话不再下发到群里,点标签看实时详情。`);
|
|
2044
|
-
};
|
|
2045
2038
|
// 收口一条 loading 气泡: finish=true 写入最终内容, 只生效一次。发送失败退回 standalone。
|
|
2046
2039
|
// raw=true skips withSessionTag (used when content already contains the linked tag header).
|
|
2047
2040
|
// WeCom 客户端收到 finish=true 后仍有打字机动画要播放, 如果紧接着就下发
|
|
@@ -2086,11 +2079,13 @@ export const startMirror = (deps) => {
|
|
|
2086
2079
|
clearCot(a); // turn 级状态 —— 进度行跟着气泡走, 不能跨 turn 残留
|
|
2087
2080
|
log.info({ sessionId: a.sessionId, turnId: q.turnId, isSlash: q.isSlash }, "brief: turn started");
|
|
2088
2081
|
};
|
|
2089
|
-
//
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2082
|
+
// 上下文断点落一条独立记录 —— 清空/轮换发生在两轮之间, 分隔线就画在两轮之间。
|
|
2083
|
+
// 挂在"下一轮"上等于要等人再开口才显形, 而那一轮还可能被当成空壳 turn 丢掉。
|
|
2084
|
+
// sessionId 记断点之后的那个: detail-store 的轮换判定以它为基准, 免得紧随其后的
|
|
2085
|
+
// 第一轮又被判成一次轮换、多画一条线。
|
|
2086
|
+
const markCut = (target, sessionId, cut) => {
|
|
2087
|
+
recordMark({ id: newMarkId(), target, sessionId, cut });
|
|
2088
|
+
log.info({ target, sessionId, cut }, "detail: context cut marked");
|
|
2094
2089
|
};
|
|
2095
2090
|
// graph 归因同样一次性: 一次注入只解释它开出的那一轮。超过 ORIGIN_TTL_MS 还没被
|
|
2096
2091
|
// 认领 = 那次注入没能开出 turn, 印章作废 —— 宁可少标一轮, 也不能把人打的字冒认成
|
|
@@ -2106,7 +2101,7 @@ export const startMirror = (deps) => {
|
|
|
2106
2101
|
a.queryEpoch = (a.queryEpoch ?? 0) + 1; // WeCom 侧的新一轮同样是 query 边界
|
|
2107
2102
|
a.turnFromChat = true; // 出处确凿: 这一轮有 frame, 群里就是它的主场
|
|
2108
2103
|
a.pendingFromCli = false; // 人改从聊天里说话了, 之前那条 CLI 输入不再是出处
|
|
2109
|
-
recordTurnStart({ id: turnId, target: a.target, sessionId: a.sessionId, cwd: a.runningCwd || undefined, userQuery: userQuery.trim() || undefined,
|
|
2104
|
+
recordTurnStart({ id: turnId, target: a.target, sessionId: a.sessionId, cwd: a.runningCwd || undefined, userQuery: userQuery.trim() || undefined, origin: consumeOrigin(a) });
|
|
2110
2105
|
// hardTimer 兜底: turn 若无终句 / turn_end 收口 (卡死/漏收), 到点仍收气泡。
|
|
2111
2106
|
const bubble = { frame, streamId, hardTimer: undefined, done: false };
|
|
2112
2107
|
const q = { turnId, bubble, isSlash };
|
|
@@ -2152,7 +2147,7 @@ export const startMirror = (deps) => {
|
|
|
2152
2147
|
const fromCli = a.pendingFromCli === true;
|
|
2153
2148
|
a.pendingFromCli = false;
|
|
2154
2149
|
a.turnFromChat = fromCli ? false : a.turnFromChat ?? true;
|
|
2155
|
-
recordTurnStart({ id: turnId, target: a.target, sessionId: a.sessionId, cwd: a.runningCwd || undefined, userQuery: query || undefined,
|
|
2150
|
+
recordTurnStart({ id: turnId, target: a.target, sessionId: a.sessionId, cwd: a.runningCwd || undefined, userQuery: query || undefined, origin: consumeOrigin(a) });
|
|
2156
2151
|
a.briefTurnId = turnId;
|
|
2157
2152
|
a.briefBubble = undefined;
|
|
2158
2153
|
a.briefIsSlash = false;
|
|
@@ -2160,13 +2155,9 @@ export const startMirror = (deps) => {
|
|
|
2160
2155
|
a.briefConcluded = false;
|
|
2161
2156
|
a.briefLastText = undefined;
|
|
2162
2157
|
clearCot(a);
|
|
2163
|
-
//
|
|
2164
|
-
//
|
|
2165
|
-
//
|
|
2166
|
-
if (turnSilent(a))
|
|
2167
|
-
noticeCliSilent(a, turnId);
|
|
2168
|
-
else
|
|
2169
|
-
a.pendingBriefHeader = briefDetailLink(turnId, a.target);
|
|
2158
|
+
// 详情链接不在这里单独发 — 本轮的每条 standalone 都由 withLinkedTag 自带
|
|
2159
|
+
// (linkedTagPrefix 读的正是 a.briefTurnId)。静默轮没有 standalone 可搭车, 那就
|
|
2160
|
+
// 一条都不发: 群里只该出现有正文的消息, 纯入口提示是噪音。
|
|
2170
2161
|
log.info({ sessionId: a.sessionId, turnId, fromCli, silent: turnSilent(a) }, "brief: turn started (CLI-side, no bubble)");
|
|
2171
2162
|
};
|
|
2172
2163
|
// 本轮出现过工具调用 / tool_result / 非 final 文本 —— 只记状态: 详情链接从 ack 起
|
|
@@ -2198,13 +2189,10 @@ export const startMirror = (deps) => {
|
|
|
2198
2189
|
const turnId = a.briefTurnId;
|
|
2199
2190
|
if (!turnId || a.briefConcluded)
|
|
2200
2191
|
return;
|
|
2201
|
-
if (!body.trim())
|
|
2202
|
-
a.pendingBriefHeader = undefined;
|
|
2192
|
+
if (!body.trim())
|
|
2203
2193
|
return;
|
|
2204
|
-
}
|
|
2205
2194
|
if (isDuplicateConclusion(a, body)) {
|
|
2206
2195
|
a.briefConcluded = true; // 本轮已"定稿", 只是不投递
|
|
2207
|
-
a.pendingBriefHeader = undefined;
|
|
2208
2196
|
log.info({ sessionId: a.sessionId, turnId, epoch: a.queryEpoch ?? 0 }, "brief: duplicate conclusion suppressed");
|
|
2209
2197
|
return;
|
|
2210
2198
|
}
|
|
@@ -2214,17 +2202,13 @@ export const startMirror = (deps) => {
|
|
|
2214
2202
|
a.lastConcludedAt = Date.now();
|
|
2215
2203
|
if (a.briefBubble && !a.briefBubble.done) {
|
|
2216
2204
|
void finishBriefBubble(a, `${briefDetailLink(turnId, a.target)} ${body}`, true);
|
|
2217
|
-
a.pendingBriefHeader = undefined;
|
|
2218
2205
|
}
|
|
2219
2206
|
else if (turnSilent(a)) {
|
|
2220
2207
|
// CLI 手敲的一轮: 终稿只留在 turn store, 详情页照常实时可见。
|
|
2221
|
-
a.pendingBriefHeader = undefined;
|
|
2222
2208
|
log.info({ sessionId: a.sessionId, turnId }, "brief: CLI-origin conclusion kept out of chat");
|
|
2223
2209
|
}
|
|
2224
2210
|
else {
|
|
2225
|
-
|
|
2226
|
-
a.pendingBriefHeader = undefined;
|
|
2227
|
-
sendStandalone(a, header ? `${header} ${body}` : body);
|
|
2211
|
+
sendStandalone(a, body); // 详情链接由 withLinkedTag 统一前缀, 不在这里拼
|
|
2228
2212
|
}
|
|
2229
2213
|
// 只保留当前 turn: 其余仍开着的 turn 记录是漏收的 close, 一并扫掉。
|
|
2230
2214
|
recordCloseOpenTurns({ target: a.target, sessionId: a.sessionId, exceptIds: [turnId] });
|
|
@@ -2246,7 +2230,6 @@ export const startMirror = (deps) => {
|
|
|
2246
2230
|
a.briefIsSlash = false;
|
|
2247
2231
|
a.briefConcluded = false;
|
|
2248
2232
|
a.briefLastText = undefined;
|
|
2249
|
-
a.pendingBriefHeader = undefined;
|
|
2250
2233
|
// 收口 = 欠账两清。前台派发的 result 不会再落回这一轮; 后台派发跨轮存活, 由完成
|
|
2251
2234
|
// 通知 / TTL 销账 (voidTurnAgents)。挂着的软收口计时器一并撤掉 —— 它到点会去收
|
|
2252
2235
|
// 「当前 turn」, 那时的当前 turn 已经是下一轮了。
|
|
@@ -2317,7 +2300,7 @@ export const startMirror = (deps) => {
|
|
|
2317
2300
|
sessionId: a.sessionId,
|
|
2318
2301
|
cwd: a.runningCwd || undefined,
|
|
2319
2302
|
userQuery: task,
|
|
2320
|
-
agent: { id: agentId, type: resolved?.type, description: resolved?.description },
|
|
2303
|
+
agent: { id: agentId, type: resolved?.type, description: resolved?.description, parentTurnId: a.briefTurnId },
|
|
2321
2304
|
});
|
|
2322
2305
|
log.info({ agentId, turnId, label: run.label }, "subagent: turn started");
|
|
2323
2306
|
if (item.kind === "task")
|
|
@@ -2505,18 +2488,12 @@ export const startMirror = (deps) => {
|
|
|
2505
2488
|
// loading 气泡。非 slash 场景的 skill_output 是用户可见的中间反馈, 走 standalone。
|
|
2506
2489
|
if (a.briefIsSlash && !a.briefHadTool && a.briefBubble && !a.briefBubble.done) {
|
|
2507
2490
|
void finishBriefBubble(a, item.body);
|
|
2508
|
-
a.pendingBriefHeader = undefined;
|
|
2509
2491
|
}
|
|
2510
2492
|
else if (turnSilent(a)) {
|
|
2511
2493
|
// CLI 里手敲的 /clear、/model 之类, 回执给敲的人看就够了 —— 只进详情页。
|
|
2512
|
-
a.pendingBriefHeader = undefined;
|
|
2513
2494
|
}
|
|
2514
2495
|
else {
|
|
2515
|
-
|
|
2516
|
-
// "只发了一条 link 渲染成空文本" 的前置消息。
|
|
2517
|
-
const header = a.pendingBriefHeader;
|
|
2518
|
-
a.pendingBriefHeader = undefined;
|
|
2519
|
-
sendStandalone(a, header ? `${header} ${item.body}` : item.body);
|
|
2496
|
+
sendStandalone(a, item.body); // 链接前缀同上, 走 withLinkedTag
|
|
2520
2497
|
}
|
|
2521
2498
|
return;
|
|
2522
2499
|
}
|
|
@@ -2755,8 +2732,11 @@ export const startMirror = (deps) => {
|
|
|
2755
2732
|
}
|
|
2756
2733
|
else if (a.softOwed)
|
|
2757
2734
|
armSoftEnd(a, a.softDeferred ? deferredSoftDelay(a) : softTurnEndMsFor(a));
|
|
2758
|
-
//
|
|
2759
|
-
|
|
2735
|
+
// user 行只作边界信号 (上面已清账/推进轮次), 不渲染。brief 下无条件丢:
|
|
2736
|
+
// 有活跃 turn 时 handleBriefItem 本就丢它, 没有 turn 时 (user_text 不是
|
|
2737
|
+
// BRIEF_TURN_OPENERS) 它会一路穿到底部的 standalone fallback —— includeUser=true
|
|
2738
|
+
// 的配置下, 人在 CLI 敲的那一行就这么原样回显进了群, 正好破了 chatOriginOnly。
|
|
2739
|
+
if (item.kind === "user_text" && (item.quiet || cfg.wrc.mirror.brief))
|
|
2760
2740
|
return;
|
|
2761
2741
|
// thinking 唯一的出口是 brief 气泡的 CoT 进度行。必须在这里就吃掉 —— 漏到下面任何
|
|
2762
2742
|
// 一条通道 (deferred buf → renderBuf / standalone / stream append) 都会把它写进正文,
|
|
@@ -3473,9 +3453,10 @@ export const startMirror = (deps) => {
|
|
|
3473
3453
|
const oldJsonlPath = a.jsonlPath;
|
|
3474
3454
|
// 迁移是所有会话轮换的唯一漏斗 (注入的 /clear、TUI 里手打的 /clear、resume fork、
|
|
3475
3455
|
// worktree drift)。只有目标 jsonl 首条用户行是 /clear 的那种才是真清空 —— fork /
|
|
3476
|
-
// drift 上下文是延续的,
|
|
3477
|
-
|
|
3478
|
-
|
|
3456
|
+
// drift 上下文是延续的, 画中性的 "switch"。
|
|
3457
|
+
const cleared = jsonlIsPostClearChild(newJsonlPath);
|
|
3458
|
+
markCut(a.target, newSessionId, cleared ? "clear" : "switch");
|
|
3459
|
+
if (cleared) {
|
|
3479
3460
|
// 真清空 = 缓存里已无任何值得保温的内容。像 /stop 一样暂停保活 —— 与
|
|
3480
3461
|
// dispatch 里 WeCom 注入 /clear 的暂停对齐;TUI 手打 /clear 只走这个漏斗,
|
|
3481
3462
|
// 不在这里停下的话旧时钟会继续 ping 一个空上下文。busy-resume(过 grace)
|
|
@@ -3903,7 +3884,7 @@ export const startMirror = (deps) => {
|
|
|
3903
3884
|
spawned.muteUntilInject = true;
|
|
3904
3885
|
// 只有换过 pane 才是断点 —— 首次 /wrc 建会话时 prev 为空, 那不是"不连续", 是开局。
|
|
3905
3886
|
if (prev)
|
|
3906
|
-
spawned.
|
|
3887
|
+
markCut(target, spawned.sessionId, "new");
|
|
3907
3888
|
// A freshly spawned session is empty — nothing in the cache to keep warm.
|
|
3908
3889
|
// Pause keepalive like /stop; the first real turn (WeCom inbound, or the
|
|
3909
3890
|
// pane going busy after the resume grace) re-earns the budget. Mirrors
|
|
@@ -5009,10 +4990,6 @@ export const startMirror = (deps) => {
|
|
|
5009
4990
|
// see this clear as an overlap by the time it evaluates a candidate.
|
|
5010
4991
|
if (armMigration)
|
|
5011
4992
|
noteClearInject(a);
|
|
5012
|
-
// 记下断点, 由下一轮 (第一轮读不到上文的轮次) 领走。/clear 自己不建 turn,
|
|
5013
|
-
// 否则这次清空在 chat 详情里毫无痕迹, 前后两轮看着还是连续的。
|
|
5014
|
-
if (armMigration)
|
|
5015
|
-
a.ctxCut = "clear";
|
|
5016
4993
|
// 新消息 = 对话边界: 上一 turn 的出站状态在此清算。softEnd 是旧 turn 的
|
|
5017
4994
|
// 静默期收口判决, 残留到新 turn 会在中途开火、提前收掉新气泡/新流;
|
|
5018
4995
|
// deferred 缓冲里是已从 tail 消费但还没下发的 item, 收入旧 streamId 收口
|