@yeaft/webchat-agent 0.1.984 → 0.1.985

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/llm-config-cli.js CHANGED
@@ -215,23 +215,9 @@ export async function useGitHubCopilot(config, options = {}) {
215
215
  }
216
216
  }
217
217
 
218
- const providerModels = [...discovery.providerModels];
219
- if (allowUnknown) {
220
- const known = new Set(discoveredIds);
221
- for (const model of [primaryModel, fastModel].filter(Boolean)) {
222
- if (!known.has(model)) {
223
- providerModels.push(model);
224
- known.add(model);
225
- }
226
- }
227
- }
228
-
229
218
  const next = { ...config };
230
219
  const providers = Array.isArray(config.providers) ? [...config.providers] : [];
231
- const provider = {
232
- ...GITHUB_COPILOT_PROVIDER,
233
- models: providerModels,
234
- };
220
+ const provider = { ...GITHUB_COPILOT_PROVIDER };
235
221
  const index = providers.findIndex(p => p && p.name === provider.name);
236
222
  if (index >= 0) providers[index] = provider;
237
223
  else providers.push(provider);
@@ -1,29 +1,11 @@
1
1
  import { getApiToken, copilotRequestHeaders } from './yeaft/llm/credentials/github-copilot.js';
2
+ import {
3
+ FALLBACK_GITHUB_COPILOT_MODELS,
4
+ GITHUB_COPILOT_PROVIDER,
5
+ modelEntryForGitHubCopilot,
6
+ } from './yeaft/llm/known-providers.js';
2
7
 
3
- export const GITHUB_COPILOT_PROVIDER = {
4
- name: 'github-copilot',
5
- baseUrl: 'https://api.githubcopilot.com',
6
- credentialProvider: 'github-copilot',
7
- protocol: 'openai-responses',
8
- };
9
-
10
- export const FALLBACK_GITHUB_COPILOT_MODELS = [
11
- 'gpt-5.4',
12
- 'gpt-5.4-mini',
13
- 'gpt-5-mini',
14
- 'gpt-5.3-codex',
15
- 'gpt-5.2-codex',
16
- 'gpt-4.1',
17
- 'gpt-4o',
18
- 'gpt-4o-mini',
19
- 'claude-opus-4.8',
20
- 'claude-opus-4.7',
21
- 'claude-opus-4.6',
22
- 'claude-sonnet-4.6',
23
- 'claude-sonnet-4.5',
24
- 'claude-haiku-4.5',
25
- 'gemini-2.5-pro',
26
- ];
8
+ export { FALLBACK_GITHUB_COPILOT_MODELS, GITHUB_COPILOT_PROVIDER };
27
9
 
