@saber2pr/ai-assistant 0.0.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.
Files changed (58) hide show
  1. package/ReadMe.md +57 -0
  2. package/lib/app.d.ts +1 -0
  3. package/lib/app.js +27 -0
  4. package/lib/chat.d.ts +3 -0
  5. package/lib/chat.js +222 -0
  6. package/lib/chat.style.d.ts +12 -0
  7. package/lib/chat.style.js +20 -0
  8. package/lib/components/Codeblock/index.d.ts +9 -0
  9. package/lib/components/Codeblock/index.js +55 -0
  10. package/lib/components/Codeblock/index.style.d.ts +1 -0
  11. package/lib/components/Codeblock/index.style.js +13 -0
  12. package/lib/components/MarkdownText/index.d.ts +3 -0
  13. package/lib/components/MarkdownText/index.js +71 -0
  14. package/lib/components/MyRuntimeProvider/index.d.ts +5 -0
  15. package/lib/components/MyRuntimeProvider/index.js +22 -0
  16. package/lib/components/MyRuntimeProvider/myModelAdapterStream.d.ts +4 -0
  17. package/lib/components/MyRuntimeProvider/myModelAdapterStream.js +180 -0
  18. package/lib/components/Thread/index.d.ts +2 -0
  19. package/lib/components/Thread/index.js +286 -0
  20. package/lib/components/Thread/index.style.d.ts +15 -0
  21. package/lib/components/Thread/index.style.js +18 -0
  22. package/lib/components/ThreadList/index.d.ts +4 -0
  23. package/lib/components/ThreadList/index.js +131 -0
  24. package/lib/constants/index.d.ts +1 -0
  25. package/lib/constants/index.js +4 -0
  26. package/lib/context.d.ts +3 -0
  27. package/lib/context.js +8 -0
  28. package/lib/hooks/useAsync.d.ts +14 -0
  29. package/lib/hooks/useAsync.js +105 -0
  30. package/lib/hooks/useCopy.d.ts +5 -0
  31. package/lib/hooks/useCopy.js +48 -0
  32. package/lib/hooks/useI18n.d.ts +5 -0
  33. package/lib/hooks/useI18n.js +16 -0
  34. package/lib/i18n/i18n.d.ts +14 -0
  35. package/lib/i18n/i18n.js +31 -0
  36. package/lib/i18n/index.d.ts +6 -0
  37. package/lib/i18n/index.js +7 -0
  38. package/lib/i18n/locale.d.ts +4 -0
  39. package/lib/i18n/locale.js +7 -0
  40. package/lib/i18n/locales.d.ts +36 -0
  41. package/lib/i18n/locales.js +37 -0
  42. package/lib/index.d.ts +1 -0
  43. package/lib/index.js +17 -0
  44. package/lib/llm/context.d.ts +3 -0
  45. package/lib/llm/context.js +10 -0
  46. package/lib/llm/engine.d.ts +6 -0
  47. package/lib/llm/engine.js +53 -0
  48. package/lib/styles.d.ts +6 -0
  49. package/lib/styles.js +18 -0
  50. package/lib/types/assistant.d.ts +53 -0
  51. package/lib/types/assistant.js +2 -0
  52. package/lib/utils/event.d.ts +8 -0
  53. package/lib/utils/event.js +28 -0
  54. package/lib/utils/parseStreamData.d.ts +5 -0
  55. package/lib/utils/parseStreamData.js +33 -0
  56. package/lib/utils/streamRequest.d.ts +4 -0
  57. package/lib/utils/streamRequest.js +150 -0
  58. package/package.json +75 -0
