@lobehub/chat 0.136.0 → 0.137.0

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 (78) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +8 -8
  3. package/README.zh-CN.md +8 -8
  4. package/docs/self-hosting/advanced/authentication.mdx +6 -7
  5. package/docs/self-hosting/advanced/authentication.zh-CN.mdx +6 -7
  6. package/docs/self-hosting/advanced/sso-providers/auth0.mdx +13 -14
  7. package/docs/self-hosting/advanced/sso-providers/auth0.zh-CN.mdx +13 -13
  8. package/docs/self-hosting/advanced/sso-providers/microsoft-entra-id.mdx +16 -21
  9. package/docs/self-hosting/advanced/sso-providers/microsoft-entra-id.zh-CN.mdx +39 -40
  10. package/docs/self-hosting/environment-variables/basic.zh-CN.mdx +1 -1
  11. package/docs/self-hosting/environment-variables/model-provider.mdx +0 -2
  12. package/docs/self-hosting/environment-variables/model-provider.zh-CN.mdx +0 -1
  13. package/docs/self-hosting/start.mdx +1 -9
  14. package/docs/usage/features/agent-market.mdx +1 -1
  15. package/docs/usage/features/tts.mdx +0 -3
  16. package/docs/usage/features/vision.mdx +0 -1
  17. package/docs/usage/providers/ollama/gemma.mdx +0 -1
  18. package/docs/usage/providers/ollama.mdx +0 -3
  19. package/docs/usage/start.mdx +1 -1
  20. package/docs/usage/start.zh-CN.mdx +1 -1
  21. package/locales/ar/error.json +8 -0
  22. package/locales/ar/setting.json +9 -1
  23. package/locales/de-DE/error.json +8 -0
  24. package/locales/de-DE/setting.json +9 -1
  25. package/locales/en-US/error.json +8 -0
  26. package/locales/en-US/setting.json +9 -1
  27. package/locales/es-ES/error.json +8 -0
  28. package/locales/es-ES/setting.json +9 -1
  29. package/locales/fr-FR/error.json +8 -0
  30. package/locales/fr-FR/setting.json +9 -1
  31. package/locales/it-IT/error.json +8 -0
  32. package/locales/it-IT/setting.json +9 -1
  33. package/locales/ja-JP/error.json +8 -0
  34. package/locales/ja-JP/setting.json +9 -1
  35. package/locales/ko-KR/error.json +8 -0
  36. package/locales/ko-KR/setting.json +9 -1
  37. package/locales/nl-NL/error.json +8 -0
  38. package/locales/nl-NL/setting.json +9 -1
  39. package/locales/pl-PL/error.json +8 -0
  40. package/locales/pl-PL/setting.json +9 -1
  41. package/locales/pt-BR/error.json +8 -0
  42. package/locales/pt-BR/setting.json +9 -1
  43. package/locales/ru-RU/error.json +8 -0
  44. package/locales/ru-RU/setting.json +9 -1
  45. package/locales/tr-TR/error.json +8 -0
  46. package/locales/tr-TR/setting.json +9 -1
  47. package/locales/vi-VN/error.json +8 -0
  48. package/locales/vi-VN/setting.json +9 -1
  49. package/locales/zh-CN/error.json +8 -0
  50. package/locales/zh-CN/setting.json +9 -1
  51. package/locales/zh-TW/error.json +8 -0
  52. package/locales/zh-TW/setting.json +9 -1
  53. package/package.json +2 -1
  54. package/src/app/api/config/route.ts +3 -2
  55. package/src/app/api/errorResponse.ts +2 -1
  56. package/src/app/settings/llm/Ollama/Checker.tsx +73 -0
  57. package/src/app/settings/llm/Ollama/index.tsx +2 -4
  58. package/src/app/settings/llm/components/Checker.tsx +23 -17
  59. package/src/components/ModelIcon/index.tsx +2 -0
  60. package/src/components/ModelTag/ModelIcon.tsx +2 -0
  61. package/src/config/modelProviders/ollama.ts +14 -0
  62. package/src/config/server/provider.ts +2 -0
  63. package/src/features/Conversation/Error/InvalidOllamaModel/index.tsx +138 -0
  64. package/src/features/Conversation/Error/InvalidOllamaModel/useDownloadMonitor.ts +48 -0
  65. package/src/features/Conversation/Error/OllamaBizError.tsx +34 -0
  66. package/src/features/Conversation/Error/index.tsx +5 -0
  67. package/src/features/Conversation/Error/style.tsx +2 -2
  68. package/src/locales/default/error.ts +8 -0
  69. package/src/locales/default/setting.ts +9 -1
  70. package/src/services/__tests__/ollama.test.ts +26 -0
  71. package/src/services/ollama.ts +64 -0
  72. package/src/store/global/slices/settings/selectors/modelProvider.ts +11 -10
  73. package/src/store/middleware/createHyperStorage/index.ts +1 -2
  74. package/src/store/middleware/createHyperStorage/indexedDB.ts +1 -1
  75. package/src/store/middleware/createHyperStorage/localStorage.ts +1 -1
  76. package/src/store/middleware/createHyperStorage/urlStorage.ts +1 -1
  77. package/src/types/fetch.ts +1 -0
  78. package/tsconfig.json +1 -1
