@yeaft/webchat-agent 0.1.977 → 0.1.979

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.
@@ -16,6 +16,8 @@ export const FALLBACK_GITHUB_COPILOT_MODELS = [
16
16
  'gpt-4.1',
17
17
  'gpt-4o',
18
18
  'gpt-4o-mini',
19
+ 'claude-opus-4.8',
20
+ 'claude-opus-4.7',
19
21
  'claude-opus-4.6',
20
22
  'claude-sonnet-4.6',
21
23
  'claude-sonnet-4.5',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.977",
3
+ "version": "0.1.979",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -231,6 +231,84 @@ export class AdapterRouter extends LLMAdapter {
231
231
  }
232
232
  }
233
233
 
234
+ /**
235
+ * Resolve an explicit provider/model ref against a provider row even when
236
+ * the local model catalog is stale. The provider name still must exist; the
237
+ * fallback only skips the per-provider models[] membership check.
238
+ *
239
+ * @param {string} modelRef
240
+ * @returns {{provider: object, entry: {id: string, protocol?: string}} | null}
241
+ */
242
+ #resolveProviderQualifiedFallback(modelRef) {
243
+ const parsed = parseModelRef(modelRef);
244
+ if (!parsed.providerName || !parsed.modelId) return null;
245
+
246
+ const candidates = this.#providers.filter(p => p && p.name === parsed.providerName);
247
+ if (candidates.length === 0) return null;
248
+
249
+ const inferred = inferProtocolFromModelId(parsed.modelId);
250
+ if (!inferred) return null;
251
+ const entry = { id: parsed.modelId, protocol: inferred };
252
+
253
+ // Provider-qualified refs are explicit enough to tolerate a stale
254
+ // providers[].models catalog. Prefer a provider row that already serves
255
+ // this protocol through at least one model entry. That covers the common
256
+ // Copilot shape: provider.protocol=openai-responses plus per-model
257
+ // protocol='anthropic' for Claude entries.
258
+ for (const provider of candidates) {
259
+ const models = Array.isArray(provider.models) ? provider.models : [];
260
+ for (const raw of models) {
261
+ const existing = normalizeModelEntry(raw);
262
+ if (!existing) continue;
263
+ try {
264
+ if (this.#effectiveProtocol(provider, existing) === inferred) {
265
+ return { provider, entry };
266
+ }
267
+ } catch {
268
+ // Ignore invalid existing entries while looking for a compatible row.
269
+ }
270
+ }
271
+ }
272
+
273
+ // If no existing entry proves mixed-protocol support, fall back to rows
274
+ // whose provider-level protocol is absent or directly compatible.
275
+ for (const provider of candidates) {
276
+ if (!provider.protocol || provider.protocol === inferred) {
277
+ return { provider, entry };
278
+ }
279
+ }
280
+
281
+ return null;
282
+ }
283
+
284
+ #unknownModelError(modelRef) {
285
+ const parsed = parseModelRef(modelRef);
286
+ if (parsed.providerName) {
287
+ const providerModels = [];
288
+ let sawProvider = false;
289
+ for (const provider of this.#providers) {
290
+ if (!provider || provider.name !== parsed.providerName) continue;
291
+ sawProvider = true;
292
+ for (const raw of Array.isArray(provider.models) ? provider.models : []) {
293
+ const entry = normalizeModelEntry(raw);
294
+ if (entry) providerModels.push(entry.id);
295
+ }
296
+ }
297
+ if (sawProvider) {
298
+ return new Error(
299
+ `Model "${modelRef}" is not listed under provider "${parsed.providerName}" and no compatible protocol row could be inferred. ` +
300
+ `Available models for this provider: ${providerModels.join(', ') || '(none)'}. ` +
301
+ `Add "${parsed.modelId}" to config.json providers[].models or refresh the model catalog.`
302
+ );
303
+ }
304
+ }
305
+ return new Error(
306
+ `Model "${modelRef}" not found in any provider. ` +
307
+ `Available models: ${[...this.#modelToProvider.keys()].join(', ') || '(none)'}. ` +
308
+ `Check your config.json providers[].models arrays.`
309
+ );
310
+ }
311
+
234
312
  /**
235
313
  * Resolve the effective wire protocol for a (provider, model) pair.
236
314
  *
@@ -283,13 +361,9 @@ export class AdapterRouter extends LLMAdapter {
283
361
  * @returns {Promise<{adapter: LLMAdapter, modelId: string}>}
284
362
  */
285
363
  async #resolveAdapter(modelRef) {
286
- const hit = this.#modelToProvider.get(modelRef);
364
+ const hit = this.#modelToProvider.get(modelRef) || this.#resolveProviderQualifiedFallback(modelRef);
287
365
  if (!hit) {
288
- throw new Error(
289
- `Model "${modelRef}" not found in any provider. ` +
290
- `Available models: ${[...this.#modelToProvider.keys()].join(', ') || '(none)'}. ` +
291
- `Check your config.json providers[].models arrays.`
292
- );
366
+ throw this.#unknownModelError(modelRef);
293
367
  }
294
368
  const { provider, entry } = hit;
295
369
 
@@ -435,7 +509,7 @@ export class AdapterRouter extends LLMAdapter {
435
509
  * @returns {object|null} — Provider config or null
436
510
  */
437
511
  getProviderForModel(modelId) {
438
- const hit = this.#modelToProvider.get(modelId);
512
+ const hit = this.#modelToProvider.get(modelId) || this.#resolveProviderQualifiedFallback(modelId);
439
513
  return hit ? hit.provider : null;
440
514
  }
441
515
 
package/yeaft/models.js CHANGED
@@ -67,6 +67,26 @@ export const MODEL_REGISTRY = new Map([
67
67
  defaultEffort: null,
68
68
  maxBudgetTokens: 64000,
69
69
  }],
70
+ ['claude-opus-4-8', {
71
+ provider: 'anthropic',
72
+ adapter: 'anthropic',
73
+ baseUrl: 'https://api.anthropic.com',
74
+ displayName: 'Claude Opus 4.8',
75
+ supportsThinking: true,
76
+ thinkingProtocol: 'anthropic',
77
+ defaultEffort: null,
78
+ maxBudgetTokens: 64000,
79
+ }],
80
+ ['claude-opus-4.8', {
81
+ provider: 'anthropic',
82
+ adapter: 'anthropic',
83
+ baseUrl: 'https://api.anthropic.com',
84
+ displayName: 'Claude Opus 4.8',
85
+ supportsThinking: true,
86
+ thinkingProtocol: 'anthropic',
87
+ defaultEffort: null,
88
+ maxBudgetTokens: 64000,
89
+ }],
70
90
  ['claude-haiku-3-20250414', {
71
91
  provider: 'anthropic',
72
92
  adapter: 'anthropic',