@yeaft/webchat-agent 0.1.926 → 0.1.927

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.926",
3
+ "version": "0.1.927",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -193,7 +193,21 @@ export class AdapterRouter extends LLMAdapter {
193
193
  */
194
194
  constructor({ providers }) {
195
195
  super();
196
- this.#providers = providers;
196
+ this.#providers = [];
197
+ this.#modelToProvider = new Map();
198
+ this.#adapterCache = new Map();
199
+ this.refreshProviders(providers);
200
+ }
201
+
202
+ /**
203
+ * Replace the provider/model index after config.json changes. Existing
204
+ * provider adapters are dropped because credentials, baseUrl, protocol,
205
+ * or model ownership may have changed along with the list.
206
+ *
207
+ * @param {object[]} providers
208
+ */
209
+ refreshProviders(providers) {
210
+ this.#providers = Array.isArray(providers) ? providers : [];
197
211
  this.#modelToProvider = new Map();
198
212
  this.#adapterCache = new Map();
199
213
 
@@ -201,7 +215,7 @@ export class AdapterRouter extends LLMAdapter {
201
215
  // model id appears in multiple providers. Each model entry may declare
202
216
  // its own `protocol`; we keep the normalized entry so #effectiveProtocol
203
217
  // can consult it later without re-parsing.
204
- for (const provider of providers) {
218
+ for (const provider of this.#providers) {
205
219
  if (!Array.isArray(provider.models)) continue;
206
220
  for (const raw of provider.models) {
207
221
  const entry = normalizeModelEntry(raw);
@@ -23,6 +23,7 @@ import { existsSync } from 'node:fs';
23
23
  import { randomUUID } from 'node:crypto';
24
24
  import { Engine } from './engine.js';
25
25
  import { loadSession } from './session.js';
26
+ import { loadConfig } from './config.js';
26
27
  import { sendToServer } from '../connection/buffer.js';
27
28
  import ctx from '../context.js';
28
29
  import { hydrateYeaftStatusFromSession } from './status-cache.js';
@@ -69,6 +70,26 @@ let session = null;
69
70
 
70
71
  let threadClassifier = defaultClassifyThread;
71
72
 
73
+ function refreshLiveSessionConfig() {
74
+ if (!session) return;
75
+ try {
76
+ const freshConfig = loadConfig({ dir: session.yeaftDir || ctx.CONFIG?.yeaftDir });
77
+ const freshModels = Array.isArray(freshConfig.availableModels) ? freshConfig.availableModels : [];
78
+ session.config.availableModels = freshModels;
79
+ if (freshConfig.model && !freshModels.some(m => m?.id === session.config.model)) {
80
+ session.config.model = freshConfig.model;
81
+ }
82
+ if (freshConfig.providers) {
83
+ session.config.providers = freshConfig.providers;
84
+ if (typeof session.adapter?.refreshProviders === 'function') {
85
+ session.adapter.refreshProviders(freshConfig.providers);
86
+ }
87
+ }
88
+ } catch (err) {
89
+ console.warn('[Yeaft] refresh live session config failed:', err?.message || err);
90
+ }
91
+ }
92
+
72
93
  /** Test-only: replace the lightweight VP thread classifier. */
73
94
  export function __testSetThreadClassifier(fn) {
74
95
  threadClassifier = typeof fn === 'function' ? fn : defaultClassifyThread;
@@ -3728,6 +3749,7 @@ export function handleYeaftModeSwitch(_msg) {
3728
3749
  /** Handle model switch from the web UI. */
3729
3750
  export function handleYeaftModelSwitch(msg) {
3730
3751
  if (!session || !msg.model) return;
3752
+ refreshLiveSessionConfig();
3731
3753
 
3732
3754
  const available = session.config.availableModels || [];
3733
3755
  const found = available.some(m => m.id === msg.model);
@@ -3774,6 +3796,7 @@ export async function handleYeaftLoadHistory(msg) {
3774
3796
  installYeaftRuntimeBridge(session);
3775
3797
 
3776
3798
  yeaftConversationId = `yeaft-${Date.now()}`;
3799
+ refreshLiveSessionConfig();
3777
3800
  hydrateYeaftStatusFromSession(session, { reason: 'history_load', emitEvent: true });
3778
3801
 
3779
3802
  // Per-group history hydrates lazily via getOrCreateSessionHistory.
@@ -3782,7 +3805,12 @@ export async function handleYeaftLoadHistory(msg) {
3782
3805
  // it doesn't (legacy callers), do nothing — the per-group lazy
3783
3806
  // hydration handles it.
3784
3807
  if (sessionId) setGroupHistory(sessionId, hydrateGroupHistory(sessionId));
3785
- } else if (sessionId) {
3808
+ } else {
3809
+ refreshLiveSessionConfig();
3810
+ hydrateYeaftStatusFromSession(session, { reason: 'history_load', emitEvent: true });
3811
+ }
3812
+
3813
+ if (sessionId) {
3786
3814
  // Re-entering an existing session with a (possibly new) group filter:
3787
3815
  // re-seed THIS group's history from disk so it doesn't carry stale
3788
3816
  // in-memory state into the next turn's context.