@@ -0,0 +1,64 @@
1
+ import { ListResponse, Ollama as OllamaBrowser, ProgressResponse } from 'ollama/browser';
2
+
3
+ import { createErrorResponse } from '@/app/api/errorResponse';
4
+ import { ModelProvider } from '@/libs/agent-runtime';
5
+ import { useGlobalStore } from '@/store/global';
6
+ import { modelProviderSelectors } from '@/store/global/selectors';
7
+ import { ChatErrorType } from '@/types/fetch';
8
+ import { getMessageError } from '@/utils/fetch';
9
+
10
+ const DEFAULT_BASE_URL = 'http://127.0.0.1:11434/v1';
11
+
12
+ class OllamaService {
13
+ getHost = (): string => {
14
+ const endpoint = modelProviderSelectors.ollamaProxyUrl(useGlobalStore.getState());
15
+ const url = new URL(endpoint || DEFAULT_BASE_URL);
16
+ return url.host;
17
+ };
18
+
19
+ getOllamaClient = () => {
20
+ return new OllamaBrowser({ host: this.getHost() });
21
+ };
22
+
23
+ pullModel = async (model: string): Promise<AsyncGenerator<ProgressResponse>> => {
24
+ let response: Response | AsyncGenerator<ProgressResponse>;
25
+ try {
26
+ response = await this.getOllamaClient().pull({ insecure: true, model, stream: true });
27
+ return response;
28
+ } catch {
29
+ response = createErrorResponse(ChatErrorType.OllamaServiceUnavailable, {
30
+ host: this.getHost(),
31
+ message: 'please check whether your ollama service is available',
32
+ provider: ModelProvider.Ollama,
33
+ });
34
+ }
35
+
36
+ if (!response.ok) {
37
+ const messageError = await getMessageError(response);
38
+ throw messageError;
39
+ }
40
+ return response.json();
41
+ };
42
+
43
+ getModels = async (): Promise<ListResponse> => {
44
+ let response: Response | ListResponse;
45
+ try {
46
+ const response = await this.getOllamaClient().list();
47
+ return response;
48
+ } catch {
49
+ response = createErrorResponse(ChatErrorType.OllamaServiceUnavailable, {
50
+ host: this.getHost(),
51
+ message: 'please check whether your ollama service is available',
52
+ provider: ModelProvider.Ollama,
53
+ });
54
+ }
55
+
56
+ if (!response.ok) {
57
+ const messageError = await getMessageError(response);
58
+ throw messageError;
59
+ }
60
+ return response.json();
61
+ };
62
+ }
63
+
64
+ export const ollamaService = new OllamaService();
@@ -48,9 +48,6 @@ const mistralAPIKey = (s: GlobalStore) => modelProvider(s).mistral.apiKey;
48
48
  const enableMoonshot = (s: GlobalStore) => modelProvider(s).moonshot.enabled;
49
49
  const moonshotAPIKey = (s: GlobalStore) => modelProvider(s).moonshot.apiKey;
50
50
 
51
- const enableOllamaConfigInSettings = (s: GlobalStore) =>
52
- s.serverConfig.languageModel?.ollama?.enabled || false;
53
-
54
51
  const enableOllama = (s: GlobalStore) => modelProvider(s).ollama.enabled;
55
52
  const ollamaProxyUrl = (s: GlobalStore) => modelProvider(s).ollama.endpoint;
56
53
 
