This commit is contained in:
Sam 2025-08-24 09:36:02 -07:00 committed by GitHub
commit b8c526586a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 174 additions and 165 deletions

View file

@ -8,48 +8,29 @@ export const PROVIDER_INFO = {
}; };
import { BaseChatModel } from '@langchain/core/language_models/chat_models'; import { BaseChatModel } from '@langchain/core/language_models/chat_models';
const anthropicChatModels: Record<string, string>[] = [ const ANTHROPIC_MODELS_ENDPOINT = 'https://api.anthropic.com/v1/models';
{
displayName: 'Claude 4.1 Opus', async function fetchAnthropicModels(apiKey: string): Promise<any[]> {
key: 'claude-opus-4-1-20250805', const resp = await fetch(ANTHROPIC_MODELS_ENDPOINT, {
}, method: 'GET',
{ headers: {
displayName: 'Claude 4 Opus', 'x-api-key': apiKey,
key: 'claude-opus-4-20250514', 'anthropic-version': '2023-06-01',
}, 'Content-Type': 'application/json',
{ },
displayName: 'Claude 4 Sonnet', });
key: 'claude-sonnet-4-20250514',
}, if (!resp.ok) {
{ throw new Error(`Anthropic models endpoint returned ${resp.status}`);
displayName: 'Claude 3.7 Sonnet', }
key: 'claude-3-7-sonnet-20250219',
}, const data = await resp.json();
{ if (!data || !Array.isArray(data.data)) {
displayName: 'Claude 3.5 Haiku', throw new Error('Unexpected Anthropic models response format');
key: 'claude-3-5-haiku-20241022', }
},
{ return data.data;
displayName: 'Claude 3.5 Sonnet v2', }
key: 'claude-3-5-sonnet-20241022',
},
{
displayName: 'Claude 3.5 Sonnet',
key: 'claude-3-5-sonnet-20240620',
},
{
displayName: 'Claude 3 Opus',
key: 'claude-3-opus-20240229',
},
{
displayName: 'Claude 3 Sonnet',
key: 'claude-3-sonnet-20240229',
},
{
displayName: 'Claude 3 Haiku',
key: 'claude-3-haiku-20240307',
},
];
export const loadAnthropicChatModels = async () => { export const loadAnthropicChatModels = async () => {
const anthropicApiKey = getAnthropicApiKey(); const anthropicApiKey = getAnthropicApiKey();
@ -57,14 +38,25 @@ export const loadAnthropicChatModels = async () => {
if (!anthropicApiKey) return {}; if (!anthropicApiKey) return {};
try { try {
const models = await fetchAnthropicModels(anthropicApiKey);
const anthropicChatModels = models
.map((model: any) => {
const id = model && model.id ? String(model.id) : '';
const display =
model && model.display_name ? String(model.display_name) : id;
return { id, display };
})
.filter((model: any) => model.id)
.sort((a: any, b: any) => a.display.localeCompare(b.display));
const chatModels: Record<string, ChatModel> = {}; const chatModels: Record<string, ChatModel> = {};
anthropicChatModels.forEach((model) => { anthropicChatModels.forEach((model: any) => {
chatModels[model.key] = { chatModels[model.id] = {
displayName: model.displayName, displayName: model.display,
model: new ChatAnthropic({ model: new ChatAnthropic({
apiKey: anthropicApiKey, apiKey: anthropicApiKey,
modelName: model.key, modelName: model.id,
temperature: 0.7, temperature: 0.7,
}) as unknown as BaseChatModel, }) as unknown as BaseChatModel,
}; };

View file

@ -12,55 +12,33 @@ export const PROVIDER_INFO = {
import { BaseChatModel } from '@langchain/core/language_models/chat_models'; import { BaseChatModel } from '@langchain/core/language_models/chat_models';
import { Embeddings } from '@langchain/core/embeddings'; import { Embeddings } from '@langchain/core/embeddings';
const geminiChatModels: Record<string, string>[] = [ const GEMINI_MODELS_ENDPOINT =
{ 'https://generativelanguage.googleapis.com/v1beta/models';
displayName: 'Gemini 2.5 Flash',
key: 'gemini-2.5-flash',
},
{
displayName: 'Gemini 2.5 Flash-Lite',
key: 'gemini-2.5-flash-lite',
},
{
displayName: 'Gemini 2.5 Pro',
key: 'gemini-2.5-pro',
},
{
displayName: 'Gemini 2.0 Flash',
key: 'gemini-2.0-flash',
},
{
displayName: 'Gemini 2.0 Flash-Lite',
key: 'gemini-2.0-flash-lite',
},
{
displayName: 'Gemini 2.0 Flash Thinking Experimental',
key: 'gemini-2.0-flash-thinking-exp-01-21',
},
{
displayName: 'Gemini 1.5 Flash',
key: 'gemini-1.5-flash',
},
{
displayName: 'Gemini 1.5 Flash-8B',
key: 'gemini-1.5-flash-8b',
},
{
displayName: 'Gemini 1.5 Pro',
key: 'gemini-1.5-pro',
},
];
const geminiEmbeddingModels: Record<string, string>[] = [ async function fetchGeminiModels(apiKey: string): Promise<any[]> {
{ const url = `${GEMINI_MODELS_ENDPOINT}?key=${encodeURIComponent(
displayName: 'Text Embedding 004', apiKey,
key: 'models/text-embedding-004', )}&pageSize=1000`;
},
{ const resp = await fetch(url, {
displayName: 'Embedding 001', method: 'GET',
key: 'models/embedding-001', headers: {
}, 'Content-Type': 'application/json',
]; },
});
if (!resp.ok) {
throw new Error(`Gemini models endpoint returned ${resp.status}`);
}
const data = await resp.json();
if (!data || !Array.isArray(data.models)) {
throw new Error('Unexpected Gemini models response format');
}
return data.models;
}
export const loadGeminiChatModels = async () => { export const loadGeminiChatModels = async () => {
const geminiApiKey = getGeminiApiKey(); const geminiApiKey = getGeminiApiKey();
@ -68,9 +46,32 @@ export const loadGeminiChatModels = async () => {
if (!geminiApiKey) return {}; if (!geminiApiKey) return {};
try { try {
const models = await fetchGeminiModels(geminiApiKey);
const geminiChatModels = models
.map((model: any) => {
const rawName = model && model.name ? String(model.name) : '';
const stripped = rawName.replace(/^models\//i, '');
return {
rawName,
key: stripped,
displayName:
model && model.displayName ? String(model.displayName) : stripped,
};
})
.filter((model: any) => {
const key = model.key.toLowerCase();
const display = (model.displayName || '').toLowerCase();
const excluded = ['audio', 'embedding', 'image', 'tts'];
return (
key.startsWith('gemini') &&
!excluded.some((s) => key.includes(s) || display.includes(s))
);
})
.sort((a: any, b: any) => a.key.localeCompare(b.key));
const chatModels: Record<string, ChatModel> = {}; const chatModels: Record<string, ChatModel> = {};
geminiChatModels.forEach((model) => { geminiChatModels.forEach((model: any) => {
chatModels[model.key] = { chatModels[model.key] = {
displayName: model.displayName, displayName: model.displayName,
model: new ChatGoogleGenerativeAI({ model: new ChatGoogleGenerativeAI({
@ -83,7 +84,7 @@ export const loadGeminiChatModels = async () => {
return chatModels; return chatModels;
} catch (err) { } catch (err) {
console.error(`Error loading Gemini models: ${err}`); console.error(`Error loading Gemini chat models: ${err}`);
return {}; return {};
} }
}; };
@ -94,9 +95,28 @@ export const loadGeminiEmbeddingModels = async () => {
if (!geminiApiKey) return {}; if (!geminiApiKey) return {};
try { try {
const models = await fetchGeminiModels(geminiApiKey);
const geminiEmbeddingModels = models
.map((model: any) => {
const rawName = model && model.name ? String(model.name) : '';
const display =
model && model.displayName ? String(model.displayName) : rawName;
return {
rawName,
key: rawName,
displayName: display,
};
})
.filter(
(model: any) =>
model.key.toLowerCase().includes('embedding') ||
model.displayName.toLowerCase().includes('embedding'),
)
.sort((a: any, b: any) => a.key.localeCompare(b.key));
const embeddingModels: Record<string, EmbeddingModel> = {}; const embeddingModels: Record<string, EmbeddingModel> = {};
geminiEmbeddingModels.forEach((model) => { geminiEmbeddingModels.forEach((model: any) => {
embeddingModels[model.key] = { embeddingModels[model.key] = {
displayName: model.displayName, displayName: model.displayName,
model: new GoogleGenerativeAIEmbeddings({ model: new GoogleGenerativeAIEmbeddings({
@ -108,7 +128,7 @@ export const loadGeminiEmbeddingModels = async () => {
return embeddingModels; return embeddingModels;
} catch (err) { } catch (err) {
console.error(`Error loading Gemini embeddings models: ${err}`); console.error(`Error loading Gemini embedding models: ${err}`);
return {}; return {};
} }
}; };

View file

@ -9,63 +9,31 @@ export const PROVIDER_INFO = {
import { BaseChatModel } from '@langchain/core/language_models/chat_models'; import { BaseChatModel } from '@langchain/core/language_models/chat_models';
import { Embeddings } from '@langchain/core/embeddings'; import { Embeddings } from '@langchain/core/embeddings';
const openaiChatModels: Record<string, string>[] = [ const OPENAI_MODELS_ENDPOINT = 'https://api.openai.com/v1/models';
{
displayName: 'GPT-3.5 Turbo',
key: 'gpt-3.5-turbo',
},
{
displayName: 'GPT-4',
key: 'gpt-4',
},
{
displayName: 'GPT-4 turbo',
key: 'gpt-4-turbo',
},
{
displayName: 'GPT-4 omni',
key: 'gpt-4o',
},
{
displayName: 'GPT-4 omni mini',
key: 'gpt-4o-mini',
},
{
displayName: 'GPT 4.1 nano',
key: 'gpt-4.1-nano',
},
{
displayName: 'GPT 4.1 mini',
key: 'gpt-4.1-mini',
},
{
displayName: 'GPT 4.1',
key: 'gpt-4.1',
},
{
displayName: 'GPT 5 nano',
key: 'gpt-5-nano',
},
{
displayName: 'GPT 5 mini',
key: 'gpt-5-mini',
},
{
displayName: 'GPT 5',
key: 'gpt-5',
},
];
const openaiEmbeddingModels: Record<string, string>[] = [ async function fetchOpenAIModels(apiKey: string): Promise<string[]> {
{ const resp = await fetch(OPENAI_MODELS_ENDPOINT, {
displayName: 'Text Embedding 3 Small', method: 'GET',
key: 'text-embedding-3-small', headers: {
}, Authorization: `Bearer ${apiKey}`,
{ 'Content-Type': 'application/json',
displayName: 'Text Embedding 3 Large', },
key: 'text-embedding-3-large', });
},
]; if (!resp.ok) {
throw new Error(`OpenAI models endpoint returned ${resp.status}`);
}
const data = await resp.json();
if (!data || !Array.isArray(data.data)) {
throw new Error('Unexpected OpenAI models response format');
}
return data.data
.map((model: any) => (model && model.id ? String(model.id) : undefined))
.filter(Boolean) as string[];
}
export const loadOpenAIChatModels = async () => { export const loadOpenAIChatModels = async () => {
const openaiApiKey = getOpenaiApiKey(); const openaiApiKey = getOpenaiApiKey();
@ -73,22 +41,41 @@ export const loadOpenAIChatModels = async () => {
if (!openaiApiKey) return {}; if (!openaiApiKey) return {};
try { try {
const modelIds = (await fetchOpenAIModels(openaiApiKey)).sort((a, b) =>
a.localeCompare(b),
);
const chatModels: Record<string, ChatModel> = {}; const chatModels: Record<string, ChatModel> = {};
openaiChatModels.forEach((model) => { modelIds.forEach((model) => {
chatModels[model.key] = { const lid = model.toLowerCase();
displayName: model.displayName, const excludedSubstrings = [
'audio',
'embedding',
'image',
'omni-moderation',
'transcribe',
'tts',
];
const isChat =
(lid.startsWith('gpt') || lid.startsWith('o')) &&
!excludedSubstrings.some((s) => lid.includes(s));
if (!isChat) return;
chatModels[model] = {
displayName: model,
model: new ChatOpenAI({ model: new ChatOpenAI({
apiKey: openaiApiKey, apiKey: openaiApiKey,
modelName: model.key, modelName: model,
temperature: model.key.includes('gpt-5') ? 1 : 0.7, temperature: model.includes('gpt-5') ? 1 : 0.7,
}) as unknown as BaseChatModel, }) as unknown as BaseChatModel,
}; };
}); });
return chatModels; return chatModels;
} catch (err) { } catch (err) {
console.error(`Error loading OpenAI models: ${err}`); console.error(`Error loading OpenAI chat models: ${err}`);
return {}; return {};
} }
}; };
@ -99,21 +86,31 @@ export const loadOpenAIEmbeddingModels = async () => {
if (!openaiApiKey) return {}; if (!openaiApiKey) return {};
try { try {
const modelIds = (await fetchOpenAIModels(openaiApiKey)).sort((a, b) =>
a.localeCompare(b),
);
const embeddingModels: Record<string, EmbeddingModel> = {}; const embeddingModels: Record<string, EmbeddingModel> = {};
openaiEmbeddingModels.forEach((model) => { modelIds.forEach((model) => {
embeddingModels[model.key] = { const lid = model.toLowerCase();
displayName: model.displayName,
const isEmbedding = lid.includes('embedding');
if (!isEmbedding) return;
embeddingModels[model] = {
displayName: model,
model: new OpenAIEmbeddings({ model: new OpenAIEmbeddings({
apiKey: openaiApiKey, apiKey: openaiApiKey,
modelName: model.key, modelName: model,
}) as unknown as Embeddings, }) as unknown as Embeddings,
}; };
}); });
return embeddingModels; return embeddingModels;
} catch (err) { } catch (err) {
console.error(`Error loading OpenAI embeddings models: ${err}`); console.error(`Error loading OpenAI embedding models: ${err}`);
return {}; return {};
} }
}; };