Skip to content

Commit

Permalink
♻️ refactor: improve model fetch behavior (#6055)
Browse files Browse the repository at this point in the history
* ♻️ refactor: refactor model fetch behavior

* 🐛 fix: fix gemini thinking model set functionCall tag

* 🐛 fix: fix Spark fc tag missing

* ✨ feat: add model fetch support for Tencent Cloud

* ♻️ refactor: refactor import `LOBE_DEFAULT_MODEL_LIST` with async method - Part 1

* ♻️ refactor: refactor import LOBE_DEFAULT_MODEL_LIST with async method - Part 2

* 🔨 chore: add vision, reasoning, fc default value

* ♻️ refactor: improve knownModel matching

* 🐛 fix: fix ci error
  • Loading branch information
hezhijie0327 authored Feb 14, 2025
1 parent e684f10 commit 4c2aaf6
Show file tree
Hide file tree
Showing 38 changed files with 1,119 additions and 553 deletions.
9 changes: 9 additions & 0 deletions src/config/aiModels/spark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ const sparkChatModels: AIChatModelCard[] = [
type: 'chat',
},
{
abilities: {
functionCall: true,
},
contextWindowTokens: 8192,
description:
'Spark Max 为功能最为全面的版本,支持联网搜索及众多内置插件。其全面优化的核心能力以及系统角色设定和函数调用功能,使其在各种复杂应用场景中的表现极为优异和出色。',
Expand All @@ -42,6 +45,9 @@ const sparkChatModels: AIChatModelCard[] = [
type: 'chat',
},
{
abilities: {
functionCall: true,
},
contextWindowTokens: 32_768,
description:
'Spark Max 32K 配置了大上下文处理能力,更强的上下文理解和逻辑推理能力,支持32K tokens的文本输入,适用于长文档阅读、私有知识问答等场景',
Expand All @@ -52,6 +58,9 @@ const sparkChatModels: AIChatModelCard[] = [
type: 'chat',
},
{
abilities: {
functionCall: true,
},
contextWindowTokens: 8192,
description:
'Spark Ultra 是星火大模型系列中最为强大的版本,在升级联网搜索链路同时,提升对文本内容的理解和总结能力。它是用于提升办公生产力和准确响应需求的全方位解决方案,是引领行业的智能产品。',
Expand Down
58 changes: 37 additions & 21 deletions src/libs/agent-runtime/ai360/index.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -22,28 +22,44 @@ 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',
];

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',
id: model.id,
maxTokens:
typeof model.max_tokens === 'number'
? model.max_tokens
: undefined,
reasoning: reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)),
};
},
const modelsPage = await client.models.list() as any;
const modelList: Ai360ModelCard[] = modelsPage.data;

return modelList
.map((model) => {
const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase());

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,
vision:
knownModel?.abilities?.vision
|| false,
};
})
.filter(Boolean) as ChatModelCard[];
},
provider: ModelProvider.Ai360,
});
22 changes: 17 additions & 5 deletions src/libs/agent-runtime/anthropic/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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: {
Expand All @@ -128,13 +129,24 @@ export class LobeAnthropicAI implements LobeRuntimeAI {

return modelList
.map((model) => {
const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase());

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'),
reasoning:
knownModel?.abilities?.reasoning
|| false,
vision:
model.id.toLowerCase().includes('claude-3') && !model.id.toLowerCase().includes('claude-3-5-haiku')
|| knownModel?.abilities?.vision
|| false,
};
})
.filter(Boolean) as ChatModelCard[];
Expand Down
13 changes: 11 additions & 2 deletions src/libs/agent-runtime/baichuan/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -32,18 +31,28 @@ 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;

return modelList
.map((model) => {
const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.model.toLowerCase() === m.id.toLowerCase());

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,
reasoning:
knownModel?.abilities?.reasoning
|| false,
vision:
knownModel?.abilities?.vision
|| false,
};
})
.filter(Boolean) as ChatModelCard[];
Expand Down
29 changes: 22 additions & 7 deletions src/libs/agent-runtime/cloudflare/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -113,6 +112,8 @@ export class LobeCloudflareAI implements LobeRuntimeAI {
}

async models(): Promise<ChatModelCard[]> {
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: {
Expand All @@ -127,16 +128,30 @@ export class LobeCloudflareAI implements LobeRuntimeAI {

return modelList
.map((model) => {
const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.name.toLowerCase() === m.id.toLowerCase());

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[];
Expand Down
42 changes: 29 additions & 13 deletions src/libs/agent-runtime/deepseek/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -59,19 +59,35 @@ 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');

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'),
id: model.id,
reasoning: model.id.toLowerCase().includes('deepseek-reasoner'),
};
},
const modelsPage = await client.models.list() as any;
const modelList: DeepSeekModelCard[] = modelsPage.data;

return modelList
.map((model) => {
const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase());

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,
vision:
knownModel?.abilities?.vision
|| false,
};
})
.filter(Boolean) as ChatModelCard[];
},
provider: ModelProvider.DeepSeek,
});
48 changes: 30 additions & 18 deletions src/libs/agent-runtime/fireworksai/index.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -15,25 +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',
];

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'),
id: model.id,
reasoning: reasoningKeywords.some(keyword => model.id.toLowerCase().includes(keyword)),
vision: model.supports_image_input,
};
},
const modelsPage = await client.models.list() as any;
const modelList: FireworksAIModelCard[] = modelsPage.data;

return modelList
.map((model) => {
const knownModel = LOBE_DEFAULT_MODEL_LIST.find((m) => model.id.toLowerCase() === m.id.toLowerCase());

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,
});
Loading

0 comments on commit 4c2aaf6

Please sign in to comment.