wezard 2.0.2 → 2.0.3
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/mirror-bridge.js +17 -11
- package/dist/daemon/mirror-bridge.js.map +1 -1
- package/dist/shared/chat-render.js +1 -1
- package/package.json +1 -1
- package/web/chat.css +24 -13
- package/web/chat.js +32 -33
|
@@ -1655,6 +1655,9 @@ export const startMirror = (deps) => {
|
|
|
1655
1655
|
// for >60s mid-turn and we don't want to drop the bubble while it's chewing.
|
|
1656
1656
|
const FLUSH_MS = 250;
|
|
1657
1657
|
const HARD_TIMEOUT_MS = 350_000;
|
|
1658
|
+
/** hard cap 到点时的中间结束语: 气泡必须 finish=true, 但 turn 还在跑 —— 明说
|
|
1659
|
+
* 「没完, 去链接看」, 而不是让气泡停在一句看似说完的话 / 一行过期的进度上。 */
|
|
1660
|
+
const STILL_WORKING = "⏳ 仍在处理中, 点击链接查看详情…";
|
|
1658
1661
|
/** 软收口静默期。后端只能说"这条消息写完了"(codebuddy) 时, 等这么久没有新 item
|
|
1659
1662
|
* 才认定一轮结束。取值只需盖住"叙述消息落盘 → 紧随其后的 function_call 落盘"
|
|
1660
1663
|
* 这一段, 与模型思考/工具执行时长无关。
|
|
@@ -1721,7 +1724,7 @@ export const startMirror = (deps) => {
|
|
|
1721
1724
|
return;
|
|
1722
1725
|
s.flushTimer = setTimeout(() => void flushStream(s), FLUSH_MS);
|
|
1723
1726
|
};
|
|
1724
|
-
const finalizeStream = async (a, s) => {
|
|
1727
|
+
const finalizeStream = async (a, s, timedOut = false) => {
|
|
1725
1728
|
if (s.closed)
|
|
1726
1729
|
return;
|
|
1727
1730
|
s.closed = true;
|
|
@@ -1743,17 +1746,20 @@ export const startMirror = (deps) => {
|
|
|
1743
1746
|
// 没正文不写: finish=true 是整条覆盖, 空正文只会把 "…" ack 覆盖成光秃秃的
|
|
1744
1747
|
// 链接头, 结束处理自己制造错发。气泡保持现有内容, 由 WeCom 6min 窗口自然
|
|
1745
1748
|
// 到期。dead 流同理只做本地清理。
|
|
1746
|
-
|
|
1749
|
+
// 例外是 hard cap 超时: turn 还在跑, 收口时缀上中间结束语 —— 这时即使没正文
|
|
1750
|
+
// 也有话可说, 不算空覆盖。
|
|
1751
|
+
const body = timedOut ? [s.acc, STILL_WORKING].filter((x) => x.trim()).join("\n\n") : s.acc;
|
|
1752
|
+
if (!s.dead && body.trim()) {
|
|
1747
1753
|
const card = detailCardFor(s, a.target);
|
|
1748
1754
|
try {
|
|
1749
1755
|
if (card) {
|
|
1750
1756
|
s.cardSent = true;
|
|
1751
|
-
await client.replyStreamWithCard(s.frame, s.streamId, withLinkedTag(a,
|
|
1757
|
+
await client.replyStreamWithCard(s.frame, s.streamId, withLinkedTag(a, body, undefined, s.turnId), true, { templateCard: card });
|
|
1752
1758
|
}
|
|
1753
1759
|
else {
|
|
1754
|
-
await client.replyStream(s.frame, s.streamId, withLinkedTag(a,
|
|
1760
|
+
await client.replyStream(s.frame, s.streamId, withLinkedTag(a, body, undefined, s.turnId), true);
|
|
1755
1761
|
}
|
|
1756
|
-
log.info({ sessionId: a.sessionId, turnId: s.turnId, accLen: s.acc.length, tools: s.tools.length, withCard: !!card }, "stream finalize");
|
|
1762
|
+
log.info({ sessionId: a.sessionId, turnId: s.turnId, accLen: s.acc.length, tools: s.tools.length, withCard: !!card, timedOut }, "stream finalize");
|
|
1757
1763
|
}
|
|
1758
1764
|
catch (e) {
|
|
1759
1765
|
log.warn({ sessionId: a.sessionId, turnId: s.turnId, err: e.message }, "stream finalize failed");
|
|
@@ -1783,7 +1789,7 @@ export const startMirror = (deps) => {
|
|
|
1783
1789
|
capped: false, closed: false, dead: false, cardSent: false,
|
|
1784
1790
|
tools: [], sawTool: false,
|
|
1785
1791
|
};
|
|
1786
|
-
s.hardTimer = setTimeout(() => void finalizeStream(a, s), HARD_TIMEOUT_MS);
|
|
1792
|
+
s.hardTimer = setTimeout(() => void finalizeStream(a, s, true), HARD_TIMEOUT_MS);
|
|
1787
1793
|
log.info({ sessionId: a.sessionId, turnId: s.turnId, streamId }, "stream open");
|
|
1788
1794
|
return s;
|
|
1789
1795
|
};
|
|
@@ -2261,11 +2267,11 @@ export const startMirror = (deps) => {
|
|
|
2261
2267
|
const bubble = { frame, streamId, hardTimer: undefined, done: false };
|
|
2262
2268
|
const q = { turnId, bubble, isSlash };
|
|
2263
2269
|
bubble.hardTimer = setTimeout(() => {
|
|
2264
|
-
// WeCom ~6min stream 窗口快到, 必须 finish=true
|
|
2265
|
-
//
|
|
2266
|
-
//
|
|
2267
|
-
const
|
|
2268
|
-
void finishBubble(a, bubble, `${briefDetailLink(turnId, a.target)}${
|
|
2270
|
+
// WeCom ~6min stream 窗口快到, 必须 finish=true 收口。finish 是整条替换 ——
|
|
2271
|
+
// 定格在一行过期的 CoT 进度上看着像卡死, 光链接又像说完了; 气泡仍是本轮活跃
|
|
2272
|
+
// 气泡 (turn 还在跑) 就明说「仍在处理中」, 已被顶替的旧轮只留链接。
|
|
2273
|
+
const live = a.briefBubble === bubble && !a.briefConcluded;
|
|
2274
|
+
void finishBubble(a, bubble, `${briefDetailLink(turnId, a.target)}${live ? ` ${STILL_WORKING}` : ""}`, true);
|
|
2269
2275
|
}, HARD_TIMEOUT_MS);
|
|
2270
2276
|
// 新消息 = 对话边界: 立刻收掉上一 turn, 新 turn 直接激活、不排队。收口语义见
|
|
2271
2277
|
// closeBriefTurn: 有正文收入旧气泡, 没正文不写一个字 (绝不因边界结束凭空新发/
|