@yeaft/webchat-agent 0.1.874 → 0.1.875

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 (46) hide show
  1. package/connection/message-router.js +20 -13
  2. package/package.json +1 -1
  3. package/yeaft/attachments.js +2 -2
  4. package/yeaft/cli.js +13 -13
  5. package/yeaft/compact/compactor.js +20 -20
  6. package/yeaft/conversation/persist.js +95 -95
  7. package/yeaft/debug-trace.js +12 -12
  8. package/yeaft/dream-v2/apply.js +15 -15
  9. package/yeaft/dream-v2/merge.js +12 -12
  10. package/yeaft/dream-v2/prompts/{extract-group.md → extract-session.md} +12 -12
  11. package/yeaft/dream-v2/prompts/index.js +3 -3
  12. package/yeaft/dream-v2/prompts/triage-pass1.md +1 -1
  13. package/yeaft/dream-v2/runner.js +37 -37
  14. package/yeaft/dream-v2/segment.js +3 -3
  15. package/yeaft/dream-v2/session-wiring.js +22 -22
  16. package/yeaft/dream-v2/state.js +7 -7
  17. package/yeaft/dream-v2/triage.js +22 -22
  18. package/yeaft/engine.js +65 -65
  19. package/yeaft/memory/ams-registry.js +22 -22
  20. package/yeaft/memory/seed-backfill.js +9 -9
  21. package/yeaft/memory/store-v2.js +27 -27
  22. package/yeaft/prompts.js +9 -9
  23. package/yeaft/routing/loop-guard.js +14 -14
  24. package/yeaft/routing/router.js +5 -5
  25. package/yeaft/session.js +5 -5
  26. package/yeaft/sessions/coordinator.js +96 -20
  27. package/yeaft/{groups → sessions}/ids.js +3 -3
  28. package/yeaft/{groups → sessions}/index.js +28 -28
  29. package/yeaft/sessions/pre-flow.js +178 -42
  30. package/yeaft/{groups → sessions}/seed-default.js +19 -19
  31. package/yeaft/{groups/group-config.js → sessions/session-config.js} +29 -29
  32. package/yeaft/{groups/group-crud.js → sessions/session-crud.js} +113 -113
  33. package/yeaft/sessions/session-store.js +85 -154
  34. package/yeaft/stop-hooks.js +4 -4
  35. package/yeaft/tools/todo-write.js +1 -1
  36. package/yeaft/tools/types.js +2 -2
  37. package/yeaft/vp/registry.js +1 -1
  38. package/yeaft/vp/vp-crud.js +1 -1
  39. package/yeaft/vp-status-broker.js +28 -28
  40. package/yeaft/web-bridge.js +411 -398
  41. package/yeaft/groups/coordinator.js +0 -221
  42. package/yeaft/groups/group-store.js +0 -212
  43. package/yeaft/groups/pre-flow.js +0 -329
  44. /package/yeaft/{groups → sessions}/feature-flag.js +0 -0
  45. /package/yeaft/{groups → sessions}/project-doc.js +0 -0
  46. /package/yeaft/{groups → sessions}/roster.js +0 -0
@@ -37,9 +37,16 @@ import { handleRestartAgent, handleUpgradeAgent } from './upgrade.js';
37
37
  import { loadMcpServers, updateMcpConfig } from '../mcp.js';
38
38
  import { getLlmConfig, updateLlmConfig, getYeaftSettings, updateYeaftSettings, getSearchSettings, updateSearchSettings, fetchTavilyUsage } from '../yeaft/config-api.js';
39
39
  import { fetchModelsDev } from '../yeaft/llm/models-dev.js';