@@ -118,27 +115,32 @@ const processChatModels = (
118
115
  };
119
116
 
120
117
  const modelSelectList = (s: GlobalStore): ModelProviderCard[] => {
121
- const string = [
118
+ const openaiModelString = [
122
119
  s.serverConfig.customModelName,
123
120
  currentSettings(s).languageModel.openAI.customModelName,
124
121
  ]
125
122
  .filter(Boolean)
126
123
  .join(',');
127
124
 
128
- const modelConfig = parseModelString(string);
125
+ const openaiModelConfig = parseModelString(openaiModelString);
129
126
 
130
- const chatModels = processChatModels(modelConfig);
127
+ const openaiChatModels = processChatModels(openaiModelConfig);
131
128
 
132
- const ollamaModelConfig = parseModelString(
129
+ const ollamaModelString = [
130
+ s.serverConfig.languageModel?.ollama?.customModelName,
133
131
  currentSettings(s).languageModel.ollama.customModelName,
134
- );
132
+ ]
133
+ .filter(Boolean)
134
+ .join(',');
135
+
136
+ const ollamaModelConfig = parseModelString(ollamaModelString);
135
137
 
136
138
  const ollamaChatModels = processChatModels(ollamaModelConfig, OllamaProvider.chatModels);
137
139
 
138
140
  return [
139
141
  {
140
142
  ...OpenAIProvider,
141
- chatModels,
143
+ chatModels: openaiChatModels,
142
144
  },
143
145
  // { ...azureModelList(s), enabled: enableAzure(s) },
144
146
  { ...ZhiPuProvider, enabled: enableZhipu(s) },
@@ -216,7 +218,6 @@ export const modelProviderSelectors = {
216
218
  moonshotAPIKey,
217
219
 
218
220
  // Ollama
219
- enableOllamaConfigInSettings,
220
221
  enableOllama,
221
222
  ollamaProxyUrl,
222
223
 
@@ -1,5 +1,4 @@
1
- import { PersistStorage } from 'zustand/middleware';
2
- import { StorageValue } from 'zustand/middleware/persist';
1
+ import { PersistStorage, StorageValue } from 'zustand/middleware';
3
2
 
4
3
  import { createIndexedDB } from './indexedDB';
5
4
  import { createKeyMapper } from './keyMapper';
@@ -1,5 +1,5 @@
1
1
  import { createStore, delMany, getMany, setMany } from 'idb-keyval';
2
- import { StorageValue } from 'zustand/middleware/persist';
2
+ import { StorageValue } from 'zustand/middleware';
3
3
 
4
4
  export const createIndexedDB = <State extends any>(dbName: string = 'indexedDB') => ({
5
5
  getItem: async <T extends State>(name: string): Promise<StorageValue<T> | undefined> => {
@@ -1,4 +1,4 @@
1
- import { StorageValue } from 'zustand/middleware/persist';
1
+ import { StorageValue } from 'zustand/middleware';
2
2
 
3
3
  export const createLocalStorage = <State extends any>() => ({
4
4
  getItem: <T extends State>(name: string): StorageValue<T> | undefined => {
@@ -1,5 +1,5 @@
1
1
  import { isEmpty } from 'lodash-es';
2
- import { StorageValue } from 'zustand/middleware/persist';
2
+ import { StorageValue } from 'zustand/middleware';
3
3
 
4
4
  interface UrlSearchHelper {
5
5
  getUrlSearch: () => string;
@@ -7,6 +7,7 @@ export const ChatErrorType = {
7
7
  InvalidAccessCode: 'InvalidAccessCode', // 密码无效
8
8
  OpenAIBizError: 'OpenAIBizError', // OpenAI 返回的业务错误
9
9
  NoOpenAIAPIKey: 'NoOpenAIAPIKey',
10
+ OllamaServiceUnavailable: 'OllamaServiceUnavailable', // 未启动/检测到 Ollama 服务
10
11
 
11
12
  // ******* 客户端错误 ******* //
12
13
  BadRequest: 400,
package/tsconfig.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "noEmit": true,
11
11
  "esModuleInterop": true,
12
12
  "module": "esnext",
13
- "moduleResolution": "node",
13
+ "moduleResolution": "bundler",
14
14
  "resolveJsonModule": true,
15
15
  "isolatedModules": true,
16
16
  "jsx": "preserve",