@lobehub/chat 0.54.2 → 0.54.4
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.
- package/CHANGELOG.md +50 -0
- package/package.json +2 -3
- package/src/pages/api/plugins.api.ts +6 -18
- package/src/plugins/searchEngine/index.ts +1 -5
- package/src/plugins/type.ts +2 -16
- package/src/plugins/weather/index.ts +1 -5
- package/src/plugins/webCrawler/index.ts +1 -4
- package/src/services/plugin.ts +3 -2
- package/src/store/global/slices/agent.ts +2 -2
- package/src/store/global/slices/settings.ts +1 -1
- package/src/plugins/searchEngine/runner.ts +0 -41
- package/src/plugins/weather/runner.ts +0 -35
- package/src/plugins/webCrawler/runner.ts +0 -46
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
### [Version 0.54.4](https://github.com/lobehub/lobe-chat/compare/v0.54.3...v0.54.4)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2023-08-21**</sup>
|
|
8
|
+
|
|
9
|
+
#### 🐛 Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **misc**: Fix not cannot change setting error.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's fixed
|
|
19
|
+
|
|
20
|
+
- **misc**: Fix not cannot change setting error, closes [#86](https://github.com/lobehub/lobe-chat/issues/86) ([6405c28](https://github.com/lobehub/lobe-chat/commit/6405c28))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
### [Version 0.54.3](https://github.com/lobehub/lobe-chat/compare/v0.54.2...v0.54.3)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2023-08-21**</sup>
|
|
33
|
+
|
|
34
|
+
#### ♻ Code Refactoring
|
|
35
|
+
|
|
36
|
+
- **misc**: Refactor plugin request.
|
|
37
|
+
|
|
38
|
+
<br/>
|
|
39
|
+
|
|
40
|
+
<details>
|
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
42
|
+
|
|
43
|
+
#### Code refactoring
|
|
44
|
+
|
|
45
|
+
- **misc**: Refactor plugin request, closes [#89](https://github.com/lobehub/lobe-chat/issues/89) ([23efee3](https://github.com/lobehub/lobe-chat/commit/23efee3))
|
|
46
|
+
|
|
47
|
+
</details>
|
|
48
|
+
|
|
49
|
+
<div align="right">
|
|
50
|
+
|
|
51
|
+
[](#readme-top)
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
|
|
5
55
|
### [Version 0.54.2](https://github.com/lobehub/lobe-chat/compare/v0.54.1...v0.54.2)
|
|
6
56
|
|
|
7
57
|
<sup>Released on **2023-08-16**</sup>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "0.54.
|
|
3
|
+
"version": "0.54.4",
|
|
4
4
|
"description": "Lobe Chat is an open-source chatbot client using LangChain, Typescript and Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chatbot",
|
|
@@ -63,10 +63,10 @@
|
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@ant-design/colors": "^7",
|
|
65
65
|
"@ant-design/icons": "^5",
|
|
66
|
-
"@commitlint/cli": "^17",
|
|
67
66
|
"@emoji-mart/data": "^1",
|
|
68
67
|
"@emoji-mart/react": "^1",
|
|
69
68
|
"@icons-pack/react-simple-icons": "^8",
|
|
69
|
+
"@lobehub/chat-plugin-sdk": "latest",
|
|
70
70
|
"@lobehub/ui": "latest",
|
|
71
71
|
"@vercel/analytics": "^1",
|
|
72
72
|
"ahooks": "^3",
|
|
@@ -86,7 +86,6 @@
|
|
|
86
86
|
"next": "13.4.7",
|
|
87
87
|
"openai-edge": "^1",
|
|
88
88
|
"polished": "^4",
|
|
89
|
-
"query-string": "^8",
|
|
90
89
|
"react": "^18",
|
|
91
90
|
"react-dom": "^18",
|
|
92
91
|
"react-hotkeys-hook": "^4",
|
|
@@ -1,22 +1,10 @@
|
|
|
1
|
-
import { OpenAIPluginPayload } from '@/types/plugin';
|
|
2
|
-
|
|
3
|
-
import { PluginsMap } from '../../plugins';
|
|
4
|
-
|
|
5
1
|
export const runtime = 'edge';
|
|
6
2
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
console.log(`检测到 functionCall: ${name}`);
|
|
3
|
+
// chat plugin gateway
|
|
4
|
+
// refs to: https://github.com/lobehub/chat-plugins-gateway
|
|
5
|
+
const PLUGIN_GATEWAY_URL = process.env.PLUGIN_GATEWAY_URL || 'https://chat-plugins.lobehub.com';
|
|
11
6
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const data = JSON.parse(args);
|
|
16
|
-
const result = await func.runner(data);
|
|
17
|
-
|
|
18
|
-
console.log(`[${name}]`, args, `result:`, JSON.stringify(result, null, 2).slice(0, 3600));
|
|
19
|
-
|
|
20
|
-
return new Response(JSON.stringify(result));
|
|
21
|
-
}
|
|
7
|
+
export default async function handler(req: Request) {
|
|
8
|
+
const payload = await req.text();
|
|
9
|
+
return fetch(`${PLUGIN_GATEWAY_URL}/api/v1/runner`, { body: payload, method: 'POST' });
|
|
22
10
|
}
|
|
@@ -2,9 +2,6 @@ import { ChatCompletionFunctions } from 'openai-edge/types/api';
|
|
|
2
2
|
|
|
3
3
|
import { PluginItem } from '@/plugins/type';
|
|
4
4
|
|
|
5
|
-
import runner from './runner';
|
|
6
|
-
import { Result } from './type';
|
|
7
|
-
|
|
8
5
|
const schema: ChatCompletionFunctions = {
|
|
9
6
|
description: '查询搜索引擎获取信息',
|
|
10
7
|
name: 'searchEngine',
|
|
@@ -20,10 +17,9 @@ const schema: ChatCompletionFunctions = {
|
|
|
20
17
|
},
|
|
21
18
|
};
|
|
22
19
|
|
|
23
|
-
const searchEngine: PluginItem
|
|
20
|
+
const searchEngine: PluginItem = {
|
|
24
21
|
avatar: '🔍',
|
|
25
22
|
name: 'searchEngine',
|
|
26
|
-
runner,
|
|
27
23
|
schema,
|
|
28
24
|
};
|
|
29
25
|
|
package/src/plugins/type.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { ReactNode } from 'react';
|
|
|
6
6
|
* @template Result - 结果类型,默认为 any
|
|
7
7
|
* @template RunnerParams - 运行参数类型,默认为 any
|
|
8
8
|
*/
|
|
9
|
-
export interface PluginItem
|
|
9
|
+
export interface PluginItem {
|
|
10
10
|
/**
|
|
11
11
|
* 头像
|
|
12
12
|
*/
|
|
@@ -15,12 +15,7 @@ export interface PluginItem<Result = any, RunnerParams = any> {
|
|
|
15
15
|
* 名称
|
|
16
16
|
*/
|
|
17
17
|
name: string;
|
|
18
|
-
|
|
19
|
-
* 运行器
|
|
20
|
-
* @param params - 运行参数
|
|
21
|
-
* @returns 运行结果的 Promise
|
|
22
|
-
*/
|
|
23
|
-
runner: PluginRunner<RunnerParams, Result>;
|
|
18
|
+
render?: PluginRender;
|
|
24
19
|
/**
|
|
25
20
|
* 聊天完成函数的模式
|
|
26
21
|
*/
|
|
@@ -34,15 +29,6 @@ export interface PluginItem<Result = any, RunnerParams = any> {
|
|
|
34
29
|
*/
|
|
35
30
|
export type PluginRender = (props: PluginRenderProps) => ReactNode;
|
|
36
31
|
|
|
37
|
-
/**
|
|
38
|
-
* 插件运行器
|
|
39
|
-
* @template Params - 参数类型,默认为 object
|
|
40
|
-
* @template Result - 结果类型,默认为 any
|
|
41
|
-
* @param params - 运行参数
|
|
42
|
-
* @returns 运行结果的 Promise
|
|
43
|
-
*/
|
|
44
|
-
export type PluginRunner<Params = object, Result = any> = (params: Params) => Promise<Result>;
|
|
45
|
-
|
|
46
32
|
/**
|
|
47
33
|
* 插件渲染属性
|
|
48
34
|
* @template Result - 结果类型,默认为 any
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import { PluginItem } from '@/plugins/type';
|
|
2
|
-
import { WeatherResult } from '@/plugins/weather/type';
|
|
3
|
-
|
|
4
|
-
import runner from './runner';
|
|
5
2
|
|
|
6
3
|
const schema = {
|
|
7
4
|
description: '获取当前天气情况',
|
|
@@ -18,10 +15,9 @@ const schema = {
|
|
|
18
15
|
},
|
|
19
16
|
};
|
|
20
17
|
|
|
21
|
-
const getWeather: PluginItem
|
|
18
|
+
const getWeather: PluginItem = {
|
|
22
19
|
avatar: '☂️',
|
|
23
20
|
name: 'realtimeWeather',
|
|
24
|
-
runner,
|
|
25
21
|
schema,
|
|
26
22
|
};
|
|
27
23
|
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { PluginItem } from '@/plugins/type';
|
|
2
2
|
|
|
3
|
-
import runner from './runner';
|
|
4
|
-
import { Result } from './type';
|
|
5
|
-
|
|
6
3
|
const schema = {
|
|
7
4
|
description: '提取网页内容并总结',
|
|
8
5
|
name: 'websiteCrawler',
|
|
@@ -18,6 +15,6 @@ const schema = {
|
|
|
18
15
|
},
|
|
19
16
|
};
|
|
20
17
|
|
|
21
|
-
const getWeather: PluginItem
|
|
18
|
+
const getWeather: PluginItem = { avatar: '🕸', name: 'websiteCrawler', schema };
|
|
22
19
|
|
|
23
20
|
export default getWeather;
|
package/src/services/plugin.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { PluginRequestPayload } from '@lobehub/chat-plugin-sdk';
|
|
2
|
+
|
|
1
3
|
import { LOBE_CHAT_ACCESS_CODE } from '@/const/fetch';
|
|
2
4
|
import { useGlobalStore } from '@/store/global';
|
|
3
|
-
import { OpenAIPluginPayload } from '@/types/plugin';
|
|
4
5
|
|
|
5
6
|
import { URLS } from './url';
|
|
6
7
|
|
|
@@ -13,7 +14,7 @@ interface FetchChatModelOptions {
|
|
|
13
14
|
* 专门用于对话的 fetch
|
|
14
15
|
*/
|
|
15
16
|
export const fetchPlugin = async (
|
|
16
|
-
params:
|
|
17
|
+
params: PluginRequestPayload,
|
|
17
18
|
options?: FetchChatModelOptions,
|
|
18
19
|
) => {
|
|
19
20
|
const res = await fetch(URLS.plugins, {
|
|
@@ -52,7 +52,7 @@ export const createAgentSlice: StateCreator<
|
|
|
52
52
|
setAgentConfig: (config) => {
|
|
53
53
|
const settings = produce(get().settings, (draft: GlobalSettings) => {
|
|
54
54
|
const oldConfig = draft.defaultAgent.config as LobeAgentConfig;
|
|
55
|
-
draft.defaultAgent.config = merge(oldConfig, config);
|
|
55
|
+
draft.defaultAgent.config = merge({}, oldConfig, config);
|
|
56
56
|
});
|
|
57
57
|
|
|
58
58
|
set({ settings }, false, t('setAgentConfig', config));
|
|
@@ -60,7 +60,7 @@ export const createAgentSlice: StateCreator<
|
|
|
60
60
|
setAgentMeta: (meta) => {
|
|
61
61
|
const settings = produce(get().settings, (draft) => {
|
|
62
62
|
const oldMeta = draft.defaultAgent.meta as MetaData;
|
|
63
|
-
draft.defaultAgent.meta = merge(oldMeta, meta);
|
|
63
|
+
draft.defaultAgent.meta = merge({}, oldMeta, meta);
|
|
64
64
|
});
|
|
65
65
|
|
|
66
66
|
set({ settings }, false, t('setAgentMeta', meta));
|
|
@@ -61,7 +61,7 @@ export const createSettingsSlice: StateCreator<
|
|
|
61
61
|
|
|
62
62
|
setSettings: (settings) => {
|
|
63
63
|
const oldSetting = get().settings;
|
|
64
|
-
set({ settings: merge(oldSetting, settings) }, false, t('setSettings', settings));
|
|
64
|
+
set({ settings: merge({}, oldSetting, settings) }, false, t('setSettings', settings));
|
|
65
65
|
},
|
|
66
66
|
switchThemeMode: (themeMode) => {
|
|
67
67
|
get().setSettings({ themeMode });
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import querystring from 'query-string';
|
|
2
|
-
|
|
3
|
-
import { PluginRunner } from '@/plugins/type';
|
|
4
|
-
|
|
5
|
-
import { OrganicResults, Result } from './type';
|
|
6
|
-
|
|
7
|
-
const BASE_URL = 'https://serpapi.com/search';
|
|
8
|
-
|
|
9
|
-
const API_KEY = process.env.SERPAI_API_KEY;
|
|
10
|
-
|
|
11
|
-
const fetchResult: PluginRunner<{ keywords: string }, Result> = async ({ keywords }) => {
|
|
12
|
-
const params = {
|
|
13
|
-
api_key: API_KEY,
|
|
14
|
-
engine: 'google',
|
|
15
|
-
gl: 'cn',
|
|
16
|
-
google_domain: 'google.com',
|
|
17
|
-
hl: 'zh-cn',
|
|
18
|
-
location: 'China',
|
|
19
|
-
q: keywords,
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const query = querystring.stringify(params);
|
|
23
|
-
|
|
24
|
-
const res = await fetch(`${BASE_URL}?${query}`);
|
|
25
|
-
|
|
26
|
-
const data = await res.json();
|
|
27
|
-
|
|
28
|
-
const results = data.organic_results as OrganicResults;
|
|
29
|
-
|
|
30
|
-
return results.map((r) => ({
|
|
31
|
-
content: r.snippet,
|
|
32
|
-
date: r.date,
|
|
33
|
-
displayed_link: r.displayed_link,
|
|
34
|
-
favicon: r.favicon,
|
|
35
|
-
link: r.link,
|
|
36
|
-
source: r.source,
|
|
37
|
-
title: r.title,
|
|
38
|
-
}));
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export default fetchResult;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { PluginRunner } from '@/plugins/type';
|
|
2
|
-
|
|
3
|
-
import { Response, WeatherParams, WeatherResult } from './type';
|
|
4
|
-
|
|
5
|
-
const weatherBaseURL = 'https://restapi.amap.com/v3/weather/weatherInfo';
|
|
6
|
-
|
|
7
|
-
const citySearchURL = 'https://restapi.amap.com/v3/config/district';
|
|
8
|
-
|
|
9
|
-
const KEY = process.env.GAODE_WEATHER_KEY;
|
|
10
|
-
|
|
11
|
-
const fetchCityCode = async (keywords: string): Promise<string> => {
|
|
12
|
-
const URL = `${citySearchURL}?keywords=${keywords}&subdistrict=0&extensions=base&key=${KEY}`;
|
|
13
|
-
const res = await fetch(URL);
|
|
14
|
-
|
|
15
|
-
const data = await res.json();
|
|
16
|
-
console.log(data);
|
|
17
|
-
|
|
18
|
-
return data.districts[0].adcode;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const fetchWeather: PluginRunner<WeatherParams, WeatherResult> = async ({
|
|
22
|
-
city,
|
|
23
|
-
extensions = 'all',
|
|
24
|
-
}) => {
|
|
25
|
-
const cityCode = await fetchCityCode(city);
|
|
26
|
-
|
|
27
|
-
const URL = `${weatherBaseURL}?city=${cityCode}&extensions=${extensions}&key=${KEY}`;
|
|
28
|
-
const res = await fetch(URL);
|
|
29
|
-
|
|
30
|
-
const data: Response = await res.json();
|
|
31
|
-
|
|
32
|
-
return data.forecasts;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export default fetchWeather;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { PluginRunner } from '@/plugins/type';
|
|
2
|
-
|
|
3
|
-
import { ParserResponse, Result } from './type';
|
|
4
|
-
|
|
5
|
-
const BASE_URL = process.env.BROWSERLESS_URL ?? 'https://chrome.browserless.io';
|
|
6
|
-
const BROWSERLESS_TOKEN = process.env.BROWSERLESS_TOKEN;
|
|
7
|
-
|
|
8
|
-
// service from: https://github.com/lobehub/html-parser/tree/master
|
|
9
|
-
const HTML_PARSER_URL = process.env.HTML_PARSER_URL;
|
|
10
|
-
|
|
11
|
-
const runner: PluginRunner<{ url: string }, Result> = async ({ url }) => {
|
|
12
|
-
const input = {
|
|
13
|
-
gotoOptions: { waitUntil: 'networkidle2' },
|
|
14
|
-
url,
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
try {
|
|
18
|
-
const res = await fetch(`${BASE_URL}/content?token=${BROWSERLESS_TOKEN}`, {
|
|
19
|
-
body: JSON.stringify(input),
|
|
20
|
-
headers: {
|
|
21
|
-
'Content-Type': 'application/json',
|
|
22
|
-
},
|
|
23
|
-
method: 'POST',
|
|
24
|
-
});
|
|
25
|
-
const html = await res.text();
|
|
26
|
-
|
|
27
|
-
const parserBody = { html, url };
|
|
28
|
-
|
|
29
|
-
const parseRes = await fetch(`${HTML_PARSER_URL}`, {
|
|
30
|
-
body: JSON.stringify(parserBody),
|
|
31
|
-
headers: {
|
|
32
|
-
'Content-Type': 'application/json',
|
|
33
|
-
},
|
|
34
|
-
method: 'POST',
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
const { title, textContent, siteName } = (await parseRes.json()) as ParserResponse;
|
|
38
|
-
|
|
39
|
-
return { content: textContent, title, url, website: siteName };
|
|
40
|
-
} catch (error) {
|
|
41
|
-
console.error(error);
|
|
42
|
-
return { content: '抓取失败', errorMessage: (error as any).message, url };
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export default runner;
|