@yeaft/webchat-agent 0.1.984 → 0.1.986
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 +1 -15
- package/llm-model-discovery.js +15 -28
- package/package.json +1 -1
- package/yeaft/config-api.js +4 -0
- package/yeaft/config.js +3 -1
- package/yeaft/llm/known-providers.js +100 -0
- package/yeaft/llm/router.js +3 -1
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);
|
package/llm-model-discovery.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
package/yeaft/config-api.js
CHANGED
|
@@ -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
|
|
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
|
+
}
|
package/yeaft/llm/router.js
CHANGED
|
@@ -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
|
|