From 03894518cfff4751f170b9fe3b5f6155a700b924 Mon Sep 17 00:00:00 2001 From: Zhijie He Date: Wed, 12 Feb 2025 20:08:39 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20refactor?= =?UTF-8?q?=20model=20fetch=20behavior?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/agent-runtime/ai360/index.ts | 16 ++++++-- src/libs/agent-runtime/anthropic/index.ts | 16 ++++++-- src/libs/agent-runtime/baichuan/index.ts | 4 +- src/libs/agent-runtime/cloudflare/index.ts | 26 ++++++++++--- src/libs/agent-runtime/deepseek/index.ts | 18 ++++++--- src/libs/agent-runtime/fireworksai/index.ts | 15 ++++++-- src/libs/agent-runtime/giteeai/index.ts | 23 +++++++++--- src/libs/agent-runtime/github/index.ts | 21 ++++++++--- src/libs/agent-runtime/google/index.ts | 21 ++++++++--- src/libs/agent-runtime/groq/index.ts | 21 ++++++++--- src/libs/agent-runtime/higress/index.ts | 26 ++++++++----- src/libs/agent-runtime/huggingface/index.ts | 26 +++++++++---- src/libs/agent-runtime/hunyuan/index.ts | 18 ++++++--- src/libs/agent-runtime/internlm/index.ts | 12 ++++-- src/libs/agent-runtime/lmstudio/index.ts | 29 +++++++++++++++ src/libs/agent-runtime/mistral/index.ts | 6 ++- src/libs/agent-runtime/moonshot/index.ts | 17 ++++++--- src/libs/agent-runtime/novita/index.ts | 20 ++++++++-- src/libs/agent-runtime/ollama/index.test.ts | 21 ++++++++++- src/libs/agent-runtime/ollama/index.ts | 37 ++++++++++++++++--- .../openai/__snapshots__/index.test.ts.snap | 2 +- src/libs/agent-runtime/openai/index.ts | 23 +++++++++--- .../__snapshots__/index.test.ts.snap | 20 +++++----- src/libs/agent-runtime/openrouter/index.ts | 26 +++++++++---- src/libs/agent-runtime/qwen/index.ts | 23 +++++++++--- src/libs/agent-runtime/sensenova/index.ts | 18 ++++++--- src/libs/agent-runtime/siliconcloud/index.ts | 23 +++++++++--- src/libs/agent-runtime/stepfun/index.ts | 18 ++++++--- src/libs/agent-runtime/togetherai/index.ts | 22 ++++++++--- src/libs/agent-runtime/xai/index.ts | 17 ++++++--- src/libs/agent-runtime/zeroone/index.ts | 18 ++++++--- .../agent-runtime/zhipu/authToken.test.ts | 18 --------- src/libs/agent-runtime/zhipu/authToken.ts | 22 ----------- src/libs/agent-runtime/zhipu/index.test.ts | 9 ----- src/libs/agent-runtime/zhipu/index.ts | 21 ++++++++--- 35 files changed, 468 insertions(+), 205 deletions(-) delete mode 100644 src/libs/agent-runtime/zhipu/authToken.test.ts delete mode 100644 src/libs/agent-runtime/zhipu/authToken.ts diff --git a/src/libs/agent-runtime/ai360/index.ts b/src/libs/agent-runtime/ai360/index.ts index 93887d7c7381a..1f793fa7d8027 100644 --- a/src/libs/agent-runtime/ai360/index.ts +++ b/src/libs/agent-runtime/ai360/index.ts @@ -31,17 +31,25 @@ export const LobeAi360AI = LobeOpenAICompatibleFactory({ const model = m as unknown as Ai360ModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { contextWindowTokens: model.total_tokens, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: model.id === '360gpt-pro', + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + model.id === '360gpt-pro' + || knownModel?.abilities?.functionCall + || false, id: model.id, maxTokens: typeof model.max_tokens === 'number' ? model.max_tokens : undefined, - reasoning: reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, }; }, }, diff --git a/src/libs/agent-runtime/anthropic/index.ts b/src/libs/agent-runtime/anthropic/index.ts index d40c4a4f4bd3f..6b2d864312e04 100644 --- a/src/libs/agent-runtime/anthropic/index.ts +++ b/src/libs/agent-runtime/anthropic/index.ts @@ -128,13 +128,21 @@ export class LobeAnthropicAI implements LobeRuntimeAI { return modelList .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined, + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, displayName: model.display_name, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: model.id.toLowerCase().includes('claude-3'), + enabled: knownModel?.enabled || false, + functionCall: + model.id.toLowerCase().includes('claude-3') + || knownModel?.abilities?.functionCall + || false, id: model.id, - vision: model.id.toLowerCase().includes('claude-3') && !model.id.toLowerCase().includes('claude-3-5-haiku'), + vision: + model.id.toLowerCase().includes('claude-3') && !model.id.toLowerCase().includes('claude-3-5-haiku') + || knownModel?.abilities?.vision + || false, }; }) .filter(Boolean) as ChatModelCard[]; diff --git a/src/libs/agent-runtime/baichuan/index.ts b/src/libs/agent-runtime/baichuan/index.ts index 3a4b25ae467a1..2fce036a79b28 100644 --- a/src/libs/agent-runtime/baichuan/index.ts +++ b/src/libs/agent-runtime/baichuan/index.ts @@ -37,10 +37,12 @@ export const LobeBaichuanAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.model === m.id); + return { contextWindowTokens: model.max_input_length, displayName: model.model_show_name, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.model === m.id)?.enabled || false, + enabled: knownModel?.enabled || false, functionCall: model.function_call, id: model.model, maxTokens: model.max_tokens, diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index ce30df82958e2..ec323e169b362 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -127,16 +127,30 @@ export class LobeCloudflareAI implements LobeRuntimeAI { return modelList .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id); + return { contextWindowTokens: model.properties?.max_total_tokens ? Number(model.properties.max_total_tokens) - : LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id)?.contextWindowTokens ?? undefined, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id)?.displayName ?? (model.properties?.["beta"] === "true" ? `${model.name} (Beta)` : undefined), - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id)?.enabled || false, - functionCall: model.description.toLowerCase().includes('function call') || model.properties?.["function_calling"] === "true", + : knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? (model.properties?.["beta"] === "true" ? `${model.name} (Beta)` : undefined), + enabled: knownModel?.enabled || false, + functionCall: + model.description.toLowerCase().includes('function call') + || model.properties?.["function_calling"] === "true" + || knownModel?.abilities?.functionCall + || false, id: model.name, - reasoning: model.name.toLowerCase().includes('deepseek-r1'), - vision: model.name.toLowerCase().includes('vision') || model.task?.name.toLowerCase().includes('image-to-text') || model.description.toLowerCase().includes('vision'), + reasoning: + model.name.toLowerCase().includes('deepseek-r1') + || knownModel?.abilities?.reasoning + || false, + vision: + model.name.toLowerCase().includes('vision') + || model.task?.name.toLowerCase().includes('image-to-text') + || model.description.toLowerCase().includes('vision') + || knownModel?.abilities?.vision + || false, }; }) .filter(Boolean) as ChatModelCard[]; diff --git a/src/libs/agent-runtime/deepseek/index.ts b/src/libs/agent-runtime/deepseek/index.ts index aa873d605b984..e4db23af893df 100644 --- a/src/libs/agent-runtime/deepseek/index.ts +++ b/src/libs/agent-runtime/deepseek/index.ts @@ -63,13 +63,21 @@ export const LobeDeepSeekAI = LobeOpenAICompatibleFactory({ transformModel: (m) => { const model = m as unknown as DeepSeekModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: !model.id.toLowerCase().includes('deepseek-reasoner'), + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + !model.id.toLowerCase().includes('reasoner') + || knownModel?.abilities?.functionCall + || false, id: model.id, - reasoning: model.id.toLowerCase().includes('deepseek-reasoner'), + reasoning: + model.id.toLowerCase().includes('reasoner') + || knownModel?.abilities?.reasoning + || false, }; }, }, diff --git a/src/libs/agent-runtime/fireworksai/index.ts b/src/libs/agent-runtime/fireworksai/index.ts index dc52d8dfdf20a..b710849c6aa34 100644 --- a/src/libs/agent-runtime/fireworksai/index.ts +++ b/src/libs/agent-runtime/fireworksai/index.ts @@ -24,13 +24,20 @@ export const LobeFireworksAI = LobeOpenAICompatibleFactory({ const model = m as unknown as FireworksAIModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { contextWindowTokens: model.context_length, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: model.supports_tools || model.id.toLowerCase().includes('function'), + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + model.supports_tools + || model.id.toLowerCase().includes('function'), id: model.id, - reasoning: reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, vision: model.supports_image_input, }; }, diff --git a/src/libs/agent-runtime/giteeai/index.ts b/src/libs/agent-runtime/giteeai/index.ts index 62ceacefdaa3d..3dfb6c3366388 100644 --- a/src/libs/agent-runtime/giteeai/index.ts +++ b/src/libs/agent-runtime/giteeai/index.ts @@ -31,14 +31,25 @@ export const LobeGiteeAI = LobeOpenAICompatibleFactory({ const model = m as unknown as GiteeAIModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('qwen2.5-coder'), + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('qwen2.5-coder') + || knownModel?.abilities?.functionCall + || false, id: model.id, - reasoning: reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), - vision: visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: + visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.vision + || false, }; }, }, diff --git a/src/libs/agent-runtime/github/index.ts b/src/libs/agent-runtime/github/index.ts index 7552b98b5aa0b..14aef23f3e071 100644 --- a/src/libs/agent-runtime/github/index.ts +++ b/src/libs/agent-runtime/github/index.ts @@ -58,15 +58,26 @@ export const LobeGithubAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id)?.contextWindowTokens ?? undefined, + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, description: model.description, displayName: model.friendly_name, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id)?.enabled || false, - functionCall: functionCallKeywords.some(keyword => model.description.toLowerCase().includes(keyword)), + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.description.toLowerCase().includes(keyword)) + || knownModel?.abilities?.functionCall + || false, id: model.name, - reasoning: reasoningKeywords.some(keyword => model.name.toLowerCase().includes(keyword)), - vision: visionKeywords.some(keyword => model.description.toLowerCase().includes(keyword)), + reasoning: + reasoningKeywords.some(keyword => model.name.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: + visionKeywords.some(keyword => model.description.toLowerCase().includes(keyword)) + || knownModel?.abilities?.vision + || false, }; }) .filter(Boolean) as ChatModelCard[]; diff --git a/src/libs/agent-runtime/google/index.ts b/src/libs/agent-runtime/google/index.ts index 8f7de84ecb401..5b00132678862 100644 --- a/src/libs/agent-runtime/google/index.ts +++ b/src/libs/agent-runtime/google/index.ts @@ -149,17 +149,26 @@ export class LobeGoogleAI implements LobeRuntimeAI { .map((model) => { const modelName = model.name.replace(/^models\//, ''); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => modelName === m.id); + return { contextWindowTokens: model.inputTokenLimit + model.outputTokenLimit, displayName: model.displayName, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => modelName === m.id)?.enabled || false, - functionCall: modelName.toLowerCase().includes('gemini'), + enabled: knownModel?.enabled || false, + functionCall: + modelName.toLowerCase().includes('gemini') + || knownModel?.abilities?.functionCall + || false, id: modelName, - reasoning: modelName.toLowerCase().includes('thinking'), + reasoning: + modelName.toLowerCase().includes('thinking') + || knownModel?.abilities?.reasoning + || false, vision: - modelName.toLowerCase().includes('vision') || - (modelName.toLowerCase().includes('gemini') && - !modelName.toLowerCase().includes('gemini-1.0')), + modelName.toLowerCase().includes('vision') + || (modelName.toLowerCase().includes('gemini') && !modelName.toLowerCase().includes('gemini-1.0')) + || knownModel?.abilities?.vision + || false, }; }) .filter(Boolean) as ChatModelCard[]; diff --git a/src/libs/agent-runtime/groq/index.ts b/src/libs/agent-runtime/groq/index.ts index c8dd645b41999..f2ea5c4c25682 100644 --- a/src/libs/agent-runtime/groq/index.ts +++ b/src/libs/agent-runtime/groq/index.ts @@ -48,14 +48,25 @@ export const LobeGroq = LobeOpenAICompatibleFactory({ const model = m as unknown as GroqModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { contextWindowTokens: model.context_window, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.functionCall + || false, id: model.id, - reasoning: reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), - vision: model.id.toLowerCase().includes('vision'), + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: + model.id.toLowerCase().includes('vision') + || knownModel?.abilities?.vision + || false, }; }, }, diff --git a/src/libs/agent-runtime/higress/index.ts b/src/libs/agent-runtime/higress/index.ts index 04554cd4d785a..0eedc149c4422 100644 --- a/src/libs/agent-runtime/higress/index.ts +++ b/src/libs/agent-runtime/higress/index.ts @@ -1,11 +1,9 @@ import { uniqueId } from 'lodash-es'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/modelProviders'; - import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -// import { OpenRouterModelCard } from './type'; +import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; export const LobeHigressAI = LobeOpenAICompatibleFactory({ constructorOptions: { @@ -22,23 +20,33 @@ export const LobeHigressAI = LobeOpenAICompatibleFactory({ transformModel: (m) => { const model = m as any; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { contextWindowTokens: model.context_length, description: model.description, displayName: model.name, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, + enabled: knownModel?.enabled || false, functionCall: - model.description.includes('function calling') || model.description.includes('tools'), + model.description.includes('function calling') + || model.description.includes('tools') + || knownModel?.abilities?.functionCall + || false, id: model.id, maxTokens: typeof model.top_provider.max_completion_tokens === 'number' ? model.top_provider.max_completion_tokens : undefined, - reasoning: model.description.includes('reasoning'), + reasoning: + model.description.includes('reasoning') + || knownModel?.abilities?.reasoning + || false, vision: - model.description.includes('vision') || - model.description.includes('multimodal') || - model.id.includes('vision'), + model.description.includes('vision') + || model.description.includes('multimodal') + || model.id.includes('vision') + || knownModel?.abilities?.vision + || false, }; }, }, diff --git a/src/libs/agent-runtime/huggingface/index.ts b/src/libs/agent-runtime/huggingface/index.ts index d1847f41fa696..146346972e8c7 100644 --- a/src/libs/agent-runtime/huggingface/index.ts +++ b/src/libs/agent-runtime/huggingface/index.ts @@ -79,16 +79,26 @@ export const LobeHuggingFaceAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: model.tags.some(tag => tag.toLowerCase().includes('function-calling')), + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + model.tags.some(tag => tag.toLowerCase().includes('function-calling')) + || knownModel?.abilities?.functionCall + || false, id: model.id, - reasoning: model.tags.some(tag => tag.toLowerCase().includes('reasoning')) || reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), - vision: model.tags.some(tag => - visionKeywords.some(keyword => tag.toLowerCase().includes(keyword)) - ), + reasoning: + model.tags.some(tag => tag.toLowerCase().includes('reasoning')) + || reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: + model.tags.some(tag => visionKeywords.some(keyword => tag.toLowerCase().includes(keyword))) + || knownModel?.abilities?.vision + || false, }; }) .filter(Boolean) as ChatModelCard[]; diff --git a/src/libs/agent-runtime/hunyuan/index.ts b/src/libs/agent-runtime/hunyuan/index.ts index 5bcf827cc54ec..852a9ae1a4975 100644 --- a/src/libs/agent-runtime/hunyuan/index.ts +++ b/src/libs/agent-runtime/hunyuan/index.ts @@ -22,13 +22,21 @@ export const LobeHunyuanAI = LobeOpenAICompatibleFactory({ const model = m as unknown as HunyuanModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('vision'), + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('vision') + || knownModel?.abilities?.functionCall + || false, id: model.id, - vision: model.id.toLowerCase().includes('vision'), + vision: + model.id.toLowerCase().includes('vision') + || knownModel?.abilities?.vision + || false, }; }, }, diff --git a/src/libs/agent-runtime/internlm/index.ts b/src/libs/agent-runtime/internlm/index.ts index 267371360eafa..58cf1227fd464 100644 --- a/src/libs/agent-runtime/internlm/index.ts +++ b/src/libs/agent-runtime/internlm/index.ts @@ -24,11 +24,15 @@ export const LobeInternLMAI = LobeOpenAICompatibleFactory({ transformModel: (m) => { const model = m as unknown as InternLMModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: true, + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + knownModel?.abilities?.functionCall + || false, id: model.id, }; }, diff --git a/src/libs/agent-runtime/lmstudio/index.ts b/src/libs/agent-runtime/lmstudio/index.ts index 9ef31ab793071..000f2ed6678be 100644 --- a/src/libs/agent-runtime/lmstudio/index.ts +++ b/src/libs/agent-runtime/lmstudio/index.ts @@ -1,11 +1,40 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; +import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; + +export interface LMStudioModelCard { + id: string; +} + export const LobeLMStudioAI = LobeOpenAICompatibleFactory({ apiKey: 'placeholder-to-avoid-error', baseURL: 'http://127.0.0.1:1234/v1', debug: { chatCompletion: () => process.env.DEBUG_LMSTUDIO_CHAT_COMPLETION === '1', }, + models: { + transformModel: (m) => { + const model = m as unknown as LMStudioModelCard; + + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + knownModel?.abilities?.functionCall + || false, + id: model.id, + reasoning: + knownModel?.abilities?.reasoning + || false, + vision: + knownModel?.abilities?.vision + || false, + }; + }, + }, provider: ModelProvider.LMStudio, }); diff --git a/src/libs/agent-runtime/mistral/index.ts b/src/libs/agent-runtime/mistral/index.ts index 27f695e36195a..592d396b20b89 100644 --- a/src/libs/agent-runtime/mistral/index.ts +++ b/src/libs/agent-runtime/mistral/index.ts @@ -34,11 +34,13 @@ export const LobeMistralAI = LobeOpenAICompatibleFactory({ transformModel: (m) => { const model = m as unknown as MistralModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { contextWindowTokens: model.max_context_length, description: model.description, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, functionCall: model.capabilities.function_calling, id: model.id, vision: model.capabilities.vision, diff --git a/src/libs/agent-runtime/moonshot/index.ts b/src/libs/agent-runtime/moonshot/index.ts index 9bb92fa2dc2a3..e213474603d29 100644 --- a/src/libs/agent-runtime/moonshot/index.ts +++ b/src/libs/agent-runtime/moonshot/index.ts @@ -28,13 +28,20 @@ export const LobeMoonshotAI = LobeOpenAICompatibleFactory({ transformModel: (m) => { const model = m as unknown as MoonshotModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: true, + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + knownModel?.abilities?.functionCall + || false, id: model.id, - vision: model.id.toLowerCase().includes('vision'), + vision: + model.id.toLowerCase().includes('vision') + || knownModel?.abilities?.vision + || false, }; }, }, diff --git a/src/libs/agent-runtime/novita/index.ts b/src/libs/agent-runtime/novita/index.ts index a7c7d33f3253d..fe4465383816b 100644 --- a/src/libs/agent-runtime/novita/index.ts +++ b/src/libs/agent-runtime/novita/index.ts @@ -22,15 +22,27 @@ export const LobeNovitaAI = LobeOpenAICompatibleFactory({ const model = m as unknown as NovitaModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { contextWindowTokens: model.context_size, description: model.description, displayName: model.title, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: model.description.toLowerCase().includes('function calling'), + enabled: knownModel?.enabled || false, + functionCall: + model.description.toLowerCase().includes('function calling') + || knownModel?.abilities?.functionCall + || false, id: model.id, - reasoning: model.description.toLowerCase().includes('reasoning task') || reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), - vision: model.description.toLowerCase().includes('vision'), + reasoning: + model.description.toLowerCase().includes('reasoning task') + || reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: + model.description.toLowerCase().includes('vision') + || knownModel?.abilities?.vision + || false, }; }, }, diff --git a/src/libs/agent-runtime/ollama/index.test.ts b/src/libs/agent-runtime/ollama/index.test.ts index 79ab4360249a7..4a1b71639cc7d 100644 --- a/src/libs/agent-runtime/ollama/index.test.ts +++ b/src/libs/agent-runtime/ollama/index.test.ts @@ -145,7 +145,26 @@ describe('LobeOllamaAI', () => { const models = await ollamaAI.models(); expect(listMock).toHaveBeenCalled(); - expect(models).toEqual([{ id: 'model-1' }, { id: 'model-2' }]); + expect(models).toEqual([ + { + contextWindowTokens: undefined, + displayName: undefined, + enabled: false, + functionCall: false, + id: 'model-1', + reasoning: false, + vision: false + }, + { + contextWindowTokens: undefined, + displayName: undefined, + enabled: false, + functionCall: false, + id: 'model-2', + reasoning: false, + vision: false + } + ]); }); }); diff --git a/src/libs/agent-runtime/ollama/index.ts b/src/libs/agent-runtime/ollama/index.ts index 4bb9c4bcefded..f2ff37218f7a1 100644 --- a/src/libs/agent-runtime/ollama/index.ts +++ b/src/libs/agent-runtime/ollama/index.ts @@ -2,7 +2,6 @@ import { Ollama, Tool } from 'ollama/browser'; import { ClientOptions } from 'openai'; import { OpenAIChatMessage } from '@/libs/agent-runtime'; -import { ChatModelCard } from '@/types/llm'; import { LobeRuntimeAI } from '../BaseAI'; import { AgentRuntimeErrorType } from '../error'; @@ -20,6 +19,13 @@ import { OllamaStream, convertIterableToStream } from '../utils/streams'; import { parseDataUri } from '../utils/uriParser'; import { OllamaMessage } from './type'; +import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import { ChatModelCard } from '@/types/llm'; + +export interface OllamaModelCard { + name: string; +} + export class LobeOllamaAI implements LobeRuntimeAI { private client: Ollama; @@ -102,11 +108,32 @@ export class LobeOllamaAI implements LobeRuntimeAI { return await Promise.all(promises); } - async models(): Promise { + async models() { const list = await this.client.list(); - return list.models.map((model) => ({ - id: model.name, - })); + + const modelList: OllamaModelCard[] = list.models; + + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + knownModel?.abilities?.functionCall + || false, + id: model.name, + reasoning: + knownModel?.abilities?.functionCall + || false, + vision: + knownModel?.abilities?.functionCall + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; } private invokeEmbeddingModel = async (payload: EmbeddingsPayload): Promise => { diff --git a/src/libs/agent-runtime/openai/__snapshots__/index.test.ts.snap b/src/libs/agent-runtime/openai/__snapshots__/index.test.ts.snap index a4541e4af7248..95754bd0502b7 100644 --- a/src/libs/agent-runtime/openai/__snapshots__/index.test.ts.snap +++ b/src/libs/agent-runtime/openai/__snapshots__/index.test.ts.snap @@ -126,7 +126,7 @@ exports[`LobeOpenAI > models > should get models 1`] = ` "functionCall": true, "id": "gpt-4", "reasoning": false, - "vision": false, + "vision": true, }, { "contextWindowTokens": 16385, diff --git a/src/libs/agent-runtime/openai/index.ts b/src/libs/agent-runtime/openai/index.ts index e925b7b98dac0..3dae2edf17589 100644 --- a/src/libs/agent-runtime/openai/index.ts +++ b/src/libs/agent-runtime/openai/index.ts @@ -75,14 +75,25 @@ export const LobeOpenAI = LobeOpenAICompatibleFactory({ const model = m as unknown as OpenAIModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('audio'), + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('audio') + || knownModel?.abilities?.functionCall + || false, id: model.id, - reasoning: reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), - vision: visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('audio'), + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: + visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('audio') + || knownModel?.abilities?.vision + || false, }; }, }, diff --git a/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap b/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap index b66823705e6c5..8b60923b8fa54 100644 --- a/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap +++ b/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap @@ -510,11 +510,11 @@ GPT-4o mini achieves an 82% score on MMLU and presently ranks higher than GPT-4 Check out the [launch announcement](https://openai.com/index/gpt-4o-mini-advancing-cost-efficient-intelligence/) to learn more.", "displayName": "OpenAI: GPT-4o-mini", "enabled": true, - "functionCall": false, + "functionCall": true, "id": "openai/gpt-4o-mini", "maxTokens": 16384, "reasoning": false, - "vision": false, + "vision": true, }, { "contextWindowTokens": 32768, @@ -560,7 +560,7 @@ Gemma models are well-suited for a variety of text generation tasks, including q See the [launch announcement](https://blog.google/technology/developers/google-gemma-2/) for more details. Usage of Gemma is subject to Google's [Gemma Terms of Use](https://ai.google.dev/gemma/terms).", "displayName": "Google: Gemma 2 27B", - "enabled": true, + "enabled": false, "functionCall": false, "id": "google/gemma-2-27b-it", "maxTokens": undefined, @@ -940,7 +940,7 @@ Usage of Gemini is subject to Google's [Gemini Terms of Use](https://ai.google.d #multimodal", "displayName": "Google: Gemini Flash 1.5", "enabled": true, - "functionCall": false, + "functionCall": true, "id": "google/gemini-flash-1.5", "maxTokens": 32768, "reasoning": false, @@ -968,7 +968,7 @@ Compared with DeepSeek 67B, DeepSeek-V2 achieves stronger performance, and meanw DeepSeek-V2 achieves remarkable performance on both standard benchmarks and open-ended generation evaluations.", "displayName": "DeepSeek-V2 Chat", "enabled": true, - "functionCall": false, + "functionCall": true, "id": "deepseek/deepseek-chat", "maxTokens": 4096, "reasoning": false, @@ -1065,11 +1065,11 @@ For benchmarking against other models, it was briefly called ["im-also-a-good-gp For benchmarking against other models, it was briefly called ["im-also-a-good-gpt2-chatbot"](https://twitter.com/LiamFedus/status/1790064963966370209)", "displayName": "OpenAI: GPT-4o", "enabled": true, - "functionCall": false, + "functionCall": true, "id": "openai/gpt-4o", "maxTokens": 4096, "reasoning": false, - "vision": false, + "vision": true, }, { "contextWindowTokens": 128000, @@ -1336,7 +1336,7 @@ Usage of Gemini is subject to Google's [Gemini Terms of Use](https://ai.google.d #multimodal", "displayName": "Google: Gemini Pro 1.5", "enabled": true, - "functionCall": false, + "functionCall": true, "id": "google/gemini-pro-1.5", "maxTokens": 32768, "reasoning": false, @@ -1438,7 +1438,7 @@ See the launch announcement and benchmark results [here](https://www.anthropic.c #multimodal", "displayName": "Anthropic: Claude 3 Haiku", "enabled": true, - "functionCall": false, + "functionCall": true, "id": "anthropic/claude-3-haiku", "maxTokens": 4096, "reasoning": false, @@ -1503,7 +1503,7 @@ See the launch announcement and benchmark results [here](https://www.anthropic.c #multimodal", "displayName": "Anthropic: Claude 3 Opus", "enabled": true, - "functionCall": false, + "functionCall": true, "id": "anthropic/claude-3-opus", "maxTokens": 4096, "reasoning": false, diff --git a/src/libs/agent-runtime/openrouter/index.ts b/src/libs/agent-runtime/openrouter/index.ts index 2767ca16c0306..20c530ff31e1c 100644 --- a/src/libs/agent-runtime/openrouter/index.ts +++ b/src/libs/agent-runtime/openrouter/index.ts @@ -1,9 +1,9 @@ -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/modelProviders'; - import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; import { OpenRouterModelCard } from './type'; +import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; + export const LobeOpenRouterAI = LobeOpenAICompatibleFactory({ baseURL: 'https://openrouter.ai/api/v1', chatCompletion: { @@ -39,23 +39,33 @@ export const LobeOpenRouterAI = LobeOpenAICompatibleFactory({ const model = m as unknown as OpenRouterModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { contextWindowTokens: model.context_length, description: model.description, displayName: model.name, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, + enabled: knownModel?.enabled || false, functionCall: - model.description.includes('function calling') || model.description.includes('tools'), + model.description.includes('function calling') + || model.description.includes('tools') + || knownModel?.abilities?.functionCall + || false, id: model.id, maxTokens: typeof model.top_provider.max_completion_tokens === 'number' ? model.top_provider.max_completion_tokens : undefined, - reasoning: reasoningKeywords.some((keyword) => model.id.toLowerCase().includes(keyword)), + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, vision: - model.description.includes('vision') || - model.description.includes('multimodal') || - visionKeywords.some((keyword) => model.id.toLowerCase().includes(keyword)), + model.description.includes('vision') + || model.description.includes('multimodal') + || visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.vision + || false, }; }, }, diff --git a/src/libs/agent-runtime/qwen/index.ts b/src/libs/agent-runtime/qwen/index.ts index 3802fdc83c519..e4bc09d8524d1 100644 --- a/src/libs/agent-runtime/qwen/index.ts +++ b/src/libs/agent-runtime/qwen/index.ts @@ -92,14 +92,25 @@ export const LobeQwenAI = LobeOpenAICompatibleFactory({ const model = m as unknown as QwenModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.functionCall + || false, id: model.id, - reasoning: reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), - vision: visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: + visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.vision + || false, }; }, }, diff --git a/src/libs/agent-runtime/sensenova/index.ts b/src/libs/agent-runtime/sensenova/index.ts index 123472019cdeb..1ed591a7d9ae7 100644 --- a/src/libs/agent-runtime/sensenova/index.ts +++ b/src/libs/agent-runtime/sensenova/index.ts @@ -44,13 +44,21 @@ export const LobeSenseNovaAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.functionCall + || false, id: model.id, - vision: model.id.toLowerCase().includes('vision'), + vision: + model.id.toLowerCase().includes('vision') + || knownModel?.abilities?.vision + || false, }; }) .filter(Boolean) as ChatModelCard[]; diff --git a/src/libs/agent-runtime/siliconcloud/index.ts b/src/libs/agent-runtime/siliconcloud/index.ts index d2625dd9295a4..9db78155780ff 100644 --- a/src/libs/agent-runtime/siliconcloud/index.ts +++ b/src/libs/agent-runtime/siliconcloud/index.ts @@ -79,14 +79,25 @@ export const LobeSiliconCloudAI = LobeOpenAICompatibleFactory({ const model = m as unknown as SiliconCloudModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('deepseek-r1'), + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('deepseek-r1') + || knownModel?.abilities?.functionCall + || false, id: model.id, - reasoning: reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), - vision: visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: + visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.vision + || false, }; }, }, diff --git a/src/libs/agent-runtime/stepfun/index.ts b/src/libs/agent-runtime/stepfun/index.ts index 598716e58a70c..bfe905f94ce4a 100644 --- a/src/libs/agent-runtime/stepfun/index.ts +++ b/src/libs/agent-runtime/stepfun/index.ts @@ -37,13 +37,21 @@ export const LobeStepfunAI = LobeOpenAICompatibleFactory({ const model = m as unknown as StepfunModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.functionCall + || false, id: model.id, - vision: visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)), + vision: + visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.vision + || false, }; }, }, diff --git a/src/libs/agent-runtime/togetherai/index.ts b/src/libs/agent-runtime/togetherai/index.ts index 1515c751d8b5d..80457c8324090 100644 --- a/src/libs/agent-runtime/togetherai/index.ts +++ b/src/libs/agent-runtime/togetherai/index.ts @@ -34,17 +34,29 @@ export const LobeTogetherAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id)?.contextWindowTokens ?? undefined, + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, description: model.description, displayName: model.display_name, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id)?.enabled || false, - functionCall: model.description?.toLowerCase().includes('function calling'), + enabled: knownModel?.enabled || false, + functionCall: + model.description?.toLowerCase().includes('function calling') + || knownModel?.abilities?.functionCall + || false, id: model.name, maxOutput: model.context_length, - reasoning: reasoningKeywords.some(keyword => model.name.toLowerCase().includes(keyword)), + reasoning: + reasoningKeywords.some(keyword => model.name.toLowerCase().includes(keyword)) + || knownModel?.abilities?.functionCall + || false, tokens: model.context_length, - vision: model.description?.toLowerCase().includes('vision') || visionKeywords.some(keyword => model.name?.toLowerCase().includes(keyword)), + vision: + model.description?.toLowerCase().includes('vision') + || visionKeywords.some(keyword => model.name?.toLowerCase().includes(keyword)) + || knownModel?.abilities?.functionCall + || false, }; }) .filter(Boolean) as ChatModelCard[]; diff --git a/src/libs/agent-runtime/xai/index.ts b/src/libs/agent-runtime/xai/index.ts index b59f1eefb7317..7f1a0fa2db497 100644 --- a/src/libs/agent-runtime/xai/index.ts +++ b/src/libs/agent-runtime/xai/index.ts @@ -16,13 +16,20 @@ export const LobeXAI = LobeOpenAICompatibleFactory({ transformModel: (m) => { const model = m as unknown as XAIModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: true, + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + knownModel?.abilities?.functionCall + || false, id: model.id, - vision: model.id.toLowerCase().includes('vision'), + vision: + model.id.toLowerCase().includes('vision') + || knownModel?.abilities?.functionCall + || false, }; }, }, diff --git a/src/libs/agent-runtime/zeroone/index.ts b/src/libs/agent-runtime/zeroone/index.ts index 839c0a832f181..48d9d3813a40e 100644 --- a/src/libs/agent-runtime/zeroone/index.ts +++ b/src/libs/agent-runtime/zeroone/index.ts @@ -16,13 +16,21 @@ export const LobeZeroOneAI = LobeOpenAICompatibleFactory({ transformModel: (m) => { const model = m as unknown as ZeroOneModelCard; + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.contextWindowTokens ?? undefined, - displayName: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.displayName ?? undefined, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id)?.enabled || false, - functionCall: model.id.toLowerCase().includes('fc'), + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + model.id.toLowerCase().includes('fc') + || knownModel?.abilities?.functionCall + || false, id: model.id, - vision: model.id.toLowerCase().includes('vision'), + vision: + model.id.toLowerCase().includes('vision') + || knownModel?.abilities?.vision + || false, }; }, }, diff --git a/src/libs/agent-runtime/zhipu/authToken.test.ts b/src/libs/agent-runtime/zhipu/authToken.test.ts deleted file mode 100644 index 406b99b5da6bd..0000000000000 --- a/src/libs/agent-runtime/zhipu/authToken.test.ts +++ /dev/null @@ -1,18 +0,0 @@ -// @vitest-environment node -import { generateApiToken } from './authToken'; - -describe('generateApiToken', () => { - it('should throw an error if no apiKey is provided', async () => { - await expect(generateApiToken()).rejects.toThrow('Invalid apiKey'); - }); - - it('should throw an error if apiKey is invalid', async () => { - await expect(generateApiToken('invalid')).rejects.toThrow('Invalid apiKey'); - }); - - it('should return a token if a valid apiKey is provided', async () => { - const apiKey = 'id.secret'; - const token = await generateApiToken(apiKey); - expect(token).toBeDefined(); - }); -}); diff --git a/src/libs/agent-runtime/zhipu/authToken.ts b/src/libs/agent-runtime/zhipu/authToken.ts deleted file mode 100644 index 6cb04afc95c2d..0000000000000 --- a/src/libs/agent-runtime/zhipu/authToken.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { SignJWT } from 'jose'; - -export const generateApiToken = async (apiKey?: string): Promise => { - if (!apiKey) { - throw new Error('Invalid apiKey'); - } - - const [id, secret] = apiKey.split('.'); - if (!id || !secret) { - throw new Error('Invalid apiKey'); - } - - const expSeconds = 60 * 60 * 24 * 30; - const nowSeconds = Math.floor(Date.now() / 1000); - const exp = nowSeconds + expSeconds; - const jwtConstructor = new SignJWT({ api_key: id }) - .setProtectedHeader({ alg: 'HS256', sign_type: 'SIGN', typ: 'JWT' }) - .setExpirationTime(exp) - .setIssuedAt(nowSeconds); - - return jwtConstructor.sign(new TextEncoder().encode(secret)); -}; diff --git a/src/libs/agent-runtime/zhipu/index.test.ts b/src/libs/agent-runtime/zhipu/index.test.ts index 54e6e648abf3a..a2cf3a6bc4ca2 100644 --- a/src/libs/agent-runtime/zhipu/index.test.ts +++ b/src/libs/agent-runtime/zhipu/index.test.ts @@ -5,21 +5,12 @@ import { Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { ChatStreamCallbacks, LobeOpenAI, LobeOpenAICompatibleRuntime } from '@/libs/agent-runtime'; import * as debugStreamModule from '@/libs/agent-runtime/utils/debugStream'; -import * as authTokenModule from './authToken'; import { LobeZhipuAI } from './index'; const bizErrorType = 'ProviderBizError'; const invalidErrorType = 'InvalidProviderAPIKey'; -// Mock相关依赖 -vi.mock('./authToken'); - describe('LobeZhipuAI', () => { - beforeEach(() => { - // Mock generateApiToken - vi.spyOn(authTokenModule, 'generateApiToken').mockResolvedValue('mocked_token'); - }); - afterEach(() => { vi.restoreAllMocks(); }); diff --git a/src/libs/agent-runtime/zhipu/index.ts b/src/libs/agent-runtime/zhipu/index.ts index 3e75d50687650..daff537aea470 100644 --- a/src/libs/agent-runtime/zhipu/index.ts +++ b/src/libs/agent-runtime/zhipu/index.ts @@ -57,15 +57,26 @@ export const LobeZhipuAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.modelCode === m.id); + return { - contextWindowTokens: LOBE_DEFAULT_MODEL_LIST.find((m) => model.modelCode === m.id)?.contextWindowTokens ?? undefined, + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, description: model.description, displayName: model.modelName, - enabled: LOBE_DEFAULT_MODEL_LIST.find((m) => model.modelCode === m.id)?.enabled || false, - functionCall: model.modelCode.toLowerCase().includes('glm-4') && !model.modelCode.toLowerCase().includes('glm-4v'), + enabled: knownModel?.enabled || false, + functionCall: + model.modelCode.toLowerCase().includes('glm-4') && !model.modelCode.toLowerCase().includes('glm-4v') + || knownModel?.abilities?.functionCall + || false, id: model.modelCode, - reasoning: model.modelCode.toLowerCase().includes('glm-zero-preview'), - vision: model.modelCode.toLowerCase().includes('glm-4v'), + reasoning: + model.modelCode.toLowerCase().includes('glm-zero-preview') + || knownModel?.abilities?.reasoning + || false, + vision: + model.modelCode.toLowerCase().includes('glm-4v') + || knownModel?.abilities?.vision + || false, }; }) .filter(Boolean) as ChatModelCard[]; From 4598565aa0b8387c437c48469f173c838cfbbd5f Mon Sep 17 00:00:00 2001 From: Zhijie He Date: Wed, 12 Feb 2025 20:38:34 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=F0=9F=90=9B=20fix:=20fix=20gemini=20thinki?= =?UTF-8?q?ng=20model=20set=20functionCall=20tag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/agent-runtime/google/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/agent-runtime/google/index.ts b/src/libs/agent-runtime/google/index.ts index 5b00132678862..bfce6d07fd03a 100644 --- a/src/libs/agent-runtime/google/index.ts +++ b/src/libs/agent-runtime/google/index.ts @@ -156,7 +156,7 @@ export class LobeGoogleAI implements LobeRuntimeAI { displayName: model.displayName, enabled: knownModel?.enabled || false, functionCall: - modelName.toLowerCase().includes('gemini') + modelName.toLowerCase().includes('gemini') && !modelName.toLowerCase().includes('thinking') || knownModel?.abilities?.functionCall || false, id: modelName, From 0e5702cede5bebc42b115e86d90e7cdb66bb964b Mon Sep 17 00:00:00 2001 From: Zhijie He Date: Wed, 12 Feb 2025 21:13:55 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=F0=9F=90=9B=20fix:=20fix=20Spark=20fc=20ta?= =?UTF-8?q?g=20missing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config/aiModels/spark.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/config/aiModels/spark.ts b/src/config/aiModels/spark.ts index 2624260f3370b..c31a9b8b583fc 100644 --- a/src/config/aiModels/spark.ts +++ b/src/config/aiModels/spark.ts @@ -32,6 +32,9 @@ const sparkChatModels: AIChatModelCard[] = [ type: 'chat', }, { + abilities: { + functionCall: true, + }, contextWindowTokens: 8192, description: 'Spark Max 为功能最为全面的版本,支持联网搜索及众多内置插件。其全面优化的核心能力以及系统角色设定和函数调用功能,使其在各种复杂应用场景中的表现极为优异和出色。', @@ -42,6 +45,9 @@ const sparkChatModels: AIChatModelCard[] = [ type: 'chat', }, { + abilities: { + functionCall: true, + }, contextWindowTokens: 32_768, description: 'Spark Max 32K 配置了大上下文处理能力,更强的上下文理解和逻辑推理能力,支持32K tokens的文本输入,适用于长文档阅读、私有知识问答等场景', @@ -52,6 +58,9 @@ const sparkChatModels: AIChatModelCard[] = [ type: 'chat', }, { + abilities: { + functionCall: true, + }, contextWindowTokens: 8192, description: 'Spark Ultra 是星火大模型系列中最为强大的版本,在升级联网搜索链路同时,提升对文本内容的理解和总结能力。它是用于提升办公生产力和准确响应需求的全方位解决方案,是引领行业的智能产品。', From de935e785c5c572b3683221b257ccb7ec8a828e7 Mon Sep 17 00:00:00 2001 From: Zhijie He Date: Wed, 12 Feb 2025 21:21:57 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E2=9C=A8=20feat:=20add=20model=20fetch=20s?= =?UTF-8?q?upport=20for=20Tencent=20Cloud?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/agent-runtime/tencentcloud/index.ts | 36 ++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/libs/agent-runtime/tencentcloud/index.ts b/src/libs/agent-runtime/tencentcloud/index.ts index 9eb60a5284b67..60c3b95a53024 100644 --- a/src/libs/agent-runtime/tencentcloud/index.ts +++ b/src/libs/agent-runtime/tencentcloud/index.ts @@ -1,10 +1,46 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; +import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; + +export interface TencentCloudModelCard { + id: string; +} + export const LobeTencentCloudAI = LobeOpenAICompatibleFactory({ baseURL: 'https://api.lkeap.cloud.tencent.com/v1', debug: { chatCompletion: () => process.env.DEBUG_TENCENT_CLOUD_CHAT_COMPLETION === '1', }, + models: { + transformModel: (m) => { + const functionCallKeywords = [ + 'deepseek-v3', + ]; + + const reasoningKeywords = [ + 'deepseek-r1', + ]; + + const model = m as unknown as TencentCloudModelCard; + + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.functionCall + || false, + id: model.id, + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + }; + }, + }, provider: ModelProvider.TencentCloud, }); From 256d0447b5ba4079c2eb9a77af8d053c8dfca297 Mon Sep 17 00:00:00 2001 From: Zhijie He Date: Thu, 13 Feb 2025 19:25:18 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20refactor?= =?UTF-8?q?=20import=20`LOBE=5FDEFAULT=5FMODEL=5FLIST`=20with=20async=20me?= =?UTF-8?q?thod=20-=20Part=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/agent-runtime/anthropic/index.ts | 3 ++- src/libs/agent-runtime/baichuan/index.ts | 3 ++- src/libs/agent-runtime/cloudflare/index.ts | 3 ++- src/libs/agent-runtime/github/index.ts | 3 ++- src/libs/agent-runtime/google/index.ts | 3 ++- src/libs/agent-runtime/huggingface/index.ts | 3 ++- src/libs/agent-runtime/ollama/index.ts | 3 ++- src/libs/agent-runtime/sensenova/index.ts | 3 ++- src/libs/agent-runtime/togetherai/index.ts | 3 ++- src/libs/agent-runtime/zhipu/index.ts | 3 ++- 10 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/libs/agent-runtime/anthropic/index.ts b/src/libs/agent-runtime/anthropic/index.ts index 6b2d864312e04..411b6e0bb6d0a 100644 --- a/src/libs/agent-runtime/anthropic/index.ts +++ b/src/libs/agent-runtime/anthropic/index.ts @@ -13,7 +13,6 @@ import { buildAnthropicMessages, buildAnthropicTools } from '../utils/anthropicH import { StreamingResponse } from '../utils/response'; import { AnthropicStream } from '../utils/streams'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; import type { ChatModelCard } from '@/types/llm'; export interface AnthropicModelCard { @@ -114,6 +113,8 @@ export class LobeAnthropicAI implements LobeRuntimeAI { } async models() { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); + const url = `${this.baseURL}/v1/models`; const response = await fetch(url, { headers: { diff --git a/src/libs/agent-runtime/baichuan/index.ts b/src/libs/agent-runtime/baichuan/index.ts index 2fce036a79b28..553b704c5ca99 100644 --- a/src/libs/agent-runtime/baichuan/index.ts +++ b/src/libs/agent-runtime/baichuan/index.ts @@ -3,7 +3,6 @@ import OpenAI from 'openai'; import { ChatStreamPayload, ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; import type { ChatModelCard } from '@/types/llm'; export interface BaichuanModelCard { @@ -32,6 +31,8 @@ export const LobeBaichuanAI = LobeOpenAICompatibleFactory({ chatCompletion: () => process.env.DEBUG_BAICHUAN_CHAT_COMPLETION === '1', }, models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); + const modelsPage = await client.models.list() as any; const modelList: BaichuanModelCard[] = modelsPage.data; diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index ec323e169b362..729133da31cfa 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -12,7 +12,6 @@ import { debugStream } from '../utils/debugStream'; import { StreamingResponse } from '../utils/response'; import { createCallbacksTransformer } from '../utils/streams'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; import { ChatModelCard } from '@/types/llm'; export interface CloudflareModelCard { @@ -113,6 +112,8 @@ export class LobeCloudflareAI implements LobeRuntimeAI { } async models(): Promise { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); + const url = `${DEFAULT_BASE_URL_PREFIX}/client/v4/accounts/${this.accountID}/ai/models/search`; const response = await fetch(url, { headers: { diff --git a/src/libs/agent-runtime/github/index.ts b/src/libs/agent-runtime/github/index.ts index 14aef23f3e071..155617b9b244d 100644 --- a/src/libs/agent-runtime/github/index.ts +++ b/src/libs/agent-runtime/github/index.ts @@ -3,7 +3,6 @@ import { pruneReasoningPayload } from '../openai'; import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; import type { ChatModelCard } from '@/types/llm'; export interface GithubModelCard { @@ -38,6 +37,8 @@ export const LobeGithubAI = LobeOpenAICompatibleFactory({ invalidAPIKey: AgentRuntimeErrorType.InvalidGithubToken, }, models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); + const functionCallKeywords = [ 'function', 'tool', diff --git a/src/libs/agent-runtime/google/index.ts b/src/libs/agent-runtime/google/index.ts index bfce6d07fd03a..074f1083ec85d 100644 --- a/src/libs/agent-runtime/google/index.ts +++ b/src/libs/agent-runtime/google/index.ts @@ -8,7 +8,6 @@ import { SchemaType, } from '@google/generative-ai'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; import type { ChatModelCard } from '@/types/llm'; import { imageUrlToBase64 } from '@/utils/imageToBase64'; import { safeParseJSON } from '@/utils/safeParseJSON'; @@ -137,6 +136,8 @@ export class LobeGoogleAI implements LobeRuntimeAI { } async models() { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); + const url = `${this.baseURL}/v1beta/models?key=${this.apiKey}`; const response = await fetch(url, { method: 'GET', diff --git a/src/libs/agent-runtime/huggingface/index.ts b/src/libs/agent-runtime/huggingface/index.ts index 146346972e8c7..5f54f18b39bc9 100644 --- a/src/libs/agent-runtime/huggingface/index.ts +++ b/src/libs/agent-runtime/huggingface/index.ts @@ -6,7 +6,6 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; import { convertIterableToStream } from '../utils/streams'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; import type { ChatModelCard } from '@/types/llm'; export interface HuggingFaceModelCard { @@ -56,6 +55,8 @@ export const LobeHuggingFaceAI = LobeOpenAICompatibleFactory({ chatCompletion: () => process.env.DEBUG_HUGGINGFACE_CHAT_COMPLETION === '1', }, models: async () => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); + const visionKeywords = [ 'image-text-to-text', 'multimodal', diff --git a/src/libs/agent-runtime/ollama/index.ts b/src/libs/agent-runtime/ollama/index.ts index f2ff37218f7a1..8c92a5c07fea7 100644 --- a/src/libs/agent-runtime/ollama/index.ts +++ b/src/libs/agent-runtime/ollama/index.ts @@ -19,7 +19,6 @@ import { OllamaStream, convertIterableToStream } from '../utils/streams'; import { parseDataUri } from '../utils/uriParser'; import { OllamaMessage } from './type'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; import { ChatModelCard } from '@/types/llm'; export interface OllamaModelCard { @@ -109,6 +108,8 @@ export class LobeOllamaAI implements LobeRuntimeAI { } async models() { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); + const list = await this.client.list(); const modelList: OllamaModelCard[] = list.models; diff --git a/src/libs/agent-runtime/sensenova/index.ts b/src/libs/agent-runtime/sensenova/index.ts index 1ed591a7d9ae7..563e50f3ea157 100644 --- a/src/libs/agent-runtime/sensenova/index.ts +++ b/src/libs/agent-runtime/sensenova/index.ts @@ -1,7 +1,6 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; import type { ChatModelCard } from '@/types/llm'; export interface SenseNovaModelCard { @@ -33,6 +32,8 @@ export const LobeSenseNovaAI = LobeOpenAICompatibleFactory({ chatCompletion: () => process.env.DEBUG_SENSENOVA_CHAT_COMPLETION === '1', }, models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); + const functionCallKeywords = [ 'sensechat-5', ]; diff --git a/src/libs/agent-runtime/togetherai/index.ts b/src/libs/agent-runtime/togetherai/index.ts index 80457c8324090..bf228168041a5 100644 --- a/src/libs/agent-runtime/togetherai/index.ts +++ b/src/libs/agent-runtime/togetherai/index.ts @@ -2,7 +2,6 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; import { TogetherAIModel } from './type'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; import type { ChatModelCard } from '@/types/llm'; export const LobeTogetherAI = LobeOpenAICompatibleFactory({ @@ -17,6 +16,8 @@ export const LobeTogetherAI = LobeOpenAICompatibleFactory({ chatCompletion: () => process.env.DEBUG_TOGETHERAI_CHAT_COMPLETION === '1', }, models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); + const visionKeywords = [ 'qvq', 'vision', diff --git a/src/libs/agent-runtime/zhipu/index.ts b/src/libs/agent-runtime/zhipu/index.ts index daff537aea470..071077debbacb 100644 --- a/src/libs/agent-runtime/zhipu/index.ts +++ b/src/libs/agent-runtime/zhipu/index.ts @@ -3,7 +3,6 @@ import OpenAI from 'openai'; import { ChatStreamPayload, ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; import type { ChatModelCard } from '@/types/llm'; export interface ZhipuModelCard { @@ -49,6 +48,8 @@ export const LobeZhipuAI = LobeOpenAICompatibleFactory({ chatCompletion: () => process.env.DEBUG_ZHIPU_CHAT_COMPLETION === '1', }, models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); + // ref: https://open.bigmodel.cn/console/modelcenter/square client.baseURL = 'https://open.bigmodel.cn/api/fine-tuning/model_center/list?pageSize=100&pageNum=1'; From b29c689eb5a60d4bd589ad40e51ff01b298472fb Mon Sep 17 00:00:00 2001 From: Zhijie He Date: Thu, 13 Feb 2025 21:13:02 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20refactor?= =?UTF-8?q?=20import=20LOBE=5FDEFAULT=5FMODEL=5FLIST=20with=20async=20meth?= =?UTF-8?q?od=20-=20Part=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/agent-runtime/ai360/index.ts | 61 +++++----- src/libs/agent-runtime/deepseek/index.ts | 45 ++++---- src/libs/agent-runtime/fireworksai/index.ts | 53 +++++---- src/libs/agent-runtime/giteeai/index.ts | 87 +++++++------- src/libs/agent-runtime/groq/index.ts | 75 ++++++------ src/libs/agent-runtime/higress/index.ts | 76 ++++++------ src/libs/agent-runtime/hunyuan/index.ts | 55 +++++---- src/libs/agent-runtime/internlm/index.ts | 35 +++--- src/libs/agent-runtime/lmstudio/index.ts | 47 ++++---- src/libs/agent-runtime/mistral/index.ts | 35 +++--- src/libs/agent-runtime/moonshot/index.ts | 43 ++++--- src/libs/agent-runtime/novita/index.ts | 63 +++++----- .../openai/__snapshots__/index.test.ts.snap | 108 ++++++++++++++++++ src/libs/agent-runtime/openai/index.ts | 79 +++++++------ .../__snapshots__/index.test.ts.snap | 28 +++++ src/libs/agent-runtime/openrouter/index.ts | 90 ++++++++------- src/libs/agent-runtime/qwen/index.ts | 83 +++++++------- src/libs/agent-runtime/siliconcloud/index.ts | 93 ++++++++------- src/libs/agent-runtime/stepfun/index.ts | 67 ++++++----- src/libs/agent-runtime/tencentcloud/index.ts | 65 ++++++----- src/libs/agent-runtime/xai/index.ts | 43 ++++--- src/libs/agent-runtime/zeroone/index.ts | 45 ++++---- 22 files changed, 811 insertions(+), 565 deletions(-) diff --git a/src/libs/agent-runtime/ai360/index.ts b/src/libs/agent-runtime/ai360/index.ts index 1f793fa7d8027..cc9969b45d0a1 100644 --- a/src/libs/agent-runtime/ai360/index.ts +++ b/src/libs/agent-runtime/ai360/index.ts @@ -1,7 +1,7 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface Ai360ModelCard { id: string; @@ -22,36 +22,41 @@ export const LobeAi360AI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_AI360_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const reasoningKeywords = [ - '360gpt2-o1', - '360zhinao2-o1', - ]; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const model = m as unknown as Ai360ModelCard; + const reasoningKeywords = [ + '360gpt2-o1', + '360zhinao2-o1', + ]; - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: Ai360ModelCard[] = modelsPage.data; - return { - contextWindowTokens: model.total_tokens, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - model.id === '360gpt-pro' - || knownModel?.abilities?.functionCall - || false, - id: model.id, - maxTokens: - typeof model.max_tokens === 'number' - ? model.max_tokens - : undefined, - reasoning: - reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.reasoning - || false, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: model.total_tokens, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + model.id === '360gpt-pro' + || knownModel?.abilities?.functionCall + || false, + id: model.id, + maxTokens: + typeof model.max_tokens === 'number' + ? model.max_tokens + : undefined, + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.Ai360, }); diff --git a/src/libs/agent-runtime/deepseek/index.ts b/src/libs/agent-runtime/deepseek/index.ts index e4db23af893df..33b0d67e6e516 100644 --- a/src/libs/agent-runtime/deepseek/index.ts +++ b/src/libs/agent-runtime/deepseek/index.ts @@ -3,7 +3,7 @@ import OpenAI from 'openai'; import { ChatStreamPayload, ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface DeepSeekModelCard { id: string; @@ -59,27 +59,32 @@ export const LobeDeepSeekAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_DEEPSEEK_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const model = m as unknown as DeepSeekModelCard; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: DeepSeekModelCard[] = modelsPage.data; - return { - contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - !model.id.toLowerCase().includes('reasoner') - || knownModel?.abilities?.functionCall - || false, - id: model.id, - reasoning: - model.id.toLowerCase().includes('reasoner') - || knownModel?.abilities?.reasoning - || false, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + !model.id.toLowerCase().includes('reasoner') + || knownModel?.abilities?.functionCall + || false, + id: model.id, + reasoning: + model.id.toLowerCase().includes('reasoner') + || knownModel?.abilities?.reasoning + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.DeepSeek, }); diff --git a/src/libs/agent-runtime/fireworksai/index.ts b/src/libs/agent-runtime/fireworksai/index.ts index b710849c6aa34..95c7d927d26f3 100644 --- a/src/libs/agent-runtime/fireworksai/index.ts +++ b/src/libs/agent-runtime/fireworksai/index.ts @@ -1,7 +1,7 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface FireworksAIModelCard { context_length: number; @@ -15,32 +15,37 @@ export const LobeFireworksAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_FIREWORKSAI_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const reasoningKeywords = [ - 'deepseek-r1', - 'qwq', - ]; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const model = m as unknown as FireworksAIModelCard; + const reasoningKeywords = [ + 'deepseek-r1', + 'qwq', + ]; - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: FireworksAIModelCard[] = modelsPage.data; - return { - contextWindowTokens: model.context_length, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - model.supports_tools - || model.id.toLowerCase().includes('function'), - id: model.id, - reasoning: - reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.reasoning - || false, - vision: model.supports_image_input, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: model.context_length, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + model.supports_tools + || model.id.toLowerCase().includes('function'), + id: model.id, + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: model.supports_image_input, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.FireworksAI, }); diff --git a/src/libs/agent-runtime/giteeai/index.ts b/src/libs/agent-runtime/giteeai/index.ts index 3dfb6c3366388..cd1a48818b8d7 100644 --- a/src/libs/agent-runtime/giteeai/index.ts +++ b/src/libs/agent-runtime/giteeai/index.ts @@ -1,7 +1,7 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface GiteeAIModelCard { id: string; @@ -12,46 +12,51 @@ export const LobeGiteeAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_GITEE_AI_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const functionCallKeywords = [ - 'qwen2.5', - 'glm-4', - ]; - - const visionKeywords = [ - 'internvl', - 'qwen2-vl', - ]; - - const reasoningKeywords = [ - 'deepseek-r1', - 'qwq', - ]; - - const model = m as unknown as GiteeAIModelCard; - - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); - - return { - contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('qwen2.5-coder') - || knownModel?.abilities?.functionCall - || false, - id: model.id, - reasoning: - reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.reasoning - || false, - vision: - visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.vision - || false, - }; - }, + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); + + const functionCallKeywords = [ + 'qwen2.5', + 'glm-4', + ]; + + const visionKeywords = [ + 'internvl', + 'qwen2-vl', + ]; + + const reasoningKeywords = [ + 'deepseek-r1', + 'qwq', + ]; + + const modelsPage = await client.models.list() as any; + const modelList: GiteeAIModelCard[] = modelsPage.data; + + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('qwen2.5-coder') + || knownModel?.abilities?.functionCall + || false, + id: model.id, + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: + visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.vision + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.GiteeAI, }); diff --git a/src/libs/agent-runtime/groq/index.ts b/src/libs/agent-runtime/groq/index.ts index f2ea5c4c25682..ae6bdd91afb56 100644 --- a/src/libs/agent-runtime/groq/index.ts +++ b/src/libs/agent-runtime/groq/index.ts @@ -2,7 +2,7 @@ import { AgentRuntimeErrorType } from '../error'; import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface GroqModelCard { context_window: number; @@ -31,44 +31,49 @@ export const LobeGroq = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_GROQ_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const functionCallKeywords = [ - 'tool', - 'llama-3.3', - 'llama-3.1', - 'llama3-', - 'mixtral-8x7b-32768', - 'gemma2-9b-it', - ]; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const reasoningKeywords = [ - 'deepseek-r1', - ]; + const functionCallKeywords = [ + 'tool', + 'llama-3.3', + 'llama-3.1', + 'llama3-', + 'mixtral-8x7b-32768', + 'gemma2-9b-it', + ]; - const model = m as unknown as GroqModelCard; + const reasoningKeywords = [ + 'deepseek-r1', + ]; - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: GroqModelCard[] = modelsPage.data; - return { - contextWindowTokens: model.context_window, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.functionCall - || false, - id: model.id, - reasoning: - reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.reasoning - || false, - vision: - model.id.toLowerCase().includes('vision') - || knownModel?.abilities?.vision - || false, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: model.context_window, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.functionCall + || false, + id: model.id, + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: + model.id.toLowerCase().includes('vision') + || knownModel?.abilities?.vision + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.Groq, }); diff --git a/src/libs/agent-runtime/higress/index.ts b/src/libs/agent-runtime/higress/index.ts index 0eedc149c4422..75c38b96f9b7a 100644 --- a/src/libs/agent-runtime/higress/index.ts +++ b/src/libs/agent-runtime/higress/index.ts @@ -3,7 +3,17 @@ import { uniqueId } from 'lodash-es'; import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; + +export interface HigressModelCard { + context_length: number; + description: string; + id: string; + name: string; + top_provider: { + max_completion_tokens: number; + } +} export const LobeHigressAI = LobeOpenAICompatibleFactory({ constructorOptions: { @@ -16,39 +26,41 @@ export const LobeHigressAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_HIGRESS_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const model = m as any; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: HigressModelCard[] = modelsPage.data; - return { - contextWindowTokens: model.context_length, - description: model.description, - displayName: model.name, - enabled: knownModel?.enabled || false, - functionCall: - model.description.includes('function calling') - || model.description.includes('tools') - || knownModel?.abilities?.functionCall - || false, - id: model.id, - maxTokens: - typeof model.top_provider.max_completion_tokens === 'number' - ? model.top_provider.max_completion_tokens - : undefined, - reasoning: - model.description.includes('reasoning') - || knownModel?.abilities?.reasoning - || false, - vision: - model.description.includes('vision') - || model.description.includes('multimodal') - || model.id.includes('vision') - || knownModel?.abilities?.vision - || false, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: model.context_length, + description: model.description, + displayName: model.name, + enabled: knownModel?.enabled || false, + functionCall: + model.description.includes('function calling') + || model.description.includes('tools') + || knownModel?.abilities?.functionCall + || false, + id: model.id, + maxTokens: model.top_provider.max_completion_tokens, + reasoning: + model.description.includes('reasoning') + || knownModel?.abilities?.reasoning + || false, + vision: + model.description.includes('vision') + || model.description.includes('multimodal') + || model.id.includes('vision') + || knownModel?.abilities?.vision + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.Higress, }); diff --git a/src/libs/agent-runtime/hunyuan/index.ts b/src/libs/agent-runtime/hunyuan/index.ts index 852a9ae1a4975..208092fd06ca1 100644 --- a/src/libs/agent-runtime/hunyuan/index.ts +++ b/src/libs/agent-runtime/hunyuan/index.ts @@ -1,7 +1,7 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface HunyuanModelCard { id: string; @@ -12,33 +12,38 @@ export const LobeHunyuanAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_HUNYUAN_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const functionCallKeywords = [ - 'hunyuan-functioncall', - 'hunyuan-turbo', - 'hunyuan-pro', - ]; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const model = m as unknown as HunyuanModelCard; + const functionCallKeywords = [ + 'hunyuan-functioncall', + 'hunyuan-turbo', + 'hunyuan-pro', + ]; - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: HunyuanModelCard[] = modelsPage.data; - return { - contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('vision') - || knownModel?.abilities?.functionCall - || false, - id: model.id, - vision: - model.id.toLowerCase().includes('vision') - || knownModel?.abilities?.vision - || false, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('vision') + || knownModel?.abilities?.functionCall + || false, + id: model.id, + vision: + model.id.toLowerCase().includes('vision') + || knownModel?.abilities?.vision + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.Hunyuan, }); diff --git a/src/libs/agent-runtime/internlm/index.ts b/src/libs/agent-runtime/internlm/index.ts index 58cf1227fd464..6d08f4ef54ac0 100644 --- a/src/libs/agent-runtime/internlm/index.ts +++ b/src/libs/agent-runtime/internlm/index.ts @@ -1,7 +1,7 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface InternLMModelCard { id: string; @@ -20,22 +20,27 @@ export const LobeInternLMAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_INTERNLM_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const model = m as unknown as InternLMModelCard; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: InternLMModelCard[] = modelsPage.data; - return { - contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - knownModel?.abilities?.functionCall - || false, - id: model.id, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + knownModel?.abilities?.functionCall + || false, + id: model.id, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.InternLM, }); diff --git a/src/libs/agent-runtime/lmstudio/index.ts b/src/libs/agent-runtime/lmstudio/index.ts index 000f2ed6678be..fa18948f199fa 100644 --- a/src/libs/agent-runtime/lmstudio/index.ts +++ b/src/libs/agent-runtime/lmstudio/index.ts @@ -1,7 +1,7 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface LMStudioModelCard { id: string; @@ -13,28 +13,33 @@ export const LobeLMStudioAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_LMSTUDIO_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const model = m as unknown as LMStudioModelCard; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: LMStudioModelCard[] = modelsPage.data; - return { - contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - knownModel?.abilities?.functionCall - || false, - id: model.id, - reasoning: - knownModel?.abilities?.reasoning - || false, - vision: - knownModel?.abilities?.vision - || false, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + knownModel?.abilities?.functionCall + || false, + id: model.id, + reasoning: + knownModel?.abilities?.reasoning + || false, + vision: + knownModel?.abilities?.vision + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.LMStudio, }); diff --git a/src/libs/agent-runtime/mistral/index.ts b/src/libs/agent-runtime/mistral/index.ts index 592d396b20b89..6b9e6c596be41 100644 --- a/src/libs/agent-runtime/mistral/index.ts +++ b/src/libs/agent-runtime/mistral/index.ts @@ -1,7 +1,7 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface MistralModelCard { capabilities: { @@ -30,22 +30,27 @@ export const LobeMistralAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_MISTRAL_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const model = m as unknown as MistralModelCard; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: MistralModelCard[] = modelsPage.data; - return { - contextWindowTokens: model.max_context_length, - description: model.description, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: model.capabilities.function_calling, - id: model.id, - vision: model.capabilities.vision, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: model.max_context_length, + description: model.description, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: model.capabilities.function_calling, + id: model.id, + vision: model.capabilities.vision, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.Mistral, }); diff --git a/src/libs/agent-runtime/moonshot/index.ts b/src/libs/agent-runtime/moonshot/index.ts index e213474603d29..e1074e1fee699 100644 --- a/src/libs/agent-runtime/moonshot/index.ts +++ b/src/libs/agent-runtime/moonshot/index.ts @@ -3,7 +3,7 @@ import OpenAI from 'openai'; import { ChatStreamPayload, ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface MoonshotModelCard { id: string; @@ -24,26 +24,31 @@ export const LobeMoonshotAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_MOONSHOT_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const model = m as unknown as MoonshotModelCard; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: MoonshotModelCard[] = modelsPage.data; - return { - contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - knownModel?.abilities?.functionCall - || false, - id: model.id, - vision: - model.id.toLowerCase().includes('vision') - || knownModel?.abilities?.vision - || false, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + knownModel?.abilities?.functionCall + || false, + id: model.id, + vision: + model.id.toLowerCase().includes('vision') + || knownModel?.abilities?.vision + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.Moonshot, }); diff --git a/src/libs/agent-runtime/novita/index.ts b/src/libs/agent-runtime/novita/index.ts index fe4465383816b..c8881bdb791db 100644 --- a/src/libs/agent-runtime/novita/index.ts +++ b/src/libs/agent-runtime/novita/index.ts @@ -2,7 +2,7 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; import { NovitaModelCard } from './type'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export const LobeNovitaAI = LobeOpenAICompatibleFactory({ baseURL: 'https://api.novita.ai/v3/openai', @@ -14,37 +14,42 @@ export const LobeNovitaAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_NOVITA_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const reasoningKeywords = [ - 'deepseek-r1', - ]; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const model = m as unknown as NovitaModelCard; + const reasoningKeywords = [ + 'deepseek-r1', + ]; - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: NovitaModelCard[] = modelsPage.data; - return { - contextWindowTokens: model.context_size, - description: model.description, - displayName: model.title, - enabled: knownModel?.enabled || false, - functionCall: - model.description.toLowerCase().includes('function calling') - || knownModel?.abilities?.functionCall - || false, - id: model.id, - reasoning: - model.description.toLowerCase().includes('reasoning task') - || reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.reasoning - || false, - vision: - model.description.toLowerCase().includes('vision') - || knownModel?.abilities?.vision - || false, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: model.context_size, + description: model.description, + displayName: model.title, + enabled: knownModel?.enabled || false, + functionCall: + model.description.toLowerCase().includes('function calling') + || knownModel?.abilities?.functionCall + || false, + id: model.id, + reasoning: + model.description.toLowerCase().includes('reasoning task') + || reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: + model.description.toLowerCase().includes('vision') + || knownModel?.abilities?.vision + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.Novita, }); diff --git a/src/libs/agent-runtime/openai/__snapshots__/index.test.ts.snap b/src/libs/agent-runtime/openai/__snapshots__/index.test.ts.snap index 95754bd0502b7..94207a061844e 100644 --- a/src/libs/agent-runtime/openai/__snapshots__/index.test.ts.snap +++ b/src/libs/agent-runtime/openai/__snapshots__/index.test.ts.snap @@ -2,6 +2,24 @@ exports[`LobeOpenAI > models > should get models 1`] = ` [ + { + "contextWindowTokens": undefined, + "displayName": "Whisper", + "enabled": false, + "functionCall": false, + "id": "whisper-1", + "reasoning": false, + "vision": false, + }, + { + "contextWindowTokens": undefined, + "displayName": undefined, + "enabled": false, + "functionCall": false, + "id": "davinci-002", + "reasoning": false, + "vision": false, + }, { "contextWindowTokens": 16385, "displayName": "GPT 3.5 Turbo", @@ -11,6 +29,15 @@ exports[`LobeOpenAI > models > should get models 1`] = ` "reasoning": false, "vision": false, }, + { + "contextWindowTokens": undefined, + "displayName": "DALL·E 2", + "enabled": false, + "functionCall": false, + "id": "dall-e-2", + "reasoning": false, + "vision": false, + }, { "contextWindowTokens": 16384, "displayName": "GPT 3.5 Turbo", @@ -20,6 +47,24 @@ exports[`LobeOpenAI > models > should get models 1`] = ` "reasoning": false, "vision": false, }, + { + "contextWindowTokens": undefined, + "displayName": undefined, + "enabled": false, + "functionCall": false, + "id": "tts-1-hd-1106", + "reasoning": false, + "vision": false, + }, + { + "contextWindowTokens": undefined, + "displayName": "TTS-1 HD", + "enabled": false, + "functionCall": false, + "id": "tts-1-hd", + "reasoning": false, + "vision": false, + }, { "contextWindowTokens": undefined, "displayName": undefined, @@ -29,6 +74,15 @@ exports[`LobeOpenAI > models > should get models 1`] = ` "reasoning": false, "vision": false, }, + { + "contextWindowTokens": 8192, + "displayName": "Text Embedding 3 Large", + "enabled": false, + "functionCall": false, + "id": "text-embedding-3-large", + "reasoning": false, + "vision": false, + }, { "contextWindowTokens": undefined, "displayName": undefined, @@ -92,6 +146,24 @@ exports[`LobeOpenAI > models > should get models 1`] = ` "reasoning": false, "vision": false, }, + { + "contextWindowTokens": undefined, + "displayName": "TTS-1", + "enabled": false, + "functionCall": false, + "id": "tts-1", + "reasoning": false, + "vision": false, + }, + { + "contextWindowTokens": undefined, + "displayName": "DALL·E 3", + "enabled": false, + "functionCall": false, + "id": "dall-e-3", + "reasoning": false, + "vision": false, + }, { "contextWindowTokens": 16385, "displayName": "GPT-3.5 Turbo 1106", @@ -110,6 +182,24 @@ exports[`LobeOpenAI > models > should get models 1`] = ` "reasoning": false, "vision": false, }, + { + "contextWindowTokens": undefined, + "displayName": undefined, + "enabled": false, + "functionCall": false, + "id": "babbage-002", + "reasoning": false, + "vision": false, + }, + { + "contextWindowTokens": undefined, + "displayName": undefined, + "enabled": false, + "functionCall": false, + "id": "tts-1-1106", + "reasoning": false, + "vision": false, + }, { "contextWindowTokens": 128000, "displayName": "GPT 4 Turbo with Vision Preview", @@ -119,6 +209,15 @@ exports[`LobeOpenAI > models > should get models 1`] = ` "reasoning": false, "vision": true, }, + { + "contextWindowTokens": 8192, + "displayName": "Text Embedding 3 Small", + "enabled": false, + "functionCall": false, + "id": "text-embedding-3-small", + "reasoning": false, + "vision": false, + }, { "contextWindowTokens": 128000, "displayName": "GPT 4 Turbo", @@ -128,6 +227,15 @@ exports[`LobeOpenAI > models > should get models 1`] = ` "reasoning": false, "vision": true, }, + { + "contextWindowTokens": undefined, + "displayName": undefined, + "enabled": false, + "functionCall": false, + "id": "text-embedding-ada-002", + "reasoning": false, + "vision": false, + }, { "contextWindowTokens": 16385, "displayName": "GPT-3.5 Turbo 0125", diff --git a/src/libs/agent-runtime/openai/index.ts b/src/libs/agent-runtime/openai/index.ts index 3dae2edf17589..330f5ceeb0c38 100644 --- a/src/libs/agent-runtime/openai/index.ts +++ b/src/libs/agent-runtime/openai/index.ts @@ -1,7 +1,7 @@ import { ChatStreamPayload, ModelProvider, OpenAIChatMessage } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface OpenAIModelCard { id: string; @@ -55,47 +55,52 @@ export const LobeOpenAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_OPENAI_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const functionCallKeywords = [ - 'gpt-4', - 'gpt-3.5', - 'o3-mini', - ]; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const visionKeywords = [ - 'gpt-4o', - 'vision', - ]; + const functionCallKeywords = [ + 'gpt-4', + 'gpt-3.5', + 'o3-mini', + ]; - const reasoningKeywords = [ - 'o1', - 'o3', - ]; + const visionKeywords = [ + 'gpt-4o', + 'vision', + ]; - const model = m as unknown as OpenAIModelCard; + const reasoningKeywords = [ + 'o1', + 'o3', + ]; - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: OpenAIModelCard[] = modelsPage.data; - return { - contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('audio') - || knownModel?.abilities?.functionCall - || false, - id: model.id, - reasoning: - reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.reasoning - || false, - vision: - visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('audio') - || knownModel?.abilities?.vision - || false, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('audio') + || knownModel?.abilities?.functionCall + || false, + id: model.id, + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: + visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('audio') + || knownModel?.abilities?.vision + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.OpenAI, }); diff --git a/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap b/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap index 8b60923b8fa54..b42b85696a3c4 100644 --- a/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap +++ b/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap @@ -2,6 +2,34 @@ exports[`LobeOpenRouterAI > models > should get models 1`] = ` [ + { + "contextWindowTokens": 131072, + "description": "Reflection Llama-3.1 70B is trained with a new technique called Reflection-Tuning that teaches a LLM to detect mistakes in its reasoning and correct course. + +The model was trained on synthetic data. + +_These are free, rate-limited endpoints for [Reflection 70B](/models/mattshumer/reflection-70b). Outputs may be cached. Read about rate limits [here](/docs/limits)._", + "displayName": "Reflection 70B (free)", + "enabled": false, + "functionCall": false, + "id": "mattshumer/reflection-70b:free", + "maxTokens": 4096, + "reasoning": false, + "vision": false, + }, + { + "contextWindowTokens": 131072, + "description": "Reflection Llama-3.1 70B is trained with a new technique called Reflection-Tuning that teaches a LLM to detect mistakes in its reasoning and correct course. + +The model was trained on synthetic data.", + "displayName": "Reflection 70B", + "enabled": false, + "functionCall": false, + "id": "mattshumer/reflection-70b", + "maxTokens": undefined, + "reasoning": false, + "vision": false, + }, { "contextWindowTokens": 128000, "description": "Command-R is a 35B parameter model that performs conversational language tasks at a higher quality, more reliably, and with a longer context than previous models. It can be used for complex workflows like code generation, retrieval augmented generation (RAG), tool use, and agents. diff --git a/src/libs/agent-runtime/openrouter/index.ts b/src/libs/agent-runtime/openrouter/index.ts index 20c530ff31e1c..03d381e910b82 100644 --- a/src/libs/agent-runtime/openrouter/index.ts +++ b/src/libs/agent-runtime/openrouter/index.ts @@ -2,7 +2,7 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; import { OpenRouterModelCard } from './type'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export const LobeOpenRouterAI = LobeOpenAICompatibleFactory({ baseURL: 'https://openrouter.ai/api/v1', @@ -24,50 +24,58 @@ export const LobeOpenRouterAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_OPENROUTER_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const visionKeywords = ['qwen/qvq', 'vision']; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const reasoningKeywords = [ - 'deepseek/deepseek-r1', - 'openai/o1', - 'openai/o3', - 'qwen/qvq', - 'qwen/qwq', - 'thinking', - ]; + const visionKeywords = [ + 'qwen/qvq', + 'vision' + ]; - const model = m as unknown as OpenRouterModelCard; + const reasoningKeywords = [ + 'deepseek/deepseek-r1', + 'openai/o1', + 'openai/o3', + 'qwen/qvq', + 'qwen/qwq', + 'thinking', + ]; - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: OpenRouterModelCard[] = modelsPage.data; - return { - contextWindowTokens: model.context_length, - description: model.description, - displayName: model.name, - enabled: knownModel?.enabled || false, - functionCall: - model.description.includes('function calling') - || model.description.includes('tools') - || knownModel?.abilities?.functionCall - || false, - id: model.id, - maxTokens: - typeof model.top_provider.max_completion_tokens === 'number' - ? model.top_provider.max_completion_tokens - : undefined, - reasoning: - reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.reasoning - || false, - vision: - model.description.includes('vision') - || model.description.includes('multimodal') - || visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.vision - || false, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: model.context_length, + description: model.description, + displayName: model.name, + enabled: knownModel?.enabled || false, + functionCall: + model.description.includes('function calling') + || model.description.includes('tools') + || knownModel?.abilities?.functionCall + || false, + id: model.id, + maxTokens: + typeof model.top_provider.max_completion_tokens === 'number' + ? model.top_provider.max_completion_tokens + : undefined, + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: + model.description.includes('vision') + || model.description.includes('multimodal') + || visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.vision + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.OpenRouter, }); diff --git a/src/libs/agent-runtime/qwen/index.ts b/src/libs/agent-runtime/qwen/index.ts index e4bc09d8524d1..cf55d96330495 100644 --- a/src/libs/agent-runtime/qwen/index.ts +++ b/src/libs/agent-runtime/qwen/index.ts @@ -3,7 +3,7 @@ import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; import { QwenAIStream } from '../utils/streams'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface QwenModelCard { id: string; @@ -70,49 +70,54 @@ export const LobeQwenAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_QWEN_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const functionCallKeywords = [ - 'qwen-max', - 'qwen-plus', - 'qwen-turbo', - 'qwen2.5', - ]; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const visionKeywords = [ - 'qvq', - 'vl', - ]; + const functionCallKeywords = [ + 'qwen-max', + 'qwen-plus', + 'qwen-turbo', + 'qwen2.5', + ]; - const reasoningKeywords = [ - 'qvq', - 'qwq', - 'deepseek-r1' - ]; + const visionKeywords = [ + 'qvq', + 'vl', + ]; - const model = m as unknown as QwenModelCard; + const reasoningKeywords = [ + 'qvq', + 'qwq', + 'deepseek-r1' + ]; - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: QwenModelCard[] = modelsPage.data; - return { - contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.functionCall - || false, - id: model.id, - reasoning: - reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.reasoning - || false, - vision: - visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.vision - || false, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.functionCall + || false, + id: model.id, + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: + visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.vision + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.Qwen, }); diff --git a/src/libs/agent-runtime/siliconcloud/index.ts b/src/libs/agent-runtime/siliconcloud/index.ts index 9db78155780ff..753d695b3ada0 100644 --- a/src/libs/agent-runtime/siliconcloud/index.ts +++ b/src/libs/agent-runtime/siliconcloud/index.ts @@ -2,7 +2,7 @@ import { AgentRuntimeErrorType } from '../error'; import { ChatCompletionErrorPayload, ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface SiliconCloudModelCard { id: string; @@ -52,54 +52,59 @@ export const LobeSiliconCloudAI = LobeOpenAICompatibleFactory({ bizError: AgentRuntimeErrorType.ProviderBizError, invalidAPIKey: AgentRuntimeErrorType.InvalidProviderAPIKey, }, - models: { - transformModel: (m) => { - const functionCallKeywords = [ - 'qwen/qwen2.5', - 'thudm/glm-4', - 'deepseek-ai/deepseek', - 'internlm/internlm2_5', - 'meta-llama/meta-llama-3.1', - 'meta-llama/meta-llama-3.3', - ]; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const visionKeywords = [ - 'opengvlab/internvl', - 'qwen/qvq', - 'qwen/qwen2-vl', - 'teleai/telemm', - 'deepseek-ai/deepseek-vl', - ]; + const functionCallKeywords = [ + 'qwen/qwen2.5', + 'thudm/glm-4', + 'deepseek-ai/deepseek', + 'internlm/internlm2_5', + 'meta-llama/meta-llama-3.1', + 'meta-llama/meta-llama-3.3', + ]; - const reasoningKeywords = [ - 'deepseek-ai/deepseek-r1', - 'qwen/qvq', - 'qwen/qwq', - ]; + const visionKeywords = [ + 'opengvlab/internvl', + 'qwen/qvq', + 'qwen/qwen2-vl', + 'teleai/telemm', + 'deepseek-ai/deepseek-vl', + ]; - const model = m as unknown as SiliconCloudModelCard; + const reasoningKeywords = [ + 'deepseek-ai/deepseek-r1', + 'qwen/qvq', + 'qwen/qwq', + ]; - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: SiliconCloudModelCard[] = modelsPage.data; - return { - contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('deepseek-r1') - || knownModel?.abilities?.functionCall - || false, - id: model.id, - reasoning: - reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.reasoning - || false, - vision: - visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.vision - || false, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) && !model.id.toLowerCase().includes('deepseek-r1') + || knownModel?.abilities?.functionCall + || false, + id: model.id, + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + vision: + visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.vision + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.SiliconCloud, }); diff --git a/src/libs/agent-runtime/stepfun/index.ts b/src/libs/agent-runtime/stepfun/index.ts index bfe905f94ce4a..bb31cc9a6b7fe 100644 --- a/src/libs/agent-runtime/stepfun/index.ts +++ b/src/libs/agent-runtime/stepfun/index.ts @@ -1,7 +1,7 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface StepfunModelCard { id: string; @@ -20,40 +20,45 @@ export const LobeStepfunAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_STEPFUN_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - // ref: https://platform.stepfun.com/docs/llm/modeloverview - const functionCallKeywords = [ - 'step-1-', - 'step-1o-', - 'step-1v-', - 'step-2-', - ]; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const visionKeywords = [ - 'step-1o-', - 'step-1v-', - ]; + // ref: https://platform.stepfun.com/docs/llm/modeloverview + const functionCallKeywords = [ + 'step-1-', + 'step-1o-', + 'step-1v-', + 'step-2-', + ]; - const model = m as unknown as StepfunModelCard; + const visionKeywords = [ + 'step-1o-', + 'step-1v-', + ]; - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: StepfunModelCard[] = modelsPage.data; - return { - contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.functionCall - || false, - id: model.id, - vision: - visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.vision - || false, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.functionCall + || false, + id: model.id, + vision: + visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.vision + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.Stepfun, }); diff --git a/src/libs/agent-runtime/tencentcloud/index.ts b/src/libs/agent-runtime/tencentcloud/index.ts index 60c3b95a53024..f7301b15bb72a 100644 --- a/src/libs/agent-runtime/tencentcloud/index.ts +++ b/src/libs/agent-runtime/tencentcloud/index.ts @@ -1,7 +1,7 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface TencentCloudModelCard { id: string; @@ -12,35 +12,40 @@ export const LobeTencentCloudAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_TENCENT_CLOUD_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const functionCallKeywords = [ - 'deepseek-v3', - ]; - - const reasoningKeywords = [ - 'deepseek-r1', - ]; - - const model = m as unknown as TencentCloudModelCard; - - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); - - return { - contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.functionCall - || false, - id: model.id, - reasoning: - reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) - || knownModel?.abilities?.reasoning - || false, - }; - }, + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); + + const functionCallKeywords = [ + 'deepseek-v3', + ]; + + const reasoningKeywords = [ + 'deepseek-r1', + ]; + + const modelsPage = await client.models.list() as any; + const modelList: TencentCloudModelCard[] = modelsPage.data; + + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + functionCallKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.functionCall + || false, + id: model.id, + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.TencentCloud, }); diff --git a/src/libs/agent-runtime/xai/index.ts b/src/libs/agent-runtime/xai/index.ts index 7f1a0fa2db497..848466d9b9eb9 100644 --- a/src/libs/agent-runtime/xai/index.ts +++ b/src/libs/agent-runtime/xai/index.ts @@ -1,7 +1,7 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface XAIModelCard { id: string; @@ -12,26 +12,31 @@ export const LobeXAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_XAI_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const model = m as unknown as XAIModelCard; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: XAIModelCard[] = modelsPage.data; - return { - contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - knownModel?.abilities?.functionCall - || false, - id: model.id, - vision: - model.id.toLowerCase().includes('vision') - || knownModel?.abilities?.functionCall - || false, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + knownModel?.abilities?.functionCall + || false, + id: model.id, + vision: + model.id.toLowerCase().includes('vision') + || knownModel?.abilities?.functionCall + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.XAI, }); diff --git a/src/libs/agent-runtime/zeroone/index.ts b/src/libs/agent-runtime/zeroone/index.ts index 48d9d3813a40e..a375a753b3778 100644 --- a/src/libs/agent-runtime/zeroone/index.ts +++ b/src/libs/agent-runtime/zeroone/index.ts @@ -1,7 +1,7 @@ import { ModelProvider } from '../types'; import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory'; -import { LOBE_DEFAULT_MODEL_LIST } from '@/config/aiModels'; +import type { ChatModelCard } from '@/types/llm'; export interface ZeroOneModelCard { id: string; @@ -12,27 +12,32 @@ export const LobeZeroOneAI = LobeOpenAICompatibleFactory({ debug: { chatCompletion: () => process.env.DEBUG_ZEROONE_CHAT_COMPLETION === '1', }, - models: { - transformModel: (m) => { - const model = m as unknown as ZeroOneModelCard; + models: async ({ client }) => { + const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const modelsPage = await client.models.list() as any; + const modelList: ZeroOneModelCard[] = modelsPage.data; - return { - contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, - displayName: knownModel?.displayName ?? undefined, - enabled: knownModel?.enabled || false, - functionCall: - model.id.toLowerCase().includes('fc') - || knownModel?.abilities?.functionCall - || false, - id: model.id, - vision: - model.id.toLowerCase().includes('vision') - || knownModel?.abilities?.vision - || false, - }; - }, + return modelList + .map((model) => { + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + + return { + contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, + displayName: knownModel?.displayName ?? undefined, + enabled: knownModel?.enabled || false, + functionCall: + model.id.toLowerCase().includes('fc') + || knownModel?.abilities?.functionCall + || false, + id: model.id, + vision: + model.id.toLowerCase().includes('vision') + || knownModel?.abilities?.vision + || false, + }; + }) + .filter(Boolean) as ChatModelCard[]; }, provider: ModelProvider.ZeroOne, }); From 93647e442bd9066ea79ccdfdf41f0be1108f63a1 Mon Sep 17 00:00:00 2001 From: Zhijie He Date: Thu, 13 Feb 2025 21:48:19 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=F0=9F=94=A8=20chore:=20add=20vision,=20rea?= =?UTF-8?q?soning,=20fc=20default=20value?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/agent-runtime/ai360/index.ts | 3 +++ src/libs/agent-runtime/anthropic/index.ts | 3 +++ src/libs/agent-runtime/baichuan/index.ts | 6 ++++++ src/libs/agent-runtime/deepseek/index.ts | 3 +++ src/libs/agent-runtime/hunyuan/index.ts | 3 +++ src/libs/agent-runtime/internlm/index.ts | 6 ++++++ src/libs/agent-runtime/mistral/index.ts | 3 +++ src/libs/agent-runtime/moonshot/index.ts | 3 +++ src/libs/agent-runtime/sensenova/index.ts | 8 ++++++++ src/libs/agent-runtime/stepfun/index.ts | 3 +++ src/libs/agent-runtime/tencentcloud/index.ts | 3 +++ src/libs/agent-runtime/xai/index.ts | 3 +++ src/libs/agent-runtime/zeroone/index.ts | 3 +++ 13 files changed, 50 insertions(+) diff --git a/src/libs/agent-runtime/ai360/index.ts b/src/libs/agent-runtime/ai360/index.ts index cc9969b45d0a1..c4c0a62d2daf6 100644 --- a/src/libs/agent-runtime/ai360/index.ts +++ b/src/libs/agent-runtime/ai360/index.ts @@ -54,6 +54,9 @@ export const LobeAi360AI = LobeOpenAICompatibleFactory({ reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) || knownModel?.abilities?.reasoning || false, + vision: + knownModel?.abilities?.vision + || false, }; }) .filter(Boolean) as ChatModelCard[]; diff --git a/src/libs/agent-runtime/anthropic/index.ts b/src/libs/agent-runtime/anthropic/index.ts index 411b6e0bb6d0a..f1e5055426a4c 100644 --- a/src/libs/agent-runtime/anthropic/index.ts +++ b/src/libs/agent-runtime/anthropic/index.ts @@ -140,6 +140,9 @@ export class LobeAnthropicAI implements LobeRuntimeAI { || knownModel?.abilities?.functionCall || false, id: model.id, + reasoning: + knownModel?.abilities?.reasoning + || false, vision: model.id.toLowerCase().includes('claude-3') && !model.id.toLowerCase().includes('claude-3-5-haiku') || knownModel?.abilities?.vision diff --git a/src/libs/agent-runtime/baichuan/index.ts b/src/libs/agent-runtime/baichuan/index.ts index 553b704c5ca99..24682ac335f00 100644 --- a/src/libs/agent-runtime/baichuan/index.ts +++ b/src/libs/agent-runtime/baichuan/index.ts @@ -47,6 +47,12 @@ export const LobeBaichuanAI = LobeOpenAICompatibleFactory({ functionCall: model.function_call, id: model.model, maxTokens: model.max_tokens, + reasoning: + knownModel?.abilities?.reasoning + || false, + vision: + knownModel?.abilities?.vision + || false, }; }) .filter(Boolean) as ChatModelCard[]; diff --git a/src/libs/agent-runtime/deepseek/index.ts b/src/libs/agent-runtime/deepseek/index.ts index 33b0d67e6e516..81d1204f57230 100644 --- a/src/libs/agent-runtime/deepseek/index.ts +++ b/src/libs/agent-runtime/deepseek/index.ts @@ -82,6 +82,9 @@ export const LobeDeepSeekAI = LobeOpenAICompatibleFactory({ model.id.toLowerCase().includes('reasoner') || knownModel?.abilities?.reasoning || false, + vision: + knownModel?.abilities?.vision + || false, }; }) .filter(Boolean) as ChatModelCard[]; diff --git a/src/libs/agent-runtime/hunyuan/index.ts b/src/libs/agent-runtime/hunyuan/index.ts index 208092fd06ca1..1ff816cf6f1d0 100644 --- a/src/libs/agent-runtime/hunyuan/index.ts +++ b/src/libs/agent-runtime/hunyuan/index.ts @@ -37,6 +37,9 @@ export const LobeHunyuanAI = LobeOpenAICompatibleFactory({ || knownModel?.abilities?.functionCall || false, id: model.id, + reasoning: + knownModel?.abilities?.reasoning + || false, vision: model.id.toLowerCase().includes('vision') || knownModel?.abilities?.vision diff --git a/src/libs/agent-runtime/internlm/index.ts b/src/libs/agent-runtime/internlm/index.ts index 6d08f4ef54ac0..058fd1a87b13f 100644 --- a/src/libs/agent-runtime/internlm/index.ts +++ b/src/libs/agent-runtime/internlm/index.ts @@ -38,6 +38,12 @@ export const LobeInternLMAI = LobeOpenAICompatibleFactory({ knownModel?.abilities?.functionCall || false, id: model.id, + reasoning: + knownModel?.abilities?.reasoning + || false, + vision: + knownModel?.abilities?.vision + || false, }; }) .filter(Boolean) as ChatModelCard[]; diff --git a/src/libs/agent-runtime/mistral/index.ts b/src/libs/agent-runtime/mistral/index.ts index 6b9e6c596be41..fefae3183cb28 100644 --- a/src/libs/agent-runtime/mistral/index.ts +++ b/src/libs/agent-runtime/mistral/index.ts @@ -47,6 +47,9 @@ export const LobeMistralAI = LobeOpenAICompatibleFactory({ enabled: knownModel?.enabled || false, functionCall: model.capabilities.function_calling, id: model.id, + reasoning: + knownModel?.abilities?.reasoning + || false, vision: model.capabilities.vision, }; }) diff --git a/src/libs/agent-runtime/moonshot/index.ts b/src/libs/agent-runtime/moonshot/index.ts index e1074e1fee699..9edb203d4aa2b 100644 --- a/src/libs/agent-runtime/moonshot/index.ts +++ b/src/libs/agent-runtime/moonshot/index.ts @@ -42,6 +42,9 @@ export const LobeMoonshotAI = LobeOpenAICompatibleFactory({ knownModel?.abilities?.functionCall || false, id: model.id, + reasoning: + knownModel?.abilities?.reasoning + || false, vision: model.id.toLowerCase().includes('vision') || knownModel?.abilities?.vision diff --git a/src/libs/agent-runtime/sensenova/index.ts b/src/libs/agent-runtime/sensenova/index.ts index 563e50f3ea157..5be6dcd6429e9 100644 --- a/src/libs/agent-runtime/sensenova/index.ts +++ b/src/libs/agent-runtime/sensenova/index.ts @@ -38,6 +38,10 @@ export const LobeSenseNovaAI = LobeOpenAICompatibleFactory({ 'sensechat-5', ]; + const reasoningKeywords = [ + 'deepseek-r1' + ]; + client.baseURL = 'https://api.sensenova.cn/v1/llm'; const modelsPage = await client.models.list() as any; @@ -56,6 +60,10 @@ export const LobeSenseNovaAI = LobeOpenAICompatibleFactory({ || knownModel?.abilities?.functionCall || false, id: model.id, + reasoning: + reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) + || knownModel?.abilities?.reasoning + || false, vision: model.id.toLowerCase().includes('vision') || knownModel?.abilities?.vision diff --git a/src/libs/agent-runtime/stepfun/index.ts b/src/libs/agent-runtime/stepfun/index.ts index bb31cc9a6b7fe..a3e11449ce8f1 100644 --- a/src/libs/agent-runtime/stepfun/index.ts +++ b/src/libs/agent-runtime/stepfun/index.ts @@ -52,6 +52,9 @@ export const LobeStepfunAI = LobeOpenAICompatibleFactory({ || knownModel?.abilities?.functionCall || false, id: model.id, + reasoning: + knownModel?.abilities?.reasoning + || false, vision: visionKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) || knownModel?.abilities?.vision diff --git a/src/libs/agent-runtime/tencentcloud/index.ts b/src/libs/agent-runtime/tencentcloud/index.ts index f7301b15bb72a..c34e3b495d27d 100644 --- a/src/libs/agent-runtime/tencentcloud/index.ts +++ b/src/libs/agent-runtime/tencentcloud/index.ts @@ -43,6 +43,9 @@ export const LobeTencentCloudAI = LobeOpenAICompatibleFactory({ reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)) || knownModel?.abilities?.reasoning || false, + vision: + knownModel?.abilities?.vision + || false, }; }) .filter(Boolean) as ChatModelCard[]; diff --git a/src/libs/agent-runtime/xai/index.ts b/src/libs/agent-runtime/xai/index.ts index 848466d9b9eb9..1246f175d846c 100644 --- a/src/libs/agent-runtime/xai/index.ts +++ b/src/libs/agent-runtime/xai/index.ts @@ -30,6 +30,9 @@ export const LobeXAI = LobeOpenAICompatibleFactory({ knownModel?.abilities?.functionCall || false, id: model.id, + reasoning: + knownModel?.abilities?.reasoning + || false, vision: model.id.toLowerCase().includes('vision') || knownModel?.abilities?.functionCall diff --git a/src/libs/agent-runtime/zeroone/index.ts b/src/libs/agent-runtime/zeroone/index.ts index a375a753b3778..419dc5ecd21e6 100644 --- a/src/libs/agent-runtime/zeroone/index.ts +++ b/src/libs/agent-runtime/zeroone/index.ts @@ -31,6 +31,9 @@ export const LobeZeroOneAI = LobeOpenAICompatibleFactory({ || knownModel?.abilities?.functionCall || false, id: model.id, + reasoning: + knownModel?.abilities?.reasoning + || false, vision: model.id.toLowerCase().includes('vision') || knownModel?.abilities?.vision From d4bb7840b682c22fa4aed8306a0ceefc388a533d Mon Sep 17 00:00:00 2001 From: Zhijie He Date: Thu, 13 Feb 2025 22:25:43 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20improve=20?= =?UTF-8?q?knownModel=20matching?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/agent-runtime/ai360/index.ts | 2 +- src/libs/agent-runtime/anthropic/index.ts | 2 +- src/libs/agent-runtime/baichuan/index.ts | 2 +- src/libs/agent-runtime/cloudflare/index.ts | 2 +- src/libs/agent-runtime/deepseek/index.ts | 2 +- src/libs/agent-runtime/fireworksai/index.ts | 2 +- src/libs/agent-runtime/giteeai/index.ts | 2 +- src/libs/agent-runtime/github/index.test.ts | 49 -------------------- src/libs/agent-runtime/github/index.ts | 2 +- src/libs/agent-runtime/google/index.ts | 2 +- src/libs/agent-runtime/groq/index.ts | 2 +- src/libs/agent-runtime/higress/index.ts | 2 +- src/libs/agent-runtime/huggingface/index.ts | 2 +- src/libs/agent-runtime/hunyuan/index.ts | 2 +- src/libs/agent-runtime/internlm/index.ts | 2 +- src/libs/agent-runtime/lmstudio/index.ts | 2 +- src/libs/agent-runtime/mistral/index.ts | 2 +- src/libs/agent-runtime/moonshot/index.ts | 2 +- src/libs/agent-runtime/novita/index.ts | 2 +- src/libs/agent-runtime/ollama/index.ts | 2 +- src/libs/agent-runtime/openai/index.ts | 2 +- src/libs/agent-runtime/openrouter/index.ts | 2 +- src/libs/agent-runtime/qwen/index.ts | 2 +- src/libs/agent-runtime/sensenova/index.ts | 3 +- src/libs/agent-runtime/siliconcloud/index.ts | 2 +- src/libs/agent-runtime/stepfun/index.ts | 2 +- src/libs/agent-runtime/tencentcloud/index.ts | 2 +- src/libs/agent-runtime/togetherai/index.ts | 2 +- src/libs/agent-runtime/xai/index.ts | 2 +- src/libs/agent-runtime/zeroone/index.ts | 2 +- src/libs/agent-runtime/zhipu/index.ts | 2 +- 31 files changed, 31 insertions(+), 79 deletions(-) diff --git a/src/libs/agent-runtime/ai360/index.ts b/src/libs/agent-runtime/ai360/index.ts index c4c0a62d2daf6..11b345bfbb7e9 100644 --- a/src/libs/agent-runtime/ai360/index.ts +++ b/src/libs/agent-runtime/ai360/index.ts @@ -35,7 +35,7 @@ export const LobeAi360AI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: model.total_tokens, diff --git a/src/libs/agent-runtime/anthropic/index.ts b/src/libs/agent-runtime/anthropic/index.ts index f1e5055426a4c..bdf64de089714 100644 --- a/src/libs/agent-runtime/anthropic/index.ts +++ b/src/libs/agent-runtime/anthropic/index.ts @@ -129,7 +129,7 @@ export class LobeAnthropicAI implements LobeRuntimeAI { return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/baichuan/index.ts b/src/libs/agent-runtime/baichuan/index.ts index 24682ac335f00..cd36499769f4f 100644 --- a/src/libs/agent-runtime/baichuan/index.ts +++ b/src/libs/agent-runtime/baichuan/index.ts @@ -38,7 +38,7 @@ export const LobeBaichuanAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.model === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.model.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: model.max_input_length, diff --git a/src/libs/agent-runtime/cloudflare/index.ts b/src/libs/agent-runtime/cloudflare/index.ts index 729133da31cfa..8ca3a0ff4c64a 100644 --- a/src/libs/agent-runtime/cloudflare/index.ts +++ b/src/libs/agent-runtime/cloudflare/index.ts @@ -128,7 +128,7 @@ export class LobeCloudflareAI implements LobeRuntimeAI { return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.name.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: model.properties?.max_total_tokens diff --git a/src/libs/agent-runtime/deepseek/index.ts b/src/libs/agent-runtime/deepseek/index.ts index 81d1204f57230..a96c35246b2e3 100644 --- a/src/libs/agent-runtime/deepseek/index.ts +++ b/src/libs/agent-runtime/deepseek/index.ts @@ -67,7 +67,7 @@ export const LobeDeepSeekAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/fireworksai/index.ts b/src/libs/agent-runtime/fireworksai/index.ts index 95c7d927d26f3..5aa8c5e7f78cd 100644 --- a/src/libs/agent-runtime/fireworksai/index.ts +++ b/src/libs/agent-runtime/fireworksai/index.ts @@ -28,7 +28,7 @@ export const LobeFireworksAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: model.context_length, diff --git a/src/libs/agent-runtime/giteeai/index.ts b/src/libs/agent-runtime/giteeai/index.ts index cd1a48818b8d7..7f08574a4cf1d 100644 --- a/src/libs/agent-runtime/giteeai/index.ts +++ b/src/libs/agent-runtime/giteeai/index.ts @@ -35,7 +35,7 @@ export const LobeGiteeAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/github/index.test.ts b/src/libs/agent-runtime/github/index.test.ts index b7be7c5d0f8e3..0e1e501245e88 100644 --- a/src/libs/agent-runtime/github/index.test.ts +++ b/src/libs/agent-runtime/github/index.test.ts @@ -210,53 +210,4 @@ describe('LobeGithubAI', () => { }); }); }); - - describe('models', () => { - beforeEach(() => {}); - - it('should return a list of models', async () => { - // Arrange - const arr = [ - { - id: 'azureml://registries/azureml-cohere/models/Cohere-command-r/versions/3', - name: 'Cohere-command-r', - friendly_name: 'Cohere Command R', - model_version: 3, - publisher: 'cohere', - model_family: 'cohere', - model_registry: 'azureml-cohere', - license: 'custom', - task: 'chat-completion', - description: - "Command R is a highly performant generative large language model, optimized for a variety of use cases including reasoning, summarization, and question answering. \n\nThe model is optimized to perform well in the following languages: English, French, Spanish, Italian, German, Brazilian Portuguese, Japanese, Korean, Simplified Chinese, and Arabic.\n\nPre-training data additionally included the following 13 languages: Russian, Polish, Turkish, Vietnamese, Dutch, Czech, Indonesian, Ukrainian, Romanian, Greek, Hindi, Hebrew, Persian.\n\n## Resources\n\nFor full details of this model, [release blog post](https://aka.ms/cohere-blog).\n\n## Model Architecture\n\nThis is an auto-regressive language model that uses an optimized transformer architecture. After pretraining, this model uses supervised fine-tuning (SFT) and preference training to align model behavior to human preferences for helpfulness and safety.\n\n### Tool use capabilities\n\nCommand R has been specifically trained with conversational tool use capabilities. These have been trained into the model via a mixture of supervised fine-tuning and preference fine-tuning, using a specific prompt template. Deviating from this prompt template will likely reduce performance, but we encourage experimentation.\n\nCommand R's tool use functionality takes a conversation as input (with an optional user-system preamble), along with a list of available tools. The model will then generate a json-formatted list of actions to execute on a subset of those tools. Command R may use one of its supplied tools more than once.\n\nThe model has been trained to recognise a special directly_answer tool, which it uses to indicate that it doesn't want to use any of its other tools. The ability to abstain from calling a specific tool can be useful in a range of situations, such as greeting a user, or asking clarifying questions. We recommend including the directly_answer tool, but it can be removed or renamed if required.\n\n### Grounded Generation and RAG Capabilities\n\nCommand R has been specifically trained with grounded generation capabilities. This means that it can generate responses based on a list of supplied document snippets, and it will include grounding spans (citations) in its response indicating the source of the information. This can be used to enable behaviors such as grounded summarization and the final step of Retrieval Augmented Generation (RAG).This behavior has been trained into the model via a mixture of supervised fine-tuning and preference fine-tuning, using a specific prompt template. Deviating from this prompt template may reduce performance, but we encourage experimentation.\n\nCommand R's grounded generation behavior takes a conversation as input (with an optional user-supplied system preamble, indicating task, context and desired output style), along with a list of retrieved document snippets. The document snippets should be chunks, rather than long documents, typically around 100-400 words per chunk. Document snippets consist of key-value pairs. The keys should be short descriptive strings, the values can be text or semi-structured.\n\nBy default, Command R will generate grounded responses by first predicting which documents are relevant, then predicting which ones it will cite, then generating an answer. Finally, it will then insert grounding spans into the answer. See below for an example. This is referred to as accurate grounded generation.\n\nThe model is trained with a number of other answering modes, which can be selected by prompt changes . A fast citation mode is supported in the tokenizer, which will directly generate an answer with grounding spans in it, without first writing the answer out in full. This sacrifices some grounding accuracy in favor of generating fewer tokens.\n\n### Code Capabilities\n\nCommand R has been optimized to interact with your code, by requesting code snippets, code explanations, or code rewrites. It might not perform well out-of-the-box for pure code completion. For better performance, we also recommend using a low temperature (and even greedy decoding) for code-generation related instructions.\n", - summary: - 'Command R is a scalable generative model targeting RAG and Tool Use to enable production-scale AI for enterprise.', - tags: ['rag', 'multilingual'], - }, - ]; - vi.spyOn(instance['client'].models, 'list').mockResolvedValue({ - body: arr, - } as any); - - // Act & Assert - const models = await instance.models(); - - const modelsCount = models.length; - expect(modelsCount).toBe(arr.length); - - for (let i = 0; i < arr.length; i++) { - const model = models[i]; - expect(model).toEqual({ - contextWindowTokens: undefined, - description: arr[i].description, - displayName: arr[i].friendly_name, - enabled: false, - functionCall: true, - id: arr[i].name, - reasoning: false, - vision: false, - }); - } - }); - }); }); diff --git a/src/libs/agent-runtime/github/index.ts b/src/libs/agent-runtime/github/index.ts index 155617b9b244d..ffe147256b35d 100644 --- a/src/libs/agent-runtime/github/index.ts +++ b/src/libs/agent-runtime/github/index.ts @@ -59,7 +59,7 @@ export const LobeGithubAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.name.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/google/index.ts b/src/libs/agent-runtime/google/index.ts index 074f1083ec85d..7dd9d77e898b5 100644 --- a/src/libs/agent-runtime/google/index.ts +++ b/src/libs/agent-runtime/google/index.ts @@ -150,7 +150,7 @@ export class LobeGoogleAI implements LobeRuntimeAI { .map((model) => { const modelName = model.name.replace(/^models\//, ''); - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => modelName === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => modelName.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: model.inputTokenLimit + model.outputTokenLimit, diff --git a/src/libs/agent-runtime/groq/index.ts b/src/libs/agent-runtime/groq/index.ts index ae6bdd91afb56..9e5c918ad0eec 100644 --- a/src/libs/agent-runtime/groq/index.ts +++ b/src/libs/agent-runtime/groq/index.ts @@ -52,7 +52,7 @@ export const LobeGroq = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: model.context_window, diff --git a/src/libs/agent-runtime/higress/index.ts b/src/libs/agent-runtime/higress/index.ts index 75c38b96f9b7a..afaa424de671f 100644 --- a/src/libs/agent-runtime/higress/index.ts +++ b/src/libs/agent-runtime/higress/index.ts @@ -34,7 +34,7 @@ export const LobeHigressAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: model.context_length, diff --git a/src/libs/agent-runtime/huggingface/index.ts b/src/libs/agent-runtime/huggingface/index.ts index 5f54f18b39bc9..ffedc314b58ae 100644 --- a/src/libs/agent-runtime/huggingface/index.ts +++ b/src/libs/agent-runtime/huggingface/index.ts @@ -80,7 +80,7 @@ export const LobeHuggingFaceAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/hunyuan/index.ts b/src/libs/agent-runtime/hunyuan/index.ts index 1ff816cf6f1d0..1abe27d4cc879 100644 --- a/src/libs/agent-runtime/hunyuan/index.ts +++ b/src/libs/agent-runtime/hunyuan/index.ts @@ -26,7 +26,7 @@ export const LobeHunyuanAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/internlm/index.ts b/src/libs/agent-runtime/internlm/index.ts index 058fd1a87b13f..d3e465364b3e0 100644 --- a/src/libs/agent-runtime/internlm/index.ts +++ b/src/libs/agent-runtime/internlm/index.ts @@ -28,7 +28,7 @@ export const LobeInternLMAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/lmstudio/index.ts b/src/libs/agent-runtime/lmstudio/index.ts index fa18948f199fa..5bfd99e9e61c0 100644 --- a/src/libs/agent-runtime/lmstudio/index.ts +++ b/src/libs/agent-runtime/lmstudio/index.ts @@ -21,7 +21,7 @@ export const LobeLMStudioAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/mistral/index.ts b/src/libs/agent-runtime/mistral/index.ts index fefae3183cb28..83b1c9944f4aa 100644 --- a/src/libs/agent-runtime/mistral/index.ts +++ b/src/libs/agent-runtime/mistral/index.ts @@ -38,7 +38,7 @@ export const LobeMistralAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: model.max_context_length, diff --git a/src/libs/agent-runtime/moonshot/index.ts b/src/libs/agent-runtime/moonshot/index.ts index 9edb203d4aa2b..39541392fc851 100644 --- a/src/libs/agent-runtime/moonshot/index.ts +++ b/src/libs/agent-runtime/moonshot/index.ts @@ -32,7 +32,7 @@ export const LobeMoonshotAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/novita/index.ts b/src/libs/agent-runtime/novita/index.ts index c8881bdb791db..56dbadacdeaa6 100644 --- a/src/libs/agent-runtime/novita/index.ts +++ b/src/libs/agent-runtime/novita/index.ts @@ -26,7 +26,7 @@ export const LobeNovitaAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: model.context_size, diff --git a/src/libs/agent-runtime/ollama/index.ts b/src/libs/agent-runtime/ollama/index.ts index 8c92a5c07fea7..7140b99491848 100644 --- a/src/libs/agent-runtime/ollama/index.ts +++ b/src/libs/agent-runtime/ollama/index.ts @@ -116,7 +116,7 @@ export class LobeOllamaAI implements LobeRuntimeAI { return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.name.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/openai/index.ts b/src/libs/agent-runtime/openai/index.ts index 330f5ceeb0c38..dca49b623e2aa 100644 --- a/src/libs/agent-runtime/openai/index.ts +++ b/src/libs/agent-runtime/openai/index.ts @@ -79,7 +79,7 @@ export const LobeOpenAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/openrouter/index.ts b/src/libs/agent-runtime/openrouter/index.ts index 03d381e910b82..eceed1744de00 100644 --- a/src/libs/agent-runtime/openrouter/index.ts +++ b/src/libs/agent-runtime/openrouter/index.ts @@ -46,7 +46,7 @@ export const LobeOpenRouterAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: model.context_length, diff --git a/src/libs/agent-runtime/qwen/index.ts b/src/libs/agent-runtime/qwen/index.ts index cf55d96330495..7b3b950262369 100644 --- a/src/libs/agent-runtime/qwen/index.ts +++ b/src/libs/agent-runtime/qwen/index.ts @@ -96,7 +96,7 @@ export const LobeQwenAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/sensenova/index.ts b/src/libs/agent-runtime/sensenova/index.ts index 5be6dcd6429e9..e24ff58c49d47 100644 --- a/src/libs/agent-runtime/sensenova/index.ts +++ b/src/libs/agent-runtime/sensenova/index.ts @@ -35,6 +35,7 @@ export const LobeSenseNovaAI = LobeOpenAICompatibleFactory({ const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels'); const functionCallKeywords = [ + 'deepseek-v3', 'sensechat-5', ]; @@ -49,7 +50,7 @@ export const LobeSenseNovaAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/siliconcloud/index.ts b/src/libs/agent-runtime/siliconcloud/index.ts index 753d695b3ada0..d72f83510f5d4 100644 --- a/src/libs/agent-runtime/siliconcloud/index.ts +++ b/src/libs/agent-runtime/siliconcloud/index.ts @@ -83,7 +83,7 @@ export const LobeSiliconCloudAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/stepfun/index.ts b/src/libs/agent-runtime/stepfun/index.ts index a3e11449ce8f1..03ed6c9bde8c7 100644 --- a/src/libs/agent-runtime/stepfun/index.ts +++ b/src/libs/agent-runtime/stepfun/index.ts @@ -41,7 +41,7 @@ export const LobeStepfunAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/tencentcloud/index.ts b/src/libs/agent-runtime/tencentcloud/index.ts index c34e3b495d27d..5a21b8f39833b 100644 --- a/src/libs/agent-runtime/tencentcloud/index.ts +++ b/src/libs/agent-runtime/tencentcloud/index.ts @@ -28,7 +28,7 @@ export const LobeTencentCloudAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/togetherai/index.ts b/src/libs/agent-runtime/togetherai/index.ts index bf228168041a5..4a3110721da63 100644 --- a/src/libs/agent-runtime/togetherai/index.ts +++ b/src/libs/agent-runtime/togetherai/index.ts @@ -35,7 +35,7 @@ export const LobeTogetherAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.name === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.name.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/xai/index.ts b/src/libs/agent-runtime/xai/index.ts index 1246f175d846c..066092a678fa6 100644 --- a/src/libs/agent-runtime/xai/index.ts +++ b/src/libs/agent-runtime/xai/index.ts @@ -20,7 +20,7 @@ export const LobeXAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/zeroone/index.ts b/src/libs/agent-runtime/zeroone/index.ts index 419dc5ecd21e6..e58a6ba0dd293 100644 --- a/src/libs/agent-runtime/zeroone/index.ts +++ b/src/libs/agent-runtime/zeroone/index.ts @@ -20,7 +20,7 @@ export const LobeZeroOneAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, diff --git a/src/libs/agent-runtime/zhipu/index.ts b/src/libs/agent-runtime/zhipu/index.ts index 071077debbacb..3e5f5e1c40606 100644 --- a/src/libs/agent-runtime/zhipu/index.ts +++ b/src/libs/agent-runtime/zhipu/index.ts @@ -58,7 +58,7 @@ export const LobeZhipuAI = LobeOpenAICompatibleFactory({ return modelList .map((model) => { - const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.modelCode === m.id); + const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.modelCode.toLowerCase() === m.id.toLowerCase()); return { contextWindowTokens: knownModel?.contextWindowTokens ?? undefined, From fc6458c36f44b31793309e6ed7b28d5edb664c8c Mon Sep 17 00:00:00 2001 From: Zhijie He Date: Thu, 13 Feb 2025 22:35:55 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=F0=9F=90=9B=20fix:=20fix=20ci=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agent-runtime/openrouter/__snapshots__/index.test.ts.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap b/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap index b42b85696a3c4..d0322ee9356d5 100644 --- a/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap +++ b/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap @@ -2129,7 +2129,7 @@ Currently based on [jondurbin/airoboros-l2-70b](https://huggingface.co/jondurbin "description": "A 7.3B parameter model that outperforms Llama 2 13B on all benchmarks, with optimizations for speed and context length.", "displayName": "Mistral: Mistral 7B Instruct v0.1", "enabled": false, - "functionCall": false, + "functionCall": true, "id": "mistralai/mistral-7b-instruct-v0.1", "maxTokens": undefined, "reasoning": false,