@yeaft/webchat-agent 0.1.315 → 0.1.317
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/crew/control.js +2 -0
- package/crew/human-interaction.js +3 -0
- package/crew/persistence.js +18 -0
- package/crew/role-management.js +7 -0
- package/crew/role-output.js +5 -0
- package/crew/routing.js +3 -0
- package/crew/ui-messages.js +2 -5
- package/package.json +1 -1
package/crew/control.js
CHANGED
|
@@ -187,6 +187,8 @@ async function resumeSession(session) {
|
|
|
187
187
|
message: { role: 'assistant', content: [{ type: 'text', text: 'Session 已恢复' }] }
|
|
188
188
|
});
|
|
189
189
|
sendStatusUpdate(session);
|
|
190
|
+
// Status changed to running — persist
|
|
191
|
+
saveSessionMeta(session).catch(e => console.warn('[Crew] Failed to save after resume:', e.message));
|
|
190
192
|
|
|
191
193
|
if (session.pendingRoutes.length > 0) {
|
|
192
194
|
const pending = session.pendingRoutes.slice();
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { dispatchToRole } from './routing.js';
|
|
6
6
|
import { sendStatusUpdate } from './ui-messages.js';
|
|
7
|
+
import { debouncedSaveSessionMeta } from './persistence.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* 处理人的输入
|
|
@@ -50,6 +51,8 @@ export async function handleCrewHumanInput(msg) {
|
|
|
50
51
|
session.status = 'running';
|
|
51
52
|
session.waitingHumanContext = null;
|
|
52
53
|
sendStatusUpdate(session);
|
|
54
|
+
// Status changed + new human message — persist (debounced, dispatch will follow)
|
|
55
|
+
debouncedSaveSessionMeta(session);
|
|
53
56
|
|
|
54
57
|
const target = targetRole || waitingContext?.fromRole || session.decisionMaker;
|
|
55
58
|
await dispatchToRole(session, target, buildHumanContent('人工回复:', content), 'human');
|
package/crew/persistence.js
CHANGED
|
@@ -119,6 +119,24 @@ export async function unhideCrewSession(sessionId) {
|
|
|
119
119
|
// =====================================================================
|
|
120
120
|
|
|
121
121
|
const MESSAGE_SHARD_SIZE = 256 * 1024; // 256KB per shard
|
|
122
|
+
const SAVE_DEBOUNCE_MS = 10_000; // 10 seconds
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Debounced version of saveSessionMeta.
|
|
126
|
+
* Coalesces rapid-fire calls (e.g. multiple role turn-ends) into a single
|
|
127
|
+
* disk write per session, at most once every SAVE_DEBOUNCE_MS.
|
|
128
|
+
*/
|
|
129
|
+
export function debouncedSaveSessionMeta(session) {
|
|
130
|
+
if (session._saveDebounceTimer) {
|
|
131
|
+
clearTimeout(session._saveDebounceTimer);
|
|
132
|
+
}
|
|
133
|
+
session._saveDebounceTimer = setTimeout(() => {
|
|
134
|
+
session._saveDebounceTimer = null;
|
|
135
|
+
saveSessionMeta(session).catch(e =>
|
|
136
|
+
console.warn('[Crew] Debounced save failed:', e.message)
|
|
137
|
+
);
|
|
138
|
+
}, SAVE_DEBOUNCE_MS);
|
|
139
|
+
}
|
|
122
140
|
|
|
123
141
|
export async function saveSessionMeta(session) {
|
|
124
142
|
const meta = {
|
package/crew/role-management.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { initRoleDir, updateSharedClaudeMd } from './shared-dir.js';
|
|
6
6
|
import { saveRoleSessionId } from './role-query.js';
|
|
7
7
|
import { sendCrewMessage, sendCrewOutput, sendStatusUpdate } from './ui-messages.js';
|
|
8
|
+
import { saveSessionMeta, upsertCrewIndex } from './persistence.js';
|
|
8
9
|
|
|
9
10
|
/** Format role label */
|
|
10
11
|
function roleLabel(r) {
|
|
@@ -94,6 +95,9 @@ export async function addRoleToSession(msg) {
|
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
sendStatusUpdate(session);
|
|
98
|
+
// Roles changed — persist
|
|
99
|
+
saveSessionMeta(session).catch(e => console.warn('[Crew] Failed to save after addRole:', e.message));
|
|
100
|
+
upsertCrewIndex(session).catch(e => console.warn('[Crew] Failed to update index after addRole:', e.message));
|
|
97
101
|
}
|
|
98
102
|
|
|
99
103
|
/**
|
|
@@ -152,4 +156,7 @@ export async function removeRoleFromSession(msg) {
|
|
|
152
156
|
});
|
|
153
157
|
|
|
154
158
|
sendStatusUpdate(session);
|
|
159
|
+
// Roles changed — persist
|
|
160
|
+
saveSessionMeta(session).catch(e => console.warn('[Crew] Failed to save after removeRole:', e.message));
|
|
161
|
+
upsertCrewIndex(session).catch(e => console.warn('[Crew] Failed to update index after removeRole:', e.message));
|
|
155
162
|
}
|
package/crew/role-output.js
CHANGED
|
@@ -6,6 +6,7 @@ import { sendCrewMessage, sendCrewOutput, sendStatusUpdate, endRoleStreaming } f
|
|
|
6
6
|
import { saveRoleSessionId, clearRoleSessionId, classifyRoleError, createRoleQuery } from './role-query.js';
|
|
7
7
|
import { parseRoutes, executeRoute, dispatchToRole } from './routing.js';
|
|
8
8
|
import { parseCompletedTasks, updateFeatureIndex, appendChangelog, saveRoleWorkSummary, updateKanban } from './task-files.js';
|
|
9
|
+
import { debouncedSaveSessionMeta, saveSessionMeta } from './persistence.js';
|
|
9
10
|
import ctx from '../context.js';
|
|
10
11
|
|
|
11
12
|
// Context 使用率常量(运行时从 ctx.CONFIG 读取)
|
|
@@ -170,6 +171,8 @@ export async function processRoleOutput(session, roleName, roleQuery, roleState)
|
|
|
170
171
|
});
|
|
171
172
|
|
|
172
173
|
sendStatusUpdate(session);
|
|
174
|
+
// Cost/tokens/messages updated — debounced persist (coalesces rapid turn-ends)
|
|
175
|
+
debouncedSaveSessionMeta(session);
|
|
173
176
|
|
|
174
177
|
// 执行路由
|
|
175
178
|
if (routes.length > 0) {
|
|
@@ -267,6 +270,8 @@ export async function processRoleOutput(session, roleName, roleQuery, roleState)
|
|
|
267
270
|
message: errDetail
|
|
268
271
|
});
|
|
269
272
|
sendStatusUpdate(session);
|
|
273
|
+
// Status changed to waiting_human — persist
|
|
274
|
+
saveSessionMeta(session).catch(e => console.warn('[Crew] Failed to save after error→human:', e.message));
|
|
270
275
|
}
|
|
271
276
|
return;
|
|
272
277
|
}
|
package/crew/routing.js
CHANGED
|
@@ -6,6 +6,7 @@ import { join } from 'path';
|
|
|
6
6
|
import { sendCrewMessage, sendCrewOutput, sendStatusUpdate } from './ui-messages.js';
|
|
7
7
|
import { ensureTaskFile, appendTaskRecord, readTaskFile, updateKanban, readKanban, saveRoleWorkSummary } from './task-files.js';
|
|
8
8
|
import { createRoleQuery, clearRoleSessionId } from './role-query.js';
|
|
9
|
+
import { saveSessionMeta } from './persistence.js';
|
|
9
10
|
import ctx from '../context.js';
|
|
10
11
|
|
|
11
12
|
/** Format role label */
|
|
@@ -169,6 +170,8 @@ export async function executeRoute(session, fromRole, route) {
|
|
|
169
170
|
message: summary
|
|
170
171
|
});
|
|
171
172
|
sendStatusUpdate(session);
|
|
173
|
+
// Status changed to waiting_human — persist
|
|
174
|
+
saveSessionMeta(session).catch(e => console.warn('[Crew] Failed to save after →human:', e.message));
|
|
172
175
|
return;
|
|
173
176
|
}
|
|
174
177
|
|
package/crew/ui-messages.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* sendCrewMessage, sendCrewOutput, sendStatusUpdate, endRoleStreaming, findActiveRole
|
|
4
4
|
*/
|
|
5
5
|
import ctx from '../context.js';
|
|
6
|
-
import { upsertCrewIndex, saveSessionMeta } from './persistence.js';
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* 发送 crew 消息到 server(透传到 Web)
|
|
@@ -257,8 +256,6 @@ export function sendStatusUpdate(session) {
|
|
|
257
256
|
features: getActiveFeatures(session),
|
|
258
257
|
initProgress: session.initProgress || null
|
|
259
258
|
});
|
|
260
|
-
|
|
261
|
-
//
|
|
262
|
-
upsertCrewIndex(session).catch(e => console.warn('[Crew] Failed to update index:', e.message));
|
|
263
|
-
saveSessionMeta(session).catch(e => console.warn('[Crew] Failed to save session meta:', e.message));
|
|
259
|
+
// Persist is NOT called here — callers that change persistent state
|
|
260
|
+
// (status, roles, cost, messages) must call saveSessionMeta explicitly.
|
|
264
261
|
}
|