wezard 1.3.19 → 1.3.20
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 +23 -39
- 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;
|
|
@@ -2086,11 +2087,13 @@ export const startMirror = (deps) => {
|
|
|
2086
2087
|
clearCot(a); // turn 级状态 —— 进度行跟着气泡走, 不能跨 turn 残留
|
|
2087
2088
|
log.info({ sessionId: a.sessionId, turnId: q.turnId, isSlash: q.isSlash }, "brief: turn started");
|
|
2088
2089
|
};
|
|
2089
|
-
//
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2090
|
+
// 上下文断点落一条独立记录 —— 清空/轮换发生在两轮之间, 分隔线就画在两轮之间。
|
|
2091
|
+
// 挂在"下一轮"上等于要等人再开口才显形, 而那一轮还可能被当成空壳 turn 丢掉。
|
|
2092
|
+
// sessionId 记断点之后的那个: detail-store 的轮换判定以它为基准, 免得紧随其后的
|
|
2093
|
+
// 第一轮又被判成一次轮换、多画一条线。
|
|
2094
|
+
const markCut = (target, sessionId, cut) => {
|
|
2095
|
+
recordMark({ id: newMarkId(), target, sessionId, cut });
|
|
2096
|
+
log.info({ target, sessionId, cut }, "detail: context cut marked");
|
|
2094
2097
|
};
|
|
2095
2098
|
// graph 归因同样一次性: 一次注入只解释它开出的那一轮。超过 ORIGIN_TTL_MS 还没被
|
|
2096
2099
|
// 认领 = 那次注入没能开出 turn, 印章作废 —— 宁可少标一轮, 也不能把人打的字冒认成
|
|
@@ -2106,7 +2109,7 @@ export const startMirror = (deps) => {
|
|
|
2106
2109
|
a.queryEpoch = (a.queryEpoch ?? 0) + 1; // WeCom 侧的新一轮同样是 query 边界
|
|
2107
2110
|
a.turnFromChat = true; // 出处确凿: 这一轮有 frame, 群里就是它的主场
|
|
2108
2111
|
a.pendingFromCli = false; // 人改从聊天里说话了, 之前那条 CLI 输入不再是出处
|
|
2109
|
-
recordTurnStart({ id: turnId, target: a.target, sessionId: a.sessionId, cwd: a.runningCwd || undefined, userQuery: userQuery.trim() || undefined,
|
|
2112
|
+
recordTurnStart({ id: turnId, target: a.target, sessionId: a.sessionId, cwd: a.runningCwd || undefined, userQuery: userQuery.trim() || undefined, origin: consumeOrigin(a) });
|
|
2110
2113
|
// hardTimer 兜底: turn 若无终句 / turn_end 收口 (卡死/漏收), 到点仍收气泡。
|
|
2111
2114
|
const bubble = { frame, streamId, hardTimer: undefined, done: false };
|
|
2112
2115
|
const q = { turnId, bubble, isSlash };
|
|
@@ -2152,7 +2155,7 @@ export const startMirror = (deps) => {
|
|
|
2152
2155
|
const fromCli = a.pendingFromCli === true;
|
|
2153
2156
|
a.pendingFromCli = false;
|
|
2154
2157
|
a.turnFromChat = fromCli ? false : a.turnFromChat ?? true;
|
|
2155
|
-
recordTurnStart({ id: turnId, target: a.target, sessionId: a.sessionId, cwd: a.runningCwd || undefined, userQuery: query || undefined,
|
|
2158
|
+
recordTurnStart({ id: turnId, target: a.target, sessionId: a.sessionId, cwd: a.runningCwd || undefined, userQuery: query || undefined, origin: consumeOrigin(a) });
|
|
2156
2159
|
a.briefTurnId = turnId;
|
|
2157
2160
|
a.briefBubble = undefined;
|
|
2158
2161
|
a.briefIsSlash = false;
|
|
@@ -2160,13 +2163,11 @@ export const startMirror = (deps) => {
|
|
|
2160
2163
|
a.briefConcluded = false;
|
|
2161
2164
|
a.briefLastText = undefined;
|
|
2162
2165
|
clearCot(a);
|
|
2163
|
-
//
|
|
2164
|
-
//
|
|
2165
|
-
//
|
|
2166
|
+
// 详情链接不在这里单独发 — 本轮的每条 standalone 都由 withLinkedTag 自带
|
|
2167
|
+
// (linkedTagPrefix 读的正是 a.briefTurnId), 再暂存一份只会在正文前拼出第二条
|
|
2168
|
+
// 一模一样的链接。静默轮没有 standalone 可搭车, 单独提示一次。
|
|
2166
2169
|
if (turnSilent(a))
|
|
2167
2170
|
noticeCliSilent(a, turnId);
|
|
2168
|
-
else
|
|
2169
|
-
a.pendingBriefHeader = briefDetailLink(turnId, a.target);
|
|
2170
2171
|
log.info({ sessionId: a.sessionId, turnId, fromCli, silent: turnSilent(a) }, "brief: turn started (CLI-side, no bubble)");
|
|
2171
2172
|
};
|
|
2172
2173
|
// 本轮出现过工具调用 / tool_result / 非 final 文本 —— 只记状态: 详情链接从 ack 起
|
|
@@ -2198,13 +2199,10 @@ export const startMirror = (deps) => {
|
|
|
2198
2199
|
const turnId = a.briefTurnId;
|
|
2199
2200
|
if (!turnId || a.briefConcluded)
|
|
2200
2201
|
return;
|
|
2201
|
-
if (!body.trim())
|
|
2202
|
-
a.pendingBriefHeader = undefined;
|
|
2202
|
+
if (!body.trim())
|
|
2203
2203
|
return;
|
|
2204
|
-
}
|
|
2205
2204
|
if (isDuplicateConclusion(a, body)) {
|
|
2206
2205
|
a.briefConcluded = true; // 本轮已"定稿", 只是不投递
|
|
2207
|
-
a.pendingBriefHeader = undefined;
|
|
2208
2206
|
log.info({ sessionId: a.sessionId, turnId, epoch: a.queryEpoch ?? 0 }, "brief: duplicate conclusion suppressed");
|
|
2209
2207
|
return;
|
|
2210
2208
|
}
|
|
@@ -2214,17 +2212,13 @@ export const startMirror = (deps) => {
|
|
|
2214
2212
|
a.lastConcludedAt = Date.now();
|
|
2215
2213
|
if (a.briefBubble && !a.briefBubble.done) {
|
|
2216
2214
|
void finishBriefBubble(a, `${briefDetailLink(turnId, a.target)} ${body}`, true);
|
|
2217
|
-
a.pendingBriefHeader = undefined;
|
|
2218
2215
|
}
|
|
2219
2216
|
else if (turnSilent(a)) {
|
|
2220
2217
|
// CLI 手敲的一轮: 终稿只留在 turn store, 详情页照常实时可见。
|
|
2221
|
-
a.pendingBriefHeader = undefined;
|
|
2222
2218
|
log.info({ sessionId: a.sessionId, turnId }, "brief: CLI-origin conclusion kept out of chat");
|
|
2223
2219
|
}
|
|
2224
2220
|
else {
|
|
2225
|
-
|
|
2226
|
-
a.pendingBriefHeader = undefined;
|
|
2227
|
-
sendStandalone(a, header ? `${header} ${body}` : body);
|
|
2221
|
+
sendStandalone(a, body); // 详情链接由 withLinkedTag 统一前缀, 不在这里拼
|
|
2228
2222
|
}
|
|
2229
2223
|
// 只保留当前 turn: 其余仍开着的 turn 记录是漏收的 close, 一并扫掉。
|
|
2230
2224
|
recordCloseOpenTurns({ target: a.target, sessionId: a.sessionId, exceptIds: [turnId] });
|
|
@@ -2246,7 +2240,6 @@ export const startMirror = (deps) => {
|
|
|
2246
2240
|
a.briefIsSlash = false;
|
|
2247
2241
|
a.briefConcluded = false;
|
|
2248
2242
|
a.briefLastText = undefined;
|
|
2249
|
-
a.pendingBriefHeader = undefined;
|
|
2250
2243
|
// 收口 = 欠账两清。前台派发的 result 不会再落回这一轮; 后台派发跨轮存活, 由完成
|
|
2251
2244
|
// 通知 / TTL 销账 (voidTurnAgents)。挂着的软收口计时器一并撤掉 —— 它到点会去收
|
|
2252
2245
|
// 「当前 turn」, 那时的当前 turn 已经是下一轮了。
|
|
@@ -2317,7 +2310,7 @@ export const startMirror = (deps) => {
|
|
|
2317
2310
|
sessionId: a.sessionId,
|
|
2318
2311
|
cwd: a.runningCwd || undefined,
|
|
2319
2312
|
userQuery: task,
|
|
2320
|
-
agent: { id: agentId, type: resolved?.type, description: resolved?.description },
|
|
2313
|
+
agent: { id: agentId, type: resolved?.type, description: resolved?.description, parentTurnId: a.briefTurnId },
|
|
2321
2314
|
});
|
|
2322
2315
|
log.info({ agentId, turnId, label: run.label }, "subagent: turn started");
|
|
2323
2316
|
if (item.kind === "task")
|
|
@@ -2505,18 +2498,12 @@ export const startMirror = (deps) => {
|
|
|
2505
2498
|
// loading 气泡。非 slash 场景的 skill_output 是用户可见的中间反馈, 走 standalone。
|
|
2506
2499
|
if (a.briefIsSlash && !a.briefHadTool && a.briefBubble && !a.briefBubble.done) {
|
|
2507
2500
|
void finishBriefBubble(a, item.body);
|
|
2508
|
-
a.pendingBriefHeader = undefined;
|
|
2509
2501
|
}
|
|
2510
2502
|
else if (turnSilent(a)) {
|
|
2511
2503
|
// CLI 里手敲的 /clear、/model 之类, 回执给敲的人看就够了 —— 只进详情页。
|
|
2512
|
-
a.pendingBriefHeader = undefined;
|
|
2513
2504
|
}
|
|
2514
2505
|
else {
|
|
2515
|
-
|
|
2516
|
-
// "只发了一条 link 渲染成空文本" 的前置消息。
|
|
2517
|
-
const header = a.pendingBriefHeader;
|
|
2518
|
-
a.pendingBriefHeader = undefined;
|
|
2519
|
-
sendStandalone(a, header ? `${header} ${item.body}` : item.body);
|
|
2506
|
+
sendStandalone(a, item.body); // 链接前缀同上, 走 withLinkedTag
|
|
2520
2507
|
}
|
|
2521
2508
|
return;
|
|
2522
2509
|
}
|
|
@@ -3473,9 +3460,10 @@ export const startMirror = (deps) => {
|
|
|
3473
3460
|
const oldJsonlPath = a.jsonlPath;
|
|
3474
3461
|
// 迁移是所有会话轮换的唯一漏斗 (注入的 /clear、TUI 里手打的 /clear、resume fork、
|
|
3475
3462
|
// worktree drift)。只有目标 jsonl 首条用户行是 /clear 的那种才是真清空 —— fork /
|
|
3476
|
-
// drift 上下文是延续的,
|
|
3477
|
-
|
|
3478
|
-
|
|
3463
|
+
// drift 上下文是延续的, 画中性的 "switch"。
|
|
3464
|
+
const cleared = jsonlIsPostClearChild(newJsonlPath);
|
|
3465
|
+
markCut(a.target, newSessionId, cleared ? "clear" : "switch");
|
|
3466
|
+
if (cleared) {
|
|
3479
3467
|
// 真清空 = 缓存里已无任何值得保温的内容。像 /stop 一样暂停保活 —— 与
|
|
3480
3468
|
// dispatch 里 WeCom 注入 /clear 的暂停对齐;TUI 手打 /clear 只走这个漏斗,
|
|
3481
3469
|
// 不在这里停下的话旧时钟会继续 ping 一个空上下文。busy-resume(过 grace)
|
|
@@ -3903,7 +3891,7 @@ export const startMirror = (deps) => {
|
|
|
3903
3891
|
spawned.muteUntilInject = true;
|
|
3904
3892
|
// 只有换过 pane 才是断点 —— 首次 /wrc 建会话时 prev 为空, 那不是"不连续", 是开局。
|
|
3905
3893
|
if (prev)
|
|
3906
|
-
spawned.
|
|
3894
|
+
markCut(target, spawned.sessionId, "new");
|
|
3907
3895
|
// A freshly spawned session is empty — nothing in the cache to keep warm.
|
|
3908
3896
|
// Pause keepalive like /stop; the first real turn (WeCom inbound, or the
|
|
3909
3897
|
// pane going busy after the resume grace) re-earns the budget. Mirrors
|
|
@@ -5009,10 +4997,6 @@ export const startMirror = (deps) => {
|
|
|
5009
4997
|
// see this clear as an overlap by the time it evaluates a candidate.
|
|
5010
4998
|
if (armMigration)
|
|
5011
4999
|
noteClearInject(a);
|
|
5012
|
-
// 记下断点, 由下一轮 (第一轮读不到上文的轮次) 领走。/clear 自己不建 turn,
|
|
5013
|
-
// 否则这次清空在 chat 详情里毫无痕迹, 前后两轮看着还是连续的。
|
|
5014
|
-
if (armMigration)
|
|
5015
|
-
a.ctxCut = "clear";
|
|
5016
5000
|
// 新消息 = 对话边界: 上一 turn 的出站状态在此清算。softEnd 是旧 turn 的
|
|
5017
5001
|
// 静默期收口判决, 残留到新 turn 会在中途开火、提前收掉新气泡/新流;
|
|
5018
5002
|
// deferred 缓冲里是已从 tail 消费但还没下发的 item, 收入旧 streamId 收口
|