40
- import { handleYeaftGroupChat, handleYeaftModeSwitch, handleYeaftModelSwitch, resetYeaftSession, handleYeaftLoadHistory, handleYeaftLoadMoreHistory, handleYeaftAbortThread, handleYeaftAbortAll, handleYeaftAbortTurn, handleYeaftVpSubscribe, handleYeaftVpCreate, handleYeaftVpUpdate, handleYeaftVpDelete, handleYeaftVpRead, handleYeaftListGroups, handleYeaftCreateGroup, handleYeaftRenameGroup, handleYeaftUpdateGroup, handleYeaftUpdateGroupConfig, handleYeaftArchiveGroup, handleYeaftDeleteGroup, handleYeaftAddMember, handleYeaftRemoveMember, handleYeaftSetDefaultVp, handleYeaftDreamTrigger, handleYeaftFetchToolStats, handleYeaftFetchDebugHistory, broadcastLanguageChange } from '../yeaft/web-bridge.js';
40
+ import { handleYeaftSessionSend, handleYeaftModeSwitch, handleYeaftModelSwitch, resetYeaftSession, handleYeaftLoadHistory, handleYeaftLoadMoreHistory, handleYeaftAbortThread, handleYeaftAbortAll, handleYeaftAbortTurn, handleYeaftVpSubscribe, handleYeaftVpCreate, handleYeaftVpUpdate, handleYeaftVpDelete, handleYeaftVpRead, handleYeaftListSessions, handleYeaftCreateSession, handleYeaftRenameSession, handleYeaftUpdateSession, handleYeaftUpdateSessionConfig, handleYeaftArchiveSession, handleYeaftDeleteSession, handleYeaftSessionAddMember, handleYeaftSessionRemoveMember, handleYeaftSessionSetDefaultVp, handleYeaftDreamTrigger, handleYeaftFetchToolStats, handleYeaftFetchDebugHistory, broadcastLanguageChange } from '../yeaft/web-bridge.js';
41
41
 
