@xcanwin/manyoyo 7.0.12 → 7.0.15
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/lib/web/server.js
CHANGED
|
@@ -2068,7 +2068,7 @@ async function prepareWebAgentExecution(ctx, state, sessionRef, prompt) {
|
|
|
2068
2068
|
|
|
2069
2069
|
function finalizeWebAgentExecution(state, sessionRef, agentSession, agentMeta, meta, result) {
|
|
2070
2070
|
const turnUsage = extractTurnUsage(agentMeta.agentProgram, result.stdout);
|
|
2071
|
-
appendWebSessionMessage(state.webHistoryDir, sessionRef, 'assistant', result.output, {
|
|
2071
|
+
const replyMessage = appendWebSessionMessage(state.webHistoryDir, sessionRef, 'assistant', result.output, {
|
|
2072
2072
|
exitCode: result.exitCode,
|
|
2073
2073
|
mode: 'agent',
|
|
2074
2074
|
contextMode: meta.contextMode,
|
|
@@ -2090,6 +2090,7 @@ function finalizeWebAgentExecution(state, sessionRef, agentSession, agentMeta, m
|
|
|
2090
2090
|
patch.usageTotal = accumulateUsageTotal(agentSession.usageTotal, turnUsage);
|
|
2091
2091
|
}
|
|
2092
2092
|
patchWebAgentSessionState(state.webHistoryDir, sessionRef, patch);
|
|
2093
|
+
return replyMessage;
|
|
2093
2094
|
}
|
|
2094
2095
|
|
|
2095
2096
|
function appendWebAgentTraceMessage(webHistoryDir, sessionRefOrContainerName, content, extra = {}) {
|
|
@@ -3799,11 +3800,37 @@ function stopWebAgentRun(state, containerName) {
|
|
|
3799
3800
|
try {
|
|
3800
3801
|
runState.process.kill('SIGTERM');
|
|
3801
3802
|
} catch (e) {
|
|
3802
|
-
|
|
3803
|
+
// 进程可能已自行退出,视为停止成功(close 事件会收尾)
|
|
3803
3804
|
}
|
|
3804
3805
|
return true;
|
|
3805
3806
|
}
|
|
3806
3807
|
|
|
3808
|
+
// serve 重启等原因会丢失 agentRuns 运行登记,但消息里可能残留 pending 标记
|
|
3809
|
+
// (孤儿任务:容器里的进程或许还在跑,但再没有任何代码会去收尾这些消息)。
|
|
3810
|
+
// 前端把 pending 视为"任务进行中"会永久禁用输入,这里把它们标记为已中断
|
|
3811
|
+
function interruptOrphanPendingMessages(webHistoryDir, sessionRef) {
|
|
3812
|
+
const history = loadWebSessionHistory(webHistoryDir, sessionRef.containerName);
|
|
3813
|
+
const agentSession = getWebAgentSession(history, sessionRef.agentId, { includeArchived: true });
|
|
3814
|
+
if (!agentSession || !Array.isArray(agentSession.messages)) {
|
|
3815
|
+
return;
|
|
3816
|
+
}
|
|
3817
|
+
let touched = false;
|
|
3818
|
+
for (const message of agentSession.messages) {
|
|
3819
|
+
if (message && message.pending === true) {
|
|
3820
|
+
message.pending = false;
|
|
3821
|
+
message.interrupted = true;
|
|
3822
|
+
touched = true;
|
|
3823
|
+
}
|
|
3824
|
+
}
|
|
3825
|
+
if (!touched) {
|
|
3826
|
+
return;
|
|
3827
|
+
}
|
|
3828
|
+
const timestamp = new Date().toISOString();
|
|
3829
|
+
agentSession.updatedAt = timestamp;
|
|
3830
|
+
history.updatedAt = timestamp;
|
|
3831
|
+
saveWebSessionHistory(webHistoryDir, sessionRef.containerName, history);
|
|
3832
|
+
}
|
|
3833
|
+
|
|
3807
3834
|
function sendHtml(res, statusCode, html, extraHeaders = {}) {
|
|
3808
3835
|
res.writeHead(statusCode, {
|
|
3809
3836
|
'Content-Type': 'text/html; charset=utf-8',
|
|
@@ -5212,7 +5239,8 @@ async function handleWebApi(req, res, pathname, ctx, state) {
|
|
|
5212
5239
|
return;
|
|
5213
5240
|
}
|
|
5214
5241
|
if (state.agentRuns.has(sessionRef.containerName)) {
|
|
5215
|
-
|
|
5242
|
+
// 锁是容器级的:同一容器里其他 agent 会话在跑任务时同样命中这里
|
|
5243
|
+
sendJson(res, 409, { error: '当前容器已有运行中的 agent 任务,请等它结束或先停止' });
|
|
5216
5244
|
return;
|
|
5217
5245
|
}
|
|
5218
5246
|
|
|
@@ -5259,6 +5287,10 @@ async function handleWebApi(req, res, pathname, ctx, state) {
|
|
|
5259
5287
|
type: 'meta',
|
|
5260
5288
|
containerName: sessionRef.containerName,
|
|
5261
5289
|
sessionName: buildWebSessionKey(sessionRef.containerName, sessionRef.agentId),
|
|
5290
|
+
// 前端用这两个 id 把本地乐观占位(local-* / __streaming_trace__)换成
|
|
5291
|
+
// 服务端持久化 id,轮询对账时 React key 才能对得上、DOM 不整体重建
|
|
5292
|
+
userMessageId: userMessage && userMessage.id,
|
|
5293
|
+
traceMessageId: traceMessage && traceMessage.id,
|
|
5262
5294
|
contextMode,
|
|
5263
5295
|
resumeAttempted,
|
|
5264
5296
|
resumeSucceeded,
|
|
@@ -5342,7 +5374,7 @@ async function handleWebApi(req, res, pathname, ctx, state) {
|
|
|
5342
5374
|
if (streamingReplyMessageId) {
|
|
5343
5375
|
removeWebSessionMessage(state.webHistoryDir, sessionRef, streamingReplyMessageId);
|
|
5344
5376
|
}
|
|
5345
|
-
finalizeWebAgentExecution(state, sessionRef, agentSession, agentMeta, {
|
|
5377
|
+
const replyMessage = finalizeWebAgentExecution(state, sessionRef, agentSession, agentMeta, {
|
|
5346
5378
|
contextMode,
|
|
5347
5379
|
resumeAttempted,
|
|
5348
5380
|
resumeSucceeded,
|
|
@@ -5353,6 +5385,9 @@ async function handleWebApi(req, res, pathname, ctx, state) {
|
|
|
5353
5385
|
type: 'result',
|
|
5354
5386
|
exitCode: result.exitCode,
|
|
5355
5387
|
output: result.output,
|
|
5388
|
+
// 最终 assistant 消息的持久化 id:前端把 __streaming__ 占位换成它,
|
|
5389
|
+
// 发送后的首次对账才不会重建整个消息列表 DOM(滚动位置/选区保持)
|
|
5390
|
+
replyMessageId: replyMessage && replyMessage.id,
|
|
5356
5391
|
contextMode,
|
|
5357
5392
|
resumeAttempted,
|
|
5358
5393
|
resumeSucceeded,
|
|
@@ -5397,6 +5432,9 @@ async function handleWebApi(req, res, pathname, ctx, state) {
|
|
|
5397
5432
|
}
|
|
5398
5433
|
const stopped = stopWebAgentRun(state, sessionRef.containerName);
|
|
5399
5434
|
if (!stopped) {
|
|
5435
|
+
// 运行登记不存在(serve 重启后常见的孤儿任务):把残留的
|
|
5436
|
+
// pending 消息标记为已中断,否则前端会因 pending 永久禁用输入
|
|
5437
|
+
interruptOrphanPendingMessages(state.webHistoryDir, sessionRef);
|
|
5400
5438
|
sendJson(res, 404, { error: '当前会话没有运行中的 agent 任务' });
|
|
5401
5439
|
return;
|
|
5402
5440
|
}
|