@lobehub/chat 1.80.4 → 1.81.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 (59) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/package.json +1 -1
  4. package/packages/electron-client-ipc/src/events/index.ts +6 -2
  5. package/packages/electron-client-ipc/src/events/remoteServer.ts +28 -0
  6. package/packages/electron-client-ipc/src/types/index.ts +1 -0
  7. package/packages/electron-client-ipc/src/types/remoteServer.ts +8 -0
  8. package/packages/electron-server-ipc/package.json +7 -1
  9. package/packages/electron-server-ipc/src/ipcClient.ts +54 -20
  10. package/packages/electron-server-ipc/src/ipcServer.ts +42 -9
  11. package/packages/web-crawler/src/crawImpl/__tests__/search1api.test.ts +33 -39
  12. package/packages/web-crawler/src/crawImpl/search1api.ts +1 -7
  13. package/packages/web-crawler/src/index.ts +1 -0
  14. package/packages/web-crawler/src/urlRules.ts +3 -1
  15. package/src/config/aiModels/ai21.ts +10 -6
  16. package/src/config/aiModels/ai360.ts +36 -2
  17. package/src/config/aiModels/stepfun.ts +1 -0
  18. package/src/config/aiModels/taichu.ts +61 -0
  19. package/src/config/aiModels/volcengine.ts +0 -1
  20. package/src/config/modelProviders/ai21.ts +1 -1
  21. package/src/config/tools.ts +2 -0
  22. package/src/database/repositories/aiInfra/index.test.ts +3 -3
  23. package/src/features/Conversation/Messages/Assistant/Tool/Inspector/Debug.tsx +9 -3
  24. package/src/features/Conversation/Messages/Assistant/Tool/Inspector/PluginState.tsx +21 -0
  25. package/src/features/Conversation/Messages/Assistant/Tool/Render/Arguments.tsx +1 -1
  26. package/src/locales/default/plugin.ts +1 -0
  27. package/src/server/routers/tools/{__test__/search.test.ts → search.test.ts} +27 -5
  28. package/src/server/routers/tools/search.ts +3 -44
  29. package/src/server/services/search/impls/index.ts +30 -0
  30. package/src/server/services/search/impls/search1api/index.ts +154 -0
  31. package/src/server/services/search/impls/search1api/type.ts +81 -0
  32. package/src/server/{modules/SearXNG.ts → services/search/impls/searxng/client.ts} +32 -2
  33. package/src/server/{routers/tools/__tests__ → services/search/impls/searxng}/fixtures/searXNG.ts +2 -2
  34. package/src/server/services/search/impls/searxng/index.test.ts +26 -0
  35. package/src/server/services/search/impls/searxng/index.ts +62 -0
  36. package/src/server/services/search/impls/type.ts +11 -0
  37. package/src/server/services/search/index.ts +59 -0
  38. package/src/store/chat/slices/builtinTool/actions/index.ts +1 -1
  39. package/src/store/chat/slices/builtinTool/actions/{searXNG.test.ts → search.test.ts} +30 -55
  40. package/src/store/chat/slices/builtinTool/actions/{searXNG.ts → search.ts} +25 -32
  41. package/src/tools/web-browsing/Portal/Search/Footer.tsx +1 -1
  42. package/src/tools/web-browsing/Portal/Search/ResultList/SearchItem/TitleExtra.tsx +2 -2
  43. package/src/tools/web-browsing/Portal/Search/ResultList/SearchItem/Video.tsx +9 -7
  44. package/src/tools/web-browsing/Portal/Search/ResultList/SearchItem/index.tsx +2 -2
  45. package/src/tools/web-browsing/Portal/Search/ResultList/index.tsx +3 -3
  46. package/src/tools/web-browsing/Portal/Search/index.tsx +4 -4
  47. package/src/tools/web-browsing/Portal/index.tsx +3 -1
  48. package/src/tools/web-browsing/Render/Search/SearchQuery/SearchView.tsx +4 -2
  49. package/src/tools/web-browsing/Render/Search/SearchQuery/index.tsx +6 -13
  50. package/src/tools/web-browsing/Render/Search/SearchResult/SearchResultItem.tsx +2 -2
  51. package/src/tools/web-browsing/Render/Search/SearchResult/index.tsx +5 -5
  52. package/src/tools/web-browsing/Render/Search/index.tsx +2 -2
  53. package/src/tools/web-browsing/Render/index.tsx +4 -3
  54. package/src/tools/web-browsing/components/SearchBar.tsx +4 -6
  55. package/src/tools/web-browsing/index.ts +54 -60
  56. package/src/tools/web-browsing/systemRole.ts +22 -13
  57. package/src/types/tool/search/index.ts +44 -0
  58. package/src/server/routers/tools/__tests__/search.test.ts +0 -48
  59. package/src/types/tool/search.ts +0 -48