42
42
  export async function handleMessage(msg) {
43
+ // Wire-compat: old web bundles send `groupId` on Yeaft messages;
44
+ // the agent runtime has switched to `sessionId`. Coerce here so
45
+ // handlers don't each have to do it. Keep both fields populated.
46
+ if (msg && typeof msg === 'object') {
47
+ if (msg.sessionId == null && typeof msg.groupId === 'string') msg.sessionId = msg.groupId;
48
+ if (msg.groupId == null && typeof msg.sessionId === 'string') msg.groupId = msg.sessionId;
49
+ }
43
50
  switch (msg.type) {
44
51
  case 'registered':
45
52
  if (msg.sessionKey) {
@@ -429,7 +436,7 @@ export async function handleMessage(msg) {
429
436
  // Yeaft — single conversation backed by the default group.
430
437
  case 'yeaft_group_chat':
431
438
  case 'unify_group_chat':
432
- await handleYeaftGroupChat(msg);
439
+ await handleYeaftSessionSend(msg);
433
440
  break;
434
441
 
435
442
  case 'yeaft_load_history':
@@ -513,56 +520,56 @@ export async function handleMessage(msg) {
513
520
  case 'yeaft_list_groups':
514
521
  case 'unify_list_groups':
515
522
  case 'yeaft_list_sessions':
516
- handleYeaftListGroups(msg);
523
+ handleYeaftListSessions(msg);
517
524
  break;
518
525
  case 'yeaft_create_group':
519
526
  case 'unify_create_group':
520
527
  case 'yeaft_create_session':
521
- handleYeaftCreateGroup(msg);
528
+ handleYeaftCreateSession(msg);
522
529
  break;
523
530
  case 'yeaft_rename_group':
524
531
  case 'unify_rename_group':
525
532
  case 'yeaft_rename_session':
526
- handleYeaftRenameGroup(msg);
533
+ handleYeaftRenameSession(msg);
527
534
  break;
528
535
  case 'yeaft_update_group':
529
536
  case 'unify_update_group':
530
537
  case 'yeaft_update_session':
531
- handleYeaftUpdateGroup(msg);
538
+ handleYeaftUpdateSession(msg);
532
539
  break;
533
540
  case 'yeaft_update_group_config':
534
541
  case 'unify_update_group_config':
535
542
  case 'yeaft_update_session_config':
536
- handleYeaftUpdateGroupConfig(msg);
543
+ handleYeaftUpdateSessionConfig(msg);
537
544
  break;
538
545
  case 'yeaft_archive_group':
539
546
  case 'unify_archive_group':
540
547
  case 'yeaft_archive_session':
541
- handleYeaftArchiveGroup(msg);
548
+ handleYeaftArchiveSession(msg);
542
549
  break;
543
550
  case 'yeaft_delete_group':
544
551
  case 'unify_delete_group':
545
552
  case 'yeaft_delete_session':
546
- handleYeaftDeleteGroup(msg);
553
+ handleYeaftDeleteSession(msg);
547
554
  break;
548
555
  case 'yeaft_add_member':
549
556
  case 'unify_add_member':
550
557
  case 'yeaft_session_add_member':
551
- handleYeaftAddMember(msg);
558
+ handleYeaftSessionAddMember(msg);
552
559
  break;
553
560
  case 'yeaft_remove_member':
554
561
  case 'unify_remove_member':
555
562
  case 'yeaft_session_remove_member':
556
- handleYeaftRemoveMember(msg);
563
+ handleYeaftSessionRemoveMember(msg);
557
564
  break;
558
565
  case 'yeaft_set_default_vp':
559
566
  case 'unify_set_default_vp':
560
567
  case 'yeaft_session_set_default_vp':
561
- handleYeaftSetDefaultVp(msg);
568
+ handleYeaftSessionSetDefaultVp(msg);
562
569
  break;
563
570
  // Phase 2: session_send is just group_chat (N≥1 fan-out already works).
564
571
  case 'yeaft_session_send':
565
- handleYeaftGroupChat(msg);
572
+ handleYeaftSessionSend(msg);
566
573
  break;
567
574
 
568
575
  // wave-6b: manual dream trigger from VP detail page
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.874",
3
+ "version": "0.1.875",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -90,7 +90,7 @@ function sanitizeBaseName(base) {
90
90
  * Resolved files from server (pendingFiles → base64).
91
91
  * @param {Object} [opts]
92
92
  * @param {string} [opts.subdir] Sub-folder under TEMP_UPLOAD_DIR
93
- * (e.g. groupId). Lets multiple groups co-exist without clobbering.
93
+ * (e.g. sessionId). Lets multiple groups co-exist without clobbering.
94
94
  * @param {string} [opts.cwd] Override base dir; defaults to process.cwd()
95
95
  * which is what yeaft tools (file-read, bash, ...) resolve relative
96
96
  * paths against.
@@ -104,7 +104,7 @@ function sanitizeBaseName(base) {
104
104
  export function persistYeaftAttachments(files, opts = {}) {
105
105
  const cwd = opts.cwd || process.cwd();
106
106
  // Subdir is OURS — it must remain ASCII-safe because we generate it
107
- // from groupId. Keep the existing strict policy here; this is NOT
107
+ // from sessionId. Keep the existing strict policy here; this is NOT
108
108
  // user-visible.
109
109
  const subdir = opts.subdir ? String(opts.subdir).replace(/[^a-zA-Z0-9._-]/g, '_') : '';
110
110
  const uploadDir = subdir
package/yeaft/cli.js CHANGED
@@ -32,7 +32,7 @@ import { listModels, resolveModel, parseModelRef } from './models.js';
32
32
  import { buildSystemPrompt } from './prompts.js';
33
33
  import { searchMessages } from './conversation/search.js';
34
34
  import { ConversationStore } from './conversation/persist.js';
35
- import { snapshotGroups } from './groups/group-crud.js';
35
+ import { snapshotSessions } from './sessions/session-crud.js';
36
36
 
37
37
  // ─── Argument parsing ──────────────────────────────────────────
38
38
 
@@ -50,7 +50,7 @@ function parseArgs(argv) {
50
50
  skipSkills: false,
51
51
  compactOrphans: false,
52
52
  compactOrphansDry: false,
53
- deleteGroup: null,
53
+ deleteSession: null,
54
54
  prompt: null,
55
55
  };
56
56
 
@@ -100,7 +100,7 @@ function parseArgs(argv) {
100
100
  args.compactOrphansDry = true;
101
101
  break;
102
102
  case '--delete-group':
103
- args.deleteGroup = rest[++i] || null;
103
+ args.deleteSession = rest[++i] || null;
104
104
  break;
105
105
  default:
106
106
  if (!arg.startsWith('-') && !args.prompt) {
@@ -216,7 +216,7 @@ function handleDryRun(args, config) {
216
216
 
217
217
  /**
218
218
  * One-shot orphan-message sweep. Reads the live group list off disk and
219
- * deletes every persisted message whose `groupId` frontmatter is missing
219
+ * deletes every persisted message whose `sessionId` frontmatter is missing
220
220
  * or points to a group that no longer exists.
221
221
  *
222
222
  * Exposed via `--compact-orphans` (delete) and `--compact-orphans-dry`
@@ -227,7 +227,7 @@ function handleCompactOrphans(config, { dryRun = false } = {}) {
227
227
  const yeaftDir = config.dir;
228
228
  let groups;
229
229
  try {
230
- groups = snapshotGroups(yeaftDir);
230
+ groups = snapshotSessions(yeaftDir);
231
231
  } catch (err) {
232
232
  console.error(`Cannot read groups directory: ${err.message}`);
233
233
  console.error('Refusing to compact orphans without an authoritative live-group list.');
@@ -258,30 +258,30 @@ function handleCompactOrphans(config, { dryRun = false } = {}) {
258
258
  * as the web-bridge `yeaft_delete_group` op, but reachable from the CLI
259
259
  * for scripted maintenance.
260
260
  */
261
- function handleDeleteGroup(config, groupId) {
261
+ function handleDeleteGroup(config, sessionId) {
262
262
  const yeaftDir = config.dir;
263
263
  // Lazy import to avoid loading the whole groups module on every CLI call.
264
264
  // (Static `import` at top is fine too — kept dynamic to mirror the web-bridge
265
265
  // pattern and keep the maintenance path self-contained.)
266
266
  // eslint-disable-next-line global-require
267
- return import('./groups/group-crud.js').then(({ deleteGroup }) => {
267
+ return import('./sessions/session-crud.js').then(({ deleteSession }) => {
268
268
  let result;
269
269
  try {
270
- result = deleteGroup(yeaftDir, groupId);
270
+ result = deleteSession(yeaftDir, sessionId);
271
271
  } catch (err) {
272
- console.error(`Failed to delete group ${groupId}: ${err.message}`);
272
+ console.error(`Failed to delete group ${sessionId}: ${err.message}`);
273
273
  process.exitCode = 1;
274
274
  return;
275
275
  }
276
276
  let messagesRemoved = 0;
277
277
  try {
278
278
  const store = new ConversationStore(yeaftDir);
279
- messagesRemoved = store.deleteByGroup(groupId);
279
+ messagesRemoved = store.deleteByGroup(sessionId);
280
280
  } catch (err) {
281
281
  console.warn(`Group dir removed, but cascade failed: ${err.message}`);
282
282
  }
283
283
  console.log('=== DELETE GROUP ===');
284
- console.log(` Group: ${result.groupId}`);
284
+ console.log(` Group: ${result.sessionId}`);
285
285
  console.log(` Legacy archives swept: ${result.legacyCleanedUp}`);
286
286
  console.log(` Messages cascaded: ${messagesRemoved}`);
287
287
  });
@@ -784,8 +784,8 @@ async function main() {
784
784
  handleCompactOrphans(config, { dryRun: args.compactOrphansDry });
785
785
  return;
786
786
  }
787
- if (args.deleteGroup) {
788
- await handleDeleteGroup(config, args.deleteGroup);
787
+ if (args.deleteSession) {
788
+ await handleDeleteGroup(config, args.deleteSession);
789
789
  return;
790
790
  }
791
791
 
@@ -19,7 +19,7 @@
19
19
  * separately via `setOnCompacted`.
20
20
  *
21
21
  * Engine instances are per-VP-per-group (`vpEngines` keyed by
22
- * `${groupId}::${vpId}`), so this orchestration cannot live on `Engine`
22
+ * `${sessionId}::${vpId}`), so this orchestration cannot live on `Engine`
23
23
  * itself: a per-group single-flight slot pinned to a per-VP Engine is a
24
24
  * category error. Compactor is constructed once per session, beside the
25
25
  * `dreamScheduler`.
@@ -67,7 +67,7 @@ export class Compactor {
67
67
  * `compactHistory` so the compactor's summary prompt + the
68
68
  * "session continued" wrapper render in the user's preferred
69
69
  * locale instead of always English.
70
- * @param {(groupId: string, result: CompactedResult) => void} [opts.onCompacted]
70
+ * @param {(sessionId: string, result: CompactedResult) => void} [opts.onCompacted]
71
71
  * Optional sink. Bridge wires this to send the
72
72
  * `yeaft_history_compacted` WS event. Default: no-op. Can be
73
73
  * replaced post-construction via `setOnCompacted`.
@@ -100,11 +100,11 @@ export class Compactor {
100
100
  }
101
101
 
102
102
  /** Get-or-create the per-group state record. */
103
- _state(groupId) {
104
- let s = this._states.get(groupId);
103
+ _state(sessionId) {
104
+ let s = this._states.get(sessionId);
105
105
  if (!s) {
106
106
  s = { inFlight: null, pending: false };
107
- this._states.set(groupId, s);
107
+ this._states.set(sessionId, s);
108
108
  }
109
109
  return s;
110
110
  }
@@ -114,11 +114,11 @@ export class Compactor {
114
114
  * so a brand-new turn never reads a half-mutated history mid-compact.
115
115
  * Other groups' compacts never block this gate (per-group keying).
116
116
  *
117
- * @param {string} groupId
117
+ * @param {string} sessionId
118
118
  */
119
- async awaitInFlight(groupId) {
120
- if (!groupId) return;
121
- const s = this._states.get(groupId);
119
+ async awaitInFlight(sessionId) {
120
+ if (!sessionId) return;
121
+ const s = this._states.get(sessionId);
122
122
  if (s && s.inFlight) {
123
123
  try { await s.inFlight; } catch { /* _runOnce already logs */ }
124
124
  }
@@ -127,7 +127,7 @@ export class Compactor {
127
127
  /**
128
128
  * Post-turn fire-and-forget. Bridge calls after the per-VP fanout
129
129
  * completes for a turn. The `historyHandle` MUST be a per-call value:
130
- * its `get` / `set` close over the bridge's groupId-scoped helpers
130
+ * its `get` / `set` close over the bridge's sessionId-scoped helpers
131
131
  * (`getOrCreateGroupHistory` / `setGroupHistory`), not over a frozen
132
132
  * snapshot, so a chained follow-up sees fresh state.
133
133
  *
@@ -136,12 +136,12 @@ export class Compactor {
136
136
  * the in-flight finishes, exactly one follow-up runs (no matter how
137
137
  * many turns piled up during the await).
138
138
  *
139
- * @param {string} groupId
139
+ * @param {string} sessionId
140
140
  * @param {CompactorHistoryHandle} historyHandle
141
141
  */
142
- scheduleAfterTurn(groupId, historyHandle) {
143
- if (!groupId || !historyHandle) return;
144
- const s = this._state(groupId);
142
+ scheduleAfterTurn(sessionId, historyHandle) {
143
+ if (!sessionId || !historyHandle) return;
144
+ const s = this._state(sessionId);
145
145
  if (s.inFlight) {
146
146
  // Anti-starvation: compact is already running. Mark a follow-up
147
147
  // so when it finishes, it re-evaluates and runs again if still
@@ -149,14 +149,14 @@ export class Compactor {
149
149
  s.pending = true;
150
150
  return;
151
151
  }
152
- s.inFlight = this._runOnce(groupId, historyHandle).finally(() => {
152
+ s.inFlight = this._runOnce(sessionId, historyHandle).finally(() => {
153
153
  s.inFlight = null;
154
154
  // If turns piled up while we were running and compaction is still
155
155
  // needed, chain a follow-up. Use a microtask so the .finally
156
156
  // chain settles cleanly before the next promise is created.
157
157
  if (s.pending) {
158
158
  s.pending = false;
159
- queueMicrotask(() => this.scheduleAfterTurn(groupId, historyHandle));
159
+ queueMicrotask(() => this.scheduleAfterTurn(sessionId, historyHandle));
160
160
  }
161
161
  });
162
162
  }
@@ -167,10 +167,10 @@ export class Compactor {
167
167
  * `historyHandle.set`, then notifies `onCompacted`. All errors are
168
168
  * swallowed (logged) so `inFlight` always clears.
169
169
  *
170
- * @param {string} groupId
170
+ * @param {string} sessionId
171
171
  * @param {CompactorHistoryHandle} historyHandle
172
172
  */
173
- async _runOnce(groupId, historyHandle) {
173
+ async _runOnce(sessionId, historyHandle) {
174
174
  try {
175
175
  // Capture reference AND length. If a different code path swaps the
176
176
  // array (`consolidate` event, session reset, manual clear) the
@@ -233,7 +233,7 @@ export class Compactor {
233
233
  );
234
234
 
235
235
  try {
236
- this._onCompacted(groupId, {
236
+ this._onCompacted(sessionId, {
237
237
  reason: result.reason,
238
238
  beforeTurns: result.beforeTurns,
239
239
  afterTurns: result.afterTurns,
@@ -243,7 +243,7 @@ export class Compactor {
243
243
  });
244
244
  } catch { /* sink failure must not abort the orchestrator */ }
245
245
  } catch (err) {
246
- console.warn(`[Yeaft] history compact: unexpected failure (groupId=${groupId})`, err?.message || err);
246
+ console.warn(`[Yeaft] history compact: unexpected failure (sessionId=${sessionId})`, err?.message || err);
247
247
  }
248
248
  }
249
249