@ray-js/t-agent-ui-ray 0.2.0-beta-9 → 0.2.0-beta-10
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "core-js/modules/web.dom-collections.iterator.js";
|
|
2
|
-
import React, { useRef, useState } from 'react';
|
|
2
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
3
3
|
import { Button, View } from '@ray-js/ray';
|
|
4
4
|
import cx from 'clsx';
|
|
5
5
|
import { useTranslate } from '../../hooks';
|
|
@@ -39,6 +39,12 @@ const AsrInput = props => {
|
|
|
39
39
|
}
|
|
40
40
|
props.onConfirm();
|
|
41
41
|
};
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (active && !props.recording) {
|
|
44
|
+
setActive(false);
|
|
45
|
+
setCancel(false);
|
|
46
|
+
}
|
|
47
|
+
}, [props.recording]);
|
|
42
48
|
return /*#__PURE__*/React.createElement(View, {
|
|
43
49
|
className: "t-agent-message-input-ptt-bar"
|
|
44
50
|
}, /*#__PURE__*/React.createElement(View, {
|
|
@@ -47,7 +47,7 @@ export default function MessageInputAIStream(props) {
|
|
|
47
47
|
setUploaded,
|
|
48
48
|
upload
|
|
49
49
|
} = attachmentInput;
|
|
50
|
-
const
|
|
50
|
+
const abortRef = useRef(null);
|
|
51
51
|
const [responding, setResponding] = useState(false);
|
|
52
52
|
const [mode, setMode] = useState('text');
|
|
53
53
|
const agent = useChatAgent();
|
|
@@ -70,16 +70,26 @@ export default function MessageInputAIStream(props) {
|
|
|
70
70
|
setUploaded([]);
|
|
71
71
|
setText('');
|
|
72
72
|
setResponding(true);
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
const controller = new AbortController();
|
|
74
|
+
let abortResolve;
|
|
75
|
+
abortRef.current = {
|
|
76
|
+
controller,
|
|
77
|
+
promise: new Promise(resolve => {
|
|
78
|
+
abortResolve = resolve;
|
|
79
|
+
})
|
|
80
|
+
};
|
|
81
|
+
controller.signal.addEventListener('abort', () => {
|
|
82
|
+
var _abortRef$current;
|
|
83
|
+
if (((_abortRef$current = abortRef.current) === null || _abortRef$current === void 0 ? void 0 : _abortRef$current.controller) === controller) {
|
|
84
|
+
abortRef.current = null;
|
|
78
85
|
setResponding(false);
|
|
79
86
|
}
|
|
80
87
|
});
|
|
81
88
|
try {
|
|
82
|
-
await agent.pushInputBlocks(inputBlocks,
|
|
89
|
+
await agent.pushInputBlocks(inputBlocks, controller.signal);
|
|
90
|
+
if (controller.signal.aborted) {
|
|
91
|
+
abortResolve();
|
|
92
|
+
}
|
|
83
93
|
} finally {
|
|
84
94
|
if (!isUnmounted()) {
|
|
85
95
|
setResponding(false);
|
|
@@ -97,16 +107,25 @@ export default function MessageInputAIStream(props) {
|
|
|
97
107
|
setMoreOpen(false);
|
|
98
108
|
setUploaded([]);
|
|
99
109
|
setResponding(true);
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
110
|
+
const controller = new AbortController();
|
|
111
|
+
let abortResolve;
|
|
112
|
+
abortRef.current = {
|
|
113
|
+
controller,
|
|
114
|
+
promise: new Promise(resolve => {
|
|
115
|
+
abortResolve = resolve;
|
|
116
|
+
})
|
|
117
|
+
};
|
|
118
|
+
controller.signal.addEventListener('abort', () => {
|
|
119
|
+
if (abortRef.current.controller === controller) {
|
|
120
|
+
abortRef.current = null;
|
|
105
121
|
}
|
|
106
122
|
setResponding(false);
|
|
107
123
|
});
|
|
108
124
|
try {
|
|
109
|
-
await agent.pushInputBlocks(blocks,
|
|
125
|
+
await agent.pushInputBlocks(blocks, controller.signal);
|
|
126
|
+
if (controller.signal.aborted) {
|
|
127
|
+
abortResolve();
|
|
128
|
+
}
|
|
110
129
|
} finally {
|
|
111
130
|
if (!isUnmounted()) {
|
|
112
131
|
setResponding(false);
|
|
@@ -143,7 +162,7 @@ export default function MessageInputAIStream(props) {
|
|
|
143
162
|
});
|
|
144
163
|
}
|
|
145
164
|
};
|
|
146
|
-
|
|
165
|
+
useSleep();
|
|
147
166
|
let container;
|
|
148
167
|
const canSend = text.trim().length && !responding && !attachmentInput.uploading;
|
|
149
168
|
if (mode === 'text') {
|
|
@@ -203,8 +222,8 @@ export default function MessageInputAIStream(props) {
|
|
|
203
222
|
"data-testid": "t-agent-message-input-button-main",
|
|
204
223
|
onClick: async () => {
|
|
205
224
|
if (responding) {
|
|
206
|
-
if (
|
|
207
|
-
|
|
225
|
+
if (abortRef.current) {
|
|
226
|
+
abortRef.current.controller.abort('User abort');
|
|
208
227
|
}
|
|
209
228
|
} else if (isMore) {
|
|
210
229
|
openMoreClick();
|
|
@@ -226,14 +245,19 @@ export default function MessageInputAIStream(props) {
|
|
|
226
245
|
if (attachmentInput.uploading) {
|
|
227
246
|
return;
|
|
228
247
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
248
|
+
const abort = abortRef.current;
|
|
249
|
+
if (responding && abort) {
|
|
250
|
+
abort.controller.abort('User abort');
|
|
251
|
+
// 中断后等待上次结束再开始
|
|
252
|
+
await abort.promise;
|
|
233
253
|
}
|
|
234
254
|
const emitter = new Emitter();
|
|
235
|
-
setTimeout(() => {
|
|
255
|
+
const id = setTimeout(() => {
|
|
236
256
|
if (r.recording) {
|
|
257
|
+
ty.showToast({
|
|
258
|
+
icon: 'none',
|
|
259
|
+
title: t('t-agent.input.asr.error.timeout')
|
|
260
|
+
});
|
|
237
261
|
r.confirm();
|
|
238
262
|
}
|
|
239
263
|
}, props.maxAudioMs || 30000);
|
|
@@ -242,6 +266,7 @@ export default function MessageInputAIStream(props) {
|
|
|
242
266
|
recording: true,
|
|
243
267
|
confirm: () => {
|
|
244
268
|
r.recording = false;
|
|
269
|
+
clearTimeout(id);
|
|
245
270
|
emitter.dispatchEvent(new EmitterEvent('confirm'));
|
|
246
271
|
setRecord({
|
|
247
272
|
startAt: 0,
|
|
@@ -252,6 +277,7 @@ export default function MessageInputAIStream(props) {
|
|
|
252
277
|
},
|
|
253
278
|
cancel: () => {
|
|
254
279
|
r.recording = false;
|
|
280
|
+
clearTimeout(id);
|
|
255
281
|
emitter.dispatchEvent(new EmitterEvent('cancel'));
|
|
256
282
|
setRecord({
|
|
257
283
|
startAt: 0,
|
|
@@ -294,8 +320,8 @@ export default function MessageInputAIStream(props) {
|
|
|
294
320
|
setMoreOpen(false);
|
|
295
321
|
},
|
|
296
322
|
onAbort: () => {
|
|
297
|
-
if (responding &&
|
|
298
|
-
|
|
323
|
+
if (responding && abortRef.current) {
|
|
324
|
+
abortRef.current.controller.abort('User abort');
|
|
299
325
|
}
|
|
300
326
|
}
|
|
301
327
|
});
|
package/dist/i18n/strings.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ declare const _default: {
|
|
|
22
22
|
't-agent.input.asr.ptt': string;
|
|
23
23
|
't-agent.input.asr.error.too-short': string;
|
|
24
24
|
't-agent.input.asr.error.empty': string;
|
|
25
|
+
't-agent.input.asr.error.timeout': string;
|
|
25
26
|
't-agent.message.feedback.success': string;
|
|
26
27
|
't-agent.message.bubble.aborted': string;
|
|
27
28
|
't-agent.message.action.copy': string;
|
|
@@ -164,6 +165,7 @@ declare const _default: {
|
|
|
164
165
|
't-agent.input.asr.ptt': string;
|
|
165
166
|
't-agent.input.asr.error.too-short': string;
|
|
166
167
|
't-agent.input.asr.error.empty': string;
|
|
168
|
+
't-agent.input.asr.error.timeout': string;
|
|
167
169
|
't-agent.message.feedback.success': string;
|
|
168
170
|
't-agent.message.bubble.aborted': string;
|
|
169
171
|
't-agent.message.action.copy': string;
|
package/dist/i18n/strings.js
CHANGED
|
@@ -22,6 +22,7 @@ export default {
|
|
|
22
22
|
't-agent.input.asr.ptt': '按住说话',
|
|
23
23
|
't-agent.input.asr.error.too-short': '说话时间太短',
|
|
24
24
|
't-agent.input.asr.error.empty': '未能从语音中识别到文字',
|
|
25
|
+
't-agent.input.asr.error.timeout': '语音识别已达时长限制,将直接发送',
|
|
25
26
|
't-agent.message.feedback.success': '反馈成功',
|
|
26
27
|
't-agent.message.bubble.aborted': '用户中断',
|
|
27
28
|
't-agent.message.action.copy': '复制消息',
|
|
@@ -160,15 +161,11 @@ export default {
|
|
|
160
161
|
't-agent.input.voice.require-permission': 'Recording Permission Required',
|
|
161
162
|
't-agent.input.upload.failed': 'File Upload Failed',
|
|
162
163
|
't-agent.input.asr.oninput.text.top': 'Listening, speak now',
|
|
163
|
-
// 语音激活态顶部提示
|
|
164
164
|
't-agent.input.asr.oninput.text.center': 'Release to send · Swipe up to cancel',
|
|
165
|
-
// 交互操作指引
|
|
166
165
|
't-agent.input.asr.ptt': 'Press & hold to talk',
|
|
167
|
-
// Push-to-Talk 按钮提示
|
|
168
166
|
't-agent.input.asr.error.too-short': 'Speaking time too short',
|
|
169
|
-
// 语音输入时间过短
|
|
170
167
|
't-agent.input.asr.error.empty': 'No text recognized from voice',
|
|
171
|
-
|
|
168
|
+
't-agent.input.asr.error.timeout': 'Voice recognition has reached time limit, sending directly',
|
|
172
169
|
't-agent.message.feedback.success': 'Feedback Successful',
|
|
173
170
|
't-agent.message.bubble.aborted': 'User Aborted',
|
|
174
171
|
't-agent.message.action.copy': 'Copy Message',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ray-js/t-agent-ui-ray",
|
|
3
|
-
"version": "0.2.0-beta-
|
|
3
|
+
"version": "0.2.0-beta-10",
|
|
4
4
|
"author": "Tuya.inc",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"@types/echarts": "^4.9.22",
|
|
41
41
|
"@types/markdown-it": "^14.1.1"
|
|
42
42
|
},
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "a17ba630a9ec71afe6a0fc46c427f664d46acf82"
|
|
44
44
|
}
|