@lobehub/lobehub 2.0.0-next.46 → 2.0.0-next.48

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.
Files changed (254) hide show
  1. package/.env.example +11 -0
  2. package/CHANGELOG.md +42 -0
  3. package/apps/desktop/src/main/controllers/AuthCtr.ts +27 -2
  4. package/apps/desktop/src/main/core/infrastructure/ProtocolManager.ts +9 -4
  5. package/changelog/v1.json +14 -0
  6. package/docs/development/database-schema.dbml +2 -0
  7. package/docs/self-hosting/environment-variables/basic.mdx +49 -3
  8. package/docs/self-hosting/environment-variables/basic.zh-CN.mdx +49 -4
  9. package/locales/ar/discover.json +45 -0
  10. package/locales/ar/marketAuth.json +42 -0
  11. package/locales/ar/setting.json +94 -1
  12. package/locales/bg-BG/discover.json +45 -0
  13. package/locales/bg-BG/marketAuth.json +42 -0
  14. package/locales/bg-BG/setting.json +94 -1
  15. package/locales/de-DE/discover.json +45 -0
  16. package/locales/de-DE/marketAuth.json +42 -0
  17. package/locales/de-DE/setting.json +94 -1
  18. package/locales/en-US/discover.json +45 -0
  19. package/locales/en-US/marketAuth.json +42 -0
  20. package/locales/en-US/setting.json +94 -1
  21. package/locales/es-ES/discover.json +45 -0
  22. package/locales/es-ES/marketAuth.json +42 -0
  23. package/locales/es-ES/setting.json +94 -1
  24. package/locales/fa-IR/discover.json +45 -0
  25. package/locales/fa-IR/marketAuth.json +42 -0
  26. package/locales/fa-IR/setting.json +94 -1
  27. package/locales/fr-FR/discover.json +45 -0
  28. package/locales/fr-FR/marketAuth.json +42 -0
  29. package/locales/fr-FR/setting.json +94 -1
  30. package/locales/it-IT/discover.json +45 -0
  31. package/locales/it-IT/marketAuth.json +42 -0
  32. package/locales/it-IT/setting.json +94 -1
  33. package/locales/ja-JP/discover.json +45 -0
  34. package/locales/ja-JP/marketAuth.json +42 -0
  35. package/locales/ja-JP/setting.json +94 -1
  36. package/locales/ko-KR/discover.json +45 -0
  37. package/locales/ko-KR/marketAuth.json +42 -0
  38. package/locales/ko-KR/setting.json +94 -1
  39. package/locales/nl-NL/discover.json +45 -0
  40. package/locales/nl-NL/marketAuth.json +42 -0
  41. package/locales/nl-NL/setting.json +94 -1
  42. package/locales/pl-PL/discover.json +45 -0
  43. package/locales/pl-PL/marketAuth.json +42 -0
  44. package/locales/pl-PL/setting.json +94 -1
  45. package/locales/pt-BR/discover.json +45 -0
  46. package/locales/pt-BR/marketAuth.json +42 -0
  47. package/locales/pt-BR/setting.json +94 -1
  48. package/locales/ru-RU/discover.json +45 -0
  49. package/locales/ru-RU/marketAuth.json +42 -0
  50. package/locales/ru-RU/setting.json +94 -1
  51. package/locales/tr-TR/discover.json +45 -0
  52. package/locales/tr-TR/marketAuth.json +42 -0
  53. package/locales/tr-TR/setting.json +94 -1
  54. package/locales/vi-VN/discover.json +45 -0
  55. package/locales/vi-VN/marketAuth.json +42 -0
  56. package/locales/vi-VN/setting.json +94 -1
  57. package/locales/zh-CN/discover.json +45 -0
  58. package/locales/zh-CN/marketAuth.json +42 -0
  59. package/locales/zh-CN/setting.json +94 -1
  60. package/locales/zh-TW/discover.json +45 -0
  61. package/locales/zh-TW/marketAuth.json +42 -0
  62. package/locales/zh-TW/setting.json +94 -1
  63. package/package.json +27 -26
  64. package/packages/const/src/url.ts +1 -0
  65. package/packages/database/migrations/0044_add_tool_intervention.sql +1 -0
  66. package/packages/database/migrations/0044_high_toxin.sql +1 -0
  67. package/packages/database/migrations/0045_add_tool_intervention.sql +1 -0
  68. package/packages/database/migrations/meta/0039_snapshot.json +1 -1
  69. package/packages/database/migrations/meta/0044_snapshot.json +7813 -0
  70. package/packages/database/migrations/meta/0045_snapshot.json +8431 -0
  71. package/packages/database/migrations/meta/_journal.json +14 -0
  72. package/packages/database/src/core/migrations.json +36 -7
  73. package/packages/database/src/models/file.ts +15 -1
  74. package/packages/database/src/models/message.ts +1 -1
  75. package/packages/database/src/models/session.ts +42 -1
  76. package/packages/database/src/repositories/aiInfra/index.test.ts +1 -1
  77. package/packages/database/src/repositories/dataExporter/index.test.ts +1 -1
  78. package/packages/database/src/repositories/tableViewer/index.test.ts +1 -1
  79. package/packages/database/src/schemas/agent.ts +1 -0
  80. package/packages/database/src/schemas/message.ts +5 -8
  81. package/packages/electron-client-ipc/src/events/index.ts +6 -1
  82. package/packages/electron-client-ipc/src/events/remoteServer.ts +8 -0
  83. package/packages/fetch-sse/package.json +29 -0
  84. package/packages/{utils/src/fetch → fetch-sse/src}/__tests__/fetchSSE.test.ts +4 -4
  85. package/packages/{utils/src/fetch → fetch-sse/src}/__tests__/parseError.test.ts +7 -4
  86. package/packages/{utils/src/fetch → fetch-sse/src}/fetchSSE.ts +2 -2
  87. package/packages/{utils/src/fetch → fetch-sse/src}/parseError.ts +3 -3
  88. package/packages/model-bank/src/aiModels/mistral.ts +2 -1
  89. package/packages/model-runtime/src/core/contextBuilders/anthropic.test.ts +17 -11
  90. package/packages/model-runtime/src/core/contextBuilders/anthropic.ts +1 -1
  91. package/packages/model-runtime/src/core/contextBuilders/google.test.ts +1 -1
  92. package/packages/model-runtime/src/core/contextBuilders/google.ts +3 -6
  93. package/packages/model-runtime/src/core/contextBuilders/openai.test.ts +4 -2
  94. package/packages/model-runtime/src/core/contextBuilders/openai.ts +1 -1
  95. package/packages/model-runtime/src/core/openaiCompatibleFactory/createImage.test.ts +1 -1
  96. package/packages/model-runtime/src/core/openaiCompatibleFactory/createImage.ts +1 -1
  97. package/packages/model-runtime/src/core/openaiCompatibleFactory/index.test.ts +3 -6
  98. package/packages/model-runtime/src/core/streams/openai/responsesStream.test.ts +1 -1
  99. package/packages/model-runtime/src/helpers/mergeChatMethodOptions.ts +2 -1
  100. package/packages/model-runtime/src/providers/aihubmix/index.test.ts +1 -1
  101. package/packages/model-runtime/src/providers/anthropic/generateObject.test.ts +1 -1
  102. package/packages/model-runtime/src/providers/anthropic/index.test.ts +1 -1
  103. package/packages/model-runtime/src/providers/baichuan/index.test.ts +1 -1
  104. package/packages/model-runtime/src/providers/bedrock/index.test.ts +1 -1
  105. package/packages/model-runtime/src/providers/bfl/createImage.test.ts +4 -4
  106. package/packages/model-runtime/src/providers/bfl/createImage.ts +1 -1
  107. package/packages/model-runtime/src/providers/cloudflare/index.test.ts +1 -1
  108. package/packages/model-runtime/src/providers/cohere/index.test.ts +1 -1
  109. package/packages/model-runtime/src/providers/google/createImage.test.ts +2 -2
  110. package/packages/model-runtime/src/providers/google/createImage.ts +1 -1
  111. package/packages/model-runtime/src/providers/google/generateObject.test.ts +1 -1
  112. package/packages/model-runtime/src/providers/google/index.test.ts +1 -4
  113. package/packages/model-runtime/src/providers/groq/index.test.ts +1 -1
  114. package/packages/model-runtime/src/providers/hunyuan/index.test.ts +1 -1
  115. package/packages/model-runtime/src/providers/minimax/createImage.test.ts +1 -1
  116. package/packages/model-runtime/src/providers/mistral/index.test.ts +1 -1
  117. package/packages/model-runtime/src/providers/moonshot/index.test.ts +1 -1
  118. package/packages/model-runtime/src/providers/novita/index.test.ts +1 -1
  119. package/packages/model-runtime/src/providers/ollama/index.test.ts +43 -32
  120. package/packages/model-runtime/src/providers/ollama/index.ts +31 -7
  121. package/packages/model-runtime/src/providers/openrouter/index.test.ts +1 -1
  122. package/packages/model-runtime/src/providers/perplexity/index.test.ts +1 -1
  123. package/packages/model-runtime/src/providers/ppio/index.test.ts +1 -1
  124. package/packages/model-runtime/src/providers/qwen/createImage.test.ts +1 -1
  125. package/packages/model-runtime/src/providers/search1api/index.test.ts +1 -1
  126. package/packages/model-runtime/src/providers/siliconcloud/createImage.ts +1 -1
  127. package/packages/model-runtime/src/providers/taichu/index.test.ts +1 -1
  128. package/packages/model-runtime/src/providers/wenxin/index.test.ts +1 -1
  129. package/packages/model-runtime/src/providers/zhipu/index.test.ts +1 -1
  130. package/packages/model-runtime/src/utils/errorResponse.test.ts +1 -1
  131. package/packages/ssrf-safe-fetch/index.browser.ts +14 -0
  132. package/packages/ssrf-safe-fetch/package.json +8 -1
  133. package/packages/types/src/aiProvider.ts +1 -1
  134. package/packages/types/src/discover/assistants.ts +16 -0
  135. package/packages/types/src/document/index.ts +38 -38
  136. package/packages/types/src/exportConfig.ts +15 -15
  137. package/packages/types/src/generation/index.ts +5 -5
  138. package/packages/types/src/index.ts +1 -0
  139. package/packages/types/src/message/common/tools.ts +10 -0
  140. package/packages/types/src/message/db/item.ts +15 -1
  141. package/packages/types/src/message/ui/params.ts +15 -1
  142. package/packages/types/src/meta.ts +4 -0
  143. package/packages/types/src/openai/chat.ts +15 -15
  144. package/packages/types/src/plugins/mcp.ts +29 -29
  145. package/packages/types/src/plugins/protocol.ts +43 -43
  146. package/packages/types/src/search.ts +4 -4
  147. package/packages/types/src/session/agentSession.ts +2 -0
  148. package/packages/types/src/tool/plugin.ts +3 -3
  149. package/packages/utils/src/imageToBase64.ts +17 -10
  150. package/packages/utils/src/index.ts +1 -1
  151. package/src/app/(backend)/f/[id]/route.ts +55 -0
  152. package/src/app/(backend)/market/agent/[[...segments]]/route.ts +153 -0
  153. package/src/app/(backend)/market/oidc/[[...segments]]/route.ts +207 -0
  154. package/src/app/[variants]/(main)/(mobile)/me/settings/features/useCategory.tsx +1 -0
  155. package/src/app/[variants]/(main)/_layout/Desktop/SideBar/PinList/index.tsx +4 -2
  156. package/src/app/[variants]/(main)/chat/settings/features/AgentInfoDescription/index.tsx +349 -0
  157. package/src/app/[variants]/(main)/chat/settings/features/HeaderContent.tsx +2 -2
  158. package/src/app/[variants]/(main)/chat/settings/features/PublishResultModal/index.tsx +64 -0
  159. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/MarketPublishButton.tsx +196 -0
  160. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/MarketPublishModal.tsx +358 -0
  161. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/index.tsx +75 -0
  162. package/src/app/[variants]/(main)/discover/(detail)/assistant/AssistantDetailPage.tsx +11 -2
  163. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/Client.tsx +12 -1
  164. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Nav.tsx +19 -12
  165. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Overview/TagList.tsx +14 -5
  166. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Overview/index.tsx +2 -0
  167. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Related/index.tsx +14 -5
  168. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/SystemRole/TagList.tsx +14 -5
  169. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/SystemRole/index.tsx +43 -29
  170. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Versions/index.tsx +137 -0
  171. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/index.tsx +2 -0
  172. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Header.tsx +9 -10
  173. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Sidebar/ActionButton/AddAgent.tsx +105 -14
  174. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Sidebar/Related/index.tsx +20 -6
  175. package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/StatusPage/index.tsx +113 -0
  176. package/src/app/[variants]/(main)/discover/(detail)/features/Breadcrumb.tsx +4 -3
  177. package/src/app/[variants]/(main)/discover/(list)/_layout/Desktop/Nav.tsx +3 -1
  178. package/src/app/[variants]/(main)/discover/(list)/assistant/AssistantPage.tsx +4 -1
  179. package/src/app/[variants]/(main)/discover/(list)/assistant/Client.tsx +6 -2
  180. package/src/app/[variants]/(main)/discover/(list)/assistant/features/Category/index.tsx +7 -3
  181. package/src/app/[variants]/(main)/discover/(list)/assistant/features/List/Item.tsx +13 -2
  182. package/src/app/[variants]/(main)/discover/(list)/assistant/features/MarketSourceSwitch.tsx +64 -0
  183. package/src/app/[variants]/(main)/discover/(list)/features/SortButton/index.tsx +26 -7
  184. package/src/app/[variants]/(main)/profile/_layout/Desktop/index.tsx +10 -10
  185. package/src/app/[variants]/(main)/settings/_layout/type.ts +1 -1
  186. package/src/app/[variants]/(main)/settings/agent/index.tsx +11 -10
  187. package/src/app/[variants]/(main)/settings/common/index.tsx +1 -1
  188. package/src/app/[variants]/(main)/settings/page.tsx +13 -10
  189. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/Item.tsx +35 -36
  190. package/src/app/[variants]/(main)/settings/provider/ProviderMenu/SearchResult.tsx +5 -5
  191. package/src/app/[variants]/(main)/settings/provider/_layout/Desktop/Container.tsx +10 -4
  192. package/src/app/market-auth-callback/layout.tsx +15 -0
  193. package/src/app/market-auth-callback/page.tsx +196 -0
  194. package/src/envs/app.ts +4 -3
  195. package/src/features/AgentSetting/AgentPrompt/TokenTag.tsx +3 -2
  196. package/src/features/AgentSetting/AgentTTS/SelectWithTTSPreview.tsx +1 -1
  197. package/src/features/AgentSetting/store/action.ts +1 -1
  198. package/src/features/ChatInput/ActionBar/STT/browser.tsx +1 -1
  199. package/src/features/ChatInput/ActionBar/STT/openai.tsx +1 -1
  200. package/src/features/Conversation/components/Extras/TTS/InitPlayer.tsx +1 -1
  201. package/src/features/Conversation/components/VirtualizedList/index.tsx +2 -1
  202. package/src/features/PluginTag/PluginStatus.tsx +1 -1
  203. package/src/features/PluginsUI/Render/MCPType/index.tsx +26 -6
  204. package/src/hooks/useAgentOwnershipCheck.ts +143 -0
  205. package/src/instrumentation.node.ts +3 -2
  206. package/src/layout/AuthProvider/MarketAuth/MarketAuthProvider.tsx +364 -0
  207. package/src/layout/AuthProvider/MarketAuth/errors.ts +75 -0
  208. package/src/layout/AuthProvider/MarketAuth/index.ts +2 -0
  209. package/src/layout/AuthProvider/MarketAuth/oidc.ts +382 -0
  210. package/src/layout/AuthProvider/MarketAuth/types.ts +64 -0
  211. package/src/layout/AuthProvider/index.tsx +17 -4
  212. package/src/locales/default/discover.ts +46 -0
  213. package/src/locales/default/index.ts +2 -0
  214. package/src/locales/default/marketAuth.ts +42 -0
  215. package/src/locales/default/setting.ts +94 -1
  216. package/src/server/globalConfig/genServerAiProviderConfig.test.ts +5 -5
  217. package/src/server/globalConfig/genServerAiProviderConfig.ts +1 -1
  218. package/src/server/routers/desktop/mcp.ts +23 -8
  219. package/src/server/routers/lambda/market/index.ts +36 -14
  220. package/src/server/routers/lambda/message.ts +2 -2
  221. package/src/server/routers/tools/mcp.ts +24 -4
  222. package/src/server/services/discover/index.test.ts +153 -11
  223. package/src/server/services/discover/index.ts +339 -40
  224. package/src/server/services/file/impls/local.ts +4 -1
  225. package/src/server/services/file/index.ts +96 -1
  226. package/src/server/services/mcp/contentProcessor.ts +101 -0
  227. package/src/server/services/mcp/index.test.ts +52 -10
  228. package/src/server/services/mcp/index.ts +29 -26
  229. package/src/server/sitemap.ts +49 -35
  230. package/src/services/_url.ts +15 -1
  231. package/src/services/chat/chat.test.ts +5 -5
  232. package/src/services/chat/clientModelRuntime.test.ts +1 -1
  233. package/src/services/chat/index.ts +6 -6
  234. package/src/services/chat/types.ts +1 -2
  235. package/src/services/discover.ts +16 -5
  236. package/src/services/electron/remoteServer.ts +8 -1
  237. package/src/services/marketApi.ts +124 -0
  238. package/src/services/models.ts +2 -1
  239. package/src/services/session/index.ts +0 -14
  240. package/src/store/discover/slices/assistant/action.ts +20 -7
  241. package/{packages/utils/src → src/utils}/electron/desktopRemoteRPCFetch.ts +1 -1
  242. package/{packages/utils/src → src/utils/server}/parseModels.ts +1 -2
  243. package/src/utils/server/routeVariants.test.ts +340 -0
  244. package/vitest.config.mts +2 -0
  245. package/packages/model-runtime/src/utils/imageToBase64.test.ts +0 -91
  246. package/packages/model-runtime/src/utils/imageToBase64.ts +0 -62
  247. package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx +0 -98
  248. package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/index.tsx +0 -35
  249. package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/style.ts +0 -47
  250. /package/packages/{utils/src/fetch → fetch-sse/src}/headers.ts +0 -0
  251. /package/packages/{utils/src/fetch → fetch-sse/src}/index.ts +0 -0
  252. /package/packages/{utils/src/fetch → fetch-sse/src}/request.ts +0 -0
  253. /package/{packages/utils/src → src/utils/server}/__snapshots__/parseModels.test.ts.snap +0 -0
  254. /package/{packages/utils/src → src/utils/server}/parseModels.test.ts +0 -0
