@yeaft/webchat-agent 0.1.788 → 0.1.790

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.788",
3
+ "version": "0.1.790",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/unify/engine.js CHANGED
@@ -1782,7 +1782,7 @@ export class Engine {
1782
1782
 
1783
1783
  // PR-L: T2 end-of-turn (asynchronous) reflection. Fires when the
1784
1784
  // total tool count for this query() exceeds TURN_SUMMARY_THRESHOLD
1785
- // (5) AND no T1 has actually rewritten the arc yet. Kicks off the
1785
+ // (8) AND no T1 has actually rewritten the arc yet. Kicks off the
1786
1786
  // primary-model call without await; the next query()'s
1787
1787
  // `#applyPendingT2Reflections` carries the result forward.
1788
1788
  //
@@ -10,16 +10,30 @@
10
10
  *
11
11
  * The constants are NOT config-driven — V7 design freezes them in code.
12
12
  *
13
+ * Invariant: TURN_SUMMARY_THRESHOLD < TOOL_BATCH_SIZE. T1 runs inside the
14
+ * turn and collapses history in place; T2 fires at end_turn and is gated
15
+ * by `t1CollapsesDone === 0` (engine.js). If T2 were ever set ≥ T1, T1
16
+ * would collapse first and T2 could never fire — silently disabling the
17
+ * end-of-turn reflection path. Keep a usefully wide gap between the two
18
+ * so the (T2, T1) band where T2-alone applies stays meaningful.
19
+ *
13
20
  * TOOL_BATCH_SIZE history: was 13 originally; raised to 30 (2026-05-15)
14
21
  * after user feedback that 13 fired too often inside a single task and
15
22
  * fragmented otherwise-coherent tool arcs into multiple reflections. 30
16
23
  * keeps the periodic-reflection contract (it still fires every N tools,
17
24
  * not just once) but gives a single task arc room to breathe before the
18
25
  * arc gets collapsed.
26
+ *
27
+ * TURN_SUMMARY_THRESHOLD history: was 5 originally; raised to 8
28
+ * (2026-05-18). 5 was too aggressive — small "read a few files, edit one,
29
+ * run tests" turns crossed it and produced a T2 reflection card the user
30
+ * didn't want. 8 lets short-to-medium turns finish without a reflection
31
+ * while still folding the long ones that genuinely benefit from a summary
32
+ * before the next turn's history grows.
19
33
  */
20
34
 
21
35
  export const TOOL_BATCH_SIZE = 30;
22
- export const TURN_SUMMARY_THRESHOLD = 5;
36
+ export const TURN_SUMMARY_THRESHOLD = 8;
23
37
  export const DUP_TOOL_THRESHOLD = 3;
24
38
 
25
39
  export { ExecLog, buildEntry, argsHashOf } from './exec-log.js';
@@ -109,9 +109,11 @@ Returns JSON: { ok, dispatched?, error?, detail? }.`,
109
109
  // task-707: hand off control. Successful forward means the originating
110
110
  // turn should NOT continue generating — the target VPs are now in
111
111
  // charge. Signal the engine to break the tool-loop after this batch.
112
- // The structured payload feeds web-bridge's `group_handoff` UX event
113
- // so the frontend can render "↪ 已转交给 @vp-x、@vp-y" without
114
- // re-parsing a string.
112
+ // The structured payload lands on `turn_end.detail` as audit metadata
113
+ // (kind, fromVpId, dispatched, broadcast, text, reason); the frontend
114
+ // renders the hand-off as a Route tool chip from the tool_call
115
+ // envelope already on the wire (see PR #793 — the previous
116
+ // `group_handoff` UI event was removed when its single consumer was).
115
117
  if (typeof ctx.requestEndTurn === 'function') {
116
118
  try {
117
119
  ctx.requestEndTurn({
@@ -1404,34 +1404,14 @@ function handleEngineEvent(event, hctx) {
1404
1404
  break;
1405
1405
 
1406
1406
  case 'turn_end':
1407
- // When a tool (currently only `route_forward`) signals
1408
- // requestEndTurn, the engine emits turn_end with
1409
- // stopReason='tool_handoff' and a structured `detail` payload.
1410
- // Surface that to the frontend as a `group_handoff` event so the
1411
- // originating VP's bubble can render "↪ 已转交给 @vp-b、@vp-c".
1412
- // Other turn_end variants are ignored (the outer loop handles
1413
- // result/end_turn semantics already).
1414
- //
1415
- // The `version` field is the wire schema version. Today there is
1416
- // only one shape. Future variants (e.g. a second hand-off tool)
1417
- // can bump it without breaking older frontends — they ignore
1418
- // unknown versions.
1419
- if (event.stopReason === 'tool_handoff' && event.detail && typeof event.detail === 'object') {
1420
- const detail = event.detail;
1421
- if (detail.kind === 'route_forward') {
1422
- sendUnifyEvent({
1423
- type: 'group_handoff',
1424
- version: 1,
1425
- kind: 'route_forward',
1426
- fromVpId: detail.fromVpId || hctx.vpId,
1427
- toVpIds: Array.isArray(detail.dispatched) ? detail.dispatched.slice() : [],
1428
- broadcast: Boolean(detail.broadcast),
1429
- text: typeof detail.text === 'string' ? detail.text : '',
1430
- reason: detail.reason || null,
1431
- ts: Date.now(),
1432
- }, envelope);
1433
- }
1434
- }
1407
+ // turn_end variants are handled by the outer loop (result /
1408
+ // end_turn semantics). PR #793 removed the `group_handoff`
1409
+ // wire event that the frontend used to render a "↪ 已转交给"
1410
+ // pill the Route tool chip (rendered from the tool_call
1411
+ // envelope already on the wire) is the single source of truth
1412
+ // for hand-off UX. If a future feature (notification toast,
1413
+ // typing-chain animation, ) needs the structured payload,
1414
+ // re-emit a wire event here from `event.detail`.
1435
1415
  break;
1436
1416
 
1437
1417
  case 'usage':