@lobehub/chat 0.68.1 → 0.69.1
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/.eslintrc.js +1 -0
- package/.github/workflows/wiki-sync.yml +18 -0
- package/.i18nrc.js +1 -1
- package/CHANGELOG.md +50 -0
- package/README-zh_CN.md +44 -90
- package/README.md +30 -76
- package/docs/Home.md +26 -0
- package/docs/Plugin-Development.en-US.md +262 -0
- package/docs/Plugin-Development.zh-CN.md +261 -0
- package/docs/_Footer.md +1 -0
- package/docs/_Sidebar.md +16 -0
- package/package.json +3 -3
- package/src/components/EmojiPicker/style.ts +3 -1
- package/src/components/Empty/index.tsx +6 -3
- package/src/components/Empty/style.ts +3 -0
- package/src/features/AvatarWithUpload/index.tsx +3 -1
- package/src/features/PluginDevModal/index.tsx +1 -1
- package/src/pages/_document.page.tsx +5 -6
- package/src/pages/api/openai.ts +33 -36
- package/src/pages/chat/SessionList/Header.tsx +2 -0
- package/src/pages/chat/features/Conversation/ChatList/Plugins/IFrameRender/index.tsx +1 -1
- package/src/pages/chat/features/Conversation/ChatList/Plugins/IFrameRender/utils.ts +1 -1
- package/src/pages/chat/features/Conversation/ChatList/Plugins/SystemJsRender/index.tsx +1 -1
- package/src/pages/welcome/Footer/index.tsx +3 -1
- package/src/services/chatModel.ts +1 -2
- package/src/store/plugin/selectors.ts +1 -1
- package/src/types/openai.ts +23 -0
package/src/pages/api/openai.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { OpenAIStream,
|
|
2
|
-
import {
|
|
1
|
+
import { OpenAIStream, StreamingTextResponse } from 'ai';
|
|
2
|
+
import OpenAI, { ClientOptions } from 'openai';
|
|
3
3
|
|
|
4
4
|
import { getServerConfig } from '@/config/server';
|
|
5
5
|
import { createErrorResponse } from '@/pages/api/error';
|
|
@@ -10,25 +10,29 @@ import { OpenAIStreamPayload } from '@/types/openai';
|
|
|
10
10
|
export const createOpenAI = (userApiKey: string | null, endpoint?: string | null) => {
|
|
11
11
|
const { OPENAI_API_KEY, OPENAI_PROXY_URL } = getServerConfig();
|
|
12
12
|
|
|
13
|
-
const
|
|
13
|
+
const baseURL = endpoint ? endpoint : OPENAI_PROXY_URL ? OPENAI_PROXY_URL : undefined;
|
|
14
|
+
|
|
15
|
+
const config: ClientOptions = {
|
|
14
16
|
apiKey: !userApiKey ? OPENAI_API_KEY : userApiKey,
|
|
15
|
-
}
|
|
17
|
+
};
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
// a bug with openai: https://github.com/openai/openai-node/issues/283
|
|
20
|
+
// TODO: should refactor when openai fix the bug
|
|
21
|
+
if (baseURL) {
|
|
22
|
+
config.baseURL = baseURL;
|
|
23
|
+
}
|
|
18
24
|
|
|
19
|
-
return new
|
|
25
|
+
return new OpenAI(config);
|
|
20
26
|
};
|
|
21
27
|
|
|
22
28
|
interface CreateChatCompletionOptions {
|
|
23
29
|
OPENAI_API_KEY: string | null;
|
|
24
|
-
callbacks?: (payload: OpenAIStreamPayload) => OpenAIStreamCallbacks;
|
|
25
30
|
endpoint?: string | null;
|
|
26
31
|
payload: OpenAIStreamPayload;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
export const createChatCompletion = async ({
|
|
30
35
|
payload,
|
|
31
|
-
callbacks,
|
|
32
36
|
OPENAI_API_KEY,
|
|
33
37
|
endpoint,
|
|
34
38
|
}: CreateChatCompletionOptions) => {
|
|
@@ -47,37 +51,30 @@ export const createChatCompletion = async ({
|
|
|
47
51
|
|
|
48
52
|
// ============ 2. 发送请求 ============ //
|
|
49
53
|
|
|
50
|
-
const requestParams = { messages: formatMessages, stream: true, ...params };
|
|
51
|
-
|
|
52
|
-
let response: Response;
|
|
53
|
-
|
|
54
54
|
try {
|
|
55
|
-
response = await openai.
|
|
55
|
+
const response = await openai.chat.completions.create({
|
|
56
|
+
messages: formatMessages,
|
|
57
|
+
...params,
|
|
58
|
+
stream: true,
|
|
59
|
+
});
|
|
60
|
+
const stream = OpenAIStream(response);
|
|
61
|
+
return new StreamingTextResponse(stream);
|
|
56
62
|
} catch (error) {
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
let error;
|
|
64
|
-
|
|
65
|
-
try {
|
|
66
|
-
// 正常情况下应该是 OpenAI 的 JSON
|
|
67
|
-
error = await response.clone().json();
|
|
68
|
-
} catch {
|
|
69
|
-
// 如果不是 JSON,那么可能是其他接口端的响应,读 text 为结果
|
|
70
|
-
const result = await response.text();
|
|
71
|
-
|
|
72
|
-
error = { message: result };
|
|
63
|
+
// Check if the error is an OpenAI APIError
|
|
64
|
+
if (error instanceof OpenAI.APIError) {
|
|
65
|
+
return createErrorResponse(ChatErrorType.OpenAIBizError, {
|
|
66
|
+
endpoint: !!endpoint ? endpoint : undefined,
|
|
67
|
+
error: error.error ?? error.cause,
|
|
68
|
+
});
|
|
73
69
|
}
|
|
74
70
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
// ============ 5. 发送正常相应 ============ //
|
|
79
|
-
|
|
80
|
-
const stream = OpenAIStream(response, callbacks?.(requestParams));
|
|
71
|
+
// track the error that not an OpenAI APIError
|
|
72
|
+
console.error(error);
|
|
81
73
|
|
|
82
|
-
|
|
74
|
+
// return as a GatewayTimeout error
|
|
75
|
+
return createErrorResponse(ChatErrorType.InternalServerError, {
|
|
76
|
+
endpoint,
|
|
77
|
+
error: JSON.stringify(error),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
83
80
|
};
|
|
@@ -63,8 +63,10 @@ const Header = memo<{ mobile?: 'navbar' | 'search' }>(({ mobile }) => {
|
|
|
63
63
|
</Flexbox>
|
|
64
64
|
<SearchBar
|
|
65
65
|
allowClear
|
|
66
|
+
enableShortKey
|
|
66
67
|
onChange={(e) => useSessionStore.setState({ searchKeywords: e.target.value })}
|
|
67
68
|
placeholder={t('searchAgentPlaceholder')}
|
|
69
|
+
shortKey={'k'}
|
|
68
70
|
spotlight
|
|
69
71
|
type={'ghost'}
|
|
70
72
|
value={keywords}
|
|
@@ -11,7 +11,9 @@ const Footer = memo(() => {
|
|
|
11
11
|
|
|
12
12
|
return (
|
|
13
13
|
<Flexbox align={'center'} horizontal justify={'space-between'} style={{ padding: 16 }}>
|
|
14
|
-
<span style={{ color: theme.colorTextDescription }}
|
|
14
|
+
<span style={{ color: theme.colorTextDescription }}>
|
|
15
|
+
©{new Date().getFullYear()} LobeHub
|
|
16
|
+
</span>
|
|
15
17
|
<Flexbox horizontal>
|
|
16
18
|
<ActionIcon
|
|
17
19
|
icon={DiscordIcon}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { merge } from 'lodash-es';
|
|
2
|
-
import { ChatCompletionFunctions } from 'openai-edge/types/api';
|
|
3
2
|
|
|
4
3
|
import { LOBE_CHAT_ACCESS_CODE, OPENAI_API_KEY_HEADER_KEY, OPENAI_END_POINT } from '@/const/fetch';
|
|
5
4
|
import { useGlobalStore } from '@/store/global';
|
|
6
5
|
import { pluginSelectors, usePluginStore } from '@/store/plugin';
|
|
7
6
|
import { initialLobeAgentConfig } from '@/store/session/initialState';
|
|
8
|
-
import type { OpenAIStreamPayload } from '@/types/openai';
|
|
7
|
+
import type { ChatCompletionFunctions, OpenAIStreamPayload } from '@/types/openai';
|
|
9
8
|
|
|
10
9
|
import { URLS } from './url';
|
|
11
10
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { uniqBy } from 'lodash-es';
|
|
2
|
-
import { ChatCompletionFunctions } from 'openai-edge/types/api';
|
|
3
2
|
|
|
4
3
|
import { PLUGIN_SCHEMA_SEPARATOR } from '@/const/plugin';
|
|
5
4
|
import { pluginHelpers } from '@/store/plugin/helpers';
|
|
5
|
+
import { ChatCompletionFunctions } from '@/types/openai';
|
|
6
6
|
|
|
7
7
|
import { PluginStoreState } from './initialState';
|
|
8
8
|
|
package/src/types/openai.ts
CHANGED
|
@@ -68,3 +68,26 @@ export interface OpenAIStreamPayload {
|
|
|
68
68
|
*/
|
|
69
69
|
top_p?: number;
|
|
70
70
|
}
|
|
71
|
+
|
|
72
|
+
export interface ChatCompletionFunctions {
|
|
73
|
+
/**
|
|
74
|
+
* The description of what the function does.
|
|
75
|
+
* @type {string}
|
|
76
|
+
* @memberof ChatCompletionFunctions
|
|
77
|
+
*/
|
|
78
|
+
description?: string;
|
|
79
|
+
/**
|
|
80
|
+
* The name of the function to be called. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 64.
|
|
81
|
+
* @type {string}
|
|
82
|
+
* @memberof ChatCompletionFunctions
|
|
83
|
+
*/
|
|
84
|
+
name: string;
|
|
85
|
+
/**
|
|
86
|
+
* The parameters the functions accepts, described as a JSON Schema object. See the [guide](/docs/guides/gpt/function-calling) for examples, and the [JSON Schema reference](https://json-schema.org/understanding-json-schema/) for documentation about the format.
|
|
87
|
+
* @type {{ [key: string]: any }}
|
|
88
|
+
* @memberof ChatCompletionFunctions
|
|
89
|
+
*/
|
|
90
|
+
parameters?: {
|
|
91
|
+
[key: string]: any;
|
|
92
|
+
};
|
|
93
|
+
}
|