@yeaft/webchat-agent 0.1.903 → 0.1.905

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.
@@ -40,13 +40,6 @@ import { fetchModelsDev } from '../yeaft/llm/models-dev.js';
40
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, broadcastYeaftSessionSnapshotEager } 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
- }
50
43
  switch (msg.type) {
51
44
  case 'registered':
52
45
  if (msg.sessionKey) {
@@ -443,8 +436,16 @@ export async function handleMessage(msg) {
443
436
  break;
444
437
  }
445
438
 
446
- // Yeaft — single conversation backed by the default group.
447
- case 'yeaft_group_chat':
439
+ // Yeaft — single conversation backed by the default session.
440
+ //
441
+ // Wire-alias scope: the `yeaft_group_chat` op (and its envelope
442
+ // dual-emit) was REMOVED in this rename. The `unify_*` aliases (and
443
+ // the `yeaft_*_group` CRUD aliases below) are PRE-EXISTING wire-
444
+ // compat hooks from earlier renames (Unify→Yeaft, Phase 2
445
+ // group→session); they remain so older agent / web bundles in the
446
+ // wild keep working. Deleting them is a separate, future PR with
447
+ // its own deployment plan.
448
+ case 'yeaft_session_chat':
448
449
  case 'unify_group_chat':
449
450
  await handleYeaftSessionSend(msg);
450
451
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.903",
3
+ "version": "0.1.905",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -14,7 +14,7 @@
14
14
  * diverges from the snapshot we captured before awaiting the LLM.
15
15
  *
16
16
  * History is passed in PER CALL via a `historyHandle = { get, set }` so
17
- * Compactor never has to know about `groupContexts`, `historyHydrated`,
17
+ * Compactor never has to know about `sessionContexts`, `historyHydrated`,
18
18
  * or any other bridge-internal field. The WS event sink is wired
19
19
  * separately via `setOnCompacted`.
20
20
  *
@@ -128,7 +128,7 @@ export class Compactor {
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
130
  * its `get` / `set` close over the bridge's sessionId-scoped helpers
131
- * (`getOrCreateGroupHistory` / `setGroupHistory`), not over a frozen
131
+ * (`getOrCreateSessionHistory` / `setGroupHistory`), not over a frozen
132
132
  * snapshot, so a chained follow-up sees fresh state.
133
133
  *
134
134
  * Anti-starvation: while a compact is in flight, additional
@@ -136,7 +136,7 @@ export function updateLlmConfig(update, dir) {
136
136
  * stable shape — `normaliseYeaftSection` guarantees that.
137
137
  *
138
138
  * @param {string} [dir] — Yeaft data directory
139
- * @returns {{ maxConcurrentThreads: number, autoArchiveIdleDays: number } | { error: string }}
139
+ * @returns {{ maxConcurrentThreads: number, autoArchiveIdleDays: number, recentTurnsLimit: number } | { error: string }}
140
140
  */
141
141
  export function getYeaftSettings(dir) {
142
142
  const root = dir || process.env.YEAFT_DIR || DEFAULT_YEAFT_DIR;
@@ -155,13 +155,14 @@ export function getYeaftSettings(dir) {
155
155
  * Update the Yeaft-section of config.json. Merges into existing config
156
156
  * (LLM provider / model fields are untouched) and validates each field:
157
157
  * `maxConcurrentThreads` must be 1..50, `autoArchiveIdleDays` must be
158
- * 1..3650. Invalid values are rejected outright so the UI sees an error
159
- * rather than silently reverting a silent revert would make "I set it
160
- * to 100 and nothing happened" impossible to debug.
158
+ * 1..3650, `recentTurnsLimit` must be 1..500. Invalid values are rejected
159
+ * outright so the UI sees an error rather than silently reverting a
160
+ * silent revert would make "I set it to 100 and nothing happened"
161
+ * impossible to debug.
161
162
  *
162
- * @param {{ maxConcurrentThreads?: number, autoArchiveIdleDays?: number }} update
163
+ * @param {{ maxConcurrentThreads?: number, autoArchiveIdleDays?: number, recentTurnsLimit?: number }} update
163
164
  * @param {string} [dir]
164
- * @returns {{ maxConcurrentThreads: number, autoArchiveIdleDays: number } | { error: string }}
165
+ * @returns {{ maxConcurrentThreads: number, autoArchiveIdleDays: number, recentTurnsLimit: number } | { error: string }}
165
166
  */
166
167
  export function updateYeaftSettings(update, dir) {
167
168
  const root = dir || process.env.YEAFT_DIR || DEFAULT_YEAFT_DIR;
@@ -185,6 +186,12 @@ export function updateYeaftSettings(update, dir) {
185
186
  return { error: 'autoArchiveIdleDays must be between 1 and 3650' };
186
187
  }
187
188
  }
189
+ if (update.recentTurnsLimit !== undefined) {
190
+ const n = Number(update.recentTurnsLimit);
191
+ if (!Number.isFinite(n) || n < 1 || n > 500) {
192
+ return { error: 'recentTurnsLimit must be between 1 and 500' };
193
+ }
194
+ }
188
195
 
189
196
  // Read existing config (preserve LLM and other top-level fields).
190
197
  let existing = {};
@@ -204,6 +211,9 @@ export function updateYeaftSettings(update, dir) {
204
211
  autoArchiveIdleDays: update.autoArchiveIdleDays !== undefined
205
212
  ? Math.floor(Number(update.autoArchiveIdleDays))
206
213
  : prev.autoArchiveIdleDays,
214
+ recentTurnsLimit: update.recentTurnsLimit !== undefined
215
+ ? Math.floor(Number(update.recentTurnsLimit))
216
+ : prev.recentTurnsLimit,
207
217
  };
208
218
  existing.yeaft = merged;
209
219
 
package/yeaft/config.js CHANGED
@@ -42,6 +42,12 @@ const DEFAULTS = {
42
42
  // plumb the knob through so the UI can set it).
43
43
  yeaftMaxConcurrentThreads: 6,
44
44
  yeaftAutoArchiveIdleDays: 30,
45
+ // Cold-start replay window: how many of the most recent turns
46
+ // ConversationStore.loadRecentBySession / loadSessionHistoryForVp
47
+ // bring back when no compact summary exists for the session. Raise
48
+ // this if your sessions routinely outgrow the 20-turn window
49
+ // before compaction fires. Range: 1–500.
50
+ yeaftRecentTurnsLimit: 20,
45
51
  // CLAUDE.md / AGENTS.md project-doc cap, in bytes. Mirrors Codex's
46
52
  // `project_doc_max_bytes`. 0 disables the feature (no project-doc
47
53
  // block is injected). Hand-edited values are NOT clamped — we let
@@ -167,12 +173,15 @@ export function normaliseYeaftSection(raw) {
167
173
  const out = {
168
174
  maxConcurrentThreads: DEFAULTS.yeaftMaxConcurrentThreads,
169
175
  autoArchiveIdleDays: DEFAULTS.yeaftAutoArchiveIdleDays,
176
+ recentTurnsLimit: DEFAULTS.yeaftRecentTurnsLimit,
170
177
  };
171
178
  if (!raw || typeof raw !== 'object') return out;
172
179
  const mc = clampYeaftField(raw.maxConcurrentThreads, 'maxConcurrentThreads');
173
180
  if (mc !== null) out.maxConcurrentThreads = mc;
174
181
  const ad = clampYeaftField(raw.autoArchiveIdleDays, 'autoArchiveIdleDays');
175
182
  if (ad !== null) out.autoArchiveIdleDays = ad;
183
+ const rt = clampYeaftField(raw.recentTurnsLimit, 'recentTurnsLimit');
184
+ if (rt !== null) out.recentTurnsLimit = rt;
176
185
  return out;
177
186
  }
178
187
 
@@ -183,14 +192,18 @@ export function normaliseYeaftSection(raw) {
183
192
  * (`normaliseYeaftSection`) and write (`updateYeaftSettings` validation).
184
193
  *
185
194
  * @param {unknown} v
186
- * @param {'maxConcurrentThreads'|'autoArchiveIdleDays'} field
195
+ * @param {'maxConcurrentThreads'|'autoArchiveIdleDays'|'recentTurnsLimit'} field
187
196
  * @returns {number | null}
188
197
  */
189
198
  export function clampYeaftField(v, field) {
190
199
  if (v === null || v === undefined) return null;
191
200
  const n = Number(v);
192
201
  if (!Number.isFinite(n)) return null;
193
- const [lo, hi] = field === 'maxConcurrentThreads' ? [1, 50] : [1, 3650];
202
+ let lo;
203
+ let hi;
204
+ if (field === 'maxConcurrentThreads') { lo = 1; hi = 50; }
205
+ else if (field === 'recentTurnsLimit') { lo = 1; hi = 500; }
206
+ else { lo = 1; hi = 3650; } // autoArchiveIdleDays
194
207
  return Math.min(hi, Math.max(lo, Math.floor(n)));
195
208
  }
196
209