Skip to content

Commit

Permalink
🐛 fix: fix released at for undefined condition (lobehub#5391)
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx authored Jan 10, 2025
1 parent fcccd57 commit 9c5822a
Show file tree
Hide file tree
Showing 23 changed files with 140 additions and 49 deletions.
2 changes: 1 addition & 1 deletion locales/ar/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "معرف فريد لمزود الخدمة، لا يمكن تعديله بعد الإنشاء",
"format": "يمكن أن يحتوي فقط على أحرف صغيرة، وشرطات (-) وشرطات سفلية (_)",
"format": "يمكن أن يحتوي فقط على أرقام، أحرف صغيرة، شرطات (-) وشرطات سفلية (_) ",
"placeholder": "يفضل أن يكون بالكامل بحروف صغيرة، مثل openai، لن يمكن تعديله بعد الإنشاء",
"required": "يرجى إدخال معرف المزود",
"title": "معرف المزود"
Expand Down
2 changes: 1 addition & 1 deletion locales/bg-BG/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "Уникален идентификатор за доставчика на услуги, който не може да бъде променян след създаването му",
"format": "Може да съдържа само малки букви, тирета (-) и долни черти (_)",
"format": "Може да съдържа само цифри, малки букви, тирета (-) и долни черти (_) ",
"placeholder": "Препоръчително изцяло с малки букви, например openai, след създаването не може да се промени",
"required": "Моля, въведете ID на доставчика",
"title": "ID на доставчика"
Expand Down
2 changes: 1 addition & 1 deletion locales/de-DE/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "Eindeutige Kennung des Anbieters, die nach der Erstellung nicht mehr geändert werden kann",
"format": "Darf nur aus Kleinbuchstaben, Bindestrichen (-) und Unterstrichen (_) bestehen",
"format": "Darf nur aus Zahlen, Kleinbuchstaben, Bindestrichen (-) und Unterstrichen (_) bestehen",
"placeholder": "Empfohlen in Kleinbuchstaben, z.B. openai, nach der Erstellung nicht mehr änderbar",
"required": "Bitte geben Sie die Anbieter-ID ein",
"title": "Anbieter-ID"
Expand Down
2 changes: 1 addition & 1 deletion locales/en-US/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "Unique identifier for the service provider, which cannot be modified after creation",
"format": "Can only contain lowercase letters, hyphens (-), and underscores (_) ",
"format": "Can only contain numbers, lowercase letters, hyphens (-), and underscores (_) ",
"placeholder": "Suggested all lowercase, e.g., openai, cannot be modified after creation",
"required": "Please enter the provider ID",
"title": "Provider ID"
Expand Down
2 changes: 1 addition & 1 deletion locales/es-ES/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "Identificador único del proveedor de servicios, no se puede modificar una vez creado",
"format": "Solo puede contener letras minúsculas, guiones (-) y guiones bajos (_)",
"format": "Solo puede contener números, letras minúsculas, guiones (-) y guiones bajos (_) ",
"placeholder": "Se recomienda en minúsculas, por ejemplo openai, no se puede modificar después de crear",
"required": "Por favor, introduce el ID del proveedor",
"title": "ID del proveedor"
Expand Down
2 changes: 1 addition & 1 deletion locales/fa-IR/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "به عنوان شناسه منحصر به فرد ارائه‌دهنده خدمات، پس از ایجاد قابل ویرایش نخواهد بود",
"format": "فقط می‌تواند شامل حروف کوچک، خط تیره (-) و زیرخط (_) باشد",
"format": "فقط می‌تواند شامل اعداد، حروف کوچک، خط تیره (-) و زیرخط (_) باشد",
"placeholder": "توصیه می‌شود تماماً با حروف کوچک باشد، مانند openai، پس از ایجاد قابل ویرایش نخواهد بود",
"required": "لطفاً شناسه ارائه‌دهنده را وارد کنید",
"title": "شناسه ارائه‌دهنده"
Expand Down
2 changes: 1 addition & 1 deletion locales/fr-FR/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "Identifiant unique du fournisseur de services, qui ne peut pas être modifié après sa création",
"format": "Ne peut contenir que des lettres minuscules, des tirets (-) et des underscores (_) ",
"format": "Ne peut contenir que des chiffres, des lettres minuscules, des tirets (-) et des underscores (_) ",
"placeholder": "Utilisez uniquement des lettres minuscules, par exemple openai, non modifiable après création",
"required": "Veuillez entrer l'ID du fournisseur",
"title": "ID du fournisseur"
Expand Down
2 changes: 1 addition & 1 deletion locales/it-IT/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "Identificatore unico del fornitore di servizi, non modificabile dopo la creazione",
"format": "Può contenere solo lettere minuscole, trattini (-) e underscore (_)",
"format": "Può contenere solo numeri, lettere minuscole, trattini (-) e underscore (_) ",
"placeholder": "Si consiglia di utilizzare solo lettere minuscole, ad esempio openai, non modificabile dopo la creazione",
"required": "Inserisci l'ID del fornitore",
"title": "ID del fornitore"
Expand Down
2 changes: 1 addition & 1 deletion locales/ja-JP/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "サービスプロバイダーの一意の識別子であり、作成後は変更できません",
"format": "小文字のアルファベット、ハイフン(-)、およびアンダースコア(_)のみを含むことができます",
"format": "数字、小文字のアルファベット、ハイフン(-)、およびアンダースコア(_)のみを含むことができます",
"placeholder": "小文字で入力してください(例: openai)。作成後は変更できません",
"required": "サービスプロバイダー ID を入力してください",
"title": "サービスプロバイダー ID"
Expand Down
2 changes: 1 addition & 1 deletion locales/ko-KR/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "서비스 제공자의 고유 식별자로, 생성 후에는 수정할 수 없습니다.",
"format": "소문자, 하이픈(-), 및 언더스코어(_)만 포함할 수 있습니다.",
"format": "숫자, 소문자, 하이픈(-), 및 언더스코어(_)만 포함할 수 있습니다.",
"placeholder": "소문자로 입력하세요, 예: openai, 생성 후 수정할 수 없습니다",
"required": "서비스 제공자 ID를 입력하세요",
"title": "서비스 제공자 ID"
Expand Down
2 changes: 1 addition & 1 deletion locales/nl-NL/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "Een unieke identificatie voor de dienstverlener, kan na creatie niet meer worden gewijzigd",
"format": "Mag alleen kleine letters, koppeltekens (-) en underscores (_) bevatten",
"format": "Mag alleen cijfers, kleine letters, koppeltekens (-) en onderstrepingstekens (_) bevatten",
"placeholder": "Gebruik alleen kleine letters, bijvoorbeeld openai, kan niet worden gewijzigd na aanmaak",
"required": "Vul de provider ID in",
"title": "Provider ID"
Expand Down
2 changes: 1 addition & 1 deletion locales/pl-PL/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "Unikalny identyfikator dostawcy usług, po utworzeniu nie można go zmienić",
"format": "Może zawierać tylko małe litery, myślniki (-) i podkreślenia (_)",
"format": "Może zawierać tylko cyfry, małe litery, myślniki (-) i podkreślenia (_) ",
"placeholder": "Zaleca się użycie małych liter, np. openai, po utworzeniu nie można edytować",
"required": "Proszę wpisać identyfikator dostawcy",
"title": "Identyfikator dostawcy"
Expand Down
2 changes: 1 addition & 1 deletion locales/pt-BR/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "Identificador único do provedor de serviços, não pode ser modificado após a criação",
"format": "Pode conter apenas letras minúsculas, hífens (-) e sublinhados (_)",
"format": "Só pode conter números, letras minúsculas, hífens (-) e sublinhados (_) ",
"placeholder": "Sugestão: tudo em minúsculas, por exemplo, openai, não poderá ser modificado após a criação",
"required": "Por favor, insira o ID do provedor",
"title": "ID do Provedor"
Expand Down
2 changes: 1 addition & 1 deletion locales/ru-RU/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "Уникальный идентификатор для поставщика услуг, который нельзя изменить после создания",
"format": "Может содержать только строчные буквы, дефисы (-) и подчеркивания (_)",
"format": "Может содержать только цифры, строчные буквы, дефисы (-) и подчеркивания (_) ",
"placeholder": "Рекомендуется использовать строчные буквы, например, openai, после создания изменить нельзя",
"required": "Пожалуйста, введите ID провайдера",
"title": "ID провайдера"
Expand Down
2 changes: 1 addition & 1 deletion locales/tr-TR/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "Hizmet sağlayıcının benzersiz kimliği, oluşturulduktan sonra değiştirilemez",
"format": "Sadece küçük harfler, tire (-) ve alt çizgi (_) içerebilir",
"format": "Sadece rakamlar, küçük harfler, tire (-) ve alt çizgi (_) içerebilir",
"placeholder": "Küçük harflerle yazılması önerilir, örneğin openai, oluşturduktan sonra değiştirilemez",
"required": "Lütfen hizmet sağlayıcı ID'sini girin",
"title": "Hizmet Sağlayıcı ID"
Expand Down
2 changes: 1 addition & 1 deletion locales/vi-VN/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "Là định danh duy nhất của nhà cung cấp dịch vụ, không thể sửa đổi sau khi tạo",
"format": "Chỉ có thể chứa chữ cái thường, dấu gạch ngang (-) và dấu gạch dưới (_)",
"format": "Chỉ có thể chứa số, chữ cái thường, dấu gạch ngang (-) và dấu gạch dưới (_) ",
"placeholder": "Nên viết toàn bộ bằng chữ thường, ví dụ openai, không thể sửa sau khi tạo",
"required": "Vui lòng nhập ID nhà cung cấp",
"title": "ID nhà cung cấp"
Expand Down
2 changes: 1 addition & 1 deletion locales/zh-CN/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "作为服务商唯一标识,创建后将不可修改",
"format": "只能包含小写字母、连字符(-)和下划线(_)",
"format": "只能包含数字、小写字母、连字符(-)和下划线(_)",
"placeholder": "例如 openai、gemini 等",
"required": "请填写服务商 ID",
"title": "服务商 ID"
Expand Down
2 changes: 1 addition & 1 deletion locales/zh-TW/modelProvider.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
},
"id": {
"desc": "作為服務商唯一標識,創建後將不可修改",
"format": "只能包含小寫字母、連字符(-)和下劃線(_)",
"format": "只能包含數字、小寫字母、連字符(-)和底線(_)",
"placeholder": "建議全小寫,例如 openai,創建後將不可修改",
"required": "請填寫服務商 ID",
"title": "服務商 ID"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const CreateNewProvider = memo<CreateNewProviderProps>(({ onClose, open }) => {
{ message: t('createNewAiProvider.id.required'), required: true },
{
message: t('createNewAiProvider.id.format'),
pattern: /^[_a-z-]+$/,
pattern: /^[\d_a-z-]+$/,
},
],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,19 @@ exports[`LobeOpenAI > models > should get models 1`] = `
},
{
"id": "gpt-3.5-turbo-16k",
"releasedAt": "2023-05-10",
},
{
"id": "gpt-3.5-turbo-16k-0613",
"releasedAt": "2023-05-30",
},
{
"id": "gpt-4-1106-vision-preview",
"releasedAt": "2024-03-26",
},
{
"id": "gpt-3.5-turbo-instruct-0914",
"releasedAt": "2023-09-07",
},
{
"contextWindowTokens": 128000,
Expand Down Expand Up @@ -63,9 +67,11 @@ exports[`LobeOpenAI > models > should get models 1`] = `
},
{
"id": "gpt-3.5-turbo-0301",
"releasedAt": "2023-03-01",
},
{
"id": "gpt-3.5-turbo-0613",
"releasedAt": "2023-06-12",
},
{
"contextWindowTokens": 16385,
Expand Down
117 changes: 94 additions & 23 deletions src/libs/agent-runtime/utils/openaiCompatibleFactory/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// @vitest-environment node
import OpenAI from 'openai';
import type { Stream } from 'openai/streaming';

import { Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

import {
Expand All @@ -11,6 +10,7 @@ import {
LobeOpenAICompatibleRuntime,
ModelProvider,
} from '@/libs/agent-runtime';
import officalOpenAIModels from '@/libs/agent-runtime/openai/fixtures/openai-models.json';
import { sleep } from '@/utils/sleep';

import * as debugStreamModule from '../debugStream';
Expand Down Expand Up @@ -802,26 +802,29 @@ describe('LobeOpenAICompatibleFactory', () => {

it('should use custom stream handler when provided', async () => {
// Create a custom stream handler that handles both ReadableStream and OpenAI Stream
const customStreamHandler = vi.fn((stream: ReadableStream | Stream<OpenAI.ChatCompletionChunk>) => {
const readableStream = stream instanceof ReadableStream ? stream : stream.toReadableStream();
return new ReadableStream({
start(controller) {
const reader = readableStream.getReader();
const process = async () => {
try {
while (true) {
const { done, value } = await reader.read();
if (done) break;
controller.enqueue(value);
const customStreamHandler = vi.fn(
(stream: ReadableStream | Stream<OpenAI.ChatCompletionChunk>) => {
const readableStream =
stream instanceof ReadableStream ? stream : stream.toReadableStream();
return new ReadableStream({
start(controller) {
const reader = readableStream.getReader();
const process = async () => {
try {
while (true) {
const { done, value } = await reader.read();
if (done) break;
controller.enqueue(value);
}
} finally {
controller.close();
}
} finally {
controller.close();
}
};
process();
},
});
});
};
process();
},
});
},
);

const LobeMockProvider = LobeOpenAICompatibleFactory({
baseURL: 'https://api.test.com/v1',
Expand Down Expand Up @@ -897,10 +900,10 @@ describe('LobeOpenAICompatibleFactory', () => {
choices: [
{
index: 0,
message: {
role: 'assistant',
message: {
role: 'assistant',
content: 'Test response',
refusal: null
refusal: null,
},
logprobs: null,
finish_reason: 'stop',
Expand Down Expand Up @@ -969,4 +972,72 @@ describe('LobeOpenAICompatibleFactory', () => {
});
});
});

describe('models', () => {
it('should get models with third party model list', async () => {
vi.spyOn(instance['client'].models, 'list').mockResolvedValue({
data: [
{ id: 'gpt-4o', object: 'model', created: 1698218177 },
{ id: 'claude-3-haiku-20240307', object: 'model' },
{ id: 'gpt-4o-mini', object: 'model', created: 1698318177 * 1000 },
{ id: 'gemini', object: 'model', created: 1736499509125 },
],
} as any);

const list = await instance.models();

expect(list).toEqual([
{
contextWindowTokens: 128000,
releasedAt: '2023-10-25',
description:
'ChatGPT-4o 是一款动态模型,实时更新以保持当前最新版本。它结合了强大的语言理解与生成能力,适合于大规模应用场景,包括客户服务、教育和技术支持。',
displayName: 'GPT-4o',
enabled: true,
functionCall: true,
id: 'gpt-4o',
pricing: {
input: 2.5,
output: 10,
},
vision: true,
},
{
contextWindowTokens: 200000,
description:
'Claude 3 Haiku 是 Anthropic 的最快且最紧凑的模型,旨在实现近乎即时的响应。它具有快速且准确的定向性能。',
displayName: 'Claude 3 Haiku',
functionCall: true,
id: 'claude-3-haiku-20240307',
maxOutput: 4096,
pricing: {
input: 0.25,
output: 1.25,
},
releasedAt: '2024-03-07',
vision: true,
},
{
contextWindowTokens: 128000,
description:
'GPT-4o mini是OpenAI在GPT-4 Omni之后推出的最新模型,支持图文输入并输出文本。作为他们最先进的小型模型,它比其他近期的前沿模型便宜很多,并且比GPT-3.5 Turbo便宜超过60%。它保持了最先进的智能,同时具有显著的性价比。GPT-4o mini在MMLU测试中获得了 82% 的得分,目前在聊天偏好上排名高于 GPT-4。',
displayName: 'GPT-4o mini',
enabled: true,
functionCall: true,
id: 'gpt-4o-mini',
maxOutput: 16385,
pricing: {
input: 0.15,
output: 0.6,
},
releasedAt: '2023-10-26',
vision: true,
},
{
id: 'gemini',
releasedAt: '2025-01-10',
},
]);
});
});
});
26 changes: 20 additions & 6 deletions src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,20 +279,34 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
return models.transformModel(item);
}

const toReleasedAt = () => {
if (!item.created) return;

// guarantee item.created in Date String format
if (
typeof (item.created as any) === 'string' ||
// or in milliseconds
item.created.toFixed(0).length === 13
) {
return dayjs.utc(item.created).format('YYYY-MM-DD');
}

// by default, the created time is in seconds
return dayjs.utc(item.created * 1000).format('YYYY-MM-DD');
};

// TODO: should refactor after remove v1 user/modelList code
const knownModel = LOBE_DEFAULT_MODEL_LIST.find((model) => model.id === item.id);

if (knownModel) {
dayjs.extend(utc);

return {
...knownModel,
releasedAt:
knownModel.releasedAt ?? dayjs.utc(item.created * 1000).format('YYYY-MM-DD'),
};
const releasedAt = knownModel.releasedAt ?? toReleasedAt();

return { ...knownModel, releasedAt };
}

return { id: item.id };
return { id: item.id, releasedAt: toReleasedAt() };
})

.filter(Boolean) as ChatModelCard[];
Expand Down
Loading

0 comments on commit 9c5822a

Please sign in to comment.