@ray-js/t-agent-ui-ray 0.1.1 → 0.2.0-beta-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 (52) hide show
  1. package/dist/ChatContainer/index.js +0 -10
  2. package/dist/MessageInput/MessageInputAIStream/AsrInput.d.ts +15 -0
  3. package/dist/MessageInput/MessageInputAIStream/AsrInput.js +109 -0
  4. package/dist/MessageInput/MessageInputAIStream/index.d.ts +10 -0
  5. package/dist/MessageInput/MessageInputAIStream/index.js +359 -0
  6. package/dist/MessageInput/{AsrInput.d.ts → MessageInputAssistant/AsrInput.d.ts} +1 -1
  7. package/dist/MessageInput/{AsrInput.js → MessageInputAssistant/AsrInput.js} +2 -2
  8. package/dist/MessageInput/MessageInputAssistant/index.d.ts +11 -0
  9. package/dist/MessageInput/MessageInputAssistant/index.js +322 -0
  10. package/dist/MessageInput/icons/keyboard.svg +1 -0
  11. package/dist/MessageInput/index.d.ts +0 -1
  12. package/dist/MessageInput/index.js +3 -320
  13. package/dist/MessageInput/index.less +78 -3
  14. package/dist/MessageList/index.d.ts +5 -0
  15. package/dist/MessageList/index.js +4 -2
  16. package/dist/MessageRender/index.d.ts +6 -1
  17. package/dist/MessageRender/index.js +19 -2
  18. package/dist/MessageRender/index.less +48 -1
  19. package/dist/PrivateImage/index.js +1 -1
  20. package/dist/cards/map.js +3 -2
  21. package/dist/contexts.d.ts +1 -2
  22. package/dist/contexts.js +1 -0
  23. package/dist/hooks/index.d.ts +1 -0
  24. package/dist/hooks/index.js +2 -1
  25. package/dist/hooks/useAttachmentInput.d.ts +3 -1
  26. package/dist/hooks/useAttachmentInput.js +75 -34
  27. package/dist/hooks/useLongPress.d.ts +1 -1
  28. package/dist/hooks/useLongPress.js +38 -36
  29. package/dist/hooks/useMultSelect.d.ts +7 -0
  30. package/dist/hooks/useMultSelect.js +12 -0
  31. package/dist/i18n/strings.d.ts +8 -0
  32. package/dist/i18n/strings.js +11 -0
  33. package/dist/renderOption.js +5 -0
  34. package/dist/tiles/BubbleTile/index.js +9 -10
  35. package/dist/tiles/CardTile/index.js +6 -7
  36. package/dist/tiles/ExecuteCardTile/index.d.ts +8 -1
  37. package/dist/tiles/ExecuteCardTile/index.js +11 -1
  38. package/dist/tiles/FileTile/index.d.ts +8 -0
  39. package/dist/tiles/FileTile/index.js +57 -0
  40. package/dist/tiles/FileTile/index.less +44 -0
  41. package/dist/tiles/ImageTile/index.js +1 -0
  42. package/dist/tiles/OperateCardTile/Expand.d.ts +7 -1
  43. package/dist/tiles/OperateCardTile/Expand.js +11 -1
  44. package/dist/tiles/OperateCardTile/index.d.ts +4 -1
  45. package/dist/tiles/OperateCardTile/index.js +2 -0
  46. package/dist/tiles/WorkflowTile/RollBack/index.js +11 -12
  47. package/dist/tiles/WorkflowTile/index.d.ts +4 -1
  48. package/dist/tiles/map.js +3 -1
  49. package/dist/types.d.ts +2 -0
  50. package/dist/utils/file.d.ts +24 -0
  51. package/dist/utils/file.js +190 -0
  52. package/package.json +2 -2
@@ -6,7 +6,6 @@ import "core-js/modules/web.dom-collections.iterator.js";
6
6
  import './index.less';
7
7
  import React, { useEffect, useMemo, useState } from 'react';
8
8
  import { View } from '@ray-js/components';
9
- import { SocketStatus } from '@ray-js/t-agent-plugin-assistant';
10
9
  import cx from 'clsx';
11
10
  import { ChatAgentContext, MessageContext, RenderContext } from '../contexts';
12
11
  import { defaultRenderOptions } from '../renderOption';
@@ -26,9 +25,6 @@ export default function ChatContainer(props) {
26
25
  if (!agent.plugins.ui) {
27
26
  throw new Error('UI plugin not found');
28
27
  }
29
- if (!agent.plugins.assistant) {
30
- throw new Error('Assistant plugin not found');
31
- }
32
28
  return agent;
33
29
  });
34
30
  if (props.agentRef) {
@@ -59,11 +55,6 @@ export default function ChatContainer(props) {
59
55
  onEvent,
60
56
  emitEvent
61
57
  } = agent.plugins.ui;
62
- const offSocketStatusChange = agent.plugins.assistant.onSocketStatusChange(status => {
63
- emitEvent('networkChange', {
64
- online: status === SocketStatus.SUCCESS
65
- });
66
- });
67
58
  const offMessageListInit = onEvent('messageListInit', _ref => {
68
59
  let {
69
60
  messages
@@ -113,7 +104,6 @@ export default function ChatContainer(props) {
113
104
  }
114
105
  });
115
106
  return () => {
116
- offSocketStatusChange();
117
107
  offMessageListInit();
118
108
  offMessageChange();
119
109
  };
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ export declare const WaveformVisualizer: React.FC<{
3
+ data: number[];
4
+ }>;
5
+ interface IProps {
6
+ amplitudeCount: number;
7
+ recording: boolean;
8
+ disabled?: boolean;
9
+ onConfirm: () => void;
10
+ onRecord: () => void;
11
+ onCancel: () => void;
12
+ onBack: () => void;
13
+ }
14
+ declare const AsrInput: (props: IProps) => React.JSX.Element;
15
+ export default AsrInput;
@@ -0,0 +1,109 @@
1
+ import "core-js/modules/es.regexp.exec.js";
2
+ import "core-js/modules/esnext.iterator.constructor.js";
3
+ import "core-js/modules/esnext.iterator.map.js";
4
+ import "core-js/modules/web.dom-collections.iterator.js";
5
+ import React, { useMemo, useState } from 'react';
6
+ import { Button, View } from '@ray-js/ray';
7
+ import cx from 'clsx';
8
+ import { useOnEvent, useTranslate } from '../../hooks';
9
+ export const WaveformVisualizer = /*#__PURE__*/React.memo(_ref => {
10
+ let {
11
+ data
12
+ } = _ref;
13
+ // 缓存计算后的波形条样式
14
+ const bars = useMemo(() => {
15
+ return data.map((value, index) => {
16
+ // 将数值映射到高度范围(0-100 → 2px-20px)
17
+
18
+ return {
19
+ height: "".concat(2 + value / 100 * 18, "px"),
20
+ // 添加渐变色偏移效果
21
+ animationDelay: "".concat(index * 10, "ms")
22
+ };
23
+ });
24
+ }, [data]);
25
+ return /*#__PURE__*/React.createElement(View, {
26
+ className: "t-agent-message-input-waveform-container"
27
+ }, bars.map((barStyle, index) => /*#__PURE__*/React.createElement(View
28
+ // eslint-disable-next-line react/no-array-index-key
29
+ , {
30
+ key: "asr_wave_".concat(index),
31
+ className: "t-agent-message-input-waveform-bar",
32
+ style: barStyle
33
+ // role="progressbar"
34
+ ,
35
+ "aria-valuenow": data[index],
36
+ "aria-valuemin": 0,
37
+ "aria-valuemax": 100
38
+ })));
39
+ });
40
+ const AsrInput = props => {
41
+ const [asrElementBounds, setAsrElementBounds] = useState(null);
42
+ const t = useTranslate();
43
+ const [waveData, setWaveData] = React.useState(Array.from({
44
+ length: props.amplitudeCount
45
+ }, () => 0));
46
+ const [ptt, setPtt] = useState(false);
47
+ useOnEvent('amplitudes', val => {
48
+ const waveBase = val.body.amplitudes || [];
49
+ setWaveData(waveBase.map(item => item > 1 ? 1 : item * 100));
50
+ });
51
+ const onVoiceTouchEnd = e => {
52
+ const touch = e.origin.changedTouches[0];
53
+ const touchY = touch.clientY;
54
+ setPtt(false);
55
+ // 误触状态
56
+ if (!asrElementBounds) {
57
+ setTimeout(() => {
58
+ props.onCancel();
59
+ }, 200);
60
+ setAsrElementBounds(null);
61
+ return;
62
+ }
63
+ // 上滑取消
64
+ if (touchY < asrElementBounds.top - 100) {
65
+ setTimeout(() => {
66
+ props.onCancel();
67
+ }, 200);
68
+ setAsrElementBounds(null);
69
+ return;
70
+ }
71
+ setTimeout(() => {
72
+ props.onConfirm();
73
+ }, 200);
74
+ setAsrElementBounds(null);
75
+ };
76
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(View, {
77
+ className: cx('t-agent-message-input-ptt', {
78
+ 't-agent-message-input-ptt-handle': ptt
79
+ }),
80
+ onTouchStart: () => {
81
+ const query = ty.createSelectorQuery();
82
+ query.select('.t-agent-message-input-ptt').boundingClientRect(rect => {
83
+ if (!rect) return;
84
+ setAsrElementBounds(rect);
85
+ }).exec();
86
+ setPtt(true);
87
+ setTimeout(() => {
88
+ props.onRecord();
89
+ }, 200);
90
+ },
91
+ onTouchCancel: onVoiceTouchEnd,
92
+ onTouchEnd: onVoiceTouchEnd
93
+ }, props.recording ? /*#__PURE__*/React.createElement(View, {
94
+ className: "t-agent-message-input-oninput"
95
+ }, /*#__PURE__*/React.createElement(View, {
96
+ className: "t-agent-message-input-oninput-text-top"
97
+ }, t('t-agent.input.asr.oninput.text.top')), /*#__PURE__*/React.createElement(View, {
98
+ className: "t-agent-message-input-oninput-text-center"
99
+ }, t('t-agent.input.asr.oninput.text.center')), /*#__PURE__*/React.createElement(WaveformVisualizer, {
100
+ data: waveData
101
+ })) : /*#__PURE__*/React.createElement(View, {
102
+ className: "t-agent-message-input-ptt-text"
103
+ }, " ", t('t-agent.input.asr.ptt'))), !props.recording && /*#__PURE__*/React.createElement(Button, {
104
+ className: "t-agent-message-input-button t-agent-message-input-button-keyboard",
105
+ "data-testid": "t-agent-message-input-button-asr",
106
+ onClick: props.onBack
107
+ }));
108
+ };
109
+ export default AsrInput;
@@ -0,0 +1,10 @@
1
+ import '../index.less';
2
+ import React from 'react';
3
+ interface Props {
4
+ className?: string;
5
+ renderTop?: React.ReactNode;
6
+ placeholder?: string;
7
+ style?: React.CSSProperties;
8
+ }
9
+ export default function MessageInputAIStream(props: Props): React.JSX.Element;
10
+ export {};
@@ -0,0 +1,359 @@
1
+ import "core-js/modules/es.string.trim.js";
2
+ import "core-js/modules/esnext.iterator.constructor.js";
3
+ import "core-js/modules/esnext.iterator.filter.js";
4
+ import "core-js/modules/esnext.iterator.map.js";
5
+ import "core-js/modules/web.dom-collections.iterator.js";
6
+ import '../index.less';
7
+ import { Button, View } from '@ray-js/components';
8
+ import React, { useRef, useState } from 'react';
9
+ import { Image, Input, ScrollView } from '@ray-js/ray';
10
+ import { AbortController, authorize } from '@ray-js/t-agent-plugin-aistream';
11
+ import { Emitter, EmitterEvent } from '@ray-js/t-agent';
12
+ import cx from 'clsx';
13
+ import imageSvg from '../icons/image.svg';
14
+ import videoSvg from '../icons/video.svg';
15
+ import loadingSvg from '../icons/loading.svg';
16
+ import closeCircleSvg from '../icons/close-circle.svg';
17
+ import { useAttachmentInput, useChatAgent, useEmitEvent, useIsUnmounted, useOnEvent, useTranslate } from '../../hooks';
18
+ import AsrInput from './AsrInput';
19
+ const AMPLITUDE_COUNT = 60;
20
+ export default function MessageInputAIStream(props) {
21
+ const [moreOpen, setMoreOpen] = useState(false);
22
+ const t = useTranslate();
23
+ const [text, setText] = useState('');
24
+ const [record, setRecord] = useState({
25
+ startAt: 0,
26
+ recording: false,
27
+ confirm: null,
28
+ cancel: null
29
+ });
30
+ const attachmentInput = useAttachmentInput({
31
+ local: true
32
+ });
33
+ const {
34
+ uploading,
35
+ uploaded,
36
+ setUploaded,
37
+ upload
38
+ } = attachmentInput;
39
+ const acRef = useRef(null);
40
+ const [responding, setResponding] = useState(false);
41
+ const [mode, setMode] = useState('text');
42
+ const agent = useChatAgent();
43
+ const emitEvent = useEmitEvent();
44
+ const isUnmounted = useIsUnmounted();
45
+ useOnEvent('networkChange', _ref => {
46
+ let {
47
+ online
48
+ } = _ref;
49
+ if (!online && responding) {
50
+ setResponding(false);
51
+ }
52
+ });
53
+ const isMore = !text.trim().length && true;
54
+ const send = async inputBlocks => {
55
+ if (!(inputBlocks !== null && inputBlocks !== void 0 && inputBlocks.length) || attachmentInput.uploading || responding) {
56
+ return;
57
+ }
58
+ setUploaded([]);
59
+ setText('');
60
+ setResponding(true);
61
+ const ac = new AbortController();
62
+ acRef.current = ac;
63
+ ac.signal.addEventListener('abort', () => {
64
+ if (acRef.current === ac) {
65
+ acRef.current = null;
66
+ }
67
+ setResponding(false);
68
+ });
69
+ try {
70
+ await agent.pushInputBlocks(inputBlocks, ac.signal);
71
+ } finally {
72
+ if (!isUnmounted()) {
73
+ setResponding(false);
74
+ }
75
+ }
76
+ };
77
+ useOnEvent('sendMessage', async _ref2 => {
78
+ let {
79
+ blocks
80
+ } = _ref2;
81
+ if (uploading || responding) {
82
+ return;
83
+ }
84
+ setText('');
85
+ setMoreOpen(false);
86
+ setUploaded([]);
87
+ setResponding(true);
88
+ const ac = new AbortController();
89
+ acRef.current = ac;
90
+ ac.signal.addEventListener('abort', () => {
91
+ if (acRef.current === ac) {
92
+ acRef.current = null;
93
+ }
94
+ setResponding(false);
95
+ });
96
+ try {
97
+ await agent.pushInputBlocks(blocks, ac.signal);
98
+ } finally {
99
+ if (!isUnmounted()) {
100
+ setResponding(false);
101
+ }
102
+ }
103
+ });
104
+ useOnEvent('setInputBlocks', async _ref3 => {
105
+ let {
106
+ blocks
107
+ } = _ref3;
108
+ if (uploading || responding) {
109
+ return;
110
+ }
111
+ if (mode !== 'text') {
112
+ setMode('text');
113
+ }
114
+ attachmentInput.loadBlocks(blocks);
115
+ let t = '';
116
+ for (const block of blocks) {
117
+ if (block.type === 'text') {
118
+ t = block.text;
119
+ }
120
+ }
121
+ if (t) {
122
+ setText(t);
123
+ }
124
+ setMoreOpen(false);
125
+ });
126
+ const openMoreClick = () => {
127
+ setMoreOpen(!moreOpen);
128
+ if (!moreOpen) {
129
+ emitEvent('scrollToBottom', {
130
+ animation: true
131
+ });
132
+ }
133
+ };
134
+ let container;
135
+ if (mode === 'text') {
136
+ container = /*#__PURE__*/React.createElement(View, {
137
+ className: "t-agent-message-input-text-bar"
138
+ }, /*#__PURE__*/React.createElement(View, {
139
+ className: "t-agent-message-input-text-group"
140
+ }, /*#__PURE__*/React.createElement(Input, {
141
+ confirmType: "send",
142
+ value: text,
143
+ onInput: event => setText(event.detail.value),
144
+ placeholder: props.placeholder,
145
+ "data-testid": "t-agent-message-input-text-inner",
146
+ className: "t-agent-message-input-text-inner",
147
+ onConfirm: () => {
148
+ if (text.trim().length) {
149
+ send([...attachmentInput.blocks, {
150
+ type: 'text',
151
+ text
152
+ }]);
153
+ }
154
+ },
155
+ maxLength: 200,
156
+ placeholderStyle: "color: var(--app-B1-N4)",
157
+ onFocus: () => {
158
+ setMoreOpen(false);
159
+ emitEvent('scrollToBottom', {
160
+ animation: true
161
+ });
162
+ }
163
+ }), /*#__PURE__*/React.createElement(Button, {
164
+ "data-testid": "t-agent-message-input-button-asr",
165
+ onClick: async () => {
166
+ const auth = await authorize({
167
+ scope: 'scope.record'
168
+ }).then(() => true, () => false);
169
+ if (!auth) {
170
+ ty.showToast({
171
+ icon: 'none',
172
+ title: t('t-agent.input.voice.require-permission')
173
+ });
174
+ return;
175
+ }
176
+ setText('');
177
+ setMode('voice');
178
+ },
179
+ className: "t-agent-message-input-button t-agent-message-input-button-voice"
180
+ })), /*#__PURE__*/React.createElement(Button, {
181
+ disabled: !isMore && uploading,
182
+ className: cx('t-agent-message-input-button', {
183
+ 't-agent-message-input-button-more': isMore,
184
+ 't-agent-message-input-button-more-open': moreOpen && isMore,
185
+ 't-agent-message-input-button-send': !isMore && !responding,
186
+ 't-agent-message-input-button-stop': responding
187
+ }),
188
+ "data-testid": "t-agent-message-input-button-main",
189
+ onClick: async () => {
190
+ if (responding) {
191
+ if (acRef.current) {
192
+ acRef.current.abort('User abort');
193
+ }
194
+ } else if (isMore) {
195
+ openMoreClick();
196
+ } else if (text.trim().length) {
197
+ await send([...attachmentInput.blocks, {
198
+ type: 'text',
199
+ text
200
+ }]);
201
+ }
202
+ }
203
+ }));
204
+ } else {
205
+ container = /*#__PURE__*/React.createElement(View, {
206
+ className: "t-agent-message-input-text-bar"
207
+ }, /*#__PURE__*/React.createElement(View, {
208
+ className: "t-agent-message-input-text-group"
209
+ }, /*#__PURE__*/React.createElement(AsrInput, {
210
+ disabled: responding,
211
+ amplitudeCount: AMPLITUDE_COUNT,
212
+ recording: record.recording,
213
+ onRecord: async () => {
214
+ const emitter = new Emitter();
215
+ setRecord({
216
+ startAt: Date.now(),
217
+ recording: true,
218
+ confirm: () => {
219
+ console.log('setRecord confirm');
220
+ emitter.dispatchEvent(new EmitterEvent('confirm'));
221
+ setRecord({
222
+ startAt: 0,
223
+ recording: false,
224
+ confirm: null,
225
+ cancel: null
226
+ });
227
+ },
228
+ cancel: () => {
229
+ console.log('setRecord cancel');
230
+ emitter.dispatchEvent(new EmitterEvent('cancel'));
231
+ setRecord({
232
+ startAt: 0,
233
+ recording: false,
234
+ confirm: null,
235
+ cancel: null
236
+ });
237
+ }
238
+ });
239
+ emitter.addEventListener('error', event => {
240
+ console.log('setRecord error');
241
+ ty.showToast({
242
+ icon: 'error',
243
+ title: t('t-agent.input.voice.recording-failed')
244
+ });
245
+ console.error(event);
246
+ setRecord({
247
+ recording: false,
248
+ confirm: null,
249
+ cancel: null
250
+ });
251
+ });
252
+ console.log('setRecord send');
253
+ await send([...attachmentInput.blocks, {
254
+ type: 'audio',
255
+ audio_emitter: emitter,
256
+ amplitude_count: AMPLITUDE_COUNT
257
+ }]);
258
+ },
259
+ onConfirm: () => {
260
+ var _record$confirm;
261
+ console.log('test onConfirm');
262
+ (_record$confirm = record.confirm) === null || _record$confirm === void 0 || _record$confirm.call(record);
263
+ },
264
+ onCancel: () => {
265
+ var _record$cancel;
266
+ console.log('test onCancel');
267
+ (_record$cancel = record.cancel) === null || _record$cancel === void 0 || _record$cancel.call(record);
268
+ },
269
+ onBack: () => setMode('text')
270
+ })));
271
+ }
272
+ return /*#__PURE__*/React.createElement(View, {
273
+ className: "".concat(props.className || '', " t-agent-message-input"),
274
+ style: props.style
275
+ }, /*#__PURE__*/React.createElement(View, {
276
+ className: "t-agent-message-input-container"
277
+ }, props.renderTop, !!uploaded.length && /*#__PURE__*/React.createElement(ScrollView, {
278
+ scrollX: true,
279
+ scrollY: false,
280
+ enableFlex: true,
281
+ className: "t-agent-message-input-uploaded-files",
282
+ refresherTriggered: false
283
+ }, uploaded.map(file => {
284
+ let content;
285
+ switch (file.type) {
286
+ case 'image':
287
+ content = /*#__PURE__*/React.createElement(Image, {
288
+ className: "t-agent-message-input-uploaded-file-image",
289
+ mode: "aspectFill",
290
+ src: file.url
291
+ });
292
+ break;
293
+ case 'video':
294
+ content = /*#__PURE__*/React.createElement(Image, {
295
+ className: "t-agent-message-input-uploaded-file-image",
296
+ mode: "aspectFill",
297
+ src: file.thumbUrl
298
+ });
299
+ break;
300
+ case 'loading':
301
+ content = /*#__PURE__*/React.createElement(View, {
302
+ className: "t-agent-message-input-uploaded-file-loading",
303
+ key: file.id
304
+ }, /*#__PURE__*/React.createElement(Image, {
305
+ src: loadingSvg,
306
+ className: "t-agent-message-input-uploaded-file-loading-icon"
307
+ }));
308
+ break;
309
+ default:
310
+ content = null;
311
+ }
312
+ return /*#__PURE__*/React.createElement(View, {
313
+ key: file.id,
314
+ className: "t-agent-message-input-uploaded-file"
315
+ }, /*#__PURE__*/React.createElement(Image, {
316
+ onClick: () => {
317
+ setUploaded(prev => prev.filter(f => f.id !== file.id));
318
+ },
319
+ className: "t-agent-message-input-uploaded-file-delete",
320
+ src: closeCircleSvg
321
+ }), content);
322
+ })), container), /*#__PURE__*/React.createElement(View, {
323
+ className: "t-agent-message-input-panel ".concat(moreOpen ? '' : 't-agent-message-input-panel-close')
324
+ }, /*#__PURE__*/React.createElement(View, {
325
+ className: "t-agent-message-input-panel-content"
326
+ }, /*#__PURE__*/React.createElement(Button, {
327
+ className: "t-agent-message-input-panel-button",
328
+ onClick: async () => {
329
+ try {
330
+ await upload('image', 1);
331
+ } catch (e) {
332
+ ty.showToast({
333
+ icon: 'error',
334
+ title: t('t-agent.input.upload.failed')
335
+ });
336
+ }
337
+ }
338
+ }, /*#__PURE__*/React.createElement(View, {
339
+ className: "t-agent-message-input-panel-button-icon"
340
+ }, /*#__PURE__*/React.createElement(Image, {
341
+ src: imageSvg
342
+ }))), /*#__PURE__*/React.createElement(Button, {
343
+ className: "t-agent-message-input-panel-button",
344
+ onClick: async () => {
345
+ try {
346
+ await upload('video', 1);
347
+ } catch (e) {
348
+ ty.showToast({
349
+ icon: 'error',
350
+ title: t('t-agent.input.upload.failed')
351
+ });
352
+ }
353
+ }
354
+ }, /*#__PURE__*/React.createElement(View, {
355
+ className: "t-agent-message-input-panel-button-icon"
356
+ }, /*#__PURE__*/React.createElement(Image, {
357
+ src: videoSvg
358
+ }))))));
359
+ }
@@ -1,4 +1,4 @@
1
- import './index.less';
1
+ import '../index.less';
2
2
  import React from 'react';
3
3
  interface Props {
4
4
  text: string;
@@ -1,8 +1,8 @@
1
- import './index.less';
1
+ import '../index.less';
2
2
  import { Button, Text, View, Textarea } from '@ray-js/components';
3
3
  import React from 'react';
4
4
  import cx from 'clsx';
5
- import { useAsrInput } from '../hooks';
5
+ import { useAsrInput } from '../../hooks';
6
6
  export default function AsrInput(props) {
7
7
  const {
8
8
  responding,
@@ -0,0 +1,11 @@
1
+ import '../index.less';
2
+ import React from 'react';
3
+ interface Props {
4
+ className?: string;
5
+ renderTop?: React.ReactNode;
6
+ placeholder?: string;
7
+ style?: React.CSSProperties;
8
+ multiModal?: boolean;
9
+ }
10
+ export default function MessageInputAssistant(props: Props): React.JSX.Element;
11
+ export {};