@lobehub/chat 1.120.1 → 1.120.2

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 (38) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/changelog/v1.json +9 -0
  3. package/docs/self-hosting/environment-variables/basic.mdx +0 -7
  4. package/docs/self-hosting/environment-variables/basic.zh-CN.mdx +0 -7
  5. package/next.config.ts +0 -2
  6. package/package.json +3 -3
  7. package/packages/const/src/url.ts +1 -2
  8. package/packages/model-runtime/src/ModelRuntime.test.ts +1 -1
  9. package/packages/web-crawler/package.json +1 -1
  10. package/src/app/[variants]/metadata.ts +1 -7
  11. package/src/components/Analytics/Google.tsx +1 -1
  12. package/src/components/Analytics/LobeAnalyticsProviderWrapper.tsx +1 -1
  13. package/src/components/Analytics/Vercel.tsx +1 -1
  14. package/src/components/Analytics/index.tsx +1 -1
  15. package/src/config/__tests__/analytics.test.ts +1 -1
  16. package/src/config/__tests__/client.test.ts +1 -1
  17. package/src/envs/app.ts +0 -3
  18. package/src/libs/analytics/index.ts +1 -1
  19. package/src/libs/traces/index.test.ts +1 -1
  20. package/src/libs/traces/index.ts +1 -1
  21. package/src/libs/trpc/client/edge.ts +1 -2
  22. package/src/libs/unstructured/index.ts +1 -1
  23. package/src/locales/create.ts +1 -1
  24. package/src/server/globalConfig/index.test.ts +1 -2
  25. package/src/server/globalConfig/index.ts +2 -2
  26. package/src/server/modules/ContentChunk/index.ts +1 -1
  27. package/src/server/routers/tools/search.test.ts +1 -1
  28. package/src/server/services/search/impls/searxng/index.test.ts +1 -1
  29. package/src/server/services/search/impls/searxng/index.ts +1 -1
  30. package/src/server/services/search/index.ts +1 -1
  31. package/src/services/_url.ts +6 -19
  32. package/src/services/share.ts +1 -2
  33. package/packages/utils/src/basePath.ts +0 -3
  34. /package/src/{config → envs}/analytics.ts +0 -0
  35. /package/src/{config → envs}/debug.ts +0 -0
  36. /package/src/{config → envs}/knowledge.ts +0 -0
  37. /package/src/{config → envs}/langfuse.ts +0 -0
  38. /package/src/{config → envs}/tools.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.120.2](https://github.com/lobehub/lobe-chat/compare/v1.120.1...v1.120.2)
6
+
7
+ <sup>Released on **2025-08-31**</sup>
8
+
9
+ #### ♻ Code Refactoring
10
+
11
+ - **misc**: Remove base path.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### Code refactoring
19
+
20
+ - **misc**: Remove base path, closes [#9015](https://github.com/lobehub/lobe-chat/issues/9015) ([2a5f8d7](https://github.com/lobehub/lobe-chat/commit/2a5f8d7))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
5
30
  ### [Version 1.120.1](https://github.com/lobehub/lobe-chat/compare/v1.120.0...v1.120.1)
6
31
 
7
32
  <sup>Released on **2025-08-31**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "improvements": [
5
+ "Remove base path."
6
+ ]
7
+ },
8
+ "date": "2025-08-31",
9
+ "version": "1.120.2"
10
+ },
2
11
  {
3
12
  "children": {
4
13
  "improvements": [
@@ -37,13 +37,6 @@ When using the `random` mode, a random API Key will be selected from the availab
37
37
 
38
38
  When using the `turn` mode, the API Keys will be retrieved in a polling manner according to the specified order.
39
39
 
40
- ### `NEXT_PUBLIC_BASE_PATH`
41
-
42
- - Type: Optional
43
- - Description: Add a `basePath` for LobeChat.
44
- - Default: -
45
- - Example: `/test`
46
-
47
40
  ### `DEFAULT_AGENT_CONFIG`
48
41
 
49
42
  - Type: Optional
@@ -34,13 +34,6 @@ LobeChat 在部署时提供了一些额外的配置项,你可以使用环境
34
34
 
35
35
  使用 `turn` 模式下,将按照填写的顺序,轮询获取得到 API Key。
36
36
 
37
- ### `NEXT_PUBLIC_BASE_PATH`
38
-
39
- - 类型:可选
40
- - 描述:为 LobeChat 添加 `basePath`
41
- - 默认值: `-`
42
- - 示例: `/test`
43
-
44
37
  ### `DEFAULT_AGENT_CONFIG`
45
38
 
46
39
  - 类型:可选
package/next.config.ts CHANGED
@@ -13,7 +13,6 @@ const shouldUseCSP = process.env.ENABLED_CSP === '1';
13
13
 
14
14
  // if you need to proxy the api endpoint to remote server
15
15
 
16
- const basePath = process.env.NEXT_PUBLIC_BASE_PATH;
17
16
  const isStandaloneMode = buildWithDocker || isDesktop;
18
17
 
19
18
  const standaloneConfig: NextConfig = {
@@ -23,7 +22,6 @@ const standaloneConfig: NextConfig = {
23
22
 
24
23
  const nextConfig: NextConfig = {
25
24
  ...(isStandaloneMode ? standaloneConfig : {}),
26
- basePath,
27
25
  compress: isProd,
28
26
  experimental: {
29
27
  optimizePackageImports: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.120.1",
3
+ "version": "1.120.2",
4
4
  "description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -190,7 +190,7 @@
190
190
  "drizzle-zod": "^0.5.1",
191
191
  "epub2": "^3.0.2",
192
192
  "fast-deep-equal": "^3.1.3",
193
- "file-type": "^20.5.0",
193
+ "file-type": "^21.0.0",
194
194
  "framer-motion": "^12.23.12",
195
195
  "gpt-tokenizer": "^2.9.0",
196
196
  "gray-matter": "^4.0.3",
@@ -335,7 +335,7 @@
335
335
  "fake-indexeddb": "^6.0.1",
336
336
  "fs-extra": "^11.3.1",
337
337
  "glob": "^11.0.3",
338
- "happy-dom": "^17.6.3",
338
+ "happy-dom": "^18.0.0",
339
339
  "husky": "^9.1.7",
340
340
  "just-diff": "^6.0.2",
341
341
  "lint-staged": "^15.5.2",
@@ -1,7 +1,6 @@
1
1
  import qs from 'query-string';
2
2
  import urlJoin from 'url-join';
3
3
 
4
- import { withBasePath } from '@/utils/basePath';
5
4
  import { isDev } from '@/utils/env';
6
5
 
7
6
  import { INBOX_SESSION_ID } from './session';
@@ -56,7 +55,7 @@ export const SESSION_CHAT_URL = (id: string = INBOX_SESSION_ID, mobile?: boolean
56
55
  url: '/chat',
57
56
  });
58
57
 
59
- export const imageUrl = (filename: string) => withBasePath(`/images/${filename}`);
58
+ export const imageUrl = (filename: string) => `/images/${filename}`;
60
59
 
61
60
  export const LOBE_URL_IMPORT_NAME = 'settings';
62
61
 
@@ -5,7 +5,7 @@ import { Langfuse } from 'langfuse';
5
5
  import { LangfuseGenerationClient, LangfuseTraceClient } from 'langfuse-core';
6
6
  import { beforeEach, describe, expect, it, vi } from 'vitest';
7
7
 
8
- import * as langfuseCfg from '@/config/langfuse';
8
+ import * as langfuseCfg from '@/envs/langfuse';
9
9
  import { createTraceOptions } from '@/server/modules/ModelRuntime';
10
10
 
11
11
  import { ChatStreamPayload, LobeOpenAI, ModelProvider, ModelRuntime } from '.';
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@mozilla/readability": "^0.6.0",
13
- "happy-dom": "^17.0.0",
13
+ "happy-dom": "^18.0.0",
14
14
  "node-html-markdown": "^1.3.0",
15
15
  "query-string": "^9.1.1",
16
16
  "url-join": "^5"
@@ -2,16 +2,10 @@ import { BRANDING_LOGO_URL, BRANDING_NAME, ORG_NAME } from '@/const/branding';
2
2
  import { DEFAULT_LANG } from '@/const/locale';
3
3
  import { OFFICIAL_URL, OG_URL } from '@/const/url';
4
4
  import { isCustomBranding, isCustomORG } from '@/const/version';
5
- import { appEnv } from '@/envs/app';
6
5
  import { translation } from '@/server/translation';
7
6
  import { DynamicLayoutProps } from '@/types/next';
8
7
  import { RouteVariants } from '@/utils/server/routeVariants';
9
8
 
10
- const BASE_PATH = appEnv.NEXT_PUBLIC_BASE_PATH;
11
-
12
- // if there is a base path, then we don't need the manifest
13
- const noManifest = !!BASE_PATH;
14
-
15
9
  export const generateMetadata = async (props: DynamicLayoutProps) => {
16
10
  const locale = await RouteVariants.getLocale(props);
17
11
  const { t } = await translation('metadata', locale);
@@ -32,7 +26,7 @@ export const generateMetadata = async (props: DynamicLayoutProps) => {
32
26
  icon: '/favicon.ico?v=1',
33
27
  shortcut: '/favicon-32x32.ico?v=1',
34
28
  },
35
- manifest: noManifest ? undefined : '/manifest.json',
29
+ manifest: '/manifest.json',
36
30
  metadataBase: new URL(OFFICIAL_URL),
37
31
  openGraph: {
38
32
  description: t('chat.description', { appName: BRANDING_NAME }),
@@ -1,6 +1,6 @@
1
1
  import { GoogleAnalytics as GA } from '@next/third-parties/google';
2
2
 
3
- import { analyticsEnv } from '@/config/analytics';
3
+ import { analyticsEnv } from '@/envs/analytics';
4
4
 
5
5
  const GoogleAnalytics = () => <GA gaId={analyticsEnv.GOOGLE_ANALYTICS_MEASUREMENT_ID!} />;
6
6
 
@@ -1,7 +1,7 @@
1
1
  import { ReactNode, memo } from 'react';
2
2
 
3
3
  import { LobeAnalyticsProvider } from '@/components/Analytics/LobeAnalyticsProvider';
4
- import { analyticsEnv } from '@/config/analytics';
4
+ import { analyticsEnv } from '@/envs/analytics';
5
5
  import { isDev } from '@/utils/env';
6
6
 
7
7
  type Props = {
@@ -1,7 +1,7 @@
1
1
  import { Analytics } from '@vercel/analytics/react';
2
2
  import { memo } from 'react';
3
3
 
4
- import { analyticsEnv } from '@/config/analytics';
4
+ import { analyticsEnv } from '@/envs/analytics';
5
5
 
6
6
  const VercelAnalytics = memo(() => <Analytics debug={analyticsEnv.DEBUG_VERCEL_ANALYTICS} />);
7
7
 
@@ -1,7 +1,7 @@
1
1
  import dynamic from 'next/dynamic';
2
2
 
3
- import { analyticsEnv } from '@/config/analytics';
4
3
  import { isDesktop } from '@/const/version';
4
+ import { analyticsEnv } from '@/envs/analytics';
5
5
 
6
6
  import Desktop from './Desktop';
7
7
  import Google from './Google';
@@ -1,7 +1,7 @@
1
1
  // @vitest-environment node
2
2
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
3
 
4
- import { analyticsEnv, getAnalyticsConfig } from '../analytics';
4
+ import { analyticsEnv, getAnalyticsConfig } from '../../envs/analytics';
5
5
 
6
6
  beforeEach(() => {
7
7
  // 在每个测试用例之前,清除所有的 console.warn mock
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, it, vi } from 'vitest';
2
2
 
3
- import { getDebugConfig } from '../debug';
3
+ import { getDebugConfig } from '../../envs/debug';
4
4
 
5
5
  // 测试前重置 process.env
6
6
  vi.stubGlobal('process', {
package/src/envs/app.ts CHANGED
@@ -32,7 +32,6 @@ export const getAppConfig = () => {
32
32
 
33
33
  return createEnv({
34
34
  client: {
35
- NEXT_PUBLIC_BASE_PATH: z.string(),
36
35
  NEXT_PUBLIC_ENABLE_SENTRY: z.boolean(),
37
36
  },
38
37
  server: {
@@ -59,8 +58,6 @@ export const getAppConfig = () => {
59
58
  SSRF_ALLOW_IP_ADDRESS_LIST: z.string().optional(),
60
59
  },
61
60
  runtimeEnv: {
62
- NEXT_PUBLIC_BASE_PATH: process.env.NEXT_PUBLIC_BASE_PATH || '',
63
-
64
61
  // Sentry
65
62
  NEXT_PUBLIC_ENABLE_SENTRY: !!process.env.NEXT_PUBLIC_SENTRY_DSN,
66
63
 
@@ -1,7 +1,7 @@
1
1
  import { createServerAnalytics } from '@lobehub/analytics/server';
2
2
 
3
- import { analyticsEnv } from '@/config/analytics';
4
3
  import { BUSINESS_LINE } from '@/const/analytics';
4
+ import { analyticsEnv } from '@/envs/analytics';
5
5
  import { isDev } from '@/utils/env';
6
6
 
7
7
  export const serverAnalytics = createServerAnalytics({
@@ -3,7 +3,7 @@ import { Langfuse } from 'langfuse';
3
3
  import { CreateLangfuseTraceBody } from 'langfuse-core';
4
4
  import { describe, expect, it, vi } from 'vitest';
5
5
 
6
- import * as server from '@/config/langfuse';
6
+ import * as server from '@/envs/langfuse';
7
7
 
8
8
  import { TraceClient } from './index';
9
9
 
@@ -1,8 +1,8 @@
1
1
  import { Langfuse } from 'langfuse';
2
2
  import { CreateLangfuseTraceBody } from 'langfuse-core';
3
3
 
4
- import { getLangfuseConfig } from '@/config/langfuse';
5
4
  import { CURRENT_VERSION } from '@/const/version';
5
+ import { getLangfuseConfig } from '@/envs/langfuse';
6
6
  import { TraceEventClient } from '@/libs/traces/event';
7
7
 
8
8
  /**
@@ -3,7 +3,6 @@ import superjson from 'superjson';
3
3
 
4
4
  import { isDesktop } from '@/const/version';
5
5
  import type { EdgeRouter } from '@/server/routers/edge';
6
- import { withBasePath } from '@/utils/basePath';
7
6
  import { fetchWithDesktopRemoteRPC } from '@/utils/electron/desktopRemoteRPCFetch';
8
7
 
9
8
  export const edgeClient = createTRPCClient<EdgeRouter>({
@@ -21,7 +20,7 @@ export const edgeClient = createTRPCClient<EdgeRouter>({
21
20
  },
22
21
  maxURLLength: 2083,
23
22
  transformer: superjson,
24
- url: withBasePath('/trpc/edge'),
23
+ url: '/trpc/edge',
25
24
  }),
26
25
  ],
27
26
  });
@@ -4,7 +4,7 @@ import { UnstructuredClient } from 'unstructured-client';
4
4
  import { Strategy } from 'unstructured-client/sdk/models/shared';
5
5
  import { PartitionResponse } from 'unstructured-client/src/sdk/models/operations';
6
6
 
7
- import { knowledgeEnv } from '@/config/knowledge';
7
+ import { knowledgeEnv } from '@/envs/knowledge';
8
8
 
9
9
  export enum ChunkingStrategy {
10
10
  Basic = 'basic',
@@ -4,8 +4,8 @@ import resourcesToBackend from 'i18next-resources-to-backend';
4
4
  import { initReactI18next } from 'react-i18next';
5
5
  import { isRtlLang } from 'rtl-detect';
6
6
 
7
- import { getDebugConfig } from '@/config/debug';
8
7
  import { DEFAULT_LANG } from '@/const/locale';
8
+ import { getDebugConfig } from '@/envs/debug';
9
9
  import { normalizeLocale } from '@/locales/resources';
10
10
  import { isDev, isOnServerSide } from '@/utils/env';
11
11
 
@@ -1,6 +1,5 @@
1
1
  import { describe, expect, it, vi } from 'vitest';
2
2
 
3
- import { knowledgeEnv } from '@/config/knowledge';
4
3
  import { getAppConfig } from '@/envs/app';
5
4
  import { SystemEmbeddingConfig } from '@/types/knowledgeBase';
6
5
  import { FilesConfigItem } from '@/types/user/settings/filesConfig';
@@ -13,7 +12,7 @@ vi.mock('@/envs/app', () => ({
13
12
  getAppConfig: vi.fn(),
14
13
  }));
15
14
 
16
- vi.mock('@/config/knowledge', () => ({
15
+ vi.mock('@/envs/knowledge', () => ({
17
16
  knowledgeEnv: {
18
17
  DEFAULT_FILES_CONFIG: 'test_config',
19
18
  },
@@ -1,10 +1,10 @@
1
1
  import { authEnv } from '@/config/auth';
2
2
  import { fileEnv } from '@/config/file';
3
- import { knowledgeEnv } from '@/config/knowledge';
4
- import { langfuseEnv } from '@/config/langfuse';
5
3
  import { enableNextAuth } from '@/const/auth';
6
4
  import { isDesktop } from '@/const/version';
7
5
  import { appEnv, getAppConfig } from '@/envs/app';
6
+ import { knowledgeEnv } from '@/envs/knowledge';
7
+ import { langfuseEnv } from '@/envs/langfuse';
8
8
  import { parseSystemAgent } from '@/server/globalConfig/parseSystemAgent';
9
9
  import { GlobalServerConfig } from '@/types/serverConfig';
10
10
 
@@ -1,7 +1,7 @@
1
1
  import { Strategy } from 'unstructured-client/sdk/models/shared';
2
2
 
3
- import { knowledgeEnv } from '@/config/knowledge';
4
3
  import type { NewChunkItem, NewUnstructuredChunkItem } from '@/database/schemas';
4
+ import { knowledgeEnv } from '@/envs/knowledge';
5
5
  import { ChunkingLoader } from '@/libs/langchain';
6
6
  import { ChunkingStrategy, Unstructured } from '@/libs/unstructured';
7
7
 
@@ -2,7 +2,7 @@
2
2
  import { TRPCError } from '@trpc/server';
3
3
  import { beforeEach, describe, expect, it, vi } from 'vitest';
4
4
 
5
- import { toolsEnv } from '@/config/tools';
5
+ import { toolsEnv } from '@/envs/tools';
6
6
  import { SearXNGClient } from '@/server/services/search/impls/searxng/client';
7
7
  import { SEARCH_SEARXNG_NOT_CONFIG } from '@/types/tool/search';
8
8
 
@@ -5,7 +5,7 @@ import { SearXNGClient } from './client';
5
5
  import { hetongxue } from './fixtures/searXNG';
6
6
  import { SearXNGImpl } from './index';
7
7
 
8
- vi.mock('@/config/tools', () => ({
8
+ vi.mock('@/envs/tools', () => ({
9
9
  toolsEnv: {
10
10
  SEARXNG_URL: 'https://demo.com',
11
11
  },
@@ -1,6 +1,6 @@
1
1
  import { TRPCError } from '@trpc/server';
2
2
 
3
- import { toolsEnv } from '@/config/tools';
3
+ import { toolsEnv } from '@/envs/tools';
4
4
  import { SearXNGClient } from '@/server/services/search/impls/searxng/client';
5
5
  import { SEARCH_SEARXNG_NOT_CONFIG, UniformSearchResponse } from '@/types/tool/search';
6
6
 
@@ -1,7 +1,7 @@
1
1
  import { CrawlImplType, Crawler } from '@lobechat/web-crawler';
2
2
  import pMap from 'p-map';
3
3
 
4
- import { toolsEnv } from '@/config/tools';
4
+ import { toolsEnv } from '@/envs/tools';
5
5
  import { SearchParams } from '@/types/tool/search';
6
6
 
7
7
  import { SearchImplType, SearchServiceImpl, createSearchServiceImpl } from './impls';
@@ -1,20 +1,7 @@
1
1
  /* eslint-disable sort-keys-fix/sort-keys-fix */
2
- import { transform } from 'lodash-es';
3
-
4
- import { withBasePath } from '@/utils/basePath';
5
-
6
- const mapWithBasePath = <T extends object>(apis: T): T => {
7
- return transform(apis, (result, value, key) => {
8
- if (typeof value === 'string') {
9
- // @ts-ignore
10
- result[key] = withBasePath(value);
11
- } else {
12
- result[key] = value;
13
- }
14
- });
15
- };
16
2
 
17
- export const API_ENDPOINTS = mapWithBasePath({
3
+
4
+ export const API_ENDPOINTS = {
18
5
  oauth: '/api/auth',
19
6
 
20
7
  proxy: '/webapi/proxy',
@@ -26,11 +13,11 @@ export const API_ENDPOINTS = mapWithBasePath({
26
13
  trace: '/webapi/trace',
27
14
 
28
15
  // chat
29
- chat: (provider: string) => withBasePath(`/webapi/chat/${provider}`),
16
+ chat: (provider: string) => `/webapi/chat/${provider}`,
30
17
 
31
18
  // models
32
- models: (provider: string) => withBasePath(`/webapi/models/${provider}`),
33
- modelPull: (provider: string) => withBasePath(`/webapi/models/${provider}/pull`),
19
+ models: (provider: string) => `/webapi/models/${provider}`,
20
+ modelPull: (provider: string) => `/webapi/models/${provider}/pull`,
34
21
 
35
22
  // image
36
23
  images: (provider: string) => `/webapi/text-to-image/${provider}`,
@@ -42,4 +29,4 @@ export const API_ENDPOINTS = mapWithBasePath({
42
29
  tts: '/webapi/tts/openai',
43
30
  edge: '/webapi/tts/edge',
44
31
  microsoft: '/webapi/tts/microsoft',
45
- });
32
+ };
@@ -2,7 +2,6 @@ import type { PartialDeep } from 'type-fest';
2
2
 
3
3
  import { LOBE_URL_IMPORT_NAME } from '@/const/url';
4
4
  import { UserSettings } from '@/types/user/settings';
5
- import { withBasePath } from '@/utils/basePath';
6
5
 
7
6
  class ShareService {
8
7
  /**
@@ -11,7 +10,7 @@ class ShareService {
11
10
  * @returns The share settings URL.
12
11
  */
13
12
  public createShareSettingsUrl = (settings: PartialDeep<UserSettings>) => {
14
- return withBasePath(`/?${LOBE_URL_IMPORT_NAME}=${encodeURI(JSON.stringify(settings))}`);
13
+ return `/?${LOBE_URL_IMPORT_NAME}=${encodeURI(JSON.stringify(settings))}`;
15
14
  };
16
15
 
17
16
  /**
@@ -1,3 +0,0 @@
1
- import { appEnv } from '@/envs/app';
2
-
3
- export const withBasePath = (path: string) => appEnv.NEXT_PUBLIC_BASE_PATH + path;
File without changes
File without changes
File without changes
File without changes
File without changes