@yeaft/webchat-agent 0.1.853 → 0.1.856

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.
Files changed (174) hide show
  1. package/bin/yeaft-stats.js +3 -3
  2. package/connection/message-router.js +73 -44
  3. package/context.js +4 -4
  4. package/expert-roles.js +1 -1
  5. package/index.js +1 -1
  6. package/package.json +4 -4
  7. package/service/index.js +1 -1
  8. package/{unify → yeaft}/attachments.js +7 -7
  9. package/{unify → yeaft}/cli.js +4 -4
  10. package/{unify → yeaft}/compact/compactor.js +10 -10
  11. package/{unify → yeaft}/config-api.js +12 -12
  12. package/{unify → yeaft}/config.js +19 -19
  13. package/{unify → yeaft}/conversation/migrate-messages-threadid.js +1 -1
  14. package/{unify → yeaft}/conversation/persist.js +194 -65
  15. package/{unify → yeaft}/conversation/search.js +28 -23
  16. package/{unify → yeaft}/debug-trace.js +1 -1
  17. package/{unify → yeaft}/dream-v2/limits.js +3 -3
  18. package/{unify → yeaft}/dream-v2/runner.js +1 -1
  19. package/{unify → yeaft}/dream-v2/session-wiring.js +2 -2
  20. package/{unify → yeaft}/effort.js +2 -2
  21. package/{unify → yeaft}/engine.js +12 -14
  22. package/{unify → yeaft}/eval/run-eval.js +11 -11
  23. package/{unify → yeaft}/eval/runner.js +1 -1
  24. package/{unify → yeaft}/groups/feature-flag.js +2 -2
  25. package/{unify → yeaft}/groups/index.js +2 -2
  26. package/{unify → yeaft}/groups/pre-flow.js +1 -1
  27. package/{unify → yeaft}/groups/project-doc.js +1 -1
  28. package/{unify → yeaft}/history-compact.js +3 -3
  29. package/{unify → yeaft}/index.js +1 -1
  30. package/{unify → yeaft}/init.js +15 -9
  31. package/{unify → yeaft}/llm/adapter.js +1 -1
  32. package/{unify → yeaft}/llm/anthropic.js +2 -2
  33. package/{unify → yeaft}/llm/models-dev.js +10 -3
  34. package/{unify → yeaft}/llm/openai-responses.js +2 -2
  35. package/{unify → yeaft}/llm/router.js +1 -1
  36. package/{unify → yeaft}/mcp.js +1 -1
  37. package/{unify → yeaft}/memory/ams-registry.js +1 -1
  38. package/{unify → yeaft}/memory/seed-backfill.js +1 -1
  39. package/{unify → yeaft}/memory/store-v2.js +1 -1
  40. package/{unify → yeaft}/models.js +3 -3
  41. package/{unify → yeaft}/pair-sanitize.js +2 -2
  42. package/{unify → yeaft}/personas.js +1 -1
  43. package/{unify → yeaft}/prompts.js +1 -1
  44. package/{unify → yeaft}/routing/index.js +1 -1
  45. package/{unify → yeaft}/routing/router.js +1 -1
  46. package/{unify → yeaft}/session.js +8 -8
  47. package/{unify → yeaft}/skills.js +2 -2
  48. package/{unify → yeaft}/stats/format.js +1 -1
  49. package/{unify → yeaft}/stop-hooks.js +1 -1
  50. package/{unify → yeaft}/sub-agent/runner.js +1 -1
  51. package/{unify → yeaft}/tools/ask-user.js +2 -2
  52. package/{unify → yeaft}/tools/enter-worktree.js +1 -1
  53. package/{unify → yeaft}/tools/exit-worktree.js +1 -1
  54. package/{unify → yeaft}/tools/mcp-tools.js +1 -1
  55. package/{unify → yeaft}/tools/registry.js +2 -2
  56. package/{unify → yeaft}/tools/skill.js +1 -1
  57. package/{unify → yeaft}/tools/start-plan.js +1 -1
  58. package/{unify → yeaft}/tools/types.js +3 -3
  59. package/{unify → yeaft}/tools/web-search.js +1 -1
  60. package/{unify → yeaft}/turn-utils.js +1 -1
  61. package/{unify → yeaft}/vp/index.js +1 -1
  62. package/{unify → yeaft}/vp/registry.js +1 -1
  63. package/{unify → yeaft}/vp/vp-bridge.js +8 -8
  64. package/{unify → yeaft}/web-bridge.js +239 -238
  65. /package/{unify → yeaft}/archive/tool-results.js +0 -0
  66. /package/{unify → yeaft}/archive/trace.js +0 -0
  67. /package/{unify → yeaft}/archive/turn-archive.js +0 -0
  68. /package/{unify → yeaft}/compact/decisions-log.js +0 -0
  69. /package/{unify → yeaft}/compact/orchestrator.js +0 -0
  70. /package/{unify → yeaft}/compact/triggers.js +0 -0
  71. /package/{unify → yeaft}/compact/turn-group.js +0 -0
  72. /package/{unify → yeaft}/dream-v2/apply.js +0 -0
  73. /package/{unify → yeaft}/dream-v2/merge.js +0 -0
  74. /package/{unify → yeaft}/dream-v2/prompts/create.md +0 -0
  75. /package/{unify → yeaft}/dream-v2/prompts/extract-group.md +0 -0
  76. /package/{unify → yeaft}/dream-v2/prompts/extract-topic.md +0 -0
  77. /package/{unify → yeaft}/dream-v2/prompts/extract-user.md +0 -0
  78. /package/{unify → yeaft}/dream-v2/prompts/extract-vp.md +0 -0
  79. /package/{unify → yeaft}/dream-v2/prompts/index.js +0 -0
  80. /package/{unify → yeaft}/dream-v2/prompts/summarize-scope.md +0 -0
  81. /package/{unify → yeaft}/dream-v2/prompts/triage-pass1.md +0 -0
  82. /package/{unify → yeaft}/dream-v2/prompts/triage-pass2.md +0 -0
  83. /package/{unify → yeaft}/dream-v2/prompts/update.md +0 -0
  84. /package/{unify → yeaft}/dream-v2/schedule.js +0 -0
  85. /package/{unify → yeaft}/dream-v2/segment.js +0 -0
  86. /package/{unify → yeaft}/dream-v2/snapshot.js +0 -0
  87. /package/{unify → yeaft}/dream-v2/state.js +0 -0
  88. /package/{unify → yeaft}/dream-v2/triage.js +0 -0
  89. /package/{unify → yeaft}/eval/cases/e2e.js +0 -0
  90. /package/{unify → yeaft}/eval/cases/memory.js +0 -0
  91. /package/{unify → yeaft}/eval/cases/skills.js +0 -0
  92. /package/{unify → yeaft}/eval/cases/tool-use.js +0 -0
  93. /package/{unify → yeaft}/groups/coordinator.js +0 -0
  94. /package/{unify → yeaft}/groups/group-config.js +0 -0
  95. /package/{unify → yeaft}/groups/group-crud.js +0 -0
  96. /package/{unify → yeaft}/groups/group-store.js +0 -0
  97. /package/{unify → yeaft}/groups/ids.js +0 -0
  98. /package/{unify → yeaft}/groups/roster.js +0 -0
  99. /package/{unify → yeaft}/groups/seed-default.js +0 -0
  100. /package/{unify → yeaft}/llm/credentials/github-copilot.js +0 -0
  101. /package/{unify → yeaft}/llm/credentials/index.js +0 -0
  102. /package/{unify → yeaft}/memory/adjust.js +0 -0
  103. /package/{unify → yeaft}/memory/ams.js +0 -0
  104. /package/{unify → yeaft}/memory/budget.js +0 -0
  105. /package/{unify → yeaft}/memory/consolidate.js +0 -0
  106. /package/{unify → yeaft}/memory/index-db.js +0 -0
  107. /package/{unify → yeaft}/memory/keywords.js +0 -0
  108. /package/{unify → yeaft}/memory/preflow.js +0 -0
  109. /package/{unify → yeaft}/memory/segment-store.js +0 -0
  110. /package/{unify → yeaft}/memory/segment-sync.js +0 -0
  111. /package/{unify → yeaft}/memory/segment.js +0 -0
  112. /package/{unify → yeaft}/memory/summary-store.js +0 -0
  113. /package/{unify → yeaft}/router/continuity.js +0 -0
  114. /package/{unify → yeaft}/router/thinking.js +0 -0
  115. /package/{unify → yeaft}/routing/loop-guard.js +0 -0
  116. /package/{unify → yeaft}/stats/tool-usage.js +0 -0
  117. /package/{unify → yeaft}/storage/atomic.js +0 -0
  118. /package/{unify → yeaft}/storage/compact.js +0 -0
  119. /package/{unify → yeaft}/storage/index.js +0 -0
  120. /package/{unify → yeaft}/storage/jsonl-index.js +0 -0
  121. /package/{unify → yeaft}/storage/jsonl-log.js +0 -0
  122. /package/{unify → yeaft}/storage/shard-index.js +0 -0
  123. /package/{unify → yeaft}/storage/shard-store.js +0 -0
  124. /package/{unify → yeaft}/sub-agent/spawned-prompt.js +0 -0
  125. /package/{unify → yeaft}/templates/base.md +0 -0
  126. /package/{unify → yeaft}/templates/common-rules.md +0 -0
  127. /package/{unify → yeaft}/templates/harness/router-handoff.md +0 -0
  128. /package/{unify → yeaft}/templates/harness/router-shape.md +0 -0
  129. /package/{unify → yeaft}/templates/harness/worker-shape.md +0 -0
  130. /package/{unify → yeaft}/templates/identity-yeaft.md +0 -0
  131. /package/{unify → yeaft}/templates/mode-dream.md +0 -0
  132. /package/{unify → yeaft}/templates/mode-unified.md +0 -0
  133. /package/{unify → yeaft}/templates/personas/explorer.md +0 -0
  134. /package/{unify → yeaft}/templates/personas/implementer.md +0 -0
  135. /package/{unify → yeaft}/templates/personas/researcher.md +0 -0
  136. /package/{unify → yeaft}/templates/personas/reviewer.md +0 -0
  137. /package/{unify → yeaft}/templates/plan-instruction.md +0 -0
  138. /package/{unify → yeaft}/templates/tool-guidance.md +0 -0
  139. /package/{unify → yeaft}/tool-folding/exec-log.js +0 -0
  140. /package/{unify → yeaft}/tool-folding/fallback-stub.js +0 -0
  141. /package/{unify → yeaft}/tool-folding/index.js +0 -0
  142. /package/{unify → yeaft}/tool-folding/reflection-prompt.js +0 -0
  143. /package/{unify → yeaft}/tool-folding/t1-reflector.js +0 -0
  144. /package/{unify → yeaft}/tool-folding/t2-reflector.js +0 -0
  145. /package/{unify → yeaft}/tools/agent.js +0 -0
  146. /package/{unify → yeaft}/tools/apply-patch.js +0 -0
  147. /package/{unify → yeaft}/tools/bash.js +0 -0
  148. /package/{unify → yeaft}/tools/close-agent.js +0 -0
  149. /package/{unify → yeaft}/tools/file-edit.js +0 -0
  150. /package/{unify → yeaft}/tools/file-read.js +0 -0
  151. /package/{unify → yeaft}/tools/file-write.js +0 -0
  152. /package/{unify → yeaft}/tools/glob.js +0 -0
  153. /package/{unify → yeaft}/tools/grep.js +0 -0
  154. /package/{unify → yeaft}/tools/history-search.js +0 -0
  155. /package/{unify → yeaft}/tools/image-generation.js +0 -0
  156. /package/{unify → yeaft}/tools/index.js +0 -0
  157. /package/{unify → yeaft}/tools/js-repl.js +0 -0
  158. /package/{unify → yeaft}/tools/list-agents.js +0 -0
  159. /package/{unify → yeaft}/tools/list-dir.js +0 -0
  160. /package/{unify → yeaft}/tools/notebook-edit.js +0 -0
  161. /package/{unify → yeaft}/tools/route-forward.js +0 -0
  162. /package/{unify → yeaft}/tools/send-message.js +0 -0
  163. /package/{unify → yeaft}/tools/todo-write.js +0 -0
  164. /package/{unify → yeaft}/tools/view-image.js +0 -0
  165. /package/{unify → yeaft}/tools/wait-agent.js +0 -0
  166. /package/{unify → yeaft}/tools/web-fetch.js +0 -0
  167. /package/{unify → yeaft}/vp/seed-defaults.js +0 -0
  168. /package/{unify → yeaft}/vp/seed-topup.js +0 -0
  169. /package/{unify → yeaft}/vp/stock-ids.js +0 -0
  170. /package/{unify → yeaft}/vp/thread-classifier.js +0 -0
  171. /package/{unify → yeaft}/vp/vp-crud.js +0 -0
  172. /package/{unify → yeaft}/vp/vp-loader.js +0 -0
  173. /package/{unify → yeaft}/vp/vp-store.js +0 -0
  174. /package/{unify → yeaft}/vp-status-broker.js +0 -0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * web-bridge.js — Bridge between web UI and Yeaft Unify Engine.
2
+ * web-bridge.js — Bridge between web UI and Yeaft Yeaft Engine.
3
3
  *
4
4
  * PR #797: group VP runtime is threaded again. Each group VP can own multiple
