yt-chat-components 0.9.9 → 1.0.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.
Files changed (49) hide show
  1. package/.idea/modules.xml +1 -1
  2. package/.idea/sonarlint/issuestore/index.pb +3 -35
  3. package/dist/build/static/js/bundle.min.js +1 -0
  4. package/package.json +76 -77
  5. package/public/index.html +108 -81
  6. package/src/YtChatView/chatWidget/chatWindow/chatMessage/index.tsx +464 -211
  7. package/src/YtChatView/chatWidget/chatWindow/controllers/index.ts +249 -246
  8. package/src/YtChatView/chatWidget/chatWindow/index.module.css +196 -196
  9. package/src/YtChatView/chatWidget/chatWindow/index.tsx +1040 -924
  10. package/src/YtChatView/chatWidget/chatWindow/types/chatWidget/index.ts +50 -37
  11. package/src/YtChatView/chatWidget/index.tsx +2586 -2502
  12. package/src/YtChatView/logoBtn/index.css +3 -3
  13. package/src/YtChatView/logoBtn/index.jsx +103 -103
  14. package/src/YtChatView/logoSplitBtn/index.css +3 -3
  15. package/src/YtChatView/logoSplitBtn/index.jsx +105 -105
  16. package/src/YtChatView/mobileChat/index.jsx +848 -0
  17. package/src/YtChatView/mobileChat/index.module.css +254 -0
  18. package/src/YtChatView/previewDialog/index.jsx +600 -600
  19. package/src/YtChatView/previewDialog/index.module.css +253 -253
  20. package/src/assets/aicenter/icon_agents.png +0 -0
  21. package/src/assets/aicenter/icon_history.png +0 -0
  22. package/src/assets/aicenter/icon_history_add.png +0 -0
  23. package/src/assets/aicenter/icon_history_headerbg.png +0 -0
  24. package/src/assets/aicenter/icon_history_upload.png +0 -0
  25. package/src/chatWidget/chatWindow/index.tsx +426 -426
  26. package/src/chatWidget/index.tsx +2193 -2193
  27. package/src/index.tsx +11 -10
  28. package/webpack.config.js +50 -50
  29. package/.idea/sonarlint/issuestore/2/e/2e9f70bf32b414323ca1647e2b6f26e1533ee2fc +0 -0
  30. package/.idea/sonarlint/issuestore/3/6/364385cedcce4c06de1901392ffeeac0caef0f3c +0 -0
  31. package/.idea/sonarlint/issuestore/3/9/39129446b425a1d640160c068e4194e96639eedf +0 -0
  32. package/.idea/sonarlint/issuestore/4/a/4a2f33951ce07c1ff7184f91877aa13db05d3785 +0 -0
  33. package/.idea/sonarlint/issuestore/4/a/4a7b99bdbee5792679d347b6474463bf5e14b66d +0 -0
  34. package/.idea/sonarlint/issuestore/4/b/4b015aa5428c4d4c3d672893ec23f5fe3969f9be +0 -0
  35. package/.idea/sonarlint/issuestore/4/b/4b6989b8ccae808ebc45d02230d336ea53800365 +0 -0
  36. package/.idea/sonarlint/issuestore/5/a/5ab44fe33ca96299f51ad4778a73e425b92bf439 +0 -0
  37. package/.idea/sonarlint/issuestore/6/1/61ebb9fd6e8cf9082658121d5d81e297791dacd0 +0 -0
  38. package/.idea/sonarlint/issuestore/6/c/6c024c1d0ad64656b9d4b0695ec3c49c0454addf +0 -0
  39. package/.idea/sonarlint/issuestore/6/e/6e75fc1c07c3a427a86fc213ca9479caaaff00ea +0 -0
  40. package/.idea/sonarlint/issuestore/8/d/8d6123af13a140f93e06299fff7ea23c547e9ec8 +0 -0
  41. package/.idea/sonarlint/issuestore/c/c/cc2352788140b6778ac06df4b33f50b390d2d8be +0 -0
  42. package/.idea/sonarlint/issuestore/d/5/d5595158cc48f9bf3e51b06f6e6805a8fd2d6262 +0 -0
  43. package/.idea/sonarlint/issuestore/d/7/d747cbed4201192dfa83a1a51345b020a050b647 +0 -0
  44. package/.idea/sonarlint/issuestore/d/9/d938938695d447dadda115e28781c6541f53fc4f +0 -0
  45. package/build/static/js/bundle.min.js +0 -2
  46. package/build/static/js/bundle.min.js.LICENSE.txt +0 -132
  47. /package/.idea/{langflow-embedded-chat.iml → langflow-embedded-chat-clone.iml} +0 -0
  48. /package/.idea/sonarlint/issuestore/{0/f/0f8c0c92cf798431ebb931ff6e997b1af86ecee5 → 7/0/7030d0b2f71b999ff89a343de08c414af32fc93a} +0 -0
  49. /package/.idea/sonarlint/issuestore/{2/7/27e69cb561aeea20c1afbdd32d260dd60b89a81b → 9/c/9cfff9a6d27bd6c255aa751213163c7901fb8ce7} +0 -0
@@ -1,247 +1,250 @@
1
- // @ts-nocheck
2
- import axios from "axios";
3
-
4
-
5
- /**
6
- * 发送消息
7
- * @param embed_app_extend 扩展参数
8
- * @param isStream 是否启用流式传输
9
- * @param handleMessageContent 处理消息内容的回调函数
10
- * @param signal 用于主动关闭请求流
11
- * @param baseUrl 接口地址
12
- * @param flowId AI应用ID
13
- * @param message 消息内容
14
- * @param input_type 输入类型
15
- * @param output_type 输出类型
16
- * @param sessionId 对话ID
17
- * @param output_component
18
- * @param tweaks
19
- * @param api_key 接口密钥
20
- * @param additional_headers
21
- */
22
- export async function sendMessage(
23
- embed_app_extend: object,
24
- isStream: boolean,
25
- handleMessageContent: Function,
26
- signal,
27
- baseUrl: string,
28
- flowId: string,
29
- message: string,
30
- input_type: string,
31
- output_type: string,
32
- sessionId: React.MutableRefObject<string>,
33
- output_component?: string,
34
- tweaks?: Object,
35
- api_key?: string,
36
- additional_headers?: {
37
- [key: string]: string;
38
- },
39
- ) {
40
- let data: any;
41
- data = {input_type, input_value: message, output_type};
42
- if (tweaks) {
43
- data['tweaks'] = tweaks;
44
- }
45
- if (output_component) {
46
- data['output_component'] = output_component;
47
- }
48
- if (embed_app_extend) {
49
- data['embed_app_extend'] = embed_app_extend;
50
- }
51
- let headers: { [key: string]: string } = {'Content-Type': 'application/json', 'timeout': 600000};
52
- if (api_key) {
53
- headers['x-api-key'] = api_key;
54
- }
55
- if (additional_headers) {
56
- headers = Object.assign(headers, additional_headers);
57
- // headers = {...headers, ...additional_headers};
58
- }
59
- // @ts-ignore
60
- if (sessionId && sessionId != '') {
61
- data.session_id = sessionId;
62
- }
63
-
64
- if (isStream) {
65
- return await fetchCustomStream(
66
- `${baseUrl}/api/v1/run/${flowId}?stream=true`,
67
- data,
68
- headers,
69
- handleMessageContent,
70
- signal,
71
- );
72
- } else {
73
- let response = axios.post(`${baseUrl}/api/v1/run/${flowId}`, data, { headers });
74
- return response;
75
- }
76
- }
77
-
78
- // 缓冲区用于累积未完成的 JSON 数据
79
- // let buffer = '';
80
-
81
- async function fetchCustomStream(url, body, headers, handleMessageContent, signal) {
82
- const response = await fetch(url, {
83
- method: 'POST',
84
- headers: {...headers, timeout: 600000},
85
- body: JSON.stringify(body),
86
- signal: signal,
87
- });
88
-
89
- if (!response.ok) {
90
- throw new Error('请求失败');
91
- }
92
-
93
- // 手动读取响应体作为可读流
94
- const reader = response.body.getReader();
95
- const decoder = new TextDecoder();
96
- let buffer = '';
97
-
98
- while (true) {
99
- const {done, value} = await reader.read();
100
- if (done) break;
101
-
102
- // 将二进制数据解码为字符串,并累积到缓冲区
103
- const chunk = decoder.decode(value, {stream: true});
104
- buffer += chunk;
105
-
106
- // 提取并解析 JSON
107
- const {parsedData, remainingBuffer} = extractAndParseJSON(buffer, handleMessageContent);
108
-
109
- // 更新缓冲区为剩余未处理的数据
110
- buffer = remainingBuffer;
111
- }
112
-
113
- // 如果缓冲区中还有剩余数据,可能是不完整的 JSON
114
- if (buffer.trim() !== '') {
115
- console.warn('缓冲区中存在未完成的 JSON 数据:', buffer);
116
- }
117
- }
118
-
119
- // 辅助函数:从缓冲区中提取并解析所有完整的 JSON 对象
120
- function extractAndParseJSON(buffer, handleMessageContent) {
121
- let remainingBuffer = buffer; // 剩余未处理的数据
122
- const parsedData = []; // 存储解析成功的 JSON 对象
123
- let bracketCount = 0; // 记录大括号的嵌套层次
124
- let jsonStartIndex = -1; // 当前 JSON 对象的起始索引
125
- let inString = false; // 是否处于字符串内部
126
- let escapeChar = false; // 是否遇到转义字符
127
-
128
- for (let i = 0; i < remainingBuffer.length; i++) {
129
- const char = remainingBuffer[i];
130
-
131
- if (escapeChar) {
132
- escapeChar = false; // 跳过转义字符后的下一个字符
133
- continue;
134
- }
135
-
136
- if (char === '\\') {
137
- escapeChar = true; // 标记转义字符
138
- continue;
139
- }
140
-
141
- if (char === '"' && !escapeChar) {
142
- inString = !inString; // 切换字符串状态
143
- continue;
144
- }
145
-
146
- if (!inString) {
147
- if (char === '{') {
148
- if (bracketCount === 0) {
149
- jsonStartIndex = i; // 标记 JSON 开始位置
150
- }
151
- bracketCount++;
152
- } else if (char === '}') {
153
- bracketCount--;
154
- if (bracketCount === 0 && jsonStartIndex !== -1) {
155
- // 找到一个完整的 JSON 对象
156
- const jsonString = remainingBuffer.slice(jsonStartIndex, i + 1);
157
-
158
- try {
159
- const parsedJson = JSON.parse(jsonString); // 解析 JSON
160
- handleMessageContent(parsedJson['event'], parsedJson['data']);
161
- parsedData.push(parsedJson); // 添加到解析结果中
162
- } catch (error) {
163
- console.warn('无法解析 JSON 数据:', error);
164
- }
165
-
166
- // 更新剩余缓冲区的起始位置
167
- remainingBuffer = remainingBuffer.slice(i + 1);
168
- i = -1; // 重置索引以重新开始扫描
169
- jsonStartIndex = -1; // 重置 JSON 起始索引
170
- }
171
- }
172
- }
173
- }
174
-
175
- return {parsedData, remainingBuffer}; // 返回解析结果和剩余缓冲区
176
- }
177
-
178
- /**
179
- * 获取对话历史列表
180
- * @param baseUrl
181
- * @param flowId
182
- * @param operatorId
183
- */
184
- export async function getHistoryList(baseUrl: string, flowId: string, operatorId: string) {
185
- return axios.get(`${baseUrl}/api/v1/embed/chat_history_list/${flowId}/${operatorId}`, {timeout: 600000});
186
- }
187
-
188
- /**
189
- * 获取对话历史记录
190
- * @param baseUrl
191
- * @param flowI
192
- * @param sessionId
193
- * @param operatorId
194
- */
195
- export async function getChatHistory(
196
- baseUrl: string,
197
- flowId: string,
198
- sessionId: string,
199
- operatorId: string,
200
- ) {
201
- return axios.get(`${baseUrl}/api/v1/embed/chat_history/${flowId}/${sessionId}/${operatorId}`);
202
- }
203
-
204
-
205
- /**
206
- * 上传文件
207
- * @param baseUrl
208
- * @param file
209
- * @param flowId
210
- * @param api_key
211
- */
212
- export async function fetchUploadFile(baseUrl: string, file: File, flowId: string, api_key: string) {
213
- const headers = {
214
- 'Content-Type': 'multipart/form-data',
215
- 'x-api-key': api_key,
216
- timeout:600000
217
- };
218
- const formData = new FormData();
219
- formData.append('file', file);
220
- formData.append('folder', flowId);
221
-
222
- return axios.post(`${baseUrl}/api/t1/file/upload`, formData, {headers});
223
- }
224
-
225
- /**
226
- * 获取场景信息
227
- * @param baseUrl
228
- * @param sceneId
229
- * @param api_key
230
- */
231
- export async function getSceneInfo(baseUrl: string, sceneId: string, api_key: string) {
232
- const headers = {
233
- 'Content-Type': 'multipart/form-data',
234
- 'x-api-key': api_key,
235
- timeout:600000
236
- };
237
- return axios.get(`${baseUrl}/api/t1/scene/detail/${sceneId}`,{headers});
238
- }
239
-
240
- export async function getFlowInfo(baseUrl: string, flowId: string, api_key: string) {
241
- const headers = {
242
- 'Content-Type': 'multipart/form-data',
243
- 'x-api-key': api_key,
244
- timeout:600000
245
- };
246
- return axios.get(`${baseUrl}/api/t1/flow/detail/${flowId}`,{headers});
1
+ // @ts-nocheck
2
+ import axios from "axios";
3
+ import {InputValueType} from "../types/chatWidget";
4
+
5
+
6
+ /**
7
+ * 发送消息
8
+ * @param input_value_type
9
+ * @param isStream
10
+ * @param embed_app_extend 扩展参数 * @param isStream 是否启用流式传输
11
+ * @param handleMessageContent 处理消息内容的回调函数
12
+ * @param signal 用于主动关闭请求流
13
+ * @param baseUrl 接口地址
14
+ * @param flowId AI应用ID
15
+ * @param message 消息内容
16
+ * @param input_type 输入类型
17
+ * @param output_type 输出类型
18
+ * @param sessionId 对话ID
19
+ * @param output_component
20
+ * @param tweaks
21
+ * @param api_key 接口密钥
22
+ * @param additional_headers
23
+ */
24
+ export async function sendMessage(
25
+ input_value_type: string = InputValueType.text,
26
+ embed_app_extend: object,
27
+ isStream: boolean,
28
+ handleMessageContent: Function,
29
+ signal,
30
+ baseUrl: string,
31
+ flowId: string,
32
+ message: string,
33
+ input_type: string,
34
+ output_type: string,
35
+ sessionId: React.MutableRefObject<string>,
36
+ output_component?: string,
37
+ tweaks?: Object,
38
+ api_key?: string,
39
+ additional_headers?: {
40
+ [key: string]: string;
41
+ },
42
+ ) {
43
+ let data: any;
44
+ data = {input_value_type, input_type, input_value: message, output_type};
45
+ if (tweaks) {
46
+ data['tweaks'] = tweaks;
47
+ }
48
+ if (output_component) {
49
+ data['output_component'] = output_component;
50
+ }
51
+ if (embed_app_extend) {
52
+ data['embed_app_extend'] = embed_app_extend;
53
+ }
54
+ let headers: { [key: string]: string } = {'Content-Type': 'application/json', 'timeout': 600000};
55
+ if (api_key) {
56
+ headers['x-api-key'] = api_key;
57
+ }
58
+ if (additional_headers) {
59
+ headers = Object.assign(headers, additional_headers);
60
+ // headers = {...headers, ...additional_headers};
61
+ }
62
+ // @ts-ignore
63
+ if (sessionId && sessionId != '') {
64
+ data.session_id = sessionId;
65
+ }
66
+
67
+ if (isStream) {
68
+ return await fetchCustomStream(
69
+ `${baseUrl}/api/v1/run/${flowId}?stream=true`,
70
+ data,
71
+ headers,
72
+ handleMessageContent,
73
+ signal,
74
+ );
75
+ } else {
76
+ let response = axios.post(`${baseUrl}/api/v1/run/${flowId}`, data, { headers });
77
+ return response;
78
+ }
79
+ }
80
+
81
+ // 缓冲区用于累积未完成的 JSON 数据
82
+ // let buffer = '';
83
+
84
+ async function fetchCustomStream(url, body, headers, handleMessageContent, signal) {
85
+ const response = await fetch(url, {
86
+ method: 'POST',
87
+ headers: {...headers, timeout: 600000},
88
+ body: JSON.stringify(body),
89
+ signal: signal,
90
+ });
91
+
92
+ if (!response.ok) {
93
+ throw new Error('请求失败');
94
+ }
95
+
96
+ // 手动读取响应体作为可读流
97
+ const reader = response.body.getReader();
98
+ const decoder = new TextDecoder();
99
+ let buffer = '';
100
+
101
+ while (true) {
102
+ const {done, value} = await reader.read();
103
+ if (done) break;
104
+
105
+ // 将二进制数据解码为字符串,并累积到缓冲区
106
+ const chunk = decoder.decode(value, {stream: true});
107
+ buffer += chunk;
108
+
109
+ // 提取并解析 JSON
110
+ const {parsedData, remainingBuffer} = extractAndParseJSON(buffer, handleMessageContent);
111
+
112
+ // 更新缓冲区为剩余未处理的数据
113
+ buffer = remainingBuffer;
114
+ }
115
+
116
+ // 如果缓冲区中还有剩余数据,可能是不完整的 JSON
117
+ if (buffer.trim() !== '') {
118
+ console.warn('缓冲区中存在未完成的 JSON 数据:', buffer);
119
+ }
120
+ }
121
+
122
+ // 辅助函数:从缓冲区中提取并解析所有完整的 JSON 对象
123
+ function extractAndParseJSON(buffer, handleMessageContent) {
124
+ let remainingBuffer = buffer; // 剩余未处理的数据
125
+ const parsedData = []; // 存储解析成功的 JSON 对象
126
+ let bracketCount = 0; // 记录大括号的嵌套层次
127
+ let jsonStartIndex = -1; // 当前 JSON 对象的起始索引
128
+ let inString = false; // 是否处于字符串内部
129
+ let escapeChar = false; // 是否遇到转义字符
130
+
131
+ for (let i = 0; i < remainingBuffer.length; i++) {
132
+ const char = remainingBuffer[i];
133
+
134
+ if (escapeChar) {
135
+ escapeChar = false; // 跳过转义字符后的下一个字符
136
+ continue;
137
+ }
138
+
139
+ if (char === '\\') {
140
+ escapeChar = true; // 标记转义字符
141
+ continue;
142
+ }
143
+
144
+ if (char === '"' && !escapeChar) {
145
+ inString = !inString; // 切换字符串状态
146
+ continue;
147
+ }
148
+
149
+ if (!inString) {
150
+ if (char === '{') {
151
+ if (bracketCount === 0) {
152
+ jsonStartIndex = i; // 标记 JSON 开始位置
153
+ }
154
+ bracketCount++;
155
+ } else if (char === '}') {
156
+ bracketCount--;
157
+ if (bracketCount === 0 && jsonStartIndex !== -1) {
158
+ // 找到一个完整的 JSON 对象
159
+ const jsonString = remainingBuffer.slice(jsonStartIndex, i + 1);
160
+
161
+ try {
162
+ const parsedJson = JSON.parse(jsonString); // 解析 JSON
163
+ handleMessageContent(parsedJson['event'], parsedJson['data']);
164
+ parsedData.push(parsedJson); // 添加到解析结果中
165
+ } catch (error) {
166
+ console.warn('无法解析 JSON 数据:', error);
167
+ }
168
+
169
+ // 更新剩余缓冲区的起始位置
170
+ remainingBuffer = remainingBuffer.slice(i + 1);
171
+ i = -1; // 重置索引以重新开始扫描
172
+ jsonStartIndex = -1; // 重置 JSON 起始索引
173
+ }
174
+ }
175
+ }
176
+ }
177
+
178
+ return {parsedData, remainingBuffer}; // 返回解析结果和剩余缓冲区
179
+ }
180
+
181
+ /**
182
+ * 获取对话历史列表
183
+ * @param baseUrl
184
+ * @param flowId
185
+ * @param operatorId
186
+ */
187
+ export async function getHistoryList(baseUrl: string, flowId: string, operatorId: string) {
188
+ return axios.get(`${baseUrl}/api/v1/embed/chat_history_list/${flowId}/${operatorId}`, {timeout: 600000});
189
+ }
190
+
191
+ /**
192
+ * 获取对话历史记录
193
+ * @param baseUrl
194
+ * @param flowI
195
+ * @param sessionId
196
+ * @param operatorId
197
+ */
198
+ export async function getChatHistory(
199
+ baseUrl: string,
200
+ flowId: string,
201
+ sessionId: string,
202
+ operatorId: string,
203
+ ) {
204
+ return axios.get(`${baseUrl}/api/v1/embed/chat_history/${flowId}/${sessionId}/${operatorId}`);
205
+ }
206
+
207
+
208
+ /**
209
+ * 上传文件
210
+ * @param baseUrl
211
+ * @param file
212
+ * @param flowId
213
+ * @param api_key
214
+ */
215
+ export async function fetchUploadFile(baseUrl: string, file: File, flowId: string, api_key: string) {
216
+ const headers = {
217
+ 'Content-Type': 'multipart/form-data',
218
+ 'x-api-key': api_key,
219
+ timeout:600000
220
+ };
221
+ const formData = new FormData();
222
+ formData.append('file', file);
223
+ formData.append('folder', flowId);
224
+
225
+ return axios.post(`${baseUrl}/api/t1/file/upload`, formData, {headers});
226
+ }
227
+
228
+ /**
229
+ * 获取场景信息
230
+ * @param baseUrl
231
+ * @param sceneId
232
+ * @param api_key
233
+ */
234
+ export async function getSceneInfo(baseUrl: string, sceneId: string, api_key: string) {
235
+ const headers = {
236
+ 'Content-Type': 'multipart/form-data',
237
+ 'x-api-key': api_key,
238
+ timeout:600000
239
+ };
240
+ return axios.get(`${baseUrl}/api/t1/scene/detail/${sceneId}`,{headers});
241
+ }
242
+
243
+ export async function getFlowInfo(baseUrl: string, flowId: string, api_key: string) {
244
+ const headers = {
245
+ 'Content-Type': 'multipart/form-data',
246
+ 'x-api-key': api_key,
247
+ timeout:600000
248
+ };
249
+ return axios.get(`${baseUrl}/api/t1/flow/detail/${flowId}`,{headers});
247
250
  }