@yeaft/webchat-agent 0.1.443 → 0.1.445

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.
@@ -25,7 +25,7 @@ import { sendToServer, flushMessageBuffer } from './buffer.js';
25
25
  import { handleRestartAgent, handleUpgradeAgent } from './upgrade.js';
26
26
  import { loadMcpServers, updateMcpConfig } from '../mcp.js';
27
27
  import { getLlmConfig, updateLlmConfig } from '../unify/config-api.js';
28
- import { handleUnifyChat, handleUnifyModeSwitch, resetUnifySession } from '../unify/web-bridge.js';
28
+ import { handleUnifyChat, handleUnifyModeSwitch, handleUnifyModelSwitch, resetUnifySession } from '../unify/web-bridge.js';
29
29
 
30
30
  export async function handleMessage(msg) {
31
31
  switch (msg.type) {
@@ -329,6 +329,10 @@ export async function handleMessage(msg) {
329
329
  handleUnifyModeSwitch(msg);
330
330
  break;
331
331
 
332
+ case 'unify_model_switch':
333
+ handleUnifyModelSwitch(msg);
334
+ break;
335
+
332
336
  case 'unify_reset':
333
337
  await resetUnifySession();
334
338
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.443",
3
+ "version": "0.1.445",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/unify/config.js CHANGED
@@ -260,6 +260,24 @@ export function loadConfig(overrides = {}) {
260
260
  adapter: null,
261
261
  };
262
262
 
263
+ // Aggregate all available models from providers
264
+ config.availableModels = [];
265
+ if (providers) {
266
+ for (const p of providers) {
267
+ if (!Array.isArray(p.models)) continue;
268
+ for (const m of p.models) {
269
+ // Avoid duplicates (first provider wins)
270
+ if (!config.availableModels.some(am => am.id === m)) {
271
+ config.availableModels.push({
272
+ id: m,
273
+ provider: p.name,
274
+ label: m,
275
+ });
276
+ }
277
+ }
278
+ }
279
+ }
280
+
263
281
  return config;
264
282
  }
265
283
 
@@ -32,6 +32,11 @@ let unifyConversationId = null;
32
32
  /** Current query mode: 'chat' or 'work' */
33
33
  let currentMode = 'chat';
34
34
 
35
+ /** Accumulated conversation messages for context continuity across queries.
36
+ * Each entry is { role: 'user'|'assistant', content: string|Array }.
37
+ * Cleared on session reset or consolidation. */
38
+ let conversationMessages = [];
39
+
35
40
  /** Whether we've already sent a permission warning to the UI */
36
41
  let _permissionDiagnosticSent = false;
37
42
 
@@ -103,6 +108,7 @@ export async function handleUnifyChat(msg) {
103
108
  type: 'session_ready',
104
109
  conversationId: unifyConversationId,
105
110
  model: session.config.model,
111
+ availableModels: session.config.availableModels || [],
106
112
  skills: session.status.skills,
107
113
  mcpServers: session.status.mcpServers,
108
114
  tools: session.status.tools,
@@ -132,10 +138,14 @@ export async function handleUnifyChat(msg) {
132
138
  resetQueryTimer();
133
139
 
134
140
  try {
141
+ // ─── Collect assistant response for conversation history ──
142
+ let assistantTextParts = [];
143
+
135
144
  // ─── Stream Engine events → claude_output format ──
136
145
  for await (const event of session.engine.query({
137
146
  prompt,
138
147
  mode: currentMode,
148
+ messages: conversationMessages,
139
149
  signal: currentAbort.signal,
140
150
  })) {
141
151
  // Reset timeout on every event — activity means the query is alive
@@ -143,6 +153,7 @@ export async function handleUnifyChat(msg) {
143
153
  switch (event.type) {
144
154
  // ── Text streaming ──
145
155
  case 'text_delta':
156
+ assistantTextParts.push(event.text);
146
157
  sendUnifyOutput({
147
158
  type: 'assistant',
148
159
  message: {
@@ -231,6 +242,9 @@ export async function handleUnifyChat(msg) {
231
242
 
232
243
  // ── Context consolidation ──
233
244
  case 'consolidate':
245
+ // Engine has compressed the context — clear our accumulated history.
246
+ // The engine's compactSummary will provide context on next query.
247
+ conversationMessages = [];
234
248
  sendUnifyEvent({
235
249
  type: 'consolidate',
236
250
  archivedCount: event.archivedCount,
@@ -302,7 +316,15 @@ export async function handleUnifyChat(msg) {
302
316
  }
303
317
  }
304
318
 
305
- // ─── Query complete — signal turn end ──
319
+ // ─── Query complete — accumulate messages for context continuity ──
320
+ conversationMessages.push({ role: 'user', content: prompt });
321
+
322
+ const fullText = assistantTextParts.join('');
323
+ if (fullText) {
324
+ conversationMessages.push({ role: 'assistant', content: fullText });
325
+ }
326
+
327
+ // ─── Signal turn end to UI ──
306
328
  // Finish any streaming text
307
329
  sendUnifyOutput({
308
330
  type: 'assistant',
@@ -385,6 +407,32 @@ export function handleUnifyModeSwitch(msg) {
385
407
  }
386
408
  }
387
409
 
410
+ /**
411
+ * Handle model switch from the web UI.
412
+ * Updates Engine's config so the next query uses the new model.
413
+ * @param {{ model: string }} msg
414
+ */
415
+ export function handleUnifyModelSwitch(msg) {
416
+ if (!session || !msg.model) return;
417
+
418
+ // Validate: model must be in availableModels list
419
+ const available = session.config.availableModels || [];
420
+ const found = available.some(m => m.id === msg.model);
421
+ if (!found) {
422
+ console.warn(`[Unify] model switch rejected — "${msg.model}" not in availableModels`);
423
+ return;
424
+ }
425
+
426
+ // Update Engine's model for subsequent queries
427
+ session.config.model = msg.model;
428
+
429
+ // Confirm switch to frontend
430
+ sendUnifyEvent({
431
+ type: 'model_switched',
432
+ model: msg.model,
433
+ });
434
+ }
435
+
388
436
  /**
389
437
  * Reset Unify session (for clear messages).
390
438
  */
@@ -399,4 +447,5 @@ export async function resetUnifySession() {
399
447
  }
400
448
  unifyConversationId = null;
401
449
  currentMode = 'chat';
450
+ conversationMessages = [];
402
451
  }