package/ReadMe.md ADDED
@@ -0,0 +1,57 @@
1
+ ### @saber2pr/ai-assistant
2
+
3
+ Quickly customize your GPT UI. **100% Client-side, No Server Required.**
4
+
5
+ ### Installation
6
+
7
+ ```bash
8
+ npm install @saber2pr/ai-assistant
9
+ # or
10
+ yarn add @saber2pr/ai-assistant
11
+ ```
12
+
13
+ ### Quick Start
14
+
15
+ Import and initialize in your project:
16
+
17
+ ```typescript
18
+ import { initAIAssistant } from '@saber2pr/ai-assistant';
19
+
20
+ initAIAssistant({
21
+ welcomeMessage: 'Hello! I am your AI assistant. How can I help you today?',
22
+ suggestions: ['How to use this UI?', 'Tell me about assistant-ui'],
23
+ locale: 'en-US'
24
+ });
25
+ ```
26
+
27
+ ### API Reference
28
+
29
+ #### `initAIAssistant(config?: AIAssistantConfig, container?: HTMLElement)`
30
+
31
+ Initializes and mounts the AI assistant. This assistant runs entirely in the browser using [web-llm](https://github.com/mlc-ai/web-llm), meaning no backend server is required.
32
+
33
+ - `config`: Configuration object (optional)
34
+ - `container`: The DOM container to mount to, defaults to `document.body`
35
+
36
+ #### `AIAssistantConfig`
37
+
38
+ | Parameter | Type | Default | Description |
39
+ | --- | --- | --- | --- |
40
+ | `welcomeMessage` | `string` | - | The welcome message displayed at the top of the chat. |
41
+ | `suggestions` | `string[]` | - | A list of suggested questions to show when the chat is empty. |
42
+ | `placeholder` | `string` | - | The placeholder text for the message input box. |
43
+ | `emptyMessage` | `string` | - | The message displayed when the thread list is empty. |
44
+ | `locale` | `'zh-CN' \| 'en-US'` | `'zh-CN'` | The language locale for the UI. |
45
+ | `containerId` | `string` | `'ai-assistant-root'` | The ID of the container element where the assistant will be mounted. |
46
+ | `initialPosition` | `{ x: number; y: number }` | Bottom-right | The initial coordinates of the floating button. |
47
+ | `onBeforeChat` | `Function` | - | A hook to intercept and modify messages before they are sent to the AI. |
48
+
49
+ ### Local Development
50
+
51
+ Start the service:
52
+
53
+ ```sh
54
+ yarn install
55
+
56
+ yarn dev
57
+ ```
package/lib/app.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/lib/app.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var chat_1 = __importDefault(require("./chat"));
7
+ var h1 = document.createElement('h1');
8
+ h1.textContent = 'Click the bottom right sidebar button to open the AI assistant';
9
+ document.body.append(h1);
10
+ // 默认执行初始化
11
+ (0, chat_1.default)({
12
+ locale: 'en-US'
13
+ // welcomeMessage: '有什么可以帮忙的?',
14
+ // suggestions: ['如何用 Typescript 实现 Helloworld?', '物联网是什么?'],
15
+ // placeholder: '给 GPT 发送消息',
16
+ // emptyMessage: '我是AI,可以回答你的问题,请在下方输入框输入你的需求~',
17
+ // async onBeforeChat(messages) {
18
+ // const knowledgeContent = await fetch('http://localhost:5001/HTML超文本标记语言/移动端禁用双指放大.md').then(res => res.text())
19
+ // return [
20
+ // {
21
+ // role: "system",
22
+ // content: `你是我的博客助手,根据我博客内容回答:移动端禁用双指放大的方法:\n${knowledgeContent}`
23
+ // },
24
+ // ...messages
25
+ // ]
26
+ // },
27
+ });
package/lib/chat.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { AIAssistantConfig } from './types/assistant';
2
+ export declare const initAIAssistant: (config?: AIAssistantConfig, container?: HTMLElement) => void;
3
+ export default initAIAssistant;
package/lib/chat.js ADDED
@@ -0,0 +1,222 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.initAIAssistant = void 0;
40
+ var antd_1 = require("antd");
41
+ var react_1 = __importStar(require("react"));
42
+ var react_dom_1 = __importDefault(require("react-dom"));
43
+ var icons_1 = require("@ant-design/icons");
44
+ var react_2 = require("@assistant-ui/react");
45
+ var MyRuntimeProvider_1 = require("./components/MyRuntimeProvider");
46
+ var Thread_1 = require("./components/Thread");
47
+ var ThreadList_1 = require("./components/ThreadList");
48
+ var context_1 = require("./context");
49
+ var useI18n_1 = require("./hooks/useI18n");
50
+ var context_2 = require("./llm/context");
51
+ var engine_1 = require("./llm/engine");
52
+ var styles_1 = require("./styles");
53
+ var chat_style_1 = require("./chat.style");
54
+ var MyApp = function (_a) {
55
+ var config = _a.config;
56
+ var _b = (0, react_1.useState)(false), open = _b[0], setOpen = _b[1];
57
+ var _c = (0, react_1.useState)('chat'), activeTab = _c[0], setActiveTab = _c[1];
58
+ return (react_1.default.createElement(context_1.AIConfigContext.Provider, { value: config },
59
+ react_1.default.createElement(MyAppContent, { open: open, setOpen: setOpen, activeTab: activeTab, setActiveTab: setActiveTab, config: config })));
60
+ };
61
+ var MyAppContent = function (_a) {
62
+ var open = _a.open, setOpen = _a.setOpen, activeTab = _a.activeTab, setActiveTab = _a.setActiveTab, config = _a.config;
63
+ var t = (0, useI18n_1.useI18n)().t;
64
+ var _b = (0, react_1.useState)(t('loadingModel')), loadingText = _b[0], setLoadingText = _b[1];
65
+ var _c = (0, react_1.useState)(0), loadingProgress = _c[0], setLoadingProgress = _c[1];
66
+ var _d = (0, react_1.useState)(false), loading = _d[0], setLoading = _d[1];
67
+ var _e = (0, react_1.useState)(null), engine = _e[0], setEngine = _e[1];
68
+ var defaultPos = config.initialPosition || { x: window.innerWidth - 100, y: window.innerHeight - 100 };
69
+ var _f = (0, react_1.useState)(defaultPos), position = _f[0], setPosition = _f[1];
70
+ var _g = (0, react_1.useState)(false), isDragging = _g[0], setIsDragging = _g[1];
71
+ var dragStartPos = react_1.default.useRef({ x: 0, y: 0 });
72
+ var buttonPos = react_1.default.useRef(defaultPos);
73
+ var lastWindowSize = react_1.default.useRef({ width: window.innerWidth, height: window.innerHeight });
74
+ // 监听窗口大小变化,修正按钮位置
75
+ (0, react_1.useEffect)(function () {
76
+ var handleResize = function () {
77
+ var currentWidth = window.innerWidth;
78
+ var currentHeight = window.innerHeight;
79
+ setPosition(function (prev) {
80
+ // 计算按钮相对于右侧和底部的距离比例,或者简单的保持吸附状态
81
+ var isAtRight = prev.x > lastWindowSize.current.width / 2;
82
+ var newX = prev.x;
83
+ // 如果原本在右侧,放大窗口时让它跟随右侧边缘
84
+ if (isAtRight) {
85
+ var offsetRight = lastWindowSize.current.width - prev.x;
86
+ newX = currentWidth - offsetRight;
87
+ }
88
+ // 垂直方向同理,如果靠下,保持相对底部的距离
89
+ var isAtBottom = prev.y > lastWindowSize.current.height / 2;
90
+ var newY = prev.y;
91
+ if (isAtBottom) {
92
+ var offsetBottom = lastWindowSize.current.height - prev.y;
93
+ newY = currentHeight - offsetBottom;
94
+ }
95
+ // 最终边界安全检查
96
+ var safeX = Math.max(20, Math.min(newX, currentWidth - 84));
97
+ var safeY = Math.max(20, Math.min(newY, currentHeight - 84));
98
+ buttonPos.current = { x: safeX, y: safeY };
99
+ return { x: safeX, y: safeY };
100
+ });
101
+ lastWindowSize.current = { width: currentWidth, height: currentHeight };
102
+ };
103
+ window.addEventListener('resize', handleResize);
104
+ return function () { return window.removeEventListener('resize', handleResize); };
105
+ }, []);
106
+ // 当语言切换时,更新初始加载文本
107
+ (0, react_1.useEffect)(function () {
108
+ if (!engine && !loading) {
109
+ setLoadingText(t('loadingModel'));
110
+ }
111
+ }, [t, engine, loading]);
112
+ // 当弹窗打开且引擎未加载时,开始加载引擎
113
+ (0, react_1.useEffect)(function () {
114
+ if (open && !engine && !loading) {
115
+ setLoading(true);
116
+ (0, engine_1.getLLMengine)({
117
+ selectedModel: 'Qwen2.5-Coder-0.5B-Instruct-q4f16_1-MLC',
118
+ initProgressCallback: function (initProgress) {
119
+ setLoadingText(initProgress.text);
120
+ setLoadingProgress(Math.round(initProgress.progress * 100));
121
+ if (initProgress.progress === 1) {
122
+ setLoading(false);
123
+ }
124
+ }
125
+ }).then(function (res) {
126
+ setEngine(res);
127
+ }).catch(function (err) {
128
+ console.error('Failed to load LLM engine:', err);
129
+ setLoading(false);
130
+ });
131
+ }
132
+ }, [open, engine, loading]);
133
+ var handleMouseDown = function (e) {
134
+ setIsDragging(false);
135
+ dragStartPos.current = { x: e.clientX, y: e.clientY };
136
+ var onMouseMove = function (moveEvent) {
137
+ var deltaX = Math.abs(moveEvent.clientX - dragStartPos.current.x);
138
+ var deltaY = Math.abs(moveEvent.clientY - dragStartPos.current.y);
139
+ if (deltaX > 5 || deltaY > 5) {
140
+ setIsDragging(true);
141
+ }
142
+ if (isDragging || deltaX > 5 || deltaY > 5) {
143
+ var newX = moveEvent.clientX - 32;
144
+ var newY = moveEvent.clientY - 32;
145
+ setPosition({ x: newX, y: newY });
146
+ buttonPos.current = { x: newX, y: newY };
147
+ }
148
+ };
149
+ var onMouseUp = function () {
150
+ document.removeEventListener('mousemove', onMouseMove);
151
+ document.removeEventListener('mouseup', onMouseUp);
152
+ // 吸附逻辑
153
+ var centerX = window.innerWidth / 2;
154
+ var finalX = buttonPos.current.x < centerX ? 20 : window.innerWidth - 84;
155
+ // 垂直边界检查
156
+ var finalY = buttonPos.current.y;
157
+ if (finalY < 20)
158
+ finalY = 20;
159
+ if (finalY > window.innerHeight - 84)
160
+ finalY = window.innerHeight - 84;
161
+ setPosition({ x: finalX, y: finalY });
162
+ buttonPos.current = { x: finalX, y: finalY };
163
+ };
164
+ document.addEventListener('mousemove', onMouseMove);
165
+ document.addEventListener('mouseup', onMouseUp);
166
+ };
167
+ var showDrawer = function () {
168
+ if (!isDragging) {
169
+ setOpen(true);
170
+ }
171
+ };
172
+ var onClose = function () {
173
+ setOpen(false);
174
+ };
175
+ return (react_1.default.createElement(context_2.LLMContext.Provider, { value: engine },
176
+ react_1.default.createElement(MyRuntimeProvider_1.MyRuntimeProvider, null,
177
+ react_1.default.createElement(styles_1.FloatButton, { onClick: showDrawer, onMouseDown: handleMouseDown, style: {
178
+ left: position.x,
179
+ top: position.y,
180
+ bottom: 'auto',
181
+ right: 'auto',
182
+ transition: isDragging ? 'none' : 'all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275)',
183
+ userSelect: 'none',
184
+ touchAction: 'none',
185
+ opacity: open ? 0 : 1,
186
+ pointerEvents: open ? 'none' : 'auto',
187
+ transform: open ? 'scale(0) rotate(-20deg)' : (isDragging ? 'scale(1.05)' : 'scale(1)')
188
+ } }, loading && !engine ? react_1.default.createElement(icons_1.LoadingOutlined, null) : react_1.default.createElement(icons_1.MessageOutlined, null)),
189
+ react_1.default.createElement(antd_1.Drawer, { title: react_1.default.createElement(chat_style_1.DrawerTitle, null,
190
+ react_1.default.createElement("span", null, t('assistantTitle')),
191
+ !loading && engine && (react_1.default.createElement(react_2.ThreadListPrimitive.New, { asChild: true },
192
+ react_1.default.createElement(antd_1.Button, { type: "text", icon: react_1.default.createElement(icons_1.PlusOutlined, null), onClick: function () { return setActiveTab('chat'); } }, t('newChat'))))), placement: "right", onClose: onClose, visible: open, width: 600, bodyStyle: { padding: '0 16px', display: 'flex', flexDirection: 'column' } },
193
+ loading || !engine ? (react_1.default.createElement(chat_style_1.LoadingContainer, null,
194
+ react_1.default.createElement(antd_1.Progress, { type: "circle", percent: loadingProgress, strokeColor: {
195
+ '0%': '#108ee9',
196
+ '100%': '#87d068',
197
+ } }),
198
+ react_1.default.createElement(chat_style_1.LoadingText, null, loadingText),
199
+ react_1.default.createElement(chat_style_1.LoadingTip, null, t('loadingTip')))) : (react_1.default.createElement(react_1.default.Fragment, null,
200
+ react_1.default.createElement(antd_1.Tabs, { activeKey: activeTab, onChange: setActiveTab, items: [
201
+ { key: 'chat', label: t('tabChat') },
202
+ { key: 'history', label: t('tabHistory') },
203
+ ] }),
204
+ react_1.default.createElement("div", { style: { flex: 1, position: 'relative', overflow: 'hidden' } },
205
+ react_1.default.createElement(chat_style_1.ChatContainer, { active: activeTab === 'chat' },
206
+ react_1.default.createElement(Thread_1.Thread, null)),
207
+ react_1.default.createElement(chat_style_1.HistoryContainer, { active: activeTab === 'history' },
208
+ react_1.default.createElement(ThreadList_1.ThreadList, { onItemClick: function () { return setActiveTab('chat'); } }))))),
209
+ react_1.default.createElement(chat_style_1.PoweredBy, null,
210
+ "Powerd by ",
211
+ react_1.default.createElement(chat_style_1.PoweredByLink, { href: "https://github.com/Saber2pr/my-gpt-ui", target: "_blank", rel: "noreferrer" }, "my-gpt-ui"))))));
212
+ };
213
+ var initAIAssistant = function (config, container) {
214
+ if (config === void 0) { config = {}; }
215
+ var target = container || document.body;
216
+ var rootDiv = document.createElement('div');
217
+ rootDiv.id = config.containerId || 'ai-assistant-root';
218
+ target.appendChild(rootDiv);
219
+ react_dom_1.default.render(react_1.default.createElement(MyApp, { config: config }), rootDiv);
220
+ };
221
+ exports.initAIAssistant = initAIAssistant;
222
+ exports.default = exports.initAIAssistant;
@@ -0,0 +1,12 @@
1
+ export declare const DrawerTitle: import("styled-components").StyledComponent<"div", any, {}, never>;
2
+ export declare const LoadingContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
3
+ export declare const LoadingText: import("styled-components").StyledComponent<"div", any, {}, never>;
4
+ export declare const LoadingTip: import("styled-components").StyledComponent<"div", any, {}, never>;
5
+ export declare const ChatContainer: import("styled-components").StyledComponent<"div", any, {
6
+ active: boolean;
7
+ }, never>;
8
+ export declare const HistoryContainer: import("styled-components").StyledComponent<"div", any, {
9
+ active: boolean;
10
+ }, never>;
11
+ export declare const PoweredBy: import("styled-components").StyledComponent<"div", any, {}, never>;
12
+ export declare const PoweredByLink: import("styled-components").StyledComponent<"a", any, {}, never>;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
3
+ if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
4
+ return cooked;
5
+ };
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.PoweredByLink = exports.PoweredBy = exports.HistoryContainer = exports.ChatContainer = exports.LoadingTip = exports.LoadingText = exports.LoadingContainer = exports.DrawerTitle = void 0;
11
+ var styled_components_1 = __importDefault(require("styled-components"));
12
+ exports.DrawerTitle = styled_components_1.default.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-right: 24px;\n"], ["\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-right: 24px;\n"])));
13
+ exports.LoadingContainer = styled_components_1.default.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n height: 100%;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n padding: 0 40px;\n"], ["\n height: 100%;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n padding: 0 40px;\n"])));
14
+ exports.LoadingText = styled_components_1.default.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n margin-top: 24px;\n font-size: 16px;\n color: #666;\n text-align: center;\n"], ["\n margin-top: 24px;\n font-size: 16px;\n color: #666;\n text-align: center;\n"])));
15
+ exports.LoadingTip = styled_components_1.default.div(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n margin-top: 8px;\n font-size: 12px;\n color: #999;\n"], ["\n margin-top: 8px;\n font-size: 12px;\n color: #999;\n"])));
16
+ exports.ChatContainer = styled_components_1.default.div(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n display: ", ";\n height: calc(100vh - 160px);\n"], ["\n display: ", ";\n height: calc(100vh - 160px);\n"])), function (props) { return props.active ? 'block' : 'none'; });
17
+ exports.HistoryContainer = styled_components_1.default.div(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n display: ", ";\n height: calc(100vh - 160px);\n overflow-y: auto;\n"], ["\n display: ", ";\n height: calc(100vh - 160px);\n overflow-y: auto;\n"])), function (props) { return props.active ? 'block' : 'none'; });
18
+ exports.PoweredBy = styled_components_1.default.div(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n padding: 12px 0;\n text-align: center;\n font-size: 12px;\n color: #bfbfbf;\n border-top: 1px solid #f0f0f0;\n background-color: #fff;\n z-index: 1;\n"], ["\n padding: 12px 0;\n text-align: center;\n font-size: 12px;\n color: #bfbfbf;\n border-top: 1px solid #f0f0f0;\n background-color: #fff;\n z-index: 1;\n"])));
19
+ exports.PoweredByLink = styled_components_1.default.a(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n color: #bfbfbf;\n text-decoration: underline;\n"], ["\n color: #bfbfbf;\n text-decoration: underline;\n"])));
20
+ var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ export declare const registerLanguage: (name: string, meta: any) => any;
3
+ export interface CodeBlockProps {
4
+ code: string;
5
+ language: string;
6
+ className: string;
7
+ children: React.ReactNode;
8
+ }
9
+ export declare const CodeBlock: React.FC<CodeBlockProps>;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.CodeBlock = exports.registerLanguage = void 0;
18
+ var react_1 = __importDefault(require("react"));
19
+ var prism_light_1 = __importDefault(require("react-syntax-highlighter/dist/cjs/prism-light"));
20
+ var atom_dark_1 = __importDefault(require("react-syntax-highlighter/dist/cjs/styles/prism/atom-dark"));
21
+ var SyntaxHighlighter = prism_light_1.default;
22
+ var useCopy_1 = require("../../hooks/useCopy");
23
+ var cpp_1 = __importDefault(require("react-syntax-highlighter/dist/cjs/languages/prism/cpp"));
24
+ var haskell_1 = __importDefault(require("react-syntax-highlighter/dist/cjs/languages/prism/haskell"));
25
+ var tsx_1 = __importDefault(require("react-syntax-highlighter/dist/cjs/languages/prism/tsx"));
26
+ var go_1 = __importDefault(require("react-syntax-highlighter/dist/cjs/languages/prism/go"));
27
+ var python_1 = __importDefault(require("react-syntax-highlighter/dist/cjs/languages/prism/python"));
28
+ var index_style_1 = require("./index.style");
29
+ var icons_1 = require("@ant-design/icons");
30
+ var registerLanguage = function (name, meta) {
31
+ return SyntaxHighlighter.registerLanguage(name, meta);
32
+ };
33
+ exports.registerLanguage = registerLanguage;
34
+ (0, exports.registerLanguage)('tsx', tsx_1.default);
35
+ (0, exports.registerLanguage)('hs', haskell_1.default);
36
+ (0, exports.registerLanguage)('cpp', cpp_1.default);
37
+ (0, exports.registerLanguage)('go', go_1.default);
38
+ (0, exports.registerLanguage)('python', python_1.default);
39
+ var CodeBlock = function (_a) {
40
+ var _b, _c, _d;
41
+ var children = _a.children, className = _a.className, props = __rest(_a, ["children", "className"]);
42
+ // @ts-ignore
43
+ var id = (_d = (_c = (_b = props === null || props === void 0 ? void 0 : props.node) === null || _b === void 0 ? void 0 : _b.position) === null || _c === void 0 ? void 0 : _c.start) === null || _d === void 0 ? void 0 : _d.line;
44
+ var copyer = (0, useCopy_1.useCopy)("".concat(id));
45
+ if (/^language-/.test(className) && children) {
46
+ var lang = className.replace(/^language-/, '');
47
+ return (react_1.default.createElement(index_style_1.Contain, null,
48
+ react_1.default.createElement("div", { className: "Paste", ref: copyer.button },
49
+ react_1.default.createElement(icons_1.CopyOutlined, null)),
50
+ react_1.default.createElement("div", { ref: copyer.target },
51
+ react_1.default.createElement(SyntaxHighlighter, { language: lang, style: atom_dark_1.default }, String(children).trim()))));
52
+ }
53
+ return react_1.default.createElement(react_1.default.Fragment, null, children);
54
+ };
55
+ exports.CodeBlock = CodeBlock;
@@ -0,0 +1 @@
1
+ export declare const Contain: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
3
+ if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
4
+ return cooked;
5
+ };
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.Contain = void 0;
11
+ var styled_components_1 = __importDefault(require("styled-components"));
12
+ exports.Contain = styled_components_1.default.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n position: relative;\n max-width: 100%;\n overflow: hidden;\n border-radius: 8px;\n margin: 8px 0;\n\n pre {\n margin: 0 !important;\n max-width: 100%;\n overflow: auto !important;\n white-space: pre-wrap !important;\n word-break: break-all !important;\n }\n\n .Paste {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n color: rgb(173, 173, 173);\n opacity: 0.5;\n cursor: pointer;\n\n &:hover {\n opacity: 1;\n }\n }\n"], ["\n position: relative;\n max-width: 100%;\n overflow: hidden;\n border-radius: 8px;\n margin: 8px 0;\n\n pre {\n margin: 0 !important;\n max-width: 100%;\n overflow: auto !important;\n white-space: pre-wrap !important;\n word-break: break-all !important;\n }\n\n .Paste {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n color: rgb(173, 173, 173);\n opacity: 0.5;\n cursor: pointer;\n\n &:hover {\n opacity: 1;\n }\n }\n"])));
13
+ var templateObject_1;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { TextContentPartProps } from '@assistant-ui/react';
3
+ export declare const MarkdownText: React.MemoExoticComponent<(props: TextContentPartProps) => JSX.Element>;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.MarkdownText = void 0;
40
+ var react_1 = __importStar(require("react"));
41
+ var remark_gfm_1 = __importDefault(require("remark-gfm"));
42
+ var react_markdown_1 = require("@assistant-ui/react-markdown");
43
+ var antd_1 = require("antd");
44
+ var Codeblock_1 = require("../Codeblock");
45
+ var useI18n_1 = require("../../hooks/useI18n");
46
+ var MarkdownTextImpl = function (props) {
47
+ var _a;
48
+ var t = (0, useI18n_1.useI18n)().t;
49
+ // props.status.type 可以拿到当前 ai 对话的进度、状态
50
+ // running、complete、incomplete
51
+ // reason: "cancelled"
52
+ var type = (_a = props === null || props === void 0 ? void 0 : props.status) === null || _a === void 0 ? void 0 : _a.type;
53
+ var text = props === null || props === void 0 ? void 0 : props.text;
54
+ if (type === 'running' && !text) {
55
+ return (react_1.default.createElement(antd_1.Skeleton.Node, { active: true, style: {
56
+ width: 100,
57
+ borderRadius: 14,
58
+ height: '38px',
59
+ } }, t('thinking')));
60
+ }
61
+ return (react_1.default.createElement("div", { style: {
62
+ marginTop: 6,
63
+ maxWidth: '100%',
64
+ overflow: 'hidden',
65
+ wordBreak: 'break-word',
66
+ } },
67
+ react_1.default.createElement(react_markdown_1.MarkdownTextPrimitive, { remarkPlugins: [remark_gfm_1.default], components: {
68
+ code: Codeblock_1.CodeBlock,
69
+ } })));
70
+ };
71
+ exports.MarkdownText = (0, react_1.memo)(MarkdownTextImpl);
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ export interface MyRuntimeProviderProps {
3
+ children: React.ReactNode;
4
+ }
5
+ export declare function MyRuntimeProvider({ children }: MyRuntimeProviderProps): JSX.Element;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MyRuntimeProvider = MyRuntimeProvider;
7
+ var react_1 = __importDefault(require("react"));
8
+ var react_2 = require("@assistant-ui/react");
9
+ var myModelAdapterStream_1 = require("./myModelAdapterStream");
10
+ var context_1 = require("@/llm/context");
11
+ var context_2 = require("../../context");
12
+ function MyRuntimeProvider(_a) {
13
+ var children = _a.children;
14
+ var llm = (0, context_1.useLLm)();
15
+ var config = react_1.default.useContext(context_2.AIConfigContext);
16
+ var runtime = (0, react_2.useLocalRuntime)((0, myModelAdapterStream_1.MyModelAdapterStream)(llm, config.onBeforeChat), {
17
+ adapters: {
18
+ speech: new react_2.WebSpeechSynthesisAdapter(),
19
+ },
20
+ });
21
+ return (react_1.default.createElement(react_2.AssistantRuntimeProvider, { runtime: runtime }, children));
22
+ }
@@ -0,0 +1,4 @@
1
+ import { ChatModelAdapter } from '@assistant-ui/react';
2
+ import { MLCEngine } from '@mlc-ai/web-llm';
3
+ import { ChatMessage } from '../../types/assistant';
4
+ export declare const MyModelAdapterStream: (llm: MLCEngine, onBeforeChat?: (messages: ChatMessage[], llm: MLCEngine) => ChatMessage[] | Promise<ChatMessage[]>) => ChatModelAdapter;