@@ -4,20 +4,21 @@ import { WebBrowsingApiName } from '@/tools/web-browsing';
4
4
  import PageContent from '@/tools/web-browsing/Render/PageContent';
5
5
  import { BuiltinRenderProps } from '@/types/tool';
6
6
  import { CrawlMultiPagesQuery, CrawlPluginState, CrawlSinglePageQuery } from '@/types/tool/crawler';
7
- import { SearchContent, SearchQuery, SearchResponse } from '@/types/tool/search';
7
+ import { SearchContent, SearchQuery, UniformSearchResponse } from '@/types/tool/search';
8
8
 
9
9
  import Search from './Search';
10
10
 
11
11
  const WebBrowsing = memo<BuiltinRenderProps<SearchContent[]>>(
12
12
  ({ messageId, args, pluginState, pluginError, apiName }) => {
13
13
  switch (apiName) {
14
- case WebBrowsingApiName.searchWithSearXNG: {
14
+ case WebBrowsingApiName.search:
15
+ case 'searchWithSearXNG': {
15
16
  return (
16
17
  <Search
17
18
  messageId={messageId}
18
19
  pluginError={pluginError}
19
20
  searchQuery={args as SearchQuery}
20
- searchResponse={pluginState as SearchResponse}
21
+ searchResponse={pluginState as UniformSearchResponse}
21
22
  />
22
23
  );
23
24
  }
@@ -45,16 +45,14 @@ const SearchBar = memo<SearchBarProps>(
45
45
  const [engines, setEngines] = useState(defaultEngines);
46
46
  const [time_range, setTimeRange] = useState(defaultTimeRange);
47
47
  const isMobile = useIsMobile();
48
- const [reSearchWithSearXNG] = useChatStore((s) => [s.reSearchWithSearXNG]);
48
+ const [reSearchWithSearXNG] = useChatStore((s) => [s.triggerSearchAgain]);
49
49
 
50
50
  const updateAndSearch = async () => {
51
51
  const data: SearchQuery = {
52
- optionalParams: {
53
- searchCategories: categories,
54
- searchEngines: engines,
55
- searchTimeRange: time_range,
56
- },
57
52
  query,
53
+ searchCategories: categories,
54
+ searchEngines: engines,
55
+ searchTimeRange: time_range,
58
56
  };
59
57
  onSearch?.(data);
60
58
  await reSearchWithSearXNG(messageId, data, { aiSummary });
@@ -7,78 +7,72 @@ import { systemPrompt } from './systemRole';
7
7
  export const WebBrowsingApiName = {
8
8
  crawlMultiPages: 'crawlMultiPages',
9
9
  crawlSinglePage: 'crawlSinglePage',
10
- searchWithSearXNG: 'searchWithSearXNG',
10
+ search: 'search',
11
11
  };
12
12
 
13
13
  export const WebBrowsingManifest: BuiltinToolManifest = {
14
14
  api: [
15
15
  {
16
16
  description:
17
- 'A meta search engine. Useful for when you need to answer questions about current events. Input should be a search query. Output is a JSON array of the query results',
18
- name: WebBrowsingApiName.searchWithSearXNG,
17
+ 'a search service. Useful for when you need to answer questions about current events. Input should be a search query. Output is a JSON array of the query results',
18
+ name: WebBrowsingApiName.search,
19
19
  parameters: {
20
20
  properties: {
21
- optionalParams: {
22
- description: 'The optional parameters for search query',
23
- properties: {
24
- searchCategories: {
25
- description: 'The search categories you can set:',
26
- items: {
27
- enum: [
28
- 'files',
29
- 'general',
30
- 'images',
31
- 'it',
32
- 'map',
33
- 'music',
34
- 'news',
35
- 'science',
36
- 'social_media',
37
- 'videos',
38
- ],
39
- type: 'string',
40
- },
41
- type: 'array',
42
- },
43
- searchEngines: {
44
- description: 'The search engines you can use:',
45
- items: {
46
- enum: [
47
- 'google',
48
- 'bilibili',
49
- 'bing',
50
- 'duckduckgo',
51
- 'npm',
52
- 'pypi',
53
- 'github',
54
- 'arxiv',
55
- 'google scholar',
56
- 'z-library',
57
- 'reddit',
58
- 'imdb',
59
- 'brave',
60
- 'wikipedia',
61
- 'pinterest',
62
- 'unsplash',
63
- 'vimeo',
64
- 'youtube',
65
- ],
66
- type: 'string',
67
- },
68
- type: 'array',
69
- },
70
- searchTimeRange: {
71
- description: 'The time range you can set:',
72
- enum: ['anytime', 'day', 'week', 'month', 'year'],
73
- type: 'string',
74
- },
75
- },
76
- type: 'object',
77
- },
78
21
  query: {
79
22
  description: 'The search query',
80
23
  type: 'string',
81
24
  },
25
+ searchCategories: {
26
+ description: 'The search categories you can set:',
27
+ items: {
28
+ enum: [
29
+ 'files',
30
+ 'general',
31
+ 'images',
32
+ 'it',
33
+ 'map',
34
+ 'music',
35
+ 'news',
36
+ 'science',
37
+ 'social_media',
38
+ 'videos',
39
+ ],
40
+ type: 'string',
41
+ },
42
+ type: 'array',
43
+ },
44
+ searchEngines: {
45
+ description: 'The search engines you can use:',
46
+ items: {
47
+ enum: [
48
+ 'google',
49
+ 'bilibili',
50
+ 'bing',
51
+ 'duckduckgo',
52
+ 'npm',
53
+ 'pypi',
54
+ 'github',
55
+ 'arxiv',
56
+ 'google scholar',
57
+ 'z-library',
58
+ 'reddit',
59
+ 'imdb',
60
+ 'brave',
61
+ 'wikipedia',
62
+ 'pinterest',
63
+ 'unsplash',
64
+ 'vimeo',
65
+ 'youtube',
66
+ ],
67
+ type: 'string',
68
+ },
69
+ type: 'array',
70
+ },
71
+ searchTimeRange: {
72
+ description: 'The time range you can set:',
73
+ enum: ['anytime', 'day', 'week', 'month', 'year'],
74
+ type: 'string',
75
+ },
82
76
  },
83
77
  required: ['query'],
84
78
  type: 'object',
@@ -3,9 +3,9 @@ export const systemPrompt = (
3
3
  ) => `You have a Web Information tool with powerful internet access capabilities. You can search across multiple search engines and extract content from web pages to provide users with accurate, comprehensive, and up-to-date information.
4
4
 
5
5
  <core_capabilities>
6
- 1. Search the web using multiple search engines (searchWithSearXNG)
6
+ 1. Search the web using multiple search engines (search)
7
+ 2. Retrieve content from multiple webpages simultaneously (crawlMultiPages)
7
8
  2. Retrieve content from a specific webpage (crawlSinglePage)
8
- 3. Retrieve content from multiple webpages simultaneously (crawlMultiPages)
9
9
  </core_capabilities>
10
10
 
11
11
  <workflow>
@@ -18,8 +18,8 @@ export const systemPrompt = (
18
18
 
19
19
  <tool_selection_guidelines>
20
20
  - For general information queries: Use searchWithSearXNG with the most relevant search engines
21
- - For detailed understanding of specific single page content: Use 'crawlSinglePage' on the most authoritative or relevant page from search results. If you need to visit multiple pages, prefer to use 'crawlMultiPages'
22
21
  - For multi-perspective information or comparative analysis: Use 'crawlMultiPages' on several different relevant sources
22
+ - For detailed understanding of specific single page content: Use 'crawlSinglePage' on the most authoritative or relevant page from search results. If you need to visit multiple pages, prefer to use 'crawlMultiPages'
23
23
  </tool_selection_guidelines>
24
24
 
25
25
  <search_categories_selection>
@@ -61,7 +61,7 @@ Choose time range based on the query type:
61
61
  - Leverage cross-platform meta-search capabilities for comprehensive results
62
62
  - Prioritize authoritative sources in search results when available
63
63
  - For region-specific information, prefer search engines popular in that region
64
- - Avoid using both 'engines' and 'categories' in a query, unless the chosen engines do not fall under the selected categories.
64
+ - Avoid using both 'engines' and 'categories' in a query, unless the chosen engines do not fall under the selected categories.
65
65
 
66
66
  <search_strategy_best_practices>
67
67
  - Combine categories for multi-faceted queries:
@@ -96,6 +96,20 @@ Choose time range based on the query type:
96
96
  - List all referenced URLs at the end of your response
97
97
  - Clearly distinguish between quoted information and your own analysis
98
98
  - Respond in the same language as the user's query
99
+
100
+ <citation_examples>
101
+ <example>
102
+ According to recent studies, global temperatures have risen by 1.1°C since pre-industrial times[^1].
103
+
104
+ [^1]: [Climate Report in 2023](https://example.org/climate-report-2023)
105
+ </example>
106
+ <example>
107
+ 以上信息主要基于业内测评和公开发布会(例如2025年4月16日的发布内容)的报道,详细介绍了 O3 与 O4-mini 模型在多模态推理、工具使用、模拟推理和成本效益等方面的综合提升。[^1][^2]
108
+
109
+ [^1]: [OpenAI发布o3与o4-mini,性能爆表,可用图像思考](https://zhuanlan.zhihu.com/p/1896105931709849860)
110
+ [^2]: [OpenAI发新模型o3和o4-mini!首次实现“图像思维”(华尔街见闻)](https://wallstreetcn.com/articles/3745356)
111
+ </example>
112
+ </citation_examples>
99
113
  </citation_requirements>
100
114
 
101
115
  <response_format>
@@ -106,15 +120,10 @@ When providing information from web searches:
106
120
  4. List all sources at the end of your response
107
121
  5. For time-sensitive information, note when the information was retrieved
108
122
 
109
- Example:
110
-
111
- According to recent studies, global temperatures have risen by 1.1°C since pre-industrial times[^1].
112
-
113
- [^1]: [Climate Report in 2023](https://example.org/climate-report-2023)
114
123
  </response_format>
115
124
 
116
- <searxng_description>
117
- SearXNG is a metasearch engine that can leverage multiple search engines including:
125
+ <search_service_description>
126
+ Our search service is a metasearch engine that can leverage multiple search engines including:
118
127
  - Google: World's most popular search engine providing broad web results
119
128
  - Bilibili: Chinese video sharing website focused on animation, comics, and games (aka B-site)
120
129
  - Bing: Microsoft's search engine providing web results with emphasis on visual search
@@ -135,7 +144,7 @@ SearXNG is a metasearch engine that can leverage multiple search engines includi
135
144
  - YouTube: Video sharing platform for searching various video content
136
145
 
137
146
  <search_syntax>
138
- SearXNG has special search syntax to modify the categories, engines, and language of searches:
147
+ Search service has special search syntax to modify the categories, engines, and language of searches:
139
148
 
140
149
  1. Use \`!\` to select engines and categories:
141
150
  - Search for "paris" in the "map" category: \`!map paris\`
@@ -148,7 +157,7 @@ SearXNG is a metasearch engine that can leverage multiple search engines includi
148
157
  3. Use \`site:\` to restrict results to a specific website:
149
158
  - Search SearXNG from a specific website: \`site:github.com SearXNG\`
150
159
  </search_syntax>
151
- </searxng_description>
160
+ </search_service_description>
152
161
 
153
162
  <crawling_best_practices>
154
163
  - Only crawl pages that are publicly accessible
@@ -0,0 +1,44 @@
1
+ export interface SearchParams {
2
+ searchCategories?: string[];
3
+ searchEngines?: string[];
4
+ searchTimeRange?: string;
5
+ }
6
+
7
+ export interface SearchQuery extends SearchParams {
8
+ query: string;
9
+ }
10
+
11
+ export const SEARCH_SEARXNG_NOT_CONFIG = 'SearXNG is not configured';
12
+
13
+ export interface SearchContent {
14
+ content?: string;
15
+ img_src?: string;
16
+ publishedDate?: string | null;
17
+ thumbnail?: string | null;
18
+ title: string;
19
+ url: string;
20
+ }
21
+
22
+ export interface UniformSearchResult {
23
+ category?: string;
24
+ content: string;
25
+ engines: string[];
26
+ /**
27
+ * 视频会用到
28
+ */
29
+ iframeSrc?: string;
30
+ imgSrc?: string;
31
+ parsedUrl: string;
32
+ publishedDate?: string;
33
+ score: number;
34
+ thumbnail?: string;
35
+ title: string;
36
+ url: string;
37
+ }
38
+
39
+ export interface UniformSearchResponse {
40
+ costTime: number;
41
+ query: string;
42
+ resultNumbers: number;
43
+ results: UniformSearchResult[];
44
+ }
@@ -1,48 +0,0 @@
1
- // @vitest-environment node
2
- import { beforeEach, describe, expect, it, vi } from 'vitest';
3
-
4
- import { toolsEnv } from '@/config/tools';
5
- import { isServerMode } from '@/const/version';
6
- /**
7
- * This file contains the root router of your tRPC-backend
8
- */
9
- import { createCallerFactory } from '@/libs/trpc/lambda';
10
- import { AuthContext, createContextInner } from '@/libs/trpc/lambda/context';
11
- import { SearXNGClient } from '@/server/modules/SearXNG';
12
-
13
- import { searchRouter } from '../search';
14
- import { hetongxue } from './fixtures/searXNG';
15
-
16
- vi.mock('@/config/tools', () => ({
17
- toolsEnv: {
18
- SEARXNG_URL: 'https://demo.com',
19
- },
20
- }));
21
-
22
- vi.mock('@/const/version', () => ({
23
- isServerMode: true,
24
- isDesktop: false,
25
- }));
26
-
27
- const createCaller = createCallerFactory(searchRouter);
28
- let ctx: AuthContext;
29
- let router: ReturnType<typeof createCaller>;
30
-
31
- beforeEach(async () => {
32
- vi.resetAllMocks();
33
- ctx = await createContextInner({ userId: 'mock' });
34
- router = createCaller(ctx);
35
- });
36
-
37
- describe('searchRouter', () => {
38
- describe('search', () => {
39
- it('搜索结果超过10个', async () => {
40
- vi.spyOn(SearXNGClient.prototype, 'search').mockResolvedValueOnce(hetongxue);
41
-
42
- const results = await router.query({ query: '何同学' });
43
-
44
- // Assert
45
- expect(results.results.length).toEqual(43);
46
- });
47
- });
48
- });
@@ -1,48 +0,0 @@
1
- export interface SearchQuery {
2
- optionalParams?: {
3
- searchCategories?: string[];
4
- searchEngines?: string[];
5
- searchTimeRange?: string;
6
- };
7
- query: string;
8
- }
9
-
10
- export const SEARCH_SEARXNG_NOT_CONFIG = 'SearXNG is not configured';
11
-
12
- export interface SearchResponse {
13
- answers: any[];
14
- corrections: any[];
15
- infoboxes: any[];
16
- number_of_results: number;
17
- query: string;
18
- results: SearchResult[];
19
- suggestions: string[];
20
- unresponsive_engines: any[];
21
- }
22
-
23
- export interface SearchResult {
24
- category: string;
25
- content?: string;
26
- engine: string;
27
- engines: string[];
28
- iframe_src?: string;
29
- img_src?: string;
30
- parsed_url: string[];
31
- positions: number[];
32
- publishedDate?: string | null;
33
- score: number;
34
- template: string;
35
- thumbnail?: string | null;
36
- thumbnail_src?: string | null;
37
- title: string;
38
- url: string;
39
- }
40
-
41
- export interface SearchContent {
42
- content?: string;
43
- img_src?: string;
44
- publishedDate?: string | null;
45
- thumbnail?: string | null;
46
- title: string;
47
- url: string;
48
- }