28
10
  function modelId(item) {
29
11
  if (typeof item === 'string') return item.trim();
@@ -51,12 +33,17 @@ export function modelEntryForProvider(id) {
51
33
  : value;
52
34
  }
53
35
 
36
+ export function modelEntryForGitHubCopilotProvider(id) {
37
+ return modelEntryForGitHubCopilot(id);
38
+ }
39
+
54
40
  export function modelIdsFromProviderModels(models) {
55
41
  return uniqueIds(models);
56
42
  }
57
43
 
58
- export function providerModelsFromIds(ids) {
59
- return uniqueIds(ids).map(modelEntryForProvider).filter(Boolean);
44
+ export function providerModelsFromIds(ids, { githubCopilot = false } = {}) {
45
+ const mapper = githubCopilot ? modelEntryForGitHubCopilotProvider : modelEntryForProvider;
46
+ return uniqueIds(ids).map(mapper).filter(Boolean);
60
47
  }
61
48
 
62
49
  function parseModelPayload(payload) {
@@ -80,7 +67,7 @@ function fallbackResult(provider, reason) {
80
67
  return {
81
68
  provider,
82
69
  models: [...FALLBACK_GITHUB_COPILOT_MODELS],
83
- providerModels: providerModelsFromIds(FALLBACK_GITHUB_COPILOT_MODELS),
70
+ providerModels: providerModelsFromIds(FALLBACK_GITHUB_COPILOT_MODELS, { githubCopilot: true }),
84
71
  source: 'fallback',
85
72
  warning: `Live model catalog unavailable (${reason}); using fallback Copilot model list.`,
86
73
  };
@@ -115,7 +102,7 @@ export async function discoverGitHubCopilotModels({ fetchFn = fetch, getTokenFn
115
102
  return {
116
103
  provider: GITHUB_COPILOT_PROVIDER,
117
104
  models,
118
- providerModels: providerModelsFromIds(models),
105
+ providerModels: providerModelsFromIds(models, { githubCopilot: true }),
119
106
  source: 'live',
120
107
  warning: null,
121
108
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.984",
3
+ "version": "0.1.985",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -13,6 +13,7 @@ import { join } from 'path';
13
13
  import { DEFAULT_YEAFT_DIR } from './init.js';
14
14
  import { normalizeProviderModels, serializeModelForPersistence } from './models.js';
15
15
  import { normaliseYeaftSection } from './config.js';
16
+ import { isGitHubCopilotProvider, serializeKnownProviderForPersistence } from './llm/known-providers.js';
16
17
 
17
18
  /**
18
19
  * Read the LLM-relevant portion of config.json.
@@ -85,6 +86,7 @@ export function updateLlmConfig(update, dir) {
85
86
  if (!p.name || typeof p.name !== 'string') {
86
87
  return { error: 'Each provider must have a name' };
87
88
  }
89
+ if (isGitHubCopilotProvider(p)) continue;
88
90
  if (!p.baseUrl || typeof p.baseUrl !== 'string') {
89
91
  return { error: `Provider "${p.name}" must have a baseUrl` };
90
92
  }
@@ -97,6 +99,8 @@ export function updateLlmConfig(update, dir) {
97
99
  // - entries with ctx / maxOutput are persisted as objects
98
100
  // - empty / 0 / NaN values get stripped
99
101
  existing.providers = update.providers.map(p => {
102
+ const managed = serializeKnownProviderForPersistence(p);
103
+ if (managed) return managed;
100
104
  const normalized = normalizeProviderModels(p);
101
105
  return {
102
106
  ...p,
package/yeaft/config.js CHANGED
@@ -23,6 +23,7 @@ import { existsSync, readFileSync } from 'fs';
23
23
  import { join } from 'path';
24
24
  import { DEFAULT_YEAFT_DIR } from './init.js';
25
25
  import { resolveModel, parseModelRef, normalizeProviderModels, resolveContextWindow, resolveMaxOutputTokens } from './models.js';
26
+ import { normalizeKnownProviderForRuntime } from './llm/known-providers.js';
26
27
 
27
28
  /** Default configuration values. */
28
29
  const DEFAULTS = {
@@ -385,7 +386,8 @@ export function loadConfig(overrides = {}) {
385
386
  // so consumers never have to deal with raw string / object ambiguity.
386
387
  config.availableModels = [];
387
388
  if (providers) {
388
- for (const p of providers) {
389
+ for (const rawProvider of providers) {
390
+ const p = normalizeKnownProviderForRuntime(rawProvider);
389
391
  const normalized = normalizeProviderModels(p);
390
392
  for (const m of normalized) {
391
393
  // Avoid duplicates (first provider wins)
@@ -0,0 +1,100 @@
1
+ export const GITHUB_COPILOT_PROVIDER_NAME = 'github-copilot';
2
+ export const GITHUB_COPILOT_BASE_URL = 'https://api.githubcopilot.com';
3
+ export const GITHUB_COPILOT_CREDENTIAL_PROVIDER = 'github-copilot';
4
+
5
+ export const FALLBACK_GITHUB_COPILOT_MODELS = [
6
+ 'gpt-5.4',
7
+ 'gpt-5.4-mini',
8
+ 'gpt-5-mini',
9
+ 'gpt-5.3-codex',
10
+ 'gpt-5.2-codex',
11
+ 'gpt-4.1',
12
+ 'gpt-4o',
13
+ 'gpt-4o-mini',
14
+ 'claude-opus-4.8',
15
+ 'claude-opus-4.7',
16
+ 'claude-opus-4.6',
17
+ 'claude-sonnet-4.6',
18
+ 'claude-sonnet-4.5',
19
+ 'claude-haiku-4.5',
20
+ 'gemini-2.5-pro',
21
+ ];
22
+
23
+ export const GITHUB_COPILOT_PROVIDER = {
24
+ name: GITHUB_COPILOT_PROVIDER_NAME,
25
+ baseUrl: GITHUB_COPILOT_BASE_URL,
26
+ credentialProvider: GITHUB_COPILOT_CREDENTIAL_PROVIDER,
27
+ managed: GITHUB_COPILOT_CREDENTIAL_PROVIDER,
28
+ };
29
+
30
+ function modelId(item) {
31
+ if (typeof item === 'string') return item.trim();
32
+ if (item && typeof item === 'object') return String(item.id || '').trim();
33
+ return '';
34
+ }
35
+
36
+ function dedupe(items) {
37
+ const seen = new Set();
38
+ const out = [];
39
+ for (const item of Array.isArray(items) ? items : []) {
40
+ const id = modelId(item);
41
+ if (!id || seen.has(id)) continue;
42
+ seen.add(id);
43
+ out.push(item);
44
+ }
45
+ return out;
46
+ }
47
+
48
+ export function isGitHubCopilotProvider(provider) {
49
+ if (!provider || typeof provider !== 'object') return false;
50
+ return provider.managed === GITHUB_COPILOT_CREDENTIAL_PROVIDER
51
+ || provider.credentialProvider === GITHUB_COPILOT_CREDENTIAL_PROVIDER
52
+ || provider.name === GITHUB_COPILOT_PROVIDER_NAME;
53
+ }
54
+
55
+ export function protocolForKnownModel(id) {
56
+ const value = String(id || '').toLowerCase();
57
+ if (!value) return null;
58
+ if (value.startsWith('claude') || value.includes('/claude') || value.includes('.claude')) {
59
+ return 'anthropic';
60
+ }
61
+ if (/^(gpt-|o1|o3|o4|chatgpt-|codex-|omni-)/.test(value)) {
62
+ return 'openai-responses';
63
+ }
64
+ return null;
65
+ }
66
+
67
+ export function modelEntryForGitHubCopilot(id) {
68
+ const value = String(id || '').trim();
69
+ if (!value) return null;
70
+ const protocol = protocolForKnownModel(value);
71
+ return protocol ? { id: value, protocol } : { id: value };
72
+ }
73
+
74
+ export function githubCopilotModelEntries(ids = FALLBACK_GITHUB_COPILOT_MODELS) {
75
+ return dedupe(ids).map(item => modelEntryForGitHubCopilot(modelId(item))).filter(Boolean);
76
+ }
77
+
78
+ export function normalizeKnownProviderForRuntime(provider) {
79
+ if (!isGitHubCopilotProvider(provider)) return provider;
80
+ const configuredModels = Array.isArray(provider.models) && provider.models.length
81
+ ? provider.models
82
+ : FALLBACK_GITHUB_COPILOT_MODELS;
83
+ return {
84
+ ...provider,
85
+ name: provider.name || GITHUB_COPILOT_PROVIDER_NAME,
86
+ baseUrl: provider.baseUrl || GITHUB_COPILOT_BASE_URL,
87
+ credentialProvider: GITHUB_COPILOT_CREDENTIAL_PROVIDER,
88
+ managed: provider.managed || GITHUB_COPILOT_CREDENTIAL_PROVIDER,
89
+ models: githubCopilotModelEntries(configuredModels),
90
+ };
91
+ }
92
+
93
+ export function serializeKnownProviderForPersistence(provider) {
94
+ if (!isGitHubCopilotProvider(provider)) return null;
95
+ return {
96
+ name: provider.name || GITHUB_COPILOT_PROVIDER_NAME,
97
+ credentialProvider: GITHUB_COPILOT_CREDENTIAL_PROVIDER,
98
+ managed: provider.managed || GITHUB_COPILOT_CREDENTIAL_PROVIDER,
99
+ };
100
+ }
@@ -23,6 +23,7 @@
23
23
 
24
24
  import { LLMAdapter } from './adapter.js';
25
25
  import { getThinkingCapability, normalizeEffort, parseModelRef } from '../models.js';
26
+ import { normalizeKnownProviderForRuntime } from './known-providers.js';
26
27
  import { pairSanitize } from '../pair-sanitize.js';
27
28
 
28
29
  /**
@@ -207,7 +208,8 @@ export class AdapterRouter extends LLMAdapter {
207
208
  * @param {object[]} providers
208
209
  */
209
210
  refreshProviders(providers) {
210
- this.#providers = Array.isArray(providers) ? providers : [];
211
+ this.#providers = (Array.isArray(providers) ? providers : [])
212
+ .map(provider => normalizeKnownProviderForRuntime(provider));
211
213
  this.#modelToProvider = new Map();
212
214
  this.#adapterCache = new Map();
213
215