5
5
  * classified threads, keyed by (groupId, vpId, threadId), with separate engine,
@@ -52,7 +52,7 @@ import { seedDefaultGroup } from './groups/seed-default.js';
52
52
  import {
53
53
  trimSnapshotForBudget,
54
54
  } from './history-compact.js';
55
- import { persistUnifyAttachments, attachmentsForPersistence, persistedAttachmentPreviewPayload } from './attachments.js';
55
+ import { persistYeaftAttachments, attachmentsForPersistence, persistedAttachmentPreviewPayload } from './attachments.js';
56
56
  import { parseSeqFromId } from './conversation/persist.js';
57
57
  import { sliceLastNTurns } from './turn-utils.js';
58
58
  import { createVpStatusBroker } from './vp-status-broker.js';
@@ -70,7 +70,7 @@ export function __testSetThreadClassifier(fn) {
70
70
 
71
71
  /**
72
72
  * Tracks scoped-dream triggers that are currently inflight, keyed by
73
- * groupId. Used by `handleUnifyDreamTrigger` to reject any overlapping
73
+ * groupId. Used by `handleYeaftDreamTrigger` to reject any overlapping
74
74
  * scoped trigger rather than racing the sink-wrapping logic against
75
75
  * itself.
76
76
  *
@@ -103,8 +103,8 @@ let currentAbortCtrl = null;
103
103
  /**
104
104
  * Per-VP-turn AbortControllers. Maps `turnId` → `AbortController`.
105
105
  * Each VP-turn in a fan-out gets its own controller so it can be stopped
106
- * independently (per-VP Stop button). `handleUnifyAbortTurn` looks up by
107
- * turnId to abort a single VP. `handleUnifyAbortAll` iterates and aborts all.
106
+ * independently (per-VP Stop button). `handleYeaftAbortTurn` looks up by
107
+ * turnId to abort a single VP. `handleYeaftAbortAll` iterates and aborts all.
108
108
  * @type {Map<string, AbortController>}
109
109
  */
110
110
  const turnAbortCtrls = new Map();
@@ -118,7 +118,7 @@ const turnAbortMeta = new Map();
118
118
 
119
119
  /**
120
120
  * Per-VP status broker — the agent-side authority for VP timeline
121
- * status. Lazy-initialized on first use because `sendUnifyEvent` is
121
+ * status. Lazy-initialized on first use because `sendYeaftEvent` is
122
122
  * declared below; trying to call it at module top-level would crash
123
123
  * with a TDZ error during agent boot.
124
124
  *
@@ -134,8 +134,8 @@ function getVpStatusBroker() {
134
134
  vpStatusBroker = createVpStatusBroker({
135
135
  send: (event) => {
136
136
  // The broker emits both `vp_status_changed` and
137
- // `vp_status_snapshot`. Both ride the standard sendUnifyEvent
138
- // envelope so the frontend's existing unify_output dispatcher
137
+ // `vp_status_snapshot`. Both ride the standard sendYeaftEvent
138
+ // envelope so the frontend's existing yeaft_output dispatcher
139
139
  // sees them. We stamp groupId/vpId on the envelope for
140
140
  // events that target a specific VP so the server's per-client
141
141
  // routing (groupId scoping, etc.) works the same way as
@@ -146,7 +146,7 @@ function getVpStatusBroker() {
146
146
  if (event.vpId) env.vpId = event.vpId;
147
147
  if (event.turnId) env.turnId = event.turnId;
148
148
  }
149
- sendUnifyEvent(event, env);
149
+ sendYeaftEvent(event, env);
150
150
  },
151
151
  });
152
152
  }
@@ -202,7 +202,7 @@ const vpAborts = new Map();
202
202
  const vpCurrentTodos = new Map();
203
203
  /**
204
204
  * Per-group cached coordinator + router. Created on first
205
- * `handleUnifyGroupChat` for a given groupId; reused across user messages
205
+ * `handleYeaftGroupChat` for a given groupId; reused across user messages
206
206
  * AND across `route_forward` deliveries inside running VP turns (the
207
207
  * router is wired into engine ctx; if we recreated coord per turn the
208
208
  * route_forward path would deliver into a freshly-created `captured[]`
@@ -213,9 +213,9 @@ const vpCurrentTodos = new Map();
213
213
  * handler that mutates roster / meta / lifecycle state on disk
214
214
  * (rename, update announcement, archive, delete, add/remove member,
215
215
  * set default VP).
216
- * - `handleUnifyGroupChat` — invalidates inline when its own
216
+ * - `handleYeaftGroupChat` — invalidates inline when its own
217
217
  * auto-add / default-VP-heal pass mutated the roster.
218
- * - `resetUnifySession` and `__testResetVpState` clear the whole map.
218
+ * - `resetYeaftSession` and `__testResetVpState` clear the whole map.
219
219
  *
220
220
  * @type {Map<string, { coord: ReturnType<typeof createCoordinator>,
221
221
  * router: ReturnType<typeof createRouter>,
@@ -383,7 +383,7 @@ function invalidateGroupContext(groupId) {
383
383
  // Engines are NOT torn down here on purpose. They hold subordinate
384
384
  // state (AMS adjustments) that should survive a meta change and a
385
385
  // closed groupHandle — they don't reach the on-disk group meta
386
- // directly. They *are* dropped on `resetUnifySession`.
386
+ // directly. They *are* dropped on `resetYeaftSession`.
387
387
  }
388
388
 
389
389
  /**
@@ -449,8 +449,8 @@ const QUERY_TIMEOUT_MS = 120_000;
449
449
  */
450
450
  const ESCALATE_AFTER_ABORT_MS = 15_000;
451
451
 
452
- /** Virtual conversationId for the Unify session */
453
- let unifyConversationId = null;
452
+ /** Virtual conversationId for the Yeaft session */
453
+ let yeaftConversationId = null;
454
454
 
455
455
  /** task-334-followup-batch-b: stored unsubscribe fn from VP subscribe,
456
456
  * called on session reset to prevent stale subscriber leaks. */
@@ -624,7 +624,7 @@ function loadVisibleGroupHistoryPage(store, groupId, limit, beforeSeq = null) {
624
624
  rows = store.loadRecentByGroup(groupId, Infinity);
625
625
  }
626
626
  } catch (err) {
627
- console.error('[Unify] visible history page load failed:', err?.message || err);
627
+ console.error('[Yeaft] visible history page load failed:', err?.message || err);
628
628
  return { messages: [], oldestSeq: null, hasMore: false };
629
629
  }
630
630
 
@@ -660,7 +660,7 @@ function hydrateGroupHistory(groupId) {
660
660
  try {
661
661
  recent = session.conversationStore.loadRecentByGroup(groupId);
662
662
  } catch (err) {
663
- console.warn('[Unify] hydrateGroupHistory failed (groupId=%s):', groupId, err?.message || err);
663
+ console.warn('[Yeaft] hydrateGroupHistory failed (groupId=%s):', groupId, err?.message || err);
664
664
  return [];
665
665
  }
666
666
  const out = [];
@@ -852,7 +852,7 @@ function getOrCreateVpEngine(groupId, vpId, threadId = 'main') {
852
852
  mcpManager: session.mcpManager,
853
853
  yeaftDir: session.yeaftDir,
854
854
  // Share the session-shared ToolUsageStats so per-VP tool calls land
855
- // in the same on-disk snapshot the `unify_fetch_tool_stats` handler
855
+ // in the same on-disk snapshot the `yeaft_fetch_tool_stats` handler
856
856
  // reads. Without this, engine's record-on-tool-exec guard
857
857
  // (`if (this.#toolStats && ...)`) is false and group VP tool calls
858
858
  // are silently dropped.
@@ -873,7 +873,7 @@ function getOrCreateVpEngine(groupId, vpId, threadId = 'main') {
873
873
  *
874
874
  * The coordinator MUST be reused across user turns AND across in-flight
875
875
  * tool calls (route_forward) — its `deliver` callback is the only way
876
- * envelopes reach `vpInboxes`. If we recreated it per `handleUnifyGroupChat`
876
+ * envelopes reach `vpInboxes`. If we recreated it per `handleYeaftGroupChat`
877
877
  * call (the pre-707 design), `route_forward` running mid-turn would
878
878
  * deliver into a doomed `captured[]` while the new dispatch ran against
879
879
  * a fresh coordinator. The persistent coordinator + module-level inboxes
@@ -984,7 +984,7 @@ async function routeEnvelopeToVpThread(groupId, vpId, envelope) {
984
984
  });
985
985
  thread.updatedAt = Date.now();
986
986
  try {
987
- sendUnifyEvent({
987
+ sendYeaftEvent({
988
988
  type: 'vp_thread_user_appended',
989
989
  groupId,
990
990
  vpId,
@@ -1006,7 +1006,7 @@ async function routeEnvelopeToVpThread(groupId, vpId, envelope) {
1006
1006
  inbox.push({ envelope, turnId, thread });
1007
1007
 
1008
1008
  try {
1009
- sendUnifyEvent({
1009
+ sendYeaftEvent({
1010
1010
  type: 'vp_typing_start',
1011
1011
  groupId,
1012
1012
  vpId,
@@ -1028,7 +1028,7 @@ async function routeEnvelopeToVpThread(groupId, vpId, envelope) {
1028
1028
  messageCount: thread.messageIds.length,
1029
1029
  });
1030
1030
  } catch (err) {
1031
- console.warn('[Unify] vp-status typing transition failed:', err?.message || err);
1031
+ console.warn('[Yeaft] vp-status typing transition failed:', err?.message || err);
1032
1032
  }
1033
1033
 
1034
1034
  ensureDriverRunning(groupId, vpId, thread.threadId);
@@ -1085,13 +1085,13 @@ function ensureDriverRunning(groupId, vpId, threadId = 'main') {
1085
1085
  baseSnapshot,
1086
1086
  });
1087
1087
  } catch (err) {
1088
- console.warn('[Unify] driveVp: runVpTurn failed', vpId, err?.message || err);
1088
+ console.warn('[Yeaft] driveVp: runVpTurn failed', vpId, err?.message || err);
1089
1089
  } finally {
1090
1090
  turnAbortCtrls.delete(turnId);
1091
1091
  turnAbortMeta.delete(turnId);
1092
1092
  if (vpAborts.get(key) === vpAbort) vpAborts.delete(key);
1093
1093
  try {
1094
- sendUnifyEvent({
1094
+ sendYeaftEvent({
1095
1095
  type: 'vp_typing_end',
1096
1096
  groupId,
1097
1097
  vpId,
@@ -1103,7 +1103,7 @@ function ensureDriverRunning(groupId, vpId, threadId = 'main') {
1103
1103
  }
1104
1104
  try {
1105
1105
  if (text && envelope?.msg) {
1106
- sendUnifyEvent({
1106
+ sendYeaftEvent({
1107
1107
  type: 'group_message',
1108
1108
  groupId,
1109
1109
  vpId,
@@ -1168,10 +1168,10 @@ function ensureDriverRunning(groupId, vpId, threadId = 'main') {
1168
1168
  messageCount: thread.messageIds.length,
1169
1169
  });
1170
1170
  } catch (err) {
1171
- console.warn('[Unify] vp-status typing transition (rescue) failed:', err?.message || err);
1171
+ console.warn('[Yeaft] vp-status typing transition (rescue) failed:', err?.message || err);
1172
1172
  }
1173
1173
  try {
1174
- sendUnifyEvent({
1174
+ sendYeaftEvent({
1175
1175
  type: 'vp_typing_start',
1176
1176
  groupId,
1177
1177
  vpId,
@@ -1239,7 +1239,7 @@ export async function __testResetVpState() {
1239
1239
 
1240
1240
 
1241
1241
  /**
1242
- * Send a unify_output message carrying claude_output-format data.
1242
+ * Send a yeaft_output message carrying claude_output-format data.
1243
1243
  * Envelope fields: conversationId, groupId, vpId, turnId, threadId let the
1244
1244
  * frontend route incremental deltas to the correct per-VP/thread block.
1245
1245
  */
@@ -1254,11 +1254,11 @@ function resolveGroupDefaultVpId(groupId) {
1254
1254
  }
1255
1255
  }
1256
1256
 
1257
- function sendUnifyOutput(data, { groupId, vpId, turnId, threadId } = {}) {
1257
+ function sendYeaftOutput(data, { groupId, vpId, turnId, threadId } = {}) {
1258
1258
  const resolvedVpId = vpId || resolveGroupDefaultVpId(groupId);
1259
1259
  sendToServer({
1260
- type: 'unify_output',
1261
- conversationId: unifyConversationId,
1260
+ type: 'yeaft_output',
1261
+ conversationId: yeaftConversationId,
1262
1262
  ...(groupId ? { groupId } : {}),
1263
1263
  ...(resolvedVpId ? { vpId: resolvedVpId } : {}),
1264
1264
  ...(turnId ? { turnId } : {}),
@@ -1267,11 +1267,11 @@ function sendUnifyOutput(data, { groupId, vpId, turnId, threadId } = {}) {
1267
1267
  });
1268
1268
  }
1269
1269
 
1270
- /** Send a unify_output event (non-claude_output metadata). */
1271
- function sendUnifyEvent(event, { groupId, vpId, turnId, threadId } = {}) {
1270
+ /** Send a yeaft_output event (non-claude_output metadata). */
1271
+ function sendYeaftEvent(event, { groupId, vpId, turnId, threadId } = {}) {
1272
1272
  sendToServer({
1273
- type: 'unify_output',
1274
- conversationId: unifyConversationId,
1273
+ type: 'yeaft_output',
1274
+ conversationId: yeaftConversationId,
1275
1275
  ...(groupId ? { groupId } : {}),
1276
1276
  ...(vpId ? { vpId } : {}),
1277
1277
  ...(turnId ? { turnId } : {}),
@@ -1290,14 +1290,14 @@ function configuredVpPaths() {
1290
1290
  };
1291
1291
  }
1292
1292
 
1293
- export function handleUnifyVpSubscribe(_msg) {
1293
+ export function handleYeaftVpSubscribe(_msg) {
1294
1294
  if (_vpUnsubscribe) {
1295
1295
  try { _vpUnsubscribe(); } catch { /* ignore */ }
1296
1296
  _vpUnsubscribe = null;
1297
1297
  }
1298
1298
  const { libDir } = configuredVpPaths();
1299
1299
  _vpUnsubscribe = handleVpSubscribe(
1300
- sendUnifyEvent,
1300
+ sendYeaftEvent,
1301
1301
  undefined,
1302
1302
  libDir ? { dir: libDir } : {},
1303
1303
  );
@@ -1307,10 +1307,10 @@ export function handleUnifyVpSubscribe(_msg) {
1307
1307
  * VP CRUD from the web client. See historic doc for full message shapes.
1308
1308
  */
1309
1309
  function sendVpCrudResult(payload) {
1310
- sendUnifyEvent({ type: 'vp_crud_result', ...payload });
1310
+ sendYeaftEvent({ type: 'vp_crud_result', ...payload });
1311
1311
  }
1312
1312
 
1313
- export function handleUnifyVpCreate(msg) {
1313
+ export function handleYeaftVpCreate(msg) {
1314
1314
  const requestId = msg && msg.requestId;
1315
1315
  const payload = msg && msg.payload;
1316
1316
  try {
@@ -1335,7 +1335,7 @@ export function handleUnifyVpCreate(msg) {
1335
1335
  }
1336
1336
  }
1337
1337
 
1338
- export function handleUnifyVpUpdate(msg) {
1338
+ export function handleYeaftVpUpdate(msg) {
1339
1339
  const requestId = msg && msg.requestId;
1340
1340
  const payload = msg && msg.payload;
1341
1341
  try {
@@ -1356,7 +1356,7 @@ export function handleUnifyVpUpdate(msg) {
1356
1356
  }
1357
1357
  }
1358
1358
 
1359
- export function handleUnifyVpDelete(msg) {
1359
+ export function handleYeaftVpDelete(msg) {
1360
1360
  const requestId = msg && msg.requestId;
1361
1361
  const vpId = msg && msg.vpId;
1362
1362
  try {
@@ -1376,7 +1376,7 @@ export function handleUnifyVpDelete(msg) {
1376
1376
  if (row.vpId === vpId) broker.forget({ groupId: row.groupId, vpId });
1377
1377
  }
1378
1378
  } catch (err) {
1379
- console.warn('[Unify] vp-status forget on delete failed:', err?.message || err);
1379
+ console.warn('[Yeaft] vp-status forget on delete failed:', err?.message || err);
1380
1380
  }
1381
1381
  sendVpCrudResult({ op: 'delete', requestId, ok: true, vpId });
1382
1382
  } catch (err) {
@@ -1393,7 +1393,7 @@ export function handleUnifyVpDelete(msg) {
1393
1393
  }
1394
1394
  }
1395
1395
 
1396
- export function handleUnifyVpRead(msg) {
1396
+ export function handleYeaftVpRead(msg) {
1397
1397
  const requestId = msg && msg.requestId;
1398
1398
  const vpId = msg && msg.vpId;
1399
1399
  const { libDir } = configuredVpPaths();
@@ -1414,7 +1414,7 @@ export function handleUnifyVpRead(msg) {
1414
1414
  * Group CRUD wired to WS events.
1415
1415
  */
1416
1416
  function sendGroupCrudResult(payload) {
1417
- sendUnifyEvent({ type: 'group_crud_result', ...payload });
1417
+ sendYeaftEvent({ type: 'group_crud_result', ...payload });
1418
1418
  }
1419
1419
 
1420
1420
  function sendGroupSnapshotBroadcast() {
@@ -1422,15 +1422,15 @@ function sendGroupSnapshotBroadcast() {
1422
1422
  const yeaftDir = ctx.CONFIG?.yeaftDir;
1423
1423
  if (!yeaftDir) return;
1424
1424
  const groups = snapshotGroups(yeaftDir);
1425
- sendUnifyEvent({ type: 'group_list_updated', groups });
1425
+ sendYeaftEvent({ type: 'group_list_updated', groups });
1426
1426
  } catch (err) {
1427
- console.warn('[Unify] sendGroupSnapshotBroadcast failed:', err?.message || err);
1427
+ console.warn('[Yeaft] sendGroupSnapshotBroadcast failed:', err?.message || err);
1428
1428
  }
1429
1429
  }
1430
1430
 
1431
1431
  function sendGroupRosterChanged(group) {
1432
1432
  if (!group) return;
1433
- sendUnifyEvent({
1433
+ sendYeaftEvent({
1434
1434
  type: 'group_roster_changed',
1435
1435
  groupId: group.id,
1436
1436
  name: group.name,
@@ -1451,7 +1451,7 @@ function groupErrorPayload(err) {
1451
1451
  };
1452
1452
  }
1453
1453
 
1454
- export function handleUnifyListGroups(msg) {
1454
+ export function handleYeaftListGroups(msg) {
1455
1455
  const requestId = msg && msg.requestId;
1456
1456
  try {
1457
1457
  const yeaftDir = ctx.CONFIG?.yeaftDir;
@@ -1462,7 +1462,7 @@ export function handleUnifyListGroups(msg) {
1462
1462
  }
1463
1463
  }
1464
1464
 
1465
- export function handleUnifyCreateGroup(msg) {
1465
+ export function handleYeaftCreateGroup(msg) {
1466
1466
  const requestId = msg && msg.requestId;
1467
1467
  const payload = (msg && msg.payload) || {};
1468
1468
  try {
@@ -1475,7 +1475,7 @@ export function handleUnifyCreateGroup(msg) {
1475
1475
  }
1476
1476
  }
1477
1477
 
1478
- export function handleUnifyRenameGroup(msg) {
1478
+ export function handleYeaftRenameGroup(msg) {
1479
1479
  const requestId = msg && msg.requestId;
1480
1480
  const groupId = msg && msg.groupId;
1481
1481
  const name = msg && msg.name;
@@ -1491,7 +1491,7 @@ export function handleUnifyRenameGroup(msg) {
1491
1491
  }
1492
1492
 
1493
1493
  /**
1494
- * `unify_update_group` — generalised group meta patch. Currently accepts
1494
+ * `yeaft_update_group` — generalised group meta patch. Currently accepts
1495
1495
  * `name` and `announcement` keys. Empty patch is rejected; an empty/
1496
1496
  * whitespace-only `name` is also rejected up front rather than letting
1497
1497
  * `renameGroup` raise a less-specific error deeper in the call stack.
@@ -1504,7 +1504,7 @@ export function handleUnifyRenameGroup(msg) {
1504
1504
  * so this is theoretical; readers extending the patch shape should know
1505
1505
  * the contract permits half-commits.
1506
1506
  */
1507
- export function handleUnifyUpdateGroup(msg) {
1507
+ export function handleYeaftUpdateGroup(msg) {
1508
1508
  const requestId = msg && msg.requestId;
1509
1509
  const groupId = msg && msg.groupId;
1510
1510
  const patch = (msg && msg.patch && typeof msg.patch === 'object') ? msg.patch : null;
@@ -1538,7 +1538,7 @@ export function handleUnifyUpdateGroup(msg) {
1538
1538
  * Payload: { groupId, requestId, config: { model?: string|null } }
1539
1539
  * - `model: ''` or `null` clears the selected group model (falls back to user default).
1540
1540
  */
1541
- export function handleUnifyUpdateGroupConfig(msg) {
1541
+ export function handleYeaftUpdateGroupConfig(msg) {
1542
1542
  const requestId = msg && msg.requestId;
1543
1543
  const groupId = msg && msg.groupId;
1544
1544
  const partial = (msg && msg.config && typeof msg.config === 'object') ? msg.config : null;
@@ -1560,7 +1560,7 @@ export function handleUnifyUpdateGroupConfig(msg) {
1560
1560
  }
1561
1561
  }
1562
1562
 
1563
- export function handleUnifyArchiveGroup(msg) {
1563
+ export function handleYeaftArchiveGroup(msg) {
1564
1564
  const requestId = msg && msg.requestId;
1565
1565
  const groupId = msg && msg.groupId;
1566
1566
  try {
@@ -1574,7 +1574,7 @@ export function handleUnifyArchiveGroup(msg) {
1574
1574
  }
1575
1575
  }
1576
1576
 
1577
- export function handleUnifyDeleteGroup(msg) {
1577
+ export function handleYeaftDeleteGroup(msg) {
1578
1578
  const requestId = msg && msg.requestId;
1579
1579
  const groupId = msg && msg.groupId;
1580
1580
  try {
@@ -1614,7 +1614,7 @@ export function handleUnifyDeleteGroup(msg) {
1614
1614
  }
1615
1615
  }
1616
1616
 
1617
- export function handleUnifyAddMember(msg) {
1617
+ export function handleYeaftAddMember(msg) {
1618
1618
  const requestId = msg && msg.requestId;
1619
1619
  const groupId = msg && msg.groupId;
1620
1620
  const vpId = msg && msg.vpId;
@@ -1629,7 +1629,7 @@ export function handleUnifyAddMember(msg) {
1629
1629
  }
1630
1630
  }
1631
1631
 
1632
- export function handleUnifyRemoveMember(msg) {
1632
+ export function handleYeaftRemoveMember(msg) {
1633
1633
  const requestId = msg && msg.requestId;
1634
1634
  const groupId = msg && msg.groupId;
1635
1635
  const vpId = msg && msg.vpId;
@@ -1650,7 +1650,7 @@ export function handleUnifyRemoveMember(msg) {
1650
1650
  }
1651
1651
  }
1652
1652
 
1653
- export function handleUnifySetDefaultVp(msg) {
1653
+ export function handleYeaftSetDefaultVp(msg) {
1654
1654
  const requestId = msg && msg.requestId;
1655
1655
  const groupId = msg && msg.groupId;
1656
1656
  const vpId = msg && msg.vpId;
@@ -1673,20 +1673,20 @@ export function handleUnifySetDefaultVp(msg) {
1673
1673
  *
1674
1674
  * @param {import('./session.js').Session} s
1675
1675
  */
1676
- export function installUnifyRuntimeBridge(s) {
1676
+ export function installYeaftRuntimeBridge(s) {
1677
1677
  if (!s) return;
1678
1678
 
1679
1679
  // Forward dream pipeline progress events to the web debug panel.
1680
1680
  //
1681
1681
  // Group-id stamping is NO LONGER done here. It used to be: this sink
1682
1682
  // read a module-level `activeScopedDreamGroupId` that
1683
- // `handleUnifyDreamTrigger({groupId})` parked before awaiting the
1683
+ // `handleYeaftDreamTrigger({groupId})` parked before awaiting the
1684
1684
  // scope-filtered pass. That created a race when two scoped triggers
1685
1685
  // overlapped (auto-tick during a manual click; or two manual clicks
1686
1686
  // for different groups): the second handler's `finally` could clear
1687
1687
  // the module slot while the first run was still emitting events,
1688
1688
  // dropping the stamp from the tail of the first pass. The new design:
1689
- // `handleUnifyDreamTrigger` wraps THIS sink for the lifetime of the
1689
+ // `handleYeaftDreamTrigger` wraps THIS sink for the lifetime of the
1690
1690
  // trigger to inject `groupId` per-call (see that function below). The
1691
1691
  // base sink is intentionally a pure passthrough.
1692
1692
  //
@@ -1696,25 +1696,25 @@ export function installUnifyRuntimeBridge(s) {
1696
1696
  try {
1697
1697
  if (evt.type === 'turn_open' || evt.type === 'turn_close' || evt.type === 'loop') {
1698
1698
  const tag = evt && evt.groupId ? { groupId: evt.groupId } : {};
1699
- sendUnifyEvent(evt, tag);
1699
+ sendYeaftEvent(evt, tag);
1700
1700
  } else {
1701
1701
  const out = { type: 'dream_progress', ...evt };
1702
1702
  const tag = evt && evt.groupId ? { groupId: evt.groupId } : {};
1703
- sendUnifyEvent(out, tag);
1703
+ sendYeaftEvent(out, tag);
1704
1704
  }
1705
1705
  } catch { /* never let event delivery throw */ }
1706
1706
  };
1707
1707
 
1708
1708
  // Wire the post-compact WS sink. Compactor is constructed in
1709
- // session.js with a no-op sink; bridge owns `sendUnifyEvent` /
1710
- // `unifyConversationId`, so the sink is wired here once a session is
1711
- // present. Per-group `unify_history_compacted` events fire after a
1709
+ // session.js with a no-op sink; bridge owns `sendYeaftEvent` /
1710
+ // `yeaftConversationId`, so the sink is wired here once a session is
1711
+ // present. Per-group `yeaft_history_compacted` events fire after a
1712
1712
  // successful summarize+swap.
1713
1713
  if (s.compactor && typeof s.compactor.setOnCompacted === 'function') {
1714
1714
  s.compactor.setOnCompacted((groupId, result) => {
1715
1715
  try {
1716
- sendUnifyEvent({
1717
- type: 'unify_history_compacted',
1716
+ sendYeaftEvent({
1717
+ type: 'yeaft_history_compacted',
1718
1718
  reason: result?.reason ?? null,
1719
1719
  beforeTurns: result?.beforeTurns,
1720
1720
  afterTurns: result?.afterTurns,
@@ -1727,9 +1727,9 @@ export function installUnifyRuntimeBridge(s) {
1727
1727
  });
1728
1728
  }
1729
1729
 
1730
- ctx.unifyRuntimeSettings = {
1730
+ ctx.yeaftRuntimeSettings = {
1731
1731
  // No multi-thread settings to surface anymore. Stub for back-compat
1732
- // with message-router's update_unify_settings branch — assignments are
1732
+ // with message-router's update_yeaft_settings branch — assignments are
1733
1733
  // accepted but ignored.
1734
1734
  get maxConcurrentThreads() { return null; },
1735
1735
  set maxConcurrentThreads(_v) { /* deprecated, ignored */ },
@@ -1764,7 +1764,7 @@ function maybeTransitionVpStatus(hctx, state) {
1764
1764
  messageCount: hctx.thread?.messageIds?.length || 0,
1765
1765
  });
1766
1766
  } catch (err) {
1767
- console.warn(`[Unify] vp-status ${state} transition failed:`, err?.message || err);
1767
+ console.warn(`[Yeaft] vp-status ${state} transition failed:`, err?.message || err);
1768
1768
  }
1769
1769
  }
1770
1770
 
@@ -1792,7 +1792,7 @@ function handleEngineEvent(event, hctx) {
1792
1792
  switch (event.type) {
1793
1793
  case 'text_delta':
1794
1794
  hctx.assistantTextParts.push(event.text);
1795
- sendUnifyOutput({
1795
+ sendYeaftOutput({
1796
1796
  type: 'assistant',
1797
1797
  message: { content: [{ type: 'text', text: event.text }] },
1798
1798
  }, envelope);
@@ -1803,7 +1803,7 @@ function handleEngineEvent(event, hctx) {
1803
1803
  break;
1804
1804
 
1805
1805
  case 'thinking_delta':
1806
- sendUnifyEvent({ type: 'thinking_delta', text: event.text }, envelope);
1806
+ sendYeaftEvent({ type: 'thinking_delta', text: event.text }, envelope);
1807
1807
  break;
1808
1808
 
1809
1809
  case 'thinking_block_end':
@@ -1812,7 +1812,7 @@ function handleEngineEvent(event, hctx) {
1812
1812
  // turns / VPs includes it. Without this echo Anthropic 400s the
1813
1813
  // next request with "content[].thinking in the thinking mode must
1814
1814
  // be passed back to the API". The signature stays server-side
1815
- // only — wire serializers (stripMetaForWire / sendUnifyOutput)
1815
+ // only — wire serializers (stripMetaForWire / sendYeaftOutput)
1816
1816
  // never reference thinkingBlocks, so it cannot leak to the UI.
1817
1817
  if (hctx.thinkingBlocksAccum && event.signature) {
1818
1818
  if (event.redacted) {
@@ -1842,11 +1842,11 @@ function handleEngineEvent(event, hctx) {
1842
1842
  });
1843
1843
  }
1844
1844
  // Finish any in-progress text streaming so UI shows typing dots
1845
- sendUnifyOutput({
1845
+ sendYeaftOutput({
1846
1846
  type: 'assistant',
1847
1847
  message: { content: [] },
1848
1848
  }, envelope);
1849
- sendUnifyOutput({
1849
+ sendYeaftOutput({
1850
1850
  type: 'assistant',
1851
1851
  message: {
1852
1852
  content: [{
@@ -1861,7 +1861,7 @@ function handleEngineEvent(event, hctx) {
1861
1861
  break;
1862
1862
 
1863
1863
  case 'tool_start':
1864
- sendUnifyEvent({
1864
+ sendYeaftEvent({
1865
1865
  type: 'tool_start',
1866
1866
  id: event.id,
1867
1867
  name: event.name,
@@ -1877,7 +1877,7 @@ function handleEngineEvent(event, hctx) {
1877
1877
  isError: !!event.isError,
1878
1878
  });
1879
1879
  }
1880
- sendUnifyOutput({
1880
+ sendYeaftOutput({
1881
1881
  type: 'user',
1882
1882
  tool_use_result: [{
1883
1883
  type: 'tool_result',
@@ -1920,9 +1920,9 @@ function handleEngineEvent(event, hctx) {
1920
1920
  messageCount: hctx.thread?.messageIds?.length || 0,
1921
1921
  });
1922
1922
  } catch (err) {
1923
- console.warn('[Unify] vp-status settleIdle (route_forward) failed:', err?.message || err);
1923
+ console.warn('[Yeaft] vp-status settleIdle (route_forward) failed:', err?.message || err);
1924
1924
  }
1925
- sendUnifyEvent({
1925
+ sendYeaftEvent({
1926
1926
  type: 'vp_turn_end',
1927
1927
  groupId: hctx.groupId,
1928
1928
  vpId: hctx.vpId,
@@ -1936,7 +1936,7 @@ function handleEngineEvent(event, hctx) {
1936
1936
  break;
1937
1937
 
1938
1938
  case 'usage':
1939
- sendUnifyEvent({
1939
+ sendYeaftEvent({
1940
1940
  type: 'context_usage',
1941
1941
  inputTokens: event.inputTokens,
1942
1942
  outputTokens: event.outputTokens,
@@ -1944,7 +1944,7 @@ function handleEngineEvent(event, hctx) {
1944
1944
  break;
1945
1945
 
1946
1946
  case 'recall':
1947
- sendUnifyEvent({
1947
+ sendYeaftEvent({
1948
1948
  type: 'recall',
1949
1949
  entryCount: event.entryCount,
1950
1950
  cached: event.cached,
@@ -1955,7 +1955,7 @@ function handleEngineEvent(event, hctx) {
1955
1955
  // Engine compressed the context — clear THIS group's accumulated
1956
1956
  // history. Other groups' histories stay intact.
1957
1957
  if (hctx.groupId) setGroupHistory(hctx.groupId, []);
1958
- sendUnifyEvent({
1958
+ sendYeaftEvent({
1959
1959
  type: 'consolidate',
1960
1960
  archivedCount: event.archivedCount,
1961
1961
  extractedCount: event.extractedCount,
@@ -1963,7 +1963,7 @@ function handleEngineEvent(event, hctx) {
1963
1963
  break;
1964
1964
 
1965
1965
  case 'fallback':
1966
- sendUnifyEvent({
1966
+ sendYeaftEvent({
1967
1967
  type: 'fallback',
1968
1968
  from: event.from,
1969
1969
  to: event.to,
@@ -1972,7 +1972,7 @@ function handleEngineEvent(event, hctx) {
1972
1972
  break;
1973
1973
 
1974
1974
  case 'reflection':
1975
- sendUnifyEvent({
1975
+ sendYeaftEvent({
1976
1976
  type: 'reflection',
1977
1977
  // feat-6af5f9f1 PR B: stamp turnId/loopNumber so the debug panel
1978
1978
  // can attach reflection cards to the matching loop.
@@ -1989,7 +1989,7 @@ function handleEngineEvent(event, hctx) {
1989
1989
  break;
1990
1990
 
1991
1991
  case 'turn_open':
1992
- sendUnifyEvent({
1992
+ sendYeaftEvent({
1993
1993
  type: 'turn_open',
1994
1994
  turnId: event.turnId,
1995
1995
  userPrompt: event.userPrompt,
@@ -2000,7 +2000,7 @@ function handleEngineEvent(event, hctx) {
2000
2000
  break;
2001
2001
 
2002
2002
  case 'turn_close':
2003
- sendUnifyEvent({
2003
+ sendYeaftEvent({
2004
2004
  type: 'turn_close',
2005
2005
  turnId: event.turnId,
2006
2006
  totalMs: event.totalMs,
@@ -2010,7 +2010,7 @@ function handleEngineEvent(event, hctx) {
2010
2010
  break;
2011
2011
 
2012
2012
  case 'memory_used':
2013
- sendUnifyEvent({
2013
+ sendYeaftEvent({
2014
2014
  type: 'memory_used',
2015
2015
  turnId: event.turnId,
2016
2016
  loaded: event.loaded || [],
@@ -2018,7 +2018,7 @@ function handleEngineEvent(event, hctx) {
2018
2018
  break;
2019
2019
 
2020
2020
  case 'memory_adjust':
2021
- sendUnifyEvent({
2021
+ sendYeaftEvent({
2022
2022
  type: 'memory_adjust',
2023
2023
  turnId: event.turnId,
2024
2024
  groupKey: event.groupKey,
@@ -2033,7 +2033,7 @@ function handleEngineEvent(event, hctx) {
2033
2033
  if (hctx && Array.isArray(hctx.appendedUserPrompts) && event.preview) {
2034
2034
  hctx.appendedUserPrompts.push(String(event.preview));
2035
2035
  }
2036
- sendUnifyEvent({
2036
+ sendYeaftEvent({
2037
2037
  type: 'vp_thread_user_append_consumed',
2038
2038
  turnId: event.turnId,
2039
2039
  threadId: event.threadId,
@@ -2044,7 +2044,7 @@ function handleEngineEvent(event, hctx) {
2044
2044
  break;
2045
2045
 
2046
2046
  case 'tool_exec':
2047
- sendUnifyEvent({
2047
+ sendYeaftEvent({
2048
2048
  type: 'tool_exec',
2049
2049
  turnId: event.turnId,
2050
2050
  loopNumber: event.loopNumber,
@@ -2058,7 +2058,7 @@ function handleEngineEvent(event, hctx) {
2058
2058
  case 'loop':
2059
2059
  // feat-6af5f9f1 PR B: replaces the old `debug_turn` event. Same
2060
2060
  // payload shape plus turnId + loopNumber + usage.totalTokens.
2061
- sendUnifyEvent({
2061
+ sendYeaftEvent({
2062
2062
  type: 'loop',
2063
2063
  turnId: event.turnId,
2064
2064
  loopNumber: event.loopNumber,
@@ -2081,7 +2081,7 @@ function handleEngineEvent(event, hctx) {
2081
2081
  if (isPermissionErrorMsg(errMsg)) {
2082
2082
  if (!_permissionDiagnosticSent) {
2083
2083
  _permissionDiagnosticSent = true;
2084
- sendUnifyOutput({
2084
+ sendYeaftOutput({
2085
2085
  type: 'assistant',
2086
2086
  message: {
2087
2087
  content: [{
@@ -2092,7 +2092,7 @@ function handleEngineEvent(event, hctx) {
2092
2092
  }, envelope);
2093
2093
  }
2094
2094
  } else {
2095
- sendUnifyOutput({
2095
+ sendYeaftOutput({
2096
2096
  type: 'assistant',
2097
2097
  message: {
2098
2098
  content: [{ type: 'text', text: `⚠️ Error: ${errMsg}` }],
@@ -2109,13 +2109,13 @@ function handleEngineEvent(event, hctx) {
2109
2109
  }
2110
2110
 
2111
2111
  /**
2112
- * Handle a unify_group_chat message from the web UI — the SOLE Unify
2112
+ * Handle a yeaft_group_chat message from the web UI — the SOLE Yeaft
2113
2113
  * conversation entry point.
2114
2114
  *
2115
- * Contract (post-consolidation, was previously split between handleUnifyChat
2116
- * and handleUnifyGroupChat):
2117
- * - Frontend ALWAYS sends `unify_group_chat`. There is no `unify_chat`.
2118
- * - `groupId` defaults to `'grp_default'` if missing — Unify is a single
2115
+ * Contract (post-consolidation, was previously split between handleYeaftChat
2116
+ * and handleYeaftGroupChat):
2117
+ * - Frontend ALWAYS sends `yeaft_group_chat`. There is no `yeaft_chat`.
2118
+ * - `groupId` defaults to `'grp_default'` if missing — Yeaft is a single
2119
2119
  * conversation backed by the default group; the user is never "outside"
2120
2120
  * a group.
2121
2121
  * - If the group dir doesn't exist and the resolved id is `'grp_default'`,
@@ -2125,12 +2125,12 @@ function handleEngineEvent(event, hctx) {
2125
2125
  * - No legacy "no-group" fallback paths — they were the source of the
2126
2126
  * router_unavailable bug fixed in v0.1.671.
2127
2127
  */
2128
- export async function handleUnifyGroupChat(msg) {
2128
+ export async function handleYeaftGroupChat(msg) {
2129
2129
  if (!msg || typeof msg !== 'object') return;
2130
2130
  const { text } = msg;
2131
2131
  // PR #721: image-only send is allowed — text may be empty when the
2132
2132
  // user attached files only. The frontend synthesizes a placeholder
2133
- // string in `sendUnifyGroupChat`, so by the time we get here `text`
2133
+ // string in `sendYeaftGroupChat`, so by the time we get here `text`
2134
2134
  // should always be non-empty; but defend anyway in case an API
2135
2135
  // caller sends a bare attachment payload.
2136
2136
  const hasFiles = Array.isArray(msg.files) && msg.files.length > 0;
@@ -2157,11 +2157,11 @@ export async function handleUnifyGroupChat(msg) {
2157
2157
  // session lying around.
2158
2158
  const yeaftDir = ctx.CONFIG?.yeaftDir;
2159
2159
  if (!yeaftDir) {
2160
- sendUnifyOutput({
2160
+ sendYeaftOutput({
2161
2161
  type: 'assistant',
2162
- message: { content: [{ type: 'text', text: '⚠️ Unify session error: no yeaft directory configured.' }] },
2162
+ message: { content: [{ type: 'text', text: '⚠️ Yeaft session error: no yeaft directory configured.' }] },
2163
2163
  }, { groupId });
2164
- sendUnifyOutput({ type: 'result', result_text: '' }, { groupId });
2164
+ sendYeaftOutput({ type: 'result', result_text: '' }, { groupId });
2165
2165
  return;
2166
2166
  }
2167
2167
 
@@ -2185,24 +2185,24 @@ export async function handleUnifyGroupChat(msg) {
2185
2185
  groupHandle = seeded.group;
2186
2186
  } catch (seedErr) {
2187
2187
  seedFailed = true;
2188
- console.warn('[Unify] unify_group_chat: seedDefaultGroup failed', seedErr?.message || seedErr);
2188
+ console.warn('[Yeaft] yeaft_group_chat: seedDefaultGroup failed', seedErr?.message || seedErr);
2189
2189
  }
2190
2190
  } else {
2191
- console.warn('[Unify] unify_group_chat: groupId %s not found', groupId);
2191
+ console.warn('[Yeaft] yeaft_group_chat: groupId %s not found', groupId);
2192
2192
  }
2193
2193
  } catch (err) {
2194
- console.warn('[Unify] unify_group_chat: group open failed', err?.message || err);
2194
+ console.warn('[Yeaft] yeaft_group_chat: group open failed', err?.message || err);
2195
2195
  }
2196
2196
 
2197
2197
  if (!groupHandle) {
2198
2198
  const errText = seedFailed
2199
2199
  ? `⚠️ Failed to seed default group ${groupId} — check group .yeaft permissions.`
2200
2200
  : `⚠️ Group ${groupId} not found.`;
2201
- sendUnifyOutput({
2201
+ sendYeaftOutput({
2202
2202
  type: 'assistant',
2203
2203
  message: { content: [{ type: 'text', text: errText }] },
2204
2204
  }, { groupId });
2205
- sendUnifyOutput({ type: 'result', result_text: '' }, { groupId });
2205
+ sendYeaftOutput({ type: 'result', result_text: '' }, { groupId });
2206
2206
  return;
2207
2207
  }
2208
2208
 
@@ -2239,7 +2239,7 @@ export async function handleUnifyGroupChat(msg) {
2239
2239
  } catch { /* best-effort */ }
2240
2240
  }
2241
2241
  } catch (err) {
2242
- console.warn('[Unify] unify_group_chat: auto-roster heal failed', err?.message || err);
2242
+ console.warn('[Yeaft] yeaft_group_chat: auto-roster heal failed', err?.message || err);
2243
2243
  }
2244
2244
 
2245
2245
  // task-707: per-group persistent coordinator/router. Created once per
@@ -2260,7 +2260,7 @@ export async function handleUnifyGroupChat(msg) {
2260
2260
  // ── Attachments (images + files) ───────────────────────────────
2261
2261
  // Server has already resolved fileId → { name, mimeType, data:base64,
2262
2262
  // isImage } via the same path crew uses (client-conversation.js relay
2263
- // for `unify_*`). We persist files to disk under the agent's CWD so
2263
+ // for `yeaft_*`). We persist files to disk under the agent's CWD so
2264
2264
  // file-tools (file-read / bash) can pick them up with relative paths,
2265
2265
  // and we build per-image content blocks for the LLM call. The
2266
2266
  // resolved metadata WITHOUT base64 rides on coord.ingest meta so it
@@ -2270,9 +2270,9 @@ export async function handleUnifyGroupChat(msg) {
2270
2270
  let attachmentBundle = { promptAttachments: [], promptSuffix: '', promptParts: [], failed: [] };
2271
2271
  if (inboundFiles.length > 0) {
2272
2272
  try {
2273
- attachmentBundle = persistUnifyAttachments(inboundFiles, { subdir: groupId });
2273
+ attachmentBundle = persistYeaftAttachments(inboundFiles, { subdir: groupId });
2274
2274
  } catch (err) {
2275
- console.warn('[Unify] unify_group_chat: attachment persist failed', err?.message || err);
2275
+ console.warn('[Yeaft] yeaft_group_chat: attachment persist failed', err?.message || err);
2276
2276
  }
2277
2277
  }
2278
2278
  // Surface partial / total upload failures to the user. We don't abort
@@ -2282,7 +2282,7 @@ export async function handleUnifyGroupChat(msg) {
2282
2282
  const detail = attachmentBundle.failed
2283
2283
  .map((f) => ` - ${f.name}: ${f.error}`)
2284
2284
  .join('\n');
2285
- sendUnifyOutput({
2285
+ sendYeaftOutput({
2286
2286
  type: 'assistant',
2287
2287
  message: { content: [{ type: 'text', text: `⚠️ ${attachmentBundle.failed.length} file(s) could not be attached:\n${detail}` }] },
2288
2288
  }, { groupId });
@@ -2311,12 +2311,12 @@ export async function handleUnifyGroupChat(msg) {
2311
2311
  _promptSuffix: attachmentBundle.promptSuffix,
2312
2312
  });
2313
2313
  } catch (err) {
2314
- console.warn('[Unify] unify_group_chat: coord.ingest failed', err?.message || err);
2315
- sendUnifyOutput({
2314
+ console.warn('[Yeaft] yeaft_group_chat: coord.ingest failed', err?.message || err);
2315
+ sendYeaftOutput({
2316
2316
  type: 'assistant',
2317
2317
  message: { content: [{ type: 'text', text: `⚠️ Group dispatch error: ${err?.message || err}` }] },
2318
2318
  }, { groupId });
2319
- sendUnifyOutput({ type: 'result', result_text: '' }, { groupId });
2319
+ sendYeaftOutput({ type: 'result', result_text: '' }, { groupId });
2320
2320
  return;
2321
2321
  }
2322
2322
 
@@ -2333,11 +2333,11 @@ export async function handleUnifyGroupChat(msg) {
2333
2333
  // with a healthy roster. Surface the failure explicitly rather than
2334
2334
  // silently retrying as a single-VP turn (the legacy fallback masked
2335
2335
  // group-roster bugs).
2336
- sendUnifyOutput({
2336
+ sendYeaftOutput({
2337
2337
  type: 'assistant',
2338
2338
  message: { content: [{ type: 'text', text: '⚠️ No VP available to respond — check the group roster.' }] },
2339
2339
  }, { groupId });
2340
- sendUnifyOutput({ type: 'result', result_text: '' }, { groupId });
2340
+ sendYeaftOutput({ type: 'result', result_text: '' }, { groupId });
2341
2341
  return;
2342
2342
  }
2343
2343
 
@@ -2502,18 +2502,18 @@ async function ensureSessionLoaded() {
2502
2502
  serverMode: true,
2503
2503
  });
2504
2504
 
2505
- installUnifyRuntimeBridge(session);
2505
+ installYeaftRuntimeBridge(session);
2506
2506
 
2507
2507
  try {
2508
2508
  if (session.engine && typeof session.engine.setSubAgentEventSink === 'function') {
2509
2509
  session.engine.setSubAgentEventSink((agentId, evt) => {
2510
2510
  try {
2511
- sendUnifyEvent({ type: 'sub_agent_event', agentId, payload: evt });
2511
+ sendYeaftEvent({ type: 'sub_agent_event', agentId, payload: evt });
2512
2512
  } catch { /* ignore */ }
2513
2513
  });
2514
2514
  }
2515
2515
  } catch (err) {
2516
- console.warn('[Unify] setSubAgentEventSink wiring failed:', err?.message || err);
2516
+ console.warn('[Yeaft] setSubAgentEventSink wiring failed:', err?.message || err);
2517
2517
  }
2518
2518
 
2519
2519
  // Bug 8: clean up legacy `.archived-*` group dirs at boot.
@@ -2521,21 +2521,21 @@ async function ensureSessionLoaded() {
2521
2521
  if (yeaftDir) {
2522
2522
  const removed = purgeArchivedGroups(yeaftDir);
2523
2523
  if (removed && removed.length > 0) {
2524
- console.log(`[Unify] purged ${removed.length} legacy .archived group dir(s)`);
2524
+ console.log(`[Yeaft] purged ${removed.length} legacy .archived group dir(s)`);
2525
2525
  }
2526
2526
  }
2527
2527
  } catch (err) {
2528
- console.warn('[Unify] purgeArchivedGroups failed:', err?.message || err);
2528
+ console.warn('[Yeaft] purgeArchivedGroups failed:', err?.message || err);
2529
2529
  }
2530
2530
 
2531
- unifyConversationId = `unify-${Date.now()}`;
2531
+ yeaftConversationId = `yeaft-${Date.now()}`;
2532
2532
 
2533
2533
  // Per-group history is hydrated lazily on first `getOrCreateGroupHistory`
2534
2534
  // — there's no global "all conversations" tape any more.
2535
2535
 
2536
- sendUnifyEvent({
2536
+ sendYeaftEvent({
2537
2537
  type: 'session_ready',
2538
- conversationId: unifyConversationId,
2538
+ conversationId: yeaftConversationId,
2539
2539
  model: session.config.model,
2540
2540
  availableModels: session.config.availableModels || [],
2541
2541
  skills: session.status.skills,
@@ -2551,7 +2551,7 @@ async function ensureSessionLoaded() {
2551
2551
  try {
2552
2552
  getVpStatusBroker().broadcastSnapshot();
2553
2553
  } catch (err) {
2554
- console.warn('[Unify] vp-status snapshot broadcast failed:', err?.message || err);
2554
+ console.warn('[Yeaft] vp-status snapshot broadcast failed:', err?.message || err);
2555
2555
  }
2556
2556
  }
2557
2557
 
@@ -2589,10 +2589,10 @@ async function runVpTurnWithEscalation(args) {
2589
2589
  deadlineMs,
2590
2590
  onEscalate: () => {
2591
2591
  console.error(
2592
- `[Unify] runVpTurn watchdog escalation: VP ${vpId} did not return ${deadlineMs}ms after enqueue — emitting synthetic stop and unblocking driver`,
2592
+ `[Yeaft] runVpTurn watchdog escalation: VP ${vpId} did not return ${deadlineMs}ms after enqueue — emitting synthetic stop and unblocking driver`,
2593
2593
  );
2594
2594
  try {
2595
- sendUnifyOutput(
2595
+ sendYeaftOutput(
2596
2596
  { type: 'result', result_text: '', stopped: true },
2597
2597
  { groupId, vpId, turnId, threadId },
2598
2598
  );
@@ -2608,7 +2608,7 @@ async function runVpTurnWithEscalation(args) {
2608
2608
  try {
2609
2609
  getVpStatusBroker().settleIdle({ groupId, vpId, threadId: threadId || 'main', title: thread?.title || '' });
2610
2610
  } catch (err) {
2611
- console.warn('[Unify] vp-status settleIdle (escalation) failed:', err?.message || err);
2611
+ console.warn('[Yeaft] vp-status settleIdle (escalation) failed:', err?.message || err);
2612
2612
  }
2613
2613
  },
2614
2614
  });
@@ -2692,7 +2692,7 @@ async function runVpTurn({ prompt, promptParts = null, groupId, vpId, threadId =
2692
2692
  if (queryTimer) clearTimeout(queryTimer);
2693
2693
  queryTimer = setTimeout(() => {
2694
2694
  if (!vpAbort.signal.aborted) {
2695
- console.error(`[Unify] query timeout after ${QUERY_TIMEOUT_MS / 1000}s of silence — aborting VP ${vpId}`);
2695
+ console.error(`[Yeaft] query timeout after ${QUERY_TIMEOUT_MS / 1000}s of silence — aborting VP ${vpId}`);
2696
2696
  try { vpAbort.abort(); } catch { /* best-effort */ }
2697
2697
  }
2698
2698
  }, QUERY_TIMEOUT_MS);
@@ -2700,12 +2700,12 @@ async function runVpTurn({ prompt, promptParts = null, groupId, vpId, threadId =
2700
2700
  resetQueryTimer();
2701
2701
 
2702
2702
  // Emit turn_start so frontend can create the message block.
2703
- sendUnifyEvent({ type: 'vp_turn_start', vpId, threadId, turnId, groupId, title: thread?.title || '' }, envelope);
2703
+ sendYeaftEvent({ type: 'vp_turn_start', vpId, threadId, turnId, groupId, title: thread?.title || '' }, envelope);
2704
2704
  // vp-status: LLM call about to start, no text/tool yet → 'thinking'.
2705
2705
  try {
2706
2706
  getVpStatusBroker().transition({ groupId, vpId, threadId, title: thread?.title || '', state: 'thinking', turnId, messageCount: thread?.messageIds?.length || 0 });
2707
2707
  } catch (err) {
2708
- console.warn('[Unify] vp-status thinking transition failed:', err?.message || err);
2708
+ console.warn('[Yeaft] vp-status thinking transition failed:', err?.message || err);
2709
2709
  }
2710
2710
 
2711
2711
  try {
@@ -2717,7 +2717,7 @@ async function runVpTurn({ prompt, promptParts = null, groupId, vpId, threadId =
2717
2717
  let vpEngine = null;
2718
2718
 
2719
2719
  // task-707: per-VP engine + persistent group coord. The coord is
2720
- // created in handleUnifyGroupChat via getOrCreateGroupContext and
2720
+ // created in handleYeaftGroupChat via getOrCreateGroupContext and
2721
2721
  // cached on `groupContexts`; we pull it here so route_forward
2722
2722
  // (router built from this same coord) lands envelopes back on the
2723
2723
  // right inbox set.
@@ -2760,7 +2760,7 @@ async function runVpTurn({ prompt, promptParts = null, groupId, vpId, threadId =
2760
2760
  messages: trimmedMessages,
2761
2761
  signal: vpAbort.signal,
2762
2762
  // Multi-VP fan-out (history-dedup): the user row was persisted
2763
- // ONCE by handleUnifyGroupChat → persistUserMessageOnce before
2763
+ // ONCE by handleYeaftGroupChat → persistUserMessageOnce before
2764
2764
  // fan-out. Tell the engine's stop-hook to skip the user-row
2765
2765
  // append for THIS VP's turn (it still writes assistant + tool
2766
2766
  // rows for this VP). Without this the magnet of N engines would
@@ -2781,11 +2781,11 @@ async function runVpTurn({ prompt, promptParts = null, groupId, vpId, threadId =
2781
2781
  // Turn completed — atomically append this VP's output to shared history.
2782
2782
  appendTurnToGroupHistory(groupId, threadId, [prompt, ...appendedUserPrompts], assistantTextParts, toolCallsAccum, toolResultsAccum, thinkingBlocksAccum);
2783
2783
 
2784
- sendUnifyOutput({
2784
+ sendYeaftOutput({
2785
2785
  type: 'assistant',
2786
2786
  message: { content: [] },
2787
2787
  }, envelope);
2788
- sendUnifyOutput({
2788
+ sendYeaftOutput({
2789
2789
  type: 'result',
2790
2790
  result_text: '',
2791
2791
  }, envelope);
@@ -2795,7 +2795,7 @@ async function runVpTurn({ prompt, promptParts = null, groupId, vpId, threadId =
2795
2795
  } catch (err) {
2796
2796
  const isAbort = err && (err.name === 'AbortError' || err.name === 'LLMAbortError');
2797
2797
  if (isAbort) {
2798
- sendUnifyOutput({
2798
+ sendYeaftOutput({
2799
2799
  type: 'result',
2800
2800
  result_text: '',
2801
2801
  stopped: true,
@@ -2803,7 +2803,7 @@ async function runVpTurn({ prompt, promptParts = null, groupId, vpId, threadId =
2803
2803
  return;
2804
2804
  }
2805
2805
 
2806
- console.error('[Unify] query error:', err);
2806
+ console.error('[Yeaft] query error:', err);
2807
2807
 
2808
2808
  // vp-status: surface a transient `error` state so the row's status
2809
2809
  // label flips red for the brief window before the outer finally
@@ -2813,13 +2813,13 @@ async function runVpTurn({ prompt, promptParts = null, groupId, vpId, threadId =
2813
2813
  try {
2814
2814
  getVpStatusBroker().transition({ groupId, vpId, threadId, title: thread?.title || '', state: 'error', turnId, messageCount: thread?.messageIds?.length || 0 });
2815
2815
  } catch (brokerErr) {
2816
- console.warn('[Unify] vp-status error transition failed:', brokerErr?.message || brokerErr);
2816
+ console.warn('[Yeaft] vp-status error transition failed:', brokerErr?.message || brokerErr);
2817
2817
  }
2818
2818
 
2819
2819
  if (isPermissionErrorMsg(err.message)) {
2820
2820
  if (!_permissionDiagnosticSent) {
2821
2821
  _permissionDiagnosticSent = true;
2822
- sendUnifyOutput({
2822
+ sendYeaftOutput({
2823
2823
  type: 'assistant',
2824
2824
  message: {
2825
2825
  content: [{
@@ -2830,7 +2830,7 @@ async function runVpTurn({ prompt, promptParts = null, groupId, vpId, threadId =
2830
2830
  }, envelope);
2831
2831
  }
2832
2832
  } else {
2833
- sendUnifyOutput({
2833
+ sendYeaftOutput({
2834
2834
  type: 'assistant',
2835
2835
  message: {
2836
2836
  content: [{
@@ -2840,7 +2840,7 @@ async function runVpTurn({ prompt, promptParts = null, groupId, vpId, threadId =
2840
2840
  },
2841
2841
  }, envelope);
2842
2842
  }
2843
- sendUnifyOutput({
2843
+ sendYeaftOutput({
2844
2844
  type: 'result',
2845
2845
  result_text: '',
2846
2846
  }, envelope);
@@ -2852,7 +2852,7 @@ async function runVpTurn({ prompt, promptParts = null, groupId, vpId, threadId =
2852
2852
  try {
2853
2853
  getVpStatusBroker().settleIdle({ groupId, vpId, threadId: threadId || 'main', title: thread?.title || '' });
2854
2854
  } catch (err) {
2855
- console.warn('[Unify] vp-status settleIdle failed:', err?.message || err);
2855
+ console.warn('[Yeaft] vp-status settleIdle failed:', err?.message || err);
2856
2856
  }
2857
2857
  // fix-vp-multi-thread (bug 2): the bridge tracks per-thread status
2858
2858
  // on `thread.status` separately from the broker. Multiple sites
@@ -2934,14 +2934,14 @@ function appendTurnToGroupHistory(groupId, threadId, prompts, assistantTextParts
2934
2934
  /**
2935
2935
  * Persist an inbound message row to disk EXACTLY ONCE per
2936
2936
  * coordinator-ingest call, keyed by the coordinator-assigned `msgId`.
2937
- * Both `handleUnifyGroupChat` (real user input, persists as
2937
+ * Both `handleYeaftGroupChat` (real user input, persists as
2938
2938
  * role='user') and `enqueueForVp`'s driver loop (route_forward
2939
2939
  * synthetic injections, persists as role='assistant' attributed via
2940
2940
  * `speakerVpId`) call this — the Set guard makes either path the
2941
2941
  * writer, whichever runs first, while the other becomes a no-op.
2942
2942
  *
2943
2943
  * Without this dedup, a 2-VP group prompt produces TWO `m{NNNN}.md`
2944
- * user rows (one per engine) — `handleUnifyLoadHistory` then replays
2944
+ * user rows (one per engine) — `handleYeaftLoadHistory` then replays
2945
2945
  * the user's prompt twice and sandwiches one VP's reply between two
2946
2946
  * copies of the user message. Visually this reads as "messages out of
2947
2947
  * order" because the second copy of the user prompt sits BETWEEN the
@@ -2992,7 +2992,7 @@ function persistInboundMessageOnceByMsgId({ msgId, text, groupId, threadId = 'ma
2992
2992
  }
2993
2993
  }
2994
2994
  try {
2995
- // role defaults to 'user' for back-compat: handleUnifyGroupChat's
2995
+ // role defaults to 'user' for back-compat: handleYeaftGroupChat's
2996
2996
  // real-user call site passes no role and gets a user row. The driver
2997
2997
  // loop passes role='assistant' + speakerVpId for route_forward
2998
2998
  // injections so the on-disk record correctly attributes the text to
@@ -3018,7 +3018,7 @@ function persistInboundMessageOnceByMsgId({ msgId, text, groupId, threadId = 'ma
3018
3018
  return true;
3019
3019
  } catch (err) {
3020
3020
  console.warn(
3021
- '[Unify] persistInboundMessageOnceByMsgId failed (non-fatal):',
3021
+ '[Yeaft] persistInboundMessageOnceByMsgId failed (non-fatal):',
3022
3022
  err?.message || err,
3023
3023
  );
3024
3024
  return false;
@@ -3026,24 +3026,24 @@ function persistInboundMessageOnceByMsgId({ msgId, text, groupId, threadId = 'ma
3026
3026
  }
3027
3027
 
3028
3028
  /**
3029
- * Cleared on session reset (resetUnifySession) so a fresh session
3029
+ * Cleared on session reset (resetYeaftSession) so a fresh session
3030
3030
  * starts with no stale msg-ids.
3031
3031
  */
3032
3032
  const _persistedUserMsgIds = new Set();
3033
3033
 
3034
3034
  // Per-group post-turn compaction lives on `session.compactor`
3035
- // (`agent/unify/compact/compactor.js`), constructed in `session.js`.
3035
+ // (`agent/yeaft/compact/compactor.js`), constructed in `session.js`.
3036
3036
  // Bridge passes a per-call `historyHandle = { get, set }` and wires the
3037
- // `unify_history_compacted` WS sink via `compactor.setOnCompacted` from
3038
- // `installUnifyRuntimeBridge`. The bridge keeps history ownership; the
3037
+ // `yeaft_history_compacted` WS sink via `compactor.setOnCompacted` from
3038
+ // `installYeaftRuntimeBridge`. The bridge keeps history ownership; the
3039
3039
  // Compactor owns single-flight, anti-starvation, race-guard, and the
3040
3040
  // LLM summarize call.
3041
3041
 
3042
3042
  /**
3043
3043
  * Abort every in-flight VP turn and clear all queued envelopes across
3044
- * every group/thread runtime. Shared by `handleUnifyAbortThread` when no
3045
- * target thread is supplied and by `handleUnifyAbortAll`. Pushes `vp:<key>`
3046
- * strings into the supplied `aborted` array for the unify_aborted event.
3044
+ * every group/thread runtime. Shared by `handleYeaftAbortThread` when no
3045
+ * target thread is supplied and by `handleYeaftAbortAll`. Pushes `vp:<key>`
3046
+ * strings into the supplied `aborted` array for the yeaft_aborted event.
3047
3047
  *
3048
3048
  * @param {string[]} aborted — output array, mutated in place
3049
3049
  */
@@ -3066,7 +3066,7 @@ function abortAllVpRuntime(aborted) {
3066
3066
  * @param {{ threadId?: string }} _msg
3067
3067
  * @returns {{ aborted: string[], all: boolean }}
3068
3068
  */
3069
- export function handleUnifyAbortThread(_msg = {}) {
3069
+ export function handleYeaftAbortThread(_msg = {}) {
3070
3070
  const aborted = [];
3071
3071
  const targetThreadId = _msg && typeof _msg.threadId === 'string' ? _msg.threadId : '';
3072
3072
 
@@ -3093,7 +3093,7 @@ export function handleUnifyAbortThread(_msg = {}) {
3093
3093
  const thread = vpMap.get(targetThreadId);
3094
3094
  if (thread) thread.status = 'aborted';
3095
3095
  }
3096
- sendUnifyEvent({ type: 'unify_aborted', aborted, all: false, threadId: targetThreadId });
3096
+ sendYeaftEvent({ type: 'yeaft_aborted', aborted, all: false, threadId: targetThreadId });
3097
3097
  return { aborted, all: false };
3098
3098
  }
3099
3099
 
@@ -3107,15 +3107,15 @@ export function handleUnifyAbortThread(_msg = {}) {
3107
3107
  turnAbortCtrls.clear();
3108
3108
  turnAbortMeta.clear();
3109
3109
  abortAllVpRuntime(aborted);
3110
- sendUnifyEvent({ type: 'unify_aborted', aborted, all: false });
3110
+ sendYeaftEvent({ type: 'yeaft_aborted', aborted, all: false });
3111
3111
  return { aborted, all: false };
3112
3112
  }
3113
3113
 
3114
3114
  /**
3115
- * Abort all in-flight Unify runtime work.
3115
+ * Abort all in-flight Yeaft runtime work.
3116
3116
  * @returns {{ aborted: string[], all: boolean }}
3117
3117
  */
3118
- export function handleUnifyAbortAll() {
3118
+ export function handleYeaftAbortAll() {
3119
3119
  const aborted = [];
3120
3120
  if (currentAbortCtrl && !currentAbortCtrl.signal.aborted) {
3121
3121
  try { currentAbortCtrl.abort(); aborted.push('main'); } catch { /* best-effort */ }
@@ -3128,19 +3128,19 @@ export function handleUnifyAbortAll() {
3128
3128
  turnAbortCtrls.clear();
3129
3129
  turnAbortMeta.clear();
3130
3130
  abortAllVpRuntime(aborted);
3131
- sendUnifyEvent({ type: 'unify_aborted', aborted, all: true });
3131
+ sendYeaftEvent({ type: 'yeaft_aborted', aborted, all: true });
3132
3132
  return { aborted, all: true };
3133
3133
  }
3134
3134
 
3135
3135
  /**
3136
3136
  * Per-VP abort: stops a single VP turn by turnId without affecting siblings.
3137
- * Frontend sends `{ type: 'unify_abort_turn', turnId }`.
3137
+ * Frontend sends `{ type: 'yeaft_abort_turn', turnId }`.
3138
3138
  * @param {{ turnId?: string }} msg
3139
3139
  */
3140
- export function handleUnifyAbortTurn(msg = {}) {
3140
+ export function handleYeaftAbortTurn(msg = {}) {
3141
3141
  const { turnId } = msg;
3142
3142
  if (!turnId) {
3143
- sendUnifyEvent({ type: 'unify_turn_aborted', turnId: null, success: false });
3143
+ sendYeaftEvent({ type: 'yeaft_turn_aborted', turnId: null, success: false });
3144
3144
  return;
3145
3145
  }
3146
3146
  const ctrl = turnAbortCtrls.get(turnId);
@@ -3148,11 +3148,11 @@ export function handleUnifyAbortTurn(msg = {}) {
3148
3148
  try { ctrl.abort(); } catch { /* best-effort */ }
3149
3149
  turnAbortCtrls.delete(turnId);
3150
3150
  turnAbortMeta.delete(turnId);
3151
- sendUnifyEvent({ type: 'unify_turn_aborted', turnId, success: true });
3151
+ sendYeaftEvent({ type: 'yeaft_turn_aborted', turnId, success: true });
3152
3152
  } else {
3153
3153
  turnAbortCtrls.delete(turnId);
3154
3154
  turnAbortMeta.delete(turnId);
3155
- sendUnifyEvent({ type: 'unify_turn_aborted', turnId, success: false });
3155
+ sendYeaftEvent({ type: 'yeaft_turn_aborted', turnId, success: false });
3156
3156
  }
3157
3157
  }
3158
3158
 
@@ -3160,11 +3160,11 @@ export function handleUnifyAbortTurn(msg = {}) {
3160
3160
  * Unified abort entry: routes by payload shape.
3161
3161
  * @param {{ threadId?: string, all?: boolean }} [opts]
3162
3162
  */
3163
- export function abortUnifySession(opts = {}) {
3164
- if (opts && opts.all) return handleUnifyAbortAll();
3165
- if (opts && opts.threadId) return handleUnifyAbortThread({ threadId: opts.threadId });
3163
+ export function abortYeaftSession(opts = {}) {
3164
+ if (opts && opts.all) return handleYeaftAbortAll();
3165
+ if (opts && opts.threadId) return handleYeaftAbortThread({ threadId: opts.threadId });
3166
3166
  // No payload — conservative no-op ack.
3167
- sendUnifyEvent({ type: 'unify_aborted', aborted: [], all: false });
3167
+ sendYeaftEvent({ type: 'yeaft_aborted', aborted: [], all: false });
3168
3168
  return { aborted: [], all: false };
3169
3169
  }
3170
3170
 
@@ -3206,7 +3206,7 @@ export function __testGetRegisteredThreadIds() {
3206
3206
  /**
3207
3207
  * Test-only: expose the bridge-level escalation helper. Lets tests verify
3208
3208
  * the "tool ignored signal → wrapper escalates" contract without booting a
3209
- * full session. See `test/agent/unify/web-bridge-escalation.test.js`.
3209
+ * full session. See `test/agent/yeaft/web-bridge-escalation.test.js`.
3210
3210
  */
3211
3211
  export const __testRaceWithEscalation = raceWithEscalation;
3212
3212
 
@@ -3215,11 +3215,11 @@ export const __testRaceWithEscalation = raceWithEscalation;
3215
3215
  *
3216
3216
  * Two call shapes, both routed through this single handler:
3217
3217
  *
3218
- * { type: 'unify_dream_trigger', vpId } — per-VP trigger (legacy
3218
+ * { type: 'yeaft_dream_trigger', vpId } — per-VP trigger (legacy
3219
3219
  * VP-detail page button). Fires an unscoped dream pass; the result
3220
3220
  * event is tagged with `vpId` so the per-VP store row updates.
3221
3221
  *
3222
- * { type: 'unify_dream_trigger', groupId } — per-GROUP trigger (new
3222
+ * { type: 'yeaft_dream_trigger', groupId } — per-GROUP trigger (new
3223
3223
  * in v0.1.754 — added so users can manually kick dream for a group
3224
3224
  * after seeing the Resident layer stuck on the bootstrap seed).
3225
3225
  * Fires a scope-filtered pass via `triggerDreamForScopes(['group/X'])`
@@ -3270,7 +3270,7 @@ export function normalizeDreamResult(result) {
3270
3270
  };
3271
3271
  }
3272
3272
 
3273
- export async function handleUnifyDreamTrigger(msg = {}) {
3273
+ export async function handleYeaftDreamTrigger(msg = {}) {
3274
3274
  // Resolve tag up-front so EVERY outbound envelope (including the
3275
3275
  // scheduler-uninitialised early-return below) carries `groupId` /
3276
3276
  // `vpId`. Without this the frontend's `applyDreamResult` couldn't
@@ -3284,7 +3284,7 @@ export async function handleUnifyDreamTrigger(msg = {}) {
3284
3284
  if (!session?.dreamScheduler) {
3285
3285
  const error = 'Dream scheduler not initialized — session not loaded.';
3286
3286
  sendToServer({
3287
- type: 'unify_dream_result',
3287
+ type: 'yeaft_dream_result',
3288
3288
  ...tag,
3289
3289
  ...normalizeDreamResult({ error }),
3290
3290
  });
@@ -3310,7 +3310,7 @@ export async function handleUnifyDreamTrigger(msg = {}) {
3310
3310
  trigger: msg.manual === false ? 'auto' : 'manual',
3311
3311
  };
3312
3312
  sendToServer({
3313
- type: 'unify_dream_result',
3313
+ type: 'yeaft_dream_result',
3314
3314
  ...tag,
3315
3315
  ...skippedResult,
3316
3316
  ...normalizeDreamResult(skippedResult),
@@ -3341,7 +3341,7 @@ export async function handleUnifyDreamTrigger(msg = {}) {
3341
3341
 
3342
3342
  try {
3343
3343
  sendToServer({
3344
- type: 'unify_dream_status',
3344
+ type: 'yeaft_dream_status',
3345
3345
  ...tag,
3346
3346
  status: 'running',
3347
3347
  });
@@ -3361,15 +3361,15 @@ export async function handleUnifyDreamTrigger(msg = {}) {
3361
3361
  // mode of the alternative ordering is silent — review feedback from
3362
3362
  // PR #743.
3363
3363
  //
3364
- // This `unify_dream_result` envelope is the SOLE terminal signal for
3365
- // a dream pass. The chat-store projects it into BOTH `unifyDreamLatest`
3366
- // (final tally row) AND `unifyDreamEvents` (ring-buffer terminal
3364
+ // This `yeaft_dream_result` envelope is the SOLE terminal signal for
3365
+ // a dream pass. The chat-store projects it into BOTH `yeaftDreamLatest`
3366
+ // (final tally row) AND `yeaftDreamEvents` (ring-buffer terminal
3367
3367
  // marker), so we no longer mirror a synthetic `phase:'result'`
3368
3368
  // dream_progress event — that mirror used to race the
3369
- // `unifyDreamLatest` writer and flip the success row back to
3369
+ // `yeaftDreamLatest` writer and flip the success row back to
3370
3370
  // 'running' (Critical reviewer finding pre-merge).
3371
3371
  sendToServer({
3372
- type: 'unify_dream_result',
3372
+ type: 'yeaft_dream_result',
3373
3373
  ...tag,
3374
3374
  ...result,
3375
3375
  ...normalized,
@@ -3377,7 +3377,7 @@ export async function handleUnifyDreamTrigger(msg = {}) {
3377
3377
  } catch (err) {
3378
3378
  const error = err?.message || String(err);
3379
3379
  sendToServer({
3380
- type: 'unify_dream_result',
3380
+ type: 'yeaft_dream_result',
3381
3381
  ...tag,
3382
3382
  ...normalizeDreamResult({ error }),
3383
3383
  });
@@ -3392,9 +3392,9 @@ export async function handleUnifyDreamTrigger(msg = {}) {
3392
3392
  }
3393
3393
 
3394
3394
  /**
3395
- * 2026-05-13: serve the Unify debug drawer's "Tool Stats" panel.
3395
+ * 2026-05-13: serve the Yeaft debug drawer's "Tool Stats" panel.
3396
3396
  *
3397
- * Replies with `{type: 'unify_tool_stats', snapshot, registered,
3397
+ * Replies with `{type: 'yeaft_tool_stats', snapshot, registered,
3398
3398
  * unused}`. `snapshot` is the `ToolUsageStats.snapshot()` keyed by
3399
3399
  * tool name (callCount, errorCount, p50Ms, p95Ms, avgMs, lastCalledAt,
3400
3400
  * lastError, errorRate). `registered` is the static list of built-in
@@ -3405,7 +3405,7 @@ export async function handleUnifyDreamTrigger(msg = {}) {
3405
3405
  * missing, we still reply with an empty snapshot so the UI can render
3406
3406
  * a placeholder rather than spin forever.
3407
3407
  */
3408
- export async function handleUnifyFetchToolStats(_msg = {}) {
3408
+ export async function handleYeaftFetchToolStats(_msg = {}) {
3409
3409
  let snapshot = {};
3410
3410
  let registered = [];
3411
3411
  let unused = [];
@@ -3427,7 +3427,7 @@ export async function handleUnifyFetchToolStats(_msg = {}) {
3427
3427
  }
3428
3428
  } catch (err) {
3429
3429
  sendToServer({
3430
- type: 'unify_tool_stats',
3430
+ type: 'yeaft_tool_stats',
3431
3431
  snapshot: {},
3432
3432
  registered: [],
3433
3433
  unused: [],
@@ -3436,7 +3436,7 @@ export async function handleUnifyFetchToolStats(_msg = {}) {
3436
3436
  return;
3437
3437
  }
3438
3438
  sendToServer({
3439
- type: 'unify_tool_stats',
3439
+ type: 'yeaft_tool_stats',
3440
3440
  snapshot,
3441
3441
  registered,
3442
3442
  unused,
@@ -3444,8 +3444,8 @@ export async function handleUnifyFetchToolStats(_msg = {}) {
3444
3444
  }
3445
3445
 
3446
3446
  /**
3447
- * Hydrate the UnifyDebugPanel from the persistent SQLite trace. The
3448
- * panel state (`unifyDebugLoops` / `unifyDebugTurnsById`) is otherwise
3447
+ * Hydrate the YeaftDebugPanel from the persistent SQLite trace. The
3448
+ * panel state (`yeaftDebugLoops` / `yeaftDebugTurnsById`) is otherwise
3449
3449
  * built ONLY from in-flight `loop` / `turn_open` events on the wire,
3450
3450
  * so a panel opened after a turn has finished sees nothing for that
3451
3451
  * turn. This handler ships back a frontend-shaped snapshot the store
@@ -3457,12 +3457,12 @@ export async function handleUnifyFetchToolStats(_msg = {}) {
3457
3457
  * - `threadId` — narrow by thread
3458
3458
  *
3459
3459
  * Sends:
3460
- * { type: 'unify_debug_history', loops: [...], turns: [...] }
3460
+ * { type: 'yeaft_debug_history', loops: [...], turns: [...] }
3461
3461
  *
3462
3462
  * Best-effort: if the session / trace isn't ready, sends an empty
3463
3463
  * snapshot so the panel renders a placeholder instead of spinning.
3464
3464
  */
3465
- export async function handleUnifyFetchDebugHistory(msg = {}) {
3465
+ export async function handleYeaftFetchDebugHistory(msg = {}) {
3466
3466
  const limit = Number.isFinite(msg?.limit) ? Number(msg.limit) : 100;
3467
3467
  const dreamLimit = Number.isFinite(msg?.dreamLimit) ? Number(msg.dreamLimit) : 5;
3468
3468
  const groupId = typeof msg?.groupId === 'string' && msg.groupId ? msg.groupId : null;
@@ -3479,7 +3479,7 @@ export async function handleUnifyFetchDebugHistory(msg = {}) {
3479
3479
  }
3480
3480
  } catch (err) {
3481
3481
  sendToServer({
3482
- type: 'unify_debug_history',
3482
+ type: 'yeaft_debug_history',
3483
3483
  loops: [],
3484
3484
  turns: [],
3485
3485
  dreamEvents: [],
@@ -3488,7 +3488,7 @@ export async function handleUnifyFetchDebugHistory(msg = {}) {
3488
3488
  return;
3489
3489
  }
3490
3490
  sendToServer({
3491
- type: 'unify_debug_history',
3491
+ type: 'yeaft_debug_history',
3492
3492
  loops,
3493
3493
  turns,
3494
3494
  dreamEvents,
@@ -3497,26 +3497,26 @@ export async function handleUnifyFetchDebugHistory(msg = {}) {
3497
3497
  });
3498
3498
  }
3499
3499
 
3500
- /** Deprecated mode switch — Unify is single-mode. */
3501
- export function handleUnifyModeSwitch(_msg) {
3502
- console.warn('[Unify] unify_mode_switch is deprecated and ignored — Unify now runs in a single unified mode.');
3500
+ /** Deprecated mode switch — Yeaft is single-mode. */
3501
+ export function handleYeaftModeSwitch(_msg) {
3502
+ console.warn('[Yeaft] yeaft_mode_switch is deprecated and ignored — Yeaft now runs in a single unified mode.');
3503
3503
  }
3504
3504
 
3505
3505
 
3506
3506
  /** Handle model switch from the web UI. */
3507
- export function handleUnifyModelSwitch(msg) {
3507
+ export function handleYeaftModelSwitch(msg) {
3508
3508
  if (!session || !msg.model) return;
3509
3509
 
3510
3510
  const available = session.config.availableModels || [];
3511
3511
  const found = available.some(m => m.id === msg.model);
3512
3512
  if (!found) {
3513
- console.warn(`[Unify] model switch rejected — "${msg.model}" not in availableModels`);
3513
+ console.warn(`[Yeaft] model switch rejected — "${msg.model}" not in availableModels`);
3514
3514
  return;
3515
3515
  }
3516
3516
 
3517
3517
  session.config.model = msg.model;
3518
3518
 
3519
- sendUnifyEvent({
3519
+ sendYeaftEvent({
3520
3520
  type: 'model_switched',
3521
3521
  model: msg.model,
3522
3522
  });
@@ -3532,7 +3532,7 @@ export function handleUnifyModelSwitch(msg) {
3532
3532
  * groupId at all — are excluded so a stale `grp_default` (or any other
3533
3533
  * group) never bleeds into the active group's pane.
3534
3534
  */
3535
- export async function handleUnifyLoadHistory(msg) {
3535
+ export async function handleYeaftLoadHistory(msg) {
3536
3536
  const groupId = (msg && typeof msg.groupId === 'string' && msg.groupId) || null;
3537
3537
  // `lim` is now expressed in TURNS, not raw messages. `loadRecent` and
3538
3538
  // `loadRecentByGroup` use turn-based slicing so the cut never lands
@@ -3549,9 +3549,9 @@ export async function handleUnifyLoadHistory(msg) {
3549
3549
  skipSkills: false,
3550
3550
  serverMode: true,
3551
3551
  });
3552
- installUnifyRuntimeBridge(session);
3552
+ installYeaftRuntimeBridge(session);
3553
3553
 
3554
- unifyConversationId = `unify-${Date.now()}`;
3554
+ yeaftConversationId = `yeaft-${Date.now()}`;
3555
3555
 
3556
3556
  // Per-group history hydrates lazily via getOrCreateGroupHistory.
3557
3557
  // When the load-history call carries a groupId, force-refresh THAT
@@ -3567,9 +3567,9 @@ export async function handleUnifyLoadHistory(msg) {
3567
3567
  }
3568
3568
 
3569
3569
  // Always replay session_ready so refresh / reconnect rebuilds UI state.
3570
- sendUnifyEvent({
3570
+ sendYeaftEvent({
3571
3571
  type: 'session_ready',
3572
- conversationId: unifyConversationId,
3572
+ conversationId: yeaftConversationId,
3573
3573
  model: session.config.model,
3574
3574
  availableModels: session.config.availableModels || [],
3575
3575
  skills: session.status.skills,
@@ -3584,18 +3584,21 @@ export async function handleUnifyLoadHistory(msg) {
3584
3584
  try {
3585
3585
  getVpStatusBroker().broadcastSnapshot();
3586
3586
  } catch (err) {
3587
- console.warn('[Unify] vp-status snapshot broadcast (replay) failed:', err?.message || err);
3587
+ console.warn('[Yeaft] vp-status snapshot broadcast (replay) failed:', err?.message || err);
3588
3588
  }
3589
3589
 
3590
3590
  // `msg.limit` is the replay-scrollback request from the frontend (UI
3591
3591
  // history pane, not engine context). Keep the bootstrap window small so
3592
3592
  // opening a group can paint the latest messages quickly; older rows are
3593
- // paged via `unify_load_more_history` when the user scrolls upward.
3593
+ // paged via `yeaft_load_more_history` when the user scrolls upward.
3594
3594
  const limit = (typeof msg.limit === 'number') ? msg.limit : 10;
3595
3595
  const visiblePage = groupId
3596
3596
  ? loadVisibleGroupHistoryPage(session.conversationStore, groupId, limit)
3597
3597
  : { messages: limit > 0 ? pickRecent(session.conversationStore, limit) : [], oldestSeq: null, hasMore: false };
3598
- const compactSummary = session.conversationStore.readCompactSummary();
3598
+ // Legacy compact.md is a non-group fallback only. For group replay, reading
3599
+ // it makes every group show "has compact" once any legacy/non-scoped compact
3600
+ // exists, even when this group has no scoped summary.
3601
+ const compactSummary = groupId ? '' : session.conversationStore.readCompactSummary();
3599
3602
  const replayEntries = groupId
3600
3603
  ? visiblePage.messages
3601
3604
  : visiblePage.messages
@@ -3604,7 +3607,7 @@ export async function handleUnifyLoadHistory(msg) {
3604
3607
 
3605
3608
  for (const entry of replayEntries) {
3606
3609
  if (entry.role === 'user') {
3607
- sendUnifyOutput({
3610
+ sendYeaftOutput({
3608
3611
  type: 'user',
3609
3612
  message: {
3610
3613
  content: entry.content,
@@ -3624,12 +3627,12 @@ export async function handleUnifyLoadHistory(msg) {
3624
3627
  turnId: entry.turnId || entry.threadId || 'main',
3625
3628
  };
3626
3629
  if (entry.speakerVpId) envelopeOpts.vpId = entry.speakerVpId;
3627
- sendUnifyOutput({
3630
+ sendYeaftOutput({
3628
3631
  type: 'assistant',
3629
3632
  message: { id: entry.id || null, content: [{ type: 'text', text: entry.content }] },
3630
3633
  ts: entry.ts || null,
3631
3634
  }, envelopeOpts);
3632
- sendUnifyOutput({ type: 'result', result_text: '' }, envelopeOpts);
3635
+ sendYeaftOutput({ type: 'result', result_text: '' }, envelopeOpts);
3633
3636
  }
3634
3637
  }
3635
3638
 
@@ -3645,18 +3648,16 @@ export async function handleUnifyLoadHistory(msg) {
3645
3648
  oldestSeq = visiblePage.oldestSeq;
3646
3649
  }
3647
3650
 
3648
- // hasCompactSummary used to read a single session-global file, so it
3649
- // was always true once ANY group/VP in the session had compacted.
3650
- // Now we check (a) the scoped dir for any per-VP summary file in this
3651
- // group, falling back to (b) the legacy global file for sessions that
3652
- // pre-date the per-(group, vp) split.
3651
+ // hasCompactSummary used to read a single session-global file, so it was
3652
+ // always true once ANY group/VP in the session had compacted. For group
3653
+ // replay, only scoped per-(group, vp) summaries count; legacy compact.md is
3654
+ // reserved for non-group / pre-scoped 1:1 callers.
3653
3655
  let hasCompactSummaryFlag = !!compactSummary;
3654
3656
  if (groupId && typeof session.conversationStore.hasAnyCompactSummaryForGroup === 'function') {
3655
- hasCompactSummaryFlag = session.conversationStore.hasAnyCompactSummaryForGroup(groupId)
3656
- || hasCompactSummaryFlag;
3657
+ hasCompactSummaryFlag = session.conversationStore.hasAnyCompactSummaryForGroup(groupId);
3657
3658
  }
3658
3659
 
3659
- sendUnifyEvent({
3660
+ sendYeaftEvent({
3660
3661
  type: 'history_loaded',
3661
3662
  count: replayEntries.length,
3662
3663
  hasCompactSummary: hasCompactSummaryFlag,
@@ -3671,21 +3672,21 @@ export async function handleUnifyLoadHistory(msg) {
3671
3672
  /**
3672
3673
  * Handle a "load older messages" pagination request. Reads `turns` more
3673
3674
  * turns of history strictly older than `beforeSeq` for `groupId`, and
3674
- * emits them in a single `unify_history_chunk` envelope (NOT a
3675
- * `unify_output` — that pipeline appends, but the frontend needs to
3675
+ * emits them in a single `yeaft_history_chunk` envelope (NOT a
3676
+ * `yeaft_output` — that pipeline appends, but the frontend needs to
3676
3677
  * PREPEND these older messages above what it already has).
3677
3678
  *
3678
3679
  * Tool replay is NOT included in this PR — same projection as
3679
- * `handleUnifyLoadHistory` (user / assistant text only). On any internal
3680
+ * `handleYeaftLoadHistory` (user / assistant text only). On any internal
3680
3681
  * failure we still emit an empty chunk so the spinner clears.
3681
3682
  *
3682
3683
  * @param {object} msg — { groupId, beforeSeq, turns }
3683
3684
  */
3684
- export async function handleUnifyLoadMoreHistory(msg) {
3685
+ export async function handleYeaftLoadMoreHistory(msg) {
3685
3686
  const groupId = (msg && typeof msg.groupId === 'string' && msg.groupId) || null;
3686
3687
  const emit = (payload) => sendToServer({
3687
- type: 'unify_history_chunk',
3688
- conversationId: unifyConversationId,
3688
+ type: 'yeaft_history_chunk',
3689
+ conversationId: yeaftConversationId,
3689
3690
  groupId,
3690
3691
  ...payload,
3691
3692
  });
@@ -3702,11 +3703,11 @@ export async function handleUnifyLoadMoreHistory(msg) {
3702
3703
  try {
3703
3704
  result = loadVisibleGroupHistoryPage(session.conversationStore, groupId, turns, beforeSeq);
3704
3705
  } catch (err) {
3705
- console.error('[Unify] loadOlderByGroup failed:', err.message);
3706
+ console.error('[Yeaft] loadOlderByGroup failed:', err.message);
3706
3707
  result = { messages: [], oldestSeq: null, hasMore: false };
3707
3708
  }
3708
3709
 
3709
- // Wire shape mirrors handleUnifyLoadHistory's projection: only visible
3710
+ // Wire shape mirrors handleYeaftLoadHistory's projection: only visible
3710
3711
  // user / assistant text rows. Internal reflection/system-only rows stay
3711
3712
  // server-side, and stable ids + speaker attribution ride with each row
3712
3713
  // so older-history prepend renders exactly like refresh replay.
@@ -3731,10 +3732,10 @@ export async function handleUnifyLoadMoreHistory(msg) {
3731
3732
  }
3732
3733
 
3733
3734
  /**
3734
- * Reset Unify session. Aborts the in-flight controller, tears down the
3735
+ * Reset Yeaft session. Aborts the in-flight controller, tears down the
3735
3736
  * session, then re-initialises so the frontend gets fresh config.
3736
3737
  */
3737
- export async function resetUnifySession() {
3738
+ export async function resetYeaftSession() {
3738
3739
  if (currentAbortCtrl && !currentAbortCtrl.signal.aborted) {
3739
3740
  try { currentAbortCtrl.abort(); } catch { /* ignore */ }
3740
3741
  }
@@ -3747,7 +3748,7 @@ export async function resetUnifySession() {
3747
3748
  await session.shutdown();
3748
3749
  session = null;
3749
3750
  }
3750
- unifyConversationId = null;
3751
+ yeaftConversationId = null;
3751
3752
  // Per-group histories live on groupContexts entries — clearing the
3752
3753
  // map (a few lines below) drops every group's history with it. No
3753
3754
  // separate global tape to clear.
@@ -3782,7 +3783,7 @@ export async function resetUnifySession() {
3782
3783
  try {
3783
3784
  getVpStatusBroker().reset();
3784
3785
  } catch (err) {
3785
- console.warn('[Unify] vp-status broker reset failed:', err?.message || err);
3786
+ console.warn('[Yeaft] vp-status broker reset failed:', err?.message || err);
3786
3787
  }
3787
3788
 
3788
3789
  try {
@@ -3793,16 +3794,16 @@ export async function resetUnifySession() {
3793
3794
  skipSkills: false,
3794
3795
  serverMode: true,
3795
3796
  });
3796
- installUnifyRuntimeBridge(session);
3797
+ installYeaftRuntimeBridge(session);
3797
3798
 
3798
- unifyConversationId = `unify-${Date.now()}`;
3799
+ yeaftConversationId = `yeaft-${Date.now()}`;
3799
3800
 
3800
3801
  // Per-group history hydrates lazily via getOrCreateGroupHistory on
3801
3802
  // first read. Nothing to seed here.
3802
3803
 
3803
- sendUnifyEvent({
3804
+ sendYeaftEvent({
3804
3805
  type: 'session_ready',
3805
- conversationId: unifyConversationId,
3806
+ conversationId: yeaftConversationId,
3806
3807
  model: session.config.model,
3807
3808
  availableModels: session.config.availableModels || [],
3808
3809
  skills: session.status.skills,
@@ -3816,9 +3817,9 @@ export async function resetUnifySession() {
3816
3817
  try {
3817
3818
  getVpStatusBroker().broadcastSnapshot();
3818
3819
  } catch (err) {
3819
- console.warn('[Unify] vp-status snapshot broadcast (reset) failed:', err?.message || err);
3820
+ console.warn('[Yeaft] vp-status snapshot broadcast (reset) failed:', err?.message || err);
3820
3821
  }
3821
3822
  } catch (err) {
3822
- console.error('[Unify] Failed to re-initialize session after reset:', err.message);
3823
+ console.error('[Yeaft] Failed to re-initialize session after reset:', err.message);
3823
3824
  }
3824
3825
  }