@yeaft/webchat-agent 0.1.452 → 0.1.454
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/role-output.js +14 -5
- package/package.json +1 -1
- package/unify/engine.js +4 -0
- package/unify/web-bridge.js +1 -0
package/crew/role-output.js
CHANGED
|
@@ -30,6 +30,9 @@ export function _detectRouteIntent(text) {
|
|
|
30
30
|
/请\s*\S+\s*审查/,
|
|
31
31
|
/转给\s*\S+/,
|
|
32
32
|
/发给\s*\S+/,
|
|
33
|
+
/请\s*(?:rev|test)-\d+/i, // 请 rev-1/test-2 (explicit role mention with request)
|
|
34
|
+
/PR\s*#\d+.*(?:请|review|审查)/i, // PR #123 + review request
|
|
35
|
+
/(?:rev|test)-\d+\s*(?:审查|review|check|测试)/i, // rev-1 审查 / test-2 测试
|
|
33
36
|
/route\s+to\s+\S+/i,
|
|
34
37
|
/submit\s+to\s+\S+/i,
|
|
35
38
|
/forward\s+to\s+\S+/i,
|
|
@@ -252,11 +255,17 @@ export async function processRoleOutput(session, roleName, roleQuery, roleState)
|
|
|
252
255
|
});
|
|
253
256
|
sendStatusUpdate(session);
|
|
254
257
|
} else {
|
|
255
|
-
// ★
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
258
|
+
// ★ No ROUTE found — decide whether to auto-forward to PM
|
|
259
|
+
const isNonPM = roleName !== session.decisionMaker;
|
|
260
|
+
const hasActiveTask = !!roleState.currentTask;
|
|
261
|
+
const hasRouteIntent = _detectRouteIntent(roleState.lastTurnText);
|
|
262
|
+
|
|
263
|
+
if (isNonPM && (hasActiveTask || hasRouteIntent)) {
|
|
264
|
+
// Non-PM role with active task OR routing intent but no ROUTE block:
|
|
265
|
+
// auto-forward to PM so the message doesn't get lost
|
|
266
|
+
const reason = hasActiveTask ? 'has active task' : 'has routing intent';
|
|
267
|
+
console.log(`[Crew] ${roleName} turn ended without ROUTE (${reason}) — auto-forwarding to PM`);
|
|
268
|
+
const autoSummary = `[auto-forward: ${roleName} turn 结束但未输出 ROUTE 块 (${reason})]\n${(roleState.lastTurnText || '').slice(-800).trim()}`;
|
|
260
269
|
await executeRoute(session, roleName, {
|
|
261
270
|
to: session.decisionMaker,
|
|
262
271
|
summary: autoSummary,
|
package/package.json
CHANGED
package/unify/engine.js
CHANGED
|
@@ -374,6 +374,7 @@ export class Engine {
|
|
|
374
374
|
});
|
|
375
375
|
|
|
376
376
|
const startTime = Date.now();
|
|
377
|
+
let ttfbMs = null; // Time to first token
|
|
377
378
|
let responseText = '';
|
|
378
379
|
const toolCalls = [];
|
|
379
380
|
let stopReason = 'end_turn';
|
|
@@ -393,6 +394,7 @@ export class Engine {
|
|
|
393
394
|
})) {
|
|
394
395
|
switch (event.type) {
|
|
395
396
|
case 'text_delta':
|
|
397
|
+
if (ttfbMs === null) ttfbMs = Date.now() - startTime;
|
|
396
398
|
responseText += event.text;
|
|
397
399
|
yield event;
|
|
398
400
|
break;
|
|
@@ -439,6 +441,7 @@ export class Engine {
|
|
|
439
441
|
toolCalls: toolCalls.map(tc => ({ id: tc.id, name: tc.name, input: tc.input })),
|
|
440
442
|
usage: { inputTokens: totalUsage.inputTokens, outputTokens: totalUsage.outputTokens },
|
|
441
443
|
latencyMs,
|
|
444
|
+
ttfbMs,
|
|
442
445
|
stopReason: 'error',
|
|
443
446
|
};
|
|
444
447
|
|
|
@@ -495,6 +498,7 @@ export class Engine {
|
|
|
495
498
|
toolCalls: toolCalls.map(tc => ({ id: tc.id, name: tc.name, input: tc.input })),
|
|
496
499
|
usage: { inputTokens: totalUsage.inputTokens, outputTokens: totalUsage.outputTokens },
|
|
497
500
|
latencyMs,
|
|
501
|
+
ttfbMs,
|
|
498
502
|
stopReason,
|
|
499
503
|
};
|
|
500
504
|
|