@@ -1,6 +1,6 @@
1
- import { AgentRuntimeErrorType } from '@lobechat/model-runtime';
2
1
  import { describe, expect, it, vi } from 'vitest';
3
2
 
3
+ import { AgentRuntimeErrorType } from '../../../types/error';
4
4
  import { FIRST_CHUNK_ERROR_KEY } from '../protocol';
5
5
  import { createReadableStream, readStreamChunk } from '../utils';
6
6
  import { OpenAIResponsesStream } from './responsesStream';
@@ -1,6 +1,7 @@
1
- import { ChatMethodOptions } from '@lobechat/model-runtime';
2
1
  import debug from 'debug';
3
2
 
3
+ import { ChatMethodOptions } from '../types/chat';
4
+
4
5
  const log = debug('model-runtime:helpers:mergeChatMethodOptions');
5
6
 
6
7
  export const mergeMultipleChatMethodOptions = (options: ChatMethodOptions[]): ChatMethodOptions => {
@@ -1,4 +1,4 @@
1
- // @vitest-environment edge-runtime
1
+ // @vitest-environment node
2
2
  import { ModelProvider } from 'model-bank';
3
3
  import { beforeEach, describe, expect, it, vi } from 'vitest';
4
4
 
@@ -1,4 +1,4 @@
1
- // @vitest-environment edge-runtime
1
+ // @vitest-environment node
2
2
  import { describe, expect, it, vi } from 'vitest';
3
3
 
4
4
  import { createAnthropicGenerateObject } from './generateObject';
@@ -1,8 +1,8 @@
1
1
  // @vitest-environment node
2
- import { ChatCompletionTool, ChatStreamPayload } from '@lobechat/model-runtime';
3
2
  import { Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
4
3
 
5
4
  import * as anthropicHelpers from '../../core/contextBuilders/anthropic';
5
+ import { ChatCompletionTool, ChatStreamPayload } from '../../types/chat';
6
6
  import * as debugStreamModule from '../../utils/debugStream';
7
7
  import { LobeAnthropicAI } from './index';
8
8
 
@@ -1,8 +1,8 @@
1
1
  // @vitest-environment node
2
- import { LobeOpenAICompatibleRuntime } from '@lobechat/model-runtime';
3
2
  import { ModelProvider } from 'model-bank';
4
3
  import { Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
5
4
 
5
+ import { LobeOpenAICompatibleRuntime } from '../../core/BaseAI';
6
6
  import { testProvider } from '../../providerTestUtils';
7
7
  import { LobeBaichuanAI, params } from './index';
8
8
 
@@ -3,10 +3,10 @@ import {
3
3
  InvokeModelCommand,
4
4
  InvokeModelWithResponseStreamCommand,
5
5
  } from '@aws-sdk/client-bedrock-runtime';
6
- import { AgentRuntimeErrorType } from '@lobechat/model-runtime';
7
6
  import { ModelProvider } from 'model-bank';
8
7
  import { Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
9
8
 
9
+ import { AgentRuntimeErrorType } from '../../types/error';
10
10
  import * as debugStreamModule from '../../utils/debugStream';
11
11
  import { LobeBedrockAI, experimental_buildLlama2Prompt } from './index';
12
12
 
@@ -6,7 +6,7 @@ import { createBflImage } from './createImage';
6
6
  import { BflStatusResponse } from './types';
7
7
 
8
8
  // Mock external dependencies
9
- vi.mock('../../utils/imageToBase64', () => ({
9
+ vi.mock('@lobechat/utils', () => ({
10
10
  imageUrlToBase64: vi.fn(),
11
11
  }));
12
12
 
@@ -187,7 +187,7 @@ describe('createBflImage', () => {
187
187
  it('should convert single imageUrl to image_prompt base64', async () => {
188
188
  // Arrange
189
189
  const { parseDataUri } = await import('../../utils/uriParser');
190
- const { imageUrlToBase64 } = await import('../../utils/imageToBase64');
190
+ const { imageUrlToBase64 } = await import('@lobechat/utils');
191
191
  const { asyncifyPolling } = await import('../../utils/asyncifyPolling');
192
192
 
193
193
  const mockParseDataUri = vi.mocked(parseDataUri);
@@ -290,7 +290,7 @@ describe('createBflImage', () => {
290
290
  it('should convert multiple imageUrls for Kontext models', async () => {
291
291
  // Arrange
292
292
  const { parseDataUri } = await import('../../utils/uriParser');
293
- const { imageUrlToBase64 } = await import('../../utils/imageToBase64');
293
+ const { imageUrlToBase64 } = await import('@lobechat/utils');
294
294
  const { asyncifyPolling } = await import('../../utils/asyncifyPolling');
295
295
 
296
296
  const mockParseDataUri = vi.mocked(parseDataUri);
@@ -350,7 +350,7 @@ describe('createBflImage', () => {
350
350
  it('should limit imageUrls to maximum 4 images', async () => {
351
351
  // Arrange
352
352
  const { parseDataUri } = await import('../../utils/uriParser');
353
- const { imageUrlToBase64 } = await import('../../utils/imageToBase64');
353
+ const { imageUrlToBase64 } = await import('@lobechat/utils');
354
354
  const { asyncifyPolling } = await import('../../utils/asyncifyPolling');
355
355
 
356
356
  const mockParseDataUri = vi.mocked(parseDataUri);
@@ -1,3 +1,4 @@
1
+ import { imageUrlToBase64 } from '@lobechat/utils';
1
2
  import createDebug from 'debug';
2
3
  import { RuntimeImageGenParamsValue } from 'model-bank';
3
4
 
@@ -5,7 +6,6 @@ import { AgentRuntimeErrorType } from '../../types/error';
5
6
  import { CreateImagePayload, CreateImageResponse } from '../../types/image';
6
7
  import { type TaskResult, asyncifyPolling } from '../../utils/asyncifyPolling';
7
8
  import { AgentRuntimeError } from '../../utils/createError';
8
- import { imageUrlToBase64 } from '../../utils/imageToBase64';
9
9
  import { parseDataUri } from '../../utils/uriParser';
10
10
  import {
11
11
  BFL_ENDPOINTS,
@@ -1,7 +1,7 @@
1
1
  // @vitest-environment node
2
- import { ChatCompletionTool } from '@lobechat/model-runtime';
3
2
  import { Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
4
3
 
4
+ import { ChatCompletionTool } from '../../types/chat';
5
5
  import * as debugStreamModule from '../../utils/debugStream';
6
6
  import { LobeCloudflareAI } from './index';
7
7
 
@@ -1,8 +1,8 @@
1
1
  // @vitest-environment node
2
- import { LobeOpenAICompatibleRuntime } from '@lobechat/model-runtime';
3
2
  import { ModelProvider } from 'model-bank';
4
3
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
5
4
 
5
+ import { LobeOpenAICompatibleRuntime } from '../../core/BaseAI';
6
6
  import { testProvider } from '../../providerTestUtils';
7
7
  import { LobeCohereAI, params } from './index';
8
8
 
@@ -1,9 +1,9 @@
1
- // @vitest-environment edge-runtime
1
+ // @vitest-environment node
2
2
  import { GoogleGenAI } from '@google/genai';
3
+ import * as imageToBase64Module from '@lobechat/utils';
3
4
  import { beforeEach, describe, expect, it, vi } from 'vitest';
4
5
 
5
6
  import { CreateImagePayload } from '../../types/image';
6
- import * as imageToBase64Module from '../../utils/imageToBase64';
7
7
  import { createGoogleImage } from './createImage';
8
8
 
9
9
  const provider = 'google';
@@ -1,11 +1,11 @@
1
1
  import { Content, GenerateContentConfig, GoogleGenAI, Part } from '@google/genai';
2
+ import { imageUrlToBase64 } from '@lobechat/utils';
2
3
 
3
4
  import { convertGoogleAIUsage } from '../../core/usageConverters/google-ai';
4
5
  import { CreateImagePayload, CreateImageResponse } from '../../types/image';
5
6
  import { AgentRuntimeError } from '../../utils/createError';
6
7
  import { getModelPricing } from '../../utils/getModelPricing';
7
8
  import { parseGoogleErrorMessage } from '../../utils/googleErrorParser';
8
- import { imageUrlToBase64 } from '../../utils/imageToBase64';
9
9
  import { parseDataUri } from '../../utils/uriParser';
10
10
 
11
11
  // Maximum number of images allowed for processing
@@ -1,4 +1,4 @@
1
- // @vitest-environment edge-runtime
1
+ // @vitest-environment node
2
2
  import { Type as SchemaType } from '@google/genai';
3
3
  import { describe, expect, it, vi } from 'vitest';
4
4
 
@@ -1,14 +1,11 @@
1
- // @vitest-environment edge-runtime
1
+ // @vitest-environment node
2
2
  import { GenerateContentResponse, Tool } from '@google/genai';
3
- import { OpenAIChatMessage } from '@lobechat/model-runtime';
4
- import { ChatStreamPayload } from '@lobechat/types';
5
3
  import OpenAI from 'openai';
6
4
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
7
5
 
8
6
  import { LOBE_ERROR_KEY } from '../../core/streams';
9
7
  import { AgentRuntimeErrorType } from '../../types/error';
10
8
  import * as debugStreamModule from '../../utils/debugStream';
11
- import * as imageToBase64Module from '../../utils/imageToBase64';
12
9
  import { LobeGoogleAI, resolveModelThinkingBudget } from './index';
13
10
 
14
11
  const provider = 'google';
@@ -1,7 +1,7 @@
1
1
  // @vitest-environment node
2
- import { LobeOpenAICompatibleRuntime } from '@lobechat/model-runtime';
3
2
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
4
3
 
4
+ import { LobeOpenAICompatibleRuntime } from '../../core/BaseAI';
5
5
  import { testProvider } from '../../providerTestUtils';
6
6
  import { AgentRuntimeErrorType } from '../../types/error';
7
7
  import { LobeGroq, params } from './index';
@@ -1,8 +1,8 @@
1
1
  // @vitest-environment node
2
- import { LobeOpenAICompatibleRuntime } from '@lobechat/model-runtime';
3
2
  import { ModelProvider } from 'model-bank';
4
3
  import { beforeEach, describe, expect, it, vi } from 'vitest';
5
4
 
5
+ import { LobeOpenAICompatibleRuntime } from '../../core/BaseAI';
6
6
  import { testProvider } from '../../providerTestUtils';
7
7
  import { LobeHunyuanAI, params } from './index';
8
8
 
@@ -1,4 +1,4 @@
1
- // @vitest-environment edge-runtime
1
+ // @vitest-environment node
2
2
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
3
 
4
4
  import { CreateImageOptions } from '../../core/openaiCompatibleFactory';
@@ -1,7 +1,7 @@
1
1
  // @vitest-environment node
2
- import { LobeOpenAICompatibleRuntime } from '@lobechat/model-runtime';
3
2
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
4
3
 
4
+ import { LobeOpenAICompatibleRuntime } from '../../core/BaseAI';
5
5
  import { testProvider } from '../../providerTestUtils';
6
6
  import { LobeMistralAI, params } from './index';
7
7
 
@@ -1,7 +1,7 @@
1
1
  // @vitest-environment node
2
- import { LobeOpenAICompatibleRuntime } from '@lobechat/model-runtime';
3
2
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
4
3
 
4
+ import { LobeOpenAICompatibleRuntime } from '../../core/BaseAI';
5
5
  import { testProvider } from '../../providerTestUtils';
6
6
  import { LobeMoonshotAI, params } from './index';
7
7
 
@@ -1,8 +1,8 @@
1
1
  // @vitest-environment node
2
- import { LobeOpenAICompatibleRuntime } from '@lobechat/model-runtime';
3
2
  import { ModelProvider } from 'model-bank';
4
3
  import { Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
5
4
 
5
+ import { LobeOpenAICompatibleRuntime } from '../../core/BaseAI';
6
6
  import { testProvider } from '../../providerTestUtils';
7
7
  import models from './fixtures/models.json';
8
8
  import { LobeNovitaAI } from './index';
@@ -1,4 +1,5 @@
1
1
  // @vitest-environment node
2
+ import { imageUrlToBase64 } from '@lobechat/utils';
2
3
  import { ModelProvider } from 'model-bank';
3
4
  import { Ollama } from 'ollama/browser';
4
5
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
@@ -9,6 +10,13 @@ import * as debugStreamModule from '../../utils/debugStream';
9
10
  import { LobeOllamaAI, params } from './index';
10
11
 
11
12
  vi.mock('ollama/browser');
13
+ vi.mock('@lobechat/utils', async () => {
14
+ const actual = await vi.importActual('@lobechat/utils');
15
+ return {
16
+ ...actual,
17
+ imageUrlToBase64: vi.fn(),
18
+ };
19
+ });
12
20
 
13
21
  // Mock the console.error to avoid polluting test output
14
22
  vi.spyOn(console, 'error').mockImplementation(() => {});
@@ -462,13 +470,13 @@ describe('LobeOllamaAI', () => {
462
470
  });
463
471
 
464
472
  describe('buildOllamaMessages', () => {
465
- it('should convert OpenAIChatMessage array to OllamaMessage array', () => {
473
+ it('should convert OpenAIChatMessage array to OllamaMessage array', async () => {
466
474
  const messages = [
467
475
  { content: 'Hello', role: 'user' },
468
476
  { content: 'Hi there!', role: 'assistant' },
469
477
  ];
470
478
 
471
- const ollamaMessages = ollamaAI['buildOllamaMessages'](messages as any);
479
+ const ollamaMessages = await ollamaAI['buildOllamaMessages'](messages as any);
472
480
 
473
481
  expect(ollamaMessages).toEqual([
474
482
  { content: 'Hello', role: 'user' },
@@ -476,15 +484,15 @@ describe('LobeOllamaAI', () => {
476
484
  ]);
477
485
  });
478
486
 
479
- it('should handle empty message array', () => {
487
+ it('should handle empty message array', async () => {
480
488
  const messages: any[] = [];
481
489
 
482
- const ollamaMessages = ollamaAI['buildOllamaMessages'](messages);
490
+ const ollamaMessages = await ollamaAI['buildOllamaMessages'](messages);
483
491
 
484
492
  expect(ollamaMessages).toEqual([]);
485
493
  });
486
494
 
487
- it('should handle multiple messages with different roles', () => {
495
+ it('should handle multiple messages with different roles', async () => {
488
496
  const messages = [
489
497
  { content: 'Hello', role: 'system' },
490
498
  { content: 'Hi', role: 'user' },
@@ -492,7 +500,7 @@ describe('LobeOllamaAI', () => {
492
500
  { content: 'How are you?', role: 'user' },
493
501
  ];
494
502
 
495
- const ollamaMessages = ollamaAI['buildOllamaMessages'](messages as any);
503
+ const ollamaMessages = await ollamaAI['buildOllamaMessages'](messages as any);
496
504
 
497
505
  expect(ollamaMessages).toHaveLength(4);
498
506
  expect(ollamaMessages[0].role).toBe('system');
@@ -503,26 +511,26 @@ describe('LobeOllamaAI', () => {
503
511
  });
504
512
 
505
513
  describe('convertContentToOllamaMessage', () => {
506
- it('should convert string content to OllamaMessage', () => {
514
+ it('should convert string content to OllamaMessage', async () => {
507
515
  const message = { content: 'Hello', role: 'user' };
508
516
 
509
- const ollamaMessage = ollamaAI['convertContentToOllamaMessage'](message as any);
517
+ const ollamaMessage = await ollamaAI['convertContentToOllamaMessage'](message as any);
510
518
 
511
519
  expect(ollamaMessage).toEqual({ content: 'Hello', role: 'user' });
512
520
  });
513
521
 
514
- it('should convert text content to OllamaMessage', () => {
522
+ it('should convert text content to OllamaMessage', async () => {
515
523
  const message = {
516
524
  content: [{ type: 'text', text: 'Hello' }],
517
525
  role: 'user',
518
526
  };
519
527
 
520
- const ollamaMessage = ollamaAI['convertContentToOllamaMessage'](message as any);
528
+ const ollamaMessage = await ollamaAI['convertContentToOllamaMessage'](message as any);
521
529
 
522
530
  expect(ollamaMessage).toEqual({ content: 'Hello', role: 'user' });
523
531
  });
524
532
 
525
- it('should convert image_url content to OllamaMessage with images', () => {
533
+ it('should convert image_url content to OllamaMessage with images', async () => {
526
534
  const message = {
527
535
  content: [
528
536
  {
@@ -533,7 +541,7 @@ describe('LobeOllamaAI', () => {
533
541
  role: 'user',
534
542
  };
535
543
 
536
- const ollamaMessage = ollamaAI['convertContentToOllamaMessage'](message as any);
544
+ const ollamaMessage = await ollamaAI['convertContentToOllamaMessage'](message as any);
537
545
 
538
546
  expect(ollamaMessage).toEqual({
539
547
  content: '',
@@ -542,7 +550,7 @@ describe('LobeOllamaAI', () => {
542
550
  });
543
551
  });
544
552
 
545
- it('should ignore invalid image_url content', () => {
553
+ it('should ignore invalid image_url content', async () => {
546
554
  const message = {
547
555
  content: [
548
556
  {
@@ -553,7 +561,7 @@ describe('LobeOllamaAI', () => {
553
561
  role: 'user',
554
562
  };
555
563
 
556
- const ollamaMessage = ollamaAI['convertContentToOllamaMessage'](message as any);
564
+ const ollamaMessage = await ollamaAI['convertContentToOllamaMessage'](message as any);
557
565
 
558
566
  expect(ollamaMessage).toEqual({
559
567
  content: '',
@@ -561,7 +569,7 @@ describe('LobeOllamaAI', () => {
561
569
  });
562
570
  });
563
571
 
564
- it('should handle mixed text and image content', () => {
572
+ it('should handle mixed text and image content', async () => {
565
573
  const message = {
566
574
  content: [
567
575
  { type: 'text', text: 'First text' },
@@ -578,7 +586,7 @@ describe('LobeOllamaAI', () => {
578
586
  role: 'user',
579
587
  };
580
588
 
581
- const ollamaMessage = ollamaAI['convertContentToOllamaMessage'](message as any);
589
+ const ollamaMessage = await ollamaAI['convertContentToOllamaMessage'](message as any);
582
590
 
583
591
  expect(ollamaMessage).toEqual({
584
592
  content: 'Second text', // Should keep latest text
@@ -587,13 +595,13 @@ describe('LobeOllamaAI', () => {
587
595
  });
588
596
  });
589
597
 
590
- it('should handle content with empty text', () => {
598
+ it('should handle content with empty text', async () => {
591
599
  const message = {
592
600
  content: [{ type: 'text', text: '' }],
593
601
  role: 'user',
594
602
  };
595
603
 
596
- const ollamaMessage = ollamaAI['convertContentToOllamaMessage'](message as any);
604
+ const ollamaMessage = await ollamaAI['convertContentToOllamaMessage'](message as any);
597
605
 
598
606
  expect(ollamaMessage).toEqual({
599
607
  content: '',
@@ -601,7 +609,7 @@ describe('LobeOllamaAI', () => {
601
609
  });
602
610
  });
603
611
 
604
- it('should handle content with only images (no text)', () => {
612
+ it('should handle content with only images (no text)', async () => {
605
613
  const message = {
606
614
  content: [
607
615
  {
@@ -612,7 +620,7 @@ describe('LobeOllamaAI', () => {
612
620
  role: 'user',
613
621
  };
614
622
 
615
- const ollamaMessage = ollamaAI['convertContentToOllamaMessage'](message as any);
623
+ const ollamaMessage = await ollamaAI['convertContentToOllamaMessage'](message as any);
616
624
 
617
625
  expect(ollamaMessage).toEqual({
618
626
  content: '',
@@ -621,7 +629,7 @@ describe('LobeOllamaAI', () => {
621
629
  });
622
630
  });
623
631
 
624
- it('should handle multiple images without text', () => {
632
+ it('should handle multiple images without text', async () => {
625
633
  const message = {
626
634
  content: [
627
635
  {
@@ -640,7 +648,7 @@ describe('LobeOllamaAI', () => {
640
648
  role: 'user',
641
649
  };
642
650
 
643
- const ollamaMessage = ollamaAI['convertContentToOllamaMessage'](message as any);
651
+ const ollamaMessage = await ollamaAI['convertContentToOllamaMessage'](message as any);
644
652
 
645
653
  expect(ollamaMessage).toEqual({
646
654
  content: '',
@@ -649,7 +657,10 @@ describe('LobeOllamaAI', () => {
649
657
  });
650
658
  });
651
659
 
652
- it('should ignore images with invalid data URIs', () => {
660
+ it('should ignore images with invalid data URIs', async () => {
661
+ // Mock imageUrlToBase64 to simulate conversion failure for external URLs
662
+ vi.mocked(imageUrlToBase64).mockRejectedValue(new Error('Network error'));
663
+
653
664
  const message = {
654
665
  content: [
655
666
  { type: 'text', text: 'Hello' },
@@ -665,7 +676,7 @@ describe('LobeOllamaAI', () => {
665
676
  role: 'user',
666
677
  };
667
678
 
668
- const ollamaMessage = ollamaAI['convertContentToOllamaMessage'](message as any);
679
+ const ollamaMessage = await ollamaAI['convertContentToOllamaMessage'](message as any);
669
680
 
670
681
  expect(ollamaMessage).toEqual({
671
682
  content: 'Hello',
@@ -674,7 +685,7 @@ describe('LobeOllamaAI', () => {
674
685
  });
675
686
  });
676
687
 
677
- it('should handle complex interleaved content', () => {
688
+ it('should handle complex interleaved content', async () => {
678
689
  const message = {
679
690
  content: [
680
691
  { type: 'text', text: 'Text 1' },
@@ -692,7 +703,7 @@ describe('LobeOllamaAI', () => {
692
703
  role: 'user',
693
704
  };
694
705
 
695
- const ollamaMessage = ollamaAI['convertContentToOllamaMessage'](message as any);
706
+ const ollamaMessage = await ollamaAI['convertContentToOllamaMessage'](message as any);
696
707
 
697
708
  expect(ollamaMessage).toEqual({
698
709
  content: 'Text 3', // Should keep latest text
@@ -701,7 +712,7 @@ describe('LobeOllamaAI', () => {
701
712
  });
702
713
  });
703
714
 
704
- it('should handle assistant role with images', () => {
715
+ it('should handle assistant role with images', async () => {
705
716
  const message = {
706
717
  content: [
707
718
  { type: 'text', text: 'Here is the image' },
@@ -713,7 +724,7 @@ describe('LobeOllamaAI', () => {
713
724
  role: 'assistant',
714
725
  };
715
726
 
716
- const ollamaMessage = ollamaAI['convertContentToOllamaMessage'](message as any);
727
+ const ollamaMessage = await ollamaAI['convertContentToOllamaMessage'](message as any);
717
728
 
718
729
  expect(ollamaMessage).toEqual({
719
730
  content: 'Here is the image',
@@ -722,13 +733,13 @@ describe('LobeOllamaAI', () => {
722
733
  });
723
734
  });
724
735
 
725
- it('should handle system role with text', () => {
736
+ it('should handle system role with text', async () => {
726
737
  const message = {
727
738
  content: [{ type: 'text', text: 'You are a helpful assistant' }],
728
739
  role: 'system',
729
740
  };
730
741
 
731
- const ollamaMessage = ollamaAI['convertContentToOllamaMessage'](message as any);
742
+ const ollamaMessage = await ollamaAI['convertContentToOllamaMessage'](message as any);
732
743
 
733
744
  expect(ollamaMessage).toEqual({
734
745
  content: 'You are a helpful assistant',
@@ -736,13 +747,13 @@ describe('LobeOllamaAI', () => {
736
747
  });
737
748
  });
738
749
 
739
- it('should handle empty content array', () => {
750
+ it('should handle empty content array', async () => {
740
751
  const message = {
741
752
  content: [],
742
753
  role: 'user',
743
754
  };
744
755
 
745
- const ollamaMessage = ollamaAI['convertContentToOllamaMessage'](message as any);
756
+ const ollamaMessage = await ollamaAI['convertContentToOllamaMessage'](message as any);
746
757
 
747
758
  expect(ollamaMessage).toEqual({
748
759
  content: '',
@@ -1,4 +1,5 @@
1
1
  import type { ChatModelCard } from '@lobechat/types';
2
+ import { imageUrlToBase64 } from '@lobechat/utils';
2
3
  import { ModelProvider } from 'model-bank';
3
4
  import { Ollama, Tool } from 'ollama/browser';
4
5
  import { ClientOptions } from 'openai';
@@ -61,7 +62,7 @@ export class LobeOllamaAI implements LobeRuntimeAI {
61
62
  options?.signal?.addEventListener('abort', abort);
62
63
 
63
64
  const response = await this.client.chat({
64
- messages: this.buildOllamaMessages(payload.messages),
65
+ messages: await this.buildOllamaMessages(payload.messages),
65
66
  model: payload.model,
66
67
  options: {
67
68
  frequency_penalty: payload.frequency_penalty,
@@ -169,11 +170,13 @@ export class LobeOllamaAI implements LobeRuntimeAI {
169
170
  }
170
171
  };
171
172
 
172
- private buildOllamaMessages(messages: OpenAIChatMessage[]) {
173
- return messages.map((message) => this.convertContentToOllamaMessage(message));
173
+ private async buildOllamaMessages(messages: OpenAIChatMessage[]) {
174
+ return Promise.all(messages.map((message) => this.convertContentToOllamaMessage(message)));
174
175
  }
175
176
 
176
- private convertContentToOllamaMessage = (message: OpenAIChatMessage): OllamaMessage => {
177
+ private convertContentToOllamaMessage = async (
178
+ message: OpenAIChatMessage,
179
+ ): Promise<OllamaMessage> => {
177
180
  if (typeof message.content === 'string') {
178
181
  return { content: message.content, role: message.role };
179
182
  }
@@ -183,6 +186,9 @@ export class LobeOllamaAI implements LobeRuntimeAI {
183
186
  role: message.role,
184
187
  };
185
188
 
189
+ // Collect image processing tasks for parallel execution
190
+ const imagePromises: Array<Promise<string | null> | string> = [];
191
+
186
192
  for (const content of message.content) {
187
193
  switch (content.type) {
188
194
  case 'text': {
@@ -191,16 +197,34 @@ export class LobeOllamaAI implements LobeRuntimeAI {
191
197
  break;
192
198
  }
193
199
  case 'image_url': {
194
- const { base64 } = parseDataUri(content.image_url.url);
200
+ const { base64, type } = parseDataUri(content.image_url.url);
201
+
202
+ // If already base64 format, use it directly
195
203
  if (base64) {
196
- ollamaMessage.images ??= [];
197
- ollamaMessage.images.push(base64);
204
+ imagePromises.push(base64);
205
+ }
206
+ // If it's a URL, add async conversion task with error handling
207
+ else if (type === 'url') {
208
+ imagePromises.push(
209
+ imageUrlToBase64(content.image_url.url)
210
+ .then((result) => result.base64)
211
+ .catch(() => null), // Silently ignore failed conversions
212
+ );
198
213
  }
199
214
  break;
200
215
  }
201
216
  }
202
217
  }
203
218
 
219
+ // Process all images in parallel and filter out failed conversions
220
+ if (imagePromises.length > 0) {
221
+ const results = await Promise.all(imagePromises);
222
+ const validImages = results.filter((img): img is string => img !== null);
223
+ if (validImages.length > 0) {
224
+ ollamaMessage.images = validImages;
225
+ }
226
+ }
227
+
204
228
  return ollamaMessage;
205
229
  };
206
230
 
@@ -1,7 +1,7 @@
1
1
  // @vitest-environment node
2
- import { LobeOpenAICompatibleRuntime } from '@lobechat/model-runtime';
3
2
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
4
3
 
4
+ import { LobeOpenAICompatibleRuntime } from '../../core/BaseAI';
5
5
  import { testProvider } from '../../providerTestUtils';
6
6
  import { LobeOpenRouterAI, params } from './index';
7
7
 
@@ -1,8 +1,8 @@
1
1
  // @vitest-environment node
2
- import { LobeOpenAICompatibleRuntime } from '@lobechat/model-runtime';
3
2
  import { ModelProvider } from 'model-bank';
4
3
  import { beforeEach, describe, expect, it, vi } from 'vitest';
5
4
 
5
+ import { LobeOpenAICompatibleRuntime } from '../../core/BaseAI';
6
6
  import { testProvider } from '../../providerTestUtils';
7
7
  import { LobePerplexityAI } from './index';
8
8
 
@@ -1,8 +1,8 @@
1
1
  // @vitest-environment node
2
- import { LobeOpenAICompatibleRuntime } from '@lobechat/model-runtime';
3
2
  import { ModelProvider } from 'model-bank';
4
3
  import { Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
5
4
 
5
+ import { LobeOpenAICompatibleRuntime } from '../../core/BaseAI';
6
6
  import { testProvider } from '../../providerTestUtils';
7
7
  import models from './fixtures/models.json';
8
8
  import { LobePPIOAI } from './index';
@@ -1,4 +1,4 @@
1
- // @vitest-environment edge-runtime
1
+ // @vitest-environment node
2
2
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
3
 
4
4
  import { CreateImageOptions } from '../../core/openaiCompatibleFactory';
@@ -1,7 +1,7 @@
1
1
  // @vitest-environment node
2
- import { LobeOpenAICompatibleRuntime } from '@lobechat/model-runtime';
3
2
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
4
3
 
4
+ import { LobeOpenAICompatibleRuntime } from '../../core/BaseAI';
5
5
  import { testProvider } from '../../providerTestUtils';
6
6
  import { LobeSearch1API, params } from './index';
7
7