@lobehub/chat 1.68.7 → 1.68.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,12 @@ import type { ChatModelCard } from '@/types/llm';
2
2
 
3
3
  import { ModelProvider } from '../types';
4
4
  import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
5
- import { OpenRouterModelCard } from './type';
5
+ import { OpenRouterModelCard, OpenRouterModelExtraInfo } from './type';
6
+
7
+ const formatPrice = (price: string) => {
8
+ if (price === '-1') return undefined;
9
+ return Number((Number(price) * 1e6).toPrecision(5));
10
+ };
6
11
 
7
12
  export const LobeOpenRouterAI = LobeOpenAICompatibleFactory({
8
13
  baseURL: 'https://openrouter.ai/api/v1',
@@ -28,8 +33,6 @@ export const LobeOpenRouterAI = LobeOpenAICompatibleFactory({
28
33
  models: async ({ client }) => {
29
34
  const { LOBE_DEFAULT_MODEL_LIST } = await import('@/config/aiModels');
30
35
 
31
- const visionKeywords = ['qwen/qvq', 'vision'];
32
-
33
36
  const reasoningKeywords = [
34
37
  'deepseek/deepseek-r1',
35
38
  'openai/o1',
@@ -42,11 +45,21 @@ export const LobeOpenRouterAI = LobeOpenAICompatibleFactory({
42
45
  const modelsPage = (await client.models.list()) as any;
43
46
  const modelList: OpenRouterModelCard[] = modelsPage.data;
44
47
 
48
+ const response = await fetch('https://openrouter.ai/api/frontend/models');
49
+ const modelsExtraInfo: OpenRouterModelExtraInfo[] = [];
50
+ if (response.ok) {
51
+ const data = await response.json();
52
+ modelsExtraInfo.push(...data['data']);
53
+ }
54
+
45
55
  return modelList
46
56
  .map((model) => {
47
57
  const knownModel = LOBE_DEFAULT_MODEL_LIST.find(
48
58
  (m) => model.id.toLowerCase() === m.id.toLowerCase(),
49
59
  );
60
+ const extraInfo = modelsExtraInfo.find(
61
+ (m) => m.slug.toLowerCase() === model.id.toLowerCase(),
62
+ );
50
63
 
51
64
  return {
52
65
  contextWindowTokens: model.context_length,
@@ -56,6 +69,7 @@ export const LobeOpenRouterAI = LobeOpenAICompatibleFactory({
56
69
  functionCall:
57
70
  model.description.includes('function calling') ||
58
71
  model.description.includes('tools') ||
72
+ extraInfo?.endpoint?.supports_tool_parameters ||
59
73
  knownModel?.abilities?.functionCall ||
60
74
  false,
61
75
  id: model.id,
@@ -63,16 +77,18 @@ export const LobeOpenRouterAI = LobeOpenAICompatibleFactory({
63
77
  typeof model.top_provider.max_completion_tokens === 'number'
64
78
  ? model.top_provider.max_completion_tokens
65
79
  : undefined,
80
+ pricing: {
81
+ input: formatPrice(model.pricing.prompt),
82
+ output: formatPrice(model.pricing.completion),
83
+ },
66
84
  reasoning:
67
85
  reasoningKeywords.some((keyword) => model.id.toLowerCase().includes(keyword)) ||
86
+ extraInfo?.endpoint?.supports_reasoning ||
68
87
  knownModel?.abilities?.reasoning ||
69
88
  false,
89
+ releasedAt: new Date(model.created * 1000).toISOString().split('T')[0],
70
90
  vision:
71
- model.description.includes('vision') ||
72
- model.description.includes('multimodal') ||
73
- visionKeywords.some((keyword) => model.id.toLowerCase().includes(keyword)) ||
74
- knownModel?.abilities?.vision ||
75
- false,
91
+ model.architecture.modality.includes('image') || knownModel?.abilities?.vision || false,
76
92
  };
77
93
  })
78
94
  .filter(Boolean) as ChatModelCard[];
@@ -19,6 +19,7 @@ interface ModelTopProvider {
19
19
  export interface OpenRouterModelCard {
20
20
  architecture: ModelArchitecture;
21
21
  context_length: number;
22
+ created: number;
22
23
  description: string;
23
24
  id: string;
24
25
  name: string;
@@ -26,3 +27,13 @@ export interface OpenRouterModelCard {
26
27
  pricing: ModelPricing;
27
28
  top_provider: ModelTopProvider;
28
29
  }
30
+
31
+ interface OpenRouterModelEndpoint {
32
+ supports_reasoning?: boolean;
33
+ supports_tool_parameters?: boolean;
34
+ }
35
+
36
+ export interface OpenRouterModelExtraInfo {
37
+ endpoint?: OpenRouterModelEndpoint;
38
+ slug: string;
39
+ }
package/src/types/llm.ts CHANGED
@@ -49,7 +49,7 @@ export interface ChatModelCard {
49
49
  reasoning?: boolean;
50
50
 
51
51
  /**
52
- * whether model is legacy (deprecated but not removed yet)
52
+ * the date when model is released
53
53
  */
54
54
  releasedAt?: string;
55
55