Merge f4c5e472f3 into 8dc54efbdd
This commit is contained in:
commit
b8c526586a
3 changed files with 174 additions and 165 deletions
|
|
@ -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: {
|
||||||
|
'x-api-key': apiKey,
|
||||||
|
'anthropic-version': '2023-06-01',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
{
|
});
|
||||||
displayName: 'Claude 4 Opus',
|
|
||||||
key: 'claude-opus-4-20250514',
|
if (!resp.ok) {
|
||||||
},
|
throw new Error(`Anthropic models endpoint returned ${resp.status}`);
|
||||||
{
|
}
|
||||||
displayName: 'Claude 4 Sonnet',
|
|
||||||
key: 'claude-sonnet-4-20250514',
|
const data = await resp.json();
|
||||||
},
|
if (!data || !Array.isArray(data.data)) {
|
||||||
{
|
throw new Error('Unexpected Anthropic models response format');
|
||||||
displayName: 'Claude 3.7 Sonnet',
|
}
|
||||||
key: 'claude-3-7-sonnet-20250219',
|
|
||||||
},
|
return data.data;
|
||||||
{
|
}
|
||||||
displayName: 'Claude 3.5 Haiku',
|
|
||||||
key: 'claude-3-5-haiku-20241022',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
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,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
{
|
});
|
||||||
displayName: 'Embedding 001',
|
|
||||||
key: 'models/embedding-001',
|
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 {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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 {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue