@ray-js/t-agent-ui-ray 0.2.0-beta-2 → 0.2.0-beta-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.
@@ -12,6 +12,13 @@ import { defaultRenderOptions } from '../renderOption';
12
12
  import logger from '../logger';
13
13
  export default function ChatContainer(props) {
14
14
  const [keyboardHeight, setKeyboardHeight] = useState(0);
15
+ const [windowSize, setWindowSize] = useState(() => {
16
+ const info = ty.getSystemInfoSync();
17
+ return {
18
+ width: info.windowWidth,
19
+ height: info.windowHeight
20
+ };
21
+ });
15
22
  const {
16
23
  createAgent,
17
24
  renderOptions = defaultRenderOptions,
@@ -25,6 +32,13 @@ export default function ChatContainer(props) {
25
32
  if (!agent.plugins.ui) {
26
33
  throw new Error('UI plugin not found');
27
34
  }
35
+ agent.session.initValue('UIRay.multiSelect.show', false);
36
+ agent.session.initValue('UIRay.multiSelect.selected', []);
37
+ agent.session.onChange((key, value) => {
38
+ if (key === 'UIRay.multiSelect.show' && !value) {
39
+ agent.session.set('UIRay.multiSelect.selected', []);
40
+ }
41
+ });
28
42
  return agent;
29
43
  });
30
44
  if (props.agentRef) {
@@ -135,6 +149,17 @@ export default function ChatContainer(props) {
135
149
  const hide = () => {
136
150
  setKeyboardHeight(0);
137
151
  };
152
+ const resize = _ref4 => {
153
+ let {
154
+ size
155
+ } = _ref4;
156
+ setWindowSize({
157
+ width: size.windowWidth,
158
+ height: size.windowHeight
159
+ });
160
+ };
161
+ // @ts-ignore
162
+ ty.onWindowResize(resize);
138
163
  ty.onKeyboardWillShow(show);
139
164
  ty.onKeyboardWillHide(hide);
140
165
  ty.onKeyboardHeightChange(show);
@@ -142,12 +167,16 @@ export default function ChatContainer(props) {
142
167
  ty.offKeyboardWillShow(show);
143
168
  ty.offKeyboardWillHide(hide);
144
169
  ty.offKeyboardHeightChange(show);
170
+ // @ts-ignore
171
+ ty.offWindowResize(resize);
145
172
  };
146
173
  }, []);
147
174
  return /*#__PURE__*/React.createElement(View, {
148
175
  style: _objectSpread({
149
176
  // @ts-ignore
150
- '--t-agent-chat-container-keyboard-height': "".concat(keyboardHeight, "px")
177
+ '--t-agent-chat-container-keyboard-height': "".concat(keyboardHeight, "px"),
178
+ '--t-agent-chat-container-window-height': "".concat(windowSize.height, "px"),
179
+ '--t-agent-chat-container-window-width': "".concat(windowSize.width, "px")
151
180
  }, style),
152
181
  className: cx('t-agent-chat-container', className, {
153
182
  't-agent-chat-container-keyboard-show': keyboardHeight > 0
@@ -1,15 +1,14 @@
1
1
  import React from 'react';
2
- export declare const WaveformVisualizer: ({ amplitudeCount }: {
3
- amplitudeCount: number;
4
- }) => React.JSX.Element;
5
- interface IProps {
2
+ interface Props {
6
3
  amplitudeCount: number;
4
+ responding: boolean;
7
5
  recording: boolean;
8
6
  disabled?: boolean;
9
7
  onConfirm: () => void;
10
8
  onRecord: () => void;
11
9
  onCancel: () => void;
12
10
  onBack: () => void;
11
+ onAbort: () => void;
13
12
  }
14
- declare const AsrInput: (props: IProps) => React.JSX.Element;
13
+ declare const AsrInput: (props: Props) => React.JSX.Element;
15
14
  export default AsrInput;
@@ -1,112 +1,80 @@
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
1
  import "core-js/modules/web.dom-collections.iterator.js";
5
- import React, { useState } from 'react';
2
+ import React, { useRef, useState } from 'react';
6
3
  import { Button, View } from '@ray-js/ray';
7
4
  import cx from 'clsx';
8
- import { useOnEvent, useTranslate } from '../../hooks';
9
- export const WaveformVisualizer = _ref => {
10
- let {
11
- amplitudeCount
12
- } = _ref;
13
- const [bars, setBars] = useState(() => Array.from({
14
- length: amplitudeCount
15
- }, (_, index) => /*#__PURE__*/React.createElement(View
16
- // eslint-disable-next-line react/no-array-index-key
17
- , {
18
- key: "asr_wave_".concat(index),
19
- className: "t-agent-message-input-waveform-bar",
20
- style: {
21
- height: 0,
22
- // 添加渐变色偏移效果
23
- animationDelay: "".concat(index * 10, "ms")
24
- }
25
- })));
26
- useOnEvent('amplitudes', val => {
27
- const waveBase = val.body.amplitudes || [];
28
- const bars = waveBase.map((item, index) => {
29
- const value = item > 1 ? 1 : item * 100;
30
- // 将数值映射到高度范围(0-100 → 2px-20px)
31
- // const height = 2 + (value / 100) * 18;
32
- return /*#__PURE__*/React.createElement(View
33
- // eslint-disable-next-line react/no-array-index-key
34
- , {
35
- key: "asr_wave_".concat(index),
36
- className: "t-agent-message-input-waveform-bar t-agent-item",
37
- style: {
38
- height: "".concat(value, "%"),
39
- // 添加渐变色偏移效果
40
- animationDelay: "".concat(index * 10, "ms")
41
- }
42
- });
43
- });
44
- setBars(bars);
45
- });
46
- return /*#__PURE__*/React.createElement(View, {
47
- className: "t-agent-message-input-waveform-container"
48
- }, bars);
49
- };
5
+ import { useTranslate } from '../../hooks';
6
+ import { WaveformVisualizer } from './WaveformVisualizer';
50
7
  const AsrInput = props => {
51
- const [asrElementBounds, setAsrElementBounds] = useState(null);
8
+ const touchRef = useRef({
9
+ startAt: 0,
10
+ y: 0
11
+ });
52
12
  const t = useTranslate();
53
- const [ptt, setPtt] = useState(false);
54
- const onVoiceTouchEnd = e => {
55
- const touch = e.origin.changedTouches[0];
56
- const touchY = touch.clientY;
57
- setPtt(false);
58
- // 误触状态
59
- if (!asrElementBounds) {
60
- setTimeout(() => {
61
- props.onCancel();
62
- }, 200);
63
- setAsrElementBounds(null);
13
+ const [active, setActive] = useState(false);
14
+ const [cancel, setCancel] = useState(false);
15
+ const onVoiceTouchEnd = event => {
16
+ const touchY = event.changedTouches[0].pageY;
17
+ setCancel(false);
18
+ setActive(false);
19
+ if (touchRef.current.y - touchY > 100) {
20
+ touchRef.current = {
21
+ startAt: 0,
22
+ y: 0
23
+ };
24
+ props.onCancel();
64
25
  return;
65
26
  }
66
- // 上滑取消
67
- if (touchY < asrElementBounds.top - 100) {
68
- setTimeout(() => {
69
- props.onCancel();
70
- }, 200);
71
- setAsrElementBounds(null);
27
+ if (Date.now() - touchRef.current.startAt < 500) {
28
+ // 这种情况是误触,直接取消
29
+ touchRef.current = {
30
+ startAt: 0,
31
+ y: 0
32
+ };
33
+ props.onCancel();
72
34
  return;
73
35
  }
74
- setTimeout(() => {
75
- props.onConfirm();
76
- }, 200);
77
- setAsrElementBounds(null);
36
+ props.onConfirm();
78
37
  };
79
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(View, {
38
+ return /*#__PURE__*/React.createElement(View, {
39
+ className: "t-agent-message-input-ptt-bar"
40
+ }, /*#__PURE__*/React.createElement(View, {
80
41
  className: cx('t-agent-message-input-ptt', {
81
- 't-agent-message-input-ptt-handle': ptt
42
+ 't-agent-message-input-ptt-active': active,
43
+ 't-agent-message-input-ptt-cancel': cancel
82
44
  }),
83
- onTouchStart: () => {
84
- const query = ty.createSelectorQuery();
85
- query.select('.t-agent-message-input-ptt').boundingClientRect(rect => {
86
- if (!rect) return;
87
- setAsrElementBounds(rect);
88
- }).exec();
89
- setPtt(true);
90
- setTimeout(() => {
91
- props.onRecord();
92
- }, 200);
45
+ onTouchStart: async event => {
46
+ var _event$touches$;
47
+ touchRef.current = {
48
+ startAt: Date.now(),
49
+ y: (_event$touches$ = event.touches[0]) === null || _event$touches$ === void 0 ? void 0 : _event$touches$.pageY
50
+ };
51
+ setActive(true);
52
+ props.onRecord();
53
+ },
54
+ onTouchMove: event => {
55
+ const touch = event.touches[0];
56
+ const touchY = touch.pageY;
57
+ setCancel(touchRef.current.y - touchY > 100);
93
58
  },
94
59
  onTouchCancel: onVoiceTouchEnd,
95
60
  onTouchEnd: onVoiceTouchEnd
96
- }, props.recording ? /*#__PURE__*/React.createElement(View, {
97
- className: "t-agent-message-input-oninput"
98
61
  }, /*#__PURE__*/React.createElement(View, {
99
- className: "t-agent-message-input-oninput-text-top"
62
+ className: "t-agent-message-input-ptt-text"
63
+ }, " ", t('t-agent.input.asr.ptt')), /*#__PURE__*/React.createElement(View, {
64
+ className: cx('t-agent-message-input-ptt-overlay', {
65
+ 't-agent-message-input-ptt-overlay-active': active,
66
+ 't-agent-message-input-ptt-overlay-cancel': cancel
67
+ })
68
+ }, /*#__PURE__*/React.createElement(View, {
69
+ className: "t-agent-message-input-ptt-active-text-top"
100
70
  }, t('t-agent.input.asr.oninput.text.top')), /*#__PURE__*/React.createElement(View, {
101
- className: "t-agent-message-input-oninput-text-center"
71
+ className: "t-agent-message-input-ptt-active-text-center"
102
72
  }, t('t-agent.input.asr.oninput.text.center')), /*#__PURE__*/React.createElement(WaveformVisualizer, {
103
73
  amplitudeCount: props.amplitudeCount
104
- })) : /*#__PURE__*/React.createElement(View, {
105
- className: "t-agent-message-input-ptt-text"
106
- }, " ", t('t-agent.input.asr.ptt'))), !props.recording && /*#__PURE__*/React.createElement(Button, {
107
- className: "t-agent-message-input-button t-agent-message-input-button-keyboard",
74
+ }))), !props.recording && /*#__PURE__*/React.createElement(Button, {
75
+ className: cx('t-agent-message-input-button', 't-agent-message-input-ptt-action-button', props.responding ? 't-agent-message-input-button-stop' : 't-agent-message-input-button-keyboard'),
108
76
  "data-testid": "t-agent-message-input-button-asr",
109
- onClick: props.onBack
77
+ onClick: props.responding ? props.onAbort : props.onBack
110
78
  }));
111
79
  };
112
80
  export default AsrInput;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export declare const WaveformVisualizer: ({ amplitudeCount }: {
3
+ amplitudeCount: number;
4
+ }) => React.JSX.Element;
@@ -0,0 +1,47 @@
1
+ import "core-js/modules/esnext.iterator.constructor.js";
2
+ import "core-js/modules/esnext.iterator.map.js";
3
+ import "core-js/modules/web.dom-collections.iterator.js";
4
+ import React, { useState } from 'react';
5
+ import { View } from '@ray-js/ray';
6
+ import { useOnEvent } from '../../hooks';
7
+ export const WaveformVisualizer = _ref => {
8
+ let {
9
+ amplitudeCount
10
+ } = _ref;
11
+ const [bars, setBars] = useState(() => Array.from({
12
+ length: amplitudeCount
13
+ }, (_, index) => /*#__PURE__*/React.createElement(View
14
+ // eslint-disable-next-line react/no-array-index-key
15
+ , {
16
+ key: "asr_wave_".concat(index),
17
+ className: "t-agent-message-input-waveform-bar",
18
+ style: {
19
+ height: 0,
20
+ // 添加渐变色偏移效果
21
+ animationDelay: "".concat(index * 10, "ms")
22
+ }
23
+ })));
24
+ useOnEvent('amplitudes', val => {
25
+ const waveBase = val.body.amplitudes || [];
26
+ const bars = waveBase.map((item, index) => {
27
+ const value = item > 1 ? 1 : item * 100;
28
+ // 将数值映射到高度范围(0-100 → 2px-20px)
29
+ // const height = 2 + (value / 100) * 18;
30
+ return /*#__PURE__*/React.createElement(View
31
+ // eslint-disable-next-line react/no-array-index-key
32
+ , {
33
+ key: "asr_wave_".concat(index),
34
+ className: "t-agent-message-input-waveform-bar",
35
+ style: {
36
+ height: "".concat(value, "%"),
37
+ // 添加渐变色偏移效果
38
+ animationDelay: "".concat(index * 10, "ms")
39
+ }
40
+ });
41
+ });
42
+ setBars(bars);
43
+ });
44
+ return /*#__PURE__*/React.createElement(View, {
45
+ className: "t-agent-message-input-waveform-container"
46
+ }, bars);
47
+ };
@@ -14,8 +14,9 @@ import imageSvg from '../icons/image.svg';
14
14
  import videoSvg from '../icons/video.svg';
15
15
  import loadingSvg from '../icons/loading.svg';
16
16
  import closeCircleSvg from '../icons/close-circle.svg';
17
- import { useAttachmentInput, useChatAgent, useEmitEvent, useIsUnmounted, useOnEvent, useTranslate } from '../../hooks';
17
+ import { useAgentSessionValue, useAttachmentInput, useChatAgent, useEmitEvent, useIsUnmounted, useOnEvent, useTranslate } from '../../hooks';
18
18
  import AsrInput from './AsrInput';
19
+ import { useSleep } from '../../hooks/useSleep';
19
20
  const AMPLITUDE_COUNT = 60;
20
21
  export default function MessageInputAIStream(props) {
21
22
  const [moreOpen, setMoreOpen] = useState(false);
@@ -50,9 +51,10 @@ export default function MessageInputAIStream(props) {
50
51
  setResponding(false);
51
52
  }
52
53
  });
53
- const isMore = !text.trim().length && true;
54
+ const [hasMore] = useAgentSessionValue('multiModal');
55
+ const isMore = !text.trim().length && hasMore;
54
56
  const send = async inputBlocks => {
55
- if (!(inputBlocks !== null && inputBlocks !== void 0 && inputBlocks.length) || attachmentInput.uploading || responding) {
57
+ if (!(inputBlocks !== null && inputBlocks !== void 0 && inputBlocks.length)) {
56
58
  return;
57
59
  }
58
60
  setUploaded([]);
@@ -63,8 +65,8 @@ export default function MessageInputAIStream(props) {
63
65
  ac.signal.addEventListener('abort', () => {
64
66
  if (acRef.current === ac) {
65
67
  acRef.current = null;
68
+ setResponding(false);
66
69
  }
67
- setResponding(false);
68
70
  });
69
71
  try {
70
72
  await agent.pushInputBlocks(inputBlocks, ac.signal);
@@ -131,7 +133,9 @@ export default function MessageInputAIStream(props) {
131
133
  });
132
134
  }
133
135
  };
136
+ const sleep = useSleep();
134
137
  let container;
138
+ const canSend = text.trim().length && !responding && !attachmentInput.uploading;
135
139
  if (mode === 'text') {
136
140
  container = /*#__PURE__*/React.createElement(View, {
137
141
  className: "t-agent-message-input-text-bar"
@@ -145,7 +149,7 @@ export default function MessageInputAIStream(props) {
145
149
  "data-testid": "t-agent-message-input-text-inner",
146
150
  className: "t-agent-message-input-text-inner",
147
151
  onConfirm: () => {
148
- if (text.trim().length) {
152
+ if (canSend) {
149
153
  send([...attachmentInput.blocks, {
150
154
  type: 'text',
151
155
  text
@@ -193,7 +197,7 @@ export default function MessageInputAIStream(props) {
193
197
  }
194
198
  } else if (isMore) {
195
199
  openMoreClick();
196
- } else if (text.trim().length) {
200
+ } else if (canSend) {
197
201
  await send([...attachmentInput.blocks, {
198
202
  type: 'text',
199
203
  text
@@ -202,21 +206,25 @@ export default function MessageInputAIStream(props) {
202
206
  }
203
207
  }));
204
208
  } 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, {
209
+ container = /*#__PURE__*/React.createElement(AsrInput, {
210
+ responding: responding,
210
211
  disabled: responding,
211
212
  amplitudeCount: AMPLITUDE_COUNT,
212
213
  recording: record.recording,
213
214
  onRecord: async () => {
215
+ if (attachmentInput.uploading) {
216
+ return;
217
+ }
218
+ if (responding && acRef.current) {
219
+ acRef.current.abort('User abort');
220
+ // 中断后等待一会再开始
221
+ await sleep(50);
222
+ }
214
223
  const emitter = new Emitter();
215
224
  setRecord({
216
225
  startAt: Date.now(),
217
226
  recording: true,
218
227
  confirm: () => {
219
- console.log('setRecord confirm');
220
228
  emitter.dispatchEvent(new EmitterEvent('confirm'));
221
229
  setRecord({
222
230
  startAt: 0,
@@ -226,7 +234,6 @@ export default function MessageInputAIStream(props) {
226
234
  });
227
235
  },
228
236
  cancel: () => {
229
- console.log('setRecord cancel');
230
237
  emitter.dispatchEvent(new EmitterEvent('cancel'));
231
238
  setRecord({
232
239
  startAt: 0,
@@ -237,7 +244,6 @@ export default function MessageInputAIStream(props) {
237
244
  }
238
245
  });
239
246
  emitter.addEventListener('error', event => {
240
- console.log('setRecord error');
241
247
  ty.showToast({
242
248
  icon: 'error',
243
249
  title: t('t-agent.input.voice.recording-failed')
@@ -250,7 +256,6 @@ export default function MessageInputAIStream(props) {
250
256
  cancel: null
251
257
  });
252
258
  });
253
- console.log('setRecord send');
254
259
  await send([...attachmentInput.blocks, {
255
260
  type: 'audio',
256
261
  audio_emitter: emitter,
@@ -259,16 +264,19 @@ export default function MessageInputAIStream(props) {
259
264
  },
260
265
  onConfirm: () => {
261
266
  var _record$confirm;
262
- console.log('test onConfirm');
263
267
  (_record$confirm = record.confirm) === null || _record$confirm === void 0 || _record$confirm.call(record);
264
268
  },
265
269
  onCancel: () => {
266
270
  var _record$cancel;
267
- console.log('test onCancel');
268
271
  (_record$cancel = record.cancel) === null || _record$cancel === void 0 || _record$cancel.call(record);
269
272
  },
270
- onBack: () => setMode('text')
271
- })));
273
+ onBack: () => setMode('text'),
274
+ onAbort: () => {
275
+ if (responding && acRef.current) {
276
+ acRef.current.abort('User abort');
277
+ }
278
+ }
279
+ });
272
280
  }
273
281
  return /*#__PURE__*/React.createElement(View, {
274
282
  className: "".concat(props.className || '', " t-agent-message-input"),
@@ -146,12 +146,16 @@
146
146
  right: 10rpx;
147
147
  }
148
148
 
149
- .t-agent-message-input-button-keyboard {
150
- background: transparent url('icons/keyboard.svg') no-repeat center;
149
+ .t-agent-message-input-ptt-action-button {
151
150
  position: absolute;
152
151
  top: 50%;
153
152
  transform: translateY(-50%);
154
- right: 10rpx;
153
+ right: 32rpx;
154
+ }
155
+
156
+ .t-agent-message-input-button-keyboard {
157
+ border: 2rpx solid var(--t-agent-input-border-color);
158
+ background: transparent url('icons/text.svg') no-repeat center;
155
159
  }
156
160
 
157
161
  .t-agent-message-input-button-stop {
@@ -314,37 +318,64 @@
314
318
  min-height: 56rpx;
315
319
  }
316
320
 
317
- @transition-duration: 0.3s;
321
+ .t-agent-message-input-ptt-bar {
322
+ padding: 16rpx 32rpx;
323
+ position: relative;
324
+ }
318
325
 
319
326
  .t-agent-message-input-ptt {
320
327
  background: transparent;
321
328
  padding: 0;
322
329
  border: none;
323
- height: 56rpx;
330
+ height: 72rpx;
324
331
  display: flex;
325
332
  justify-content: center;
326
333
  align-items: center;
327
- transition: height @transition-duration ease-in-out; // 定义高度变化的过渡效果
328
- }
329
-
330
- .t-agent-message-input-ptt-handle {
331
- height: 224rpx;
334
+ transition: height 0.3s ease-in-out; // 定义高度变化的过渡效果
332
335
  }
333
336
 
334
337
  .t-agent-message-input-ptt-text {
335
338
  font-size: 32rpx;
336
339
  line-height: 56rpx;
337
- color: var(--app-M1-B1);
340
+ color: var(--app-B1-N1);
338
341
  text-align: center;
339
342
  }
340
343
 
341
- .t-agent-message-input-oninput-text-top {
344
+ .t-agent-message-input-ptt-overlay-cancel {
345
+
346
+ }
347
+
348
+ .t-agent-message-input-ptt-overlay {
349
+ position: absolute;
350
+ height: 100%;
351
+ left: 0;
352
+ right: 0;
353
+ bottom: 0;
354
+ background-color: var(--app-B1);
355
+ pointer-events: none;
356
+ opacity: 0;
357
+ display: flex;
358
+ flex-direction: column;
359
+ justify-content: center;
360
+ border-top: 2rpx solid var(--t-agent-input-border-color);
361
+ z-index: 2;
362
+ transition: opacity 0s ease 0.1s, height 0.3s ease;
363
+
364
+ &.t-agent-message-input-ptt-overlay-active {
365
+ transition: opacity 0s ease 0s, height 0.3s ease;
366
+ opacity: 1;
367
+ height: calc(100% + 150rpx);
368
+ }
369
+ }
370
+
371
+ .t-agent-message-input-ptt-active-text-top {
342
372
  font-size: 32rpx;
343
373
  line-height: 56rpx;
344
374
  color: var(--app-M1-B1);
345
375
  text-align: center;
346
376
  }
347
- .t-agent-message-input-oninput-text-center {
377
+
378
+ .t-agent-message-input-ptt-active-text-center {
348
379
  font-size: 20rpx;
349
380
  color: var(--app-M1-B1);
350
381
  text-align: center;
@@ -365,7 +396,7 @@
365
396
  background-color: var(--app-M4);
366
397
  border-radius: 2rpx;
367
398
  transition: height 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s ease;
368
- animation: colorPulse 2s infinite;
399
+ animation: t-agent-message-input-waveform-bar-color-pulse 2s infinite;
369
400
  margin-right: 4rpx;
370
401
  opacity: 1;
371
402
 
@@ -374,7 +405,7 @@
374
405
  }
375
406
  }
376
407
 
377
- @keyframes colorPulse {
408
+ @keyframes t-agent-message-input-waveform-bar-color-pulse {
378
409
  0% {
379
410
  opacity: 1;
380
411
  }
@@ -10,11 +10,6 @@ interface Props {
10
10
  assistant?: 'start' | 'end' | string;
11
11
  [key: string]: 'start' | 'end' | string;
12
12
  };
13
- multSelect?: {
14
- show: boolean;
15
- select: string[];
16
- onSelect: (msgs: string[]) => void;
17
- };
18
13
  historyLimit?: {
19
14
  /** 历史消息数量限制 */
20
15
  count: number;
@@ -10,7 +10,7 @@ import { ScrollView } from '@ray-js/ray';
10
10
  import { generateId } from '@ray-js/t-agent';
11
11
  import { isVersionMatch } from '@ray-js/t-agent-plugin-aistream';
12
12
  import MessageRender from '../MessageRender';
13
- import { useAgentMessage, useOnEvent } from '../hooks';
13
+ import { useAgentMessage, useAgentSessionValue, useOnEvent } from '../hooks';
14
14
  import { useDebouncedFn } from '../hooks/useDebouncedFn';
15
15
  import { useSleep } from '../hooks/useSleep';
16
16
  export default function MessageList(props) {
@@ -20,8 +20,7 @@ export default function MessageList(props) {
20
20
  style,
21
21
  wrapperClassName,
22
22
  wrapperStyle,
23
- historyLimit,
24
- multSelect
23
+ historyLimit
25
24
  } = props;
26
25
  const {
27
26
  messages
@@ -32,6 +31,7 @@ export default function MessageList(props) {
32
31
  const [scrollTop, setScrollTop] = useState(() => 1000000000000000 + Math.floor(Date.now() / 10));
33
32
  const followNewMessageRef = useRef(true);
34
33
  const sleep = useSleep();
34
+ const [showSelect] = useAgentSessionValue('UIRay.multiSelect.show');
35
35
  const canIUse = useMemo(() => {
36
36
  // @ts-ignore
37
37
  const {
@@ -104,7 +104,7 @@ export default function MessageList(props) {
104
104
  side = msg.role === 'user' ? 'end' : 'start';
105
105
  }
106
106
  return /*#__PURE__*/React.createElement(MessageRender, {
107
- multSelect: multSelect,
107
+ showSelect: showSelect,
108
108
  key: msg.id,
109
109
  message: msg,
110
110
  isLatestMessage: index === 0,
@@ -5,11 +5,7 @@ interface Props {
5
5
  message: ChatMessageObject;
6
6
  isLatestMessage: boolean;
7
7
  side: 'start' | 'end' | string;
8
- multSelect?: {
9
- show: boolean;
10
- select: string[];
11
- onSelect: (msgs: string[]) => void;
12
- };
8
+ showSelect?: boolean;
13
9
  }
14
- export default function MessageRender({ message, isLatestMessage, side, multSelect }: Props): React.JSX.Element;
10
+ export default function MessageRender({ message, isLatestMessage, side, showSelect }: Props): React.JSX.Element;
15
11
  export {};
@@ -4,24 +4,34 @@ import "core-js/modules/esnext.iterator.map.js";
4
4
  import "core-js/modules/web.dom-collections.iterator.js";
5
5
  import './index.less';
6
6
  import { View } from '@ray-js/components';
7
- import React from 'react';
7
+ import React, { useState } from 'react';
8
8
  import TileRender from '../TileRender';
9
+ import { useChatAgent, useOnEvent } from '../hooks';
9
10
  export default function MessageRender(_ref) {
10
11
  let {
11
12
  message,
12
13
  isLatestMessage,
13
14
  side,
14
- multSelect
15
+ showSelect
15
16
  } = _ref;
16
17
  const {
17
18
  id,
18
19
  tiles
19
20
  } = message;
20
- const {
21
- select = [],
22
- onSelect = () => {},
23
- show: showMultSelect = false
24
- } = multSelect || {};
21
+ const agent = useChatAgent();
22
+ const [isSelected, setIsSelected] = useState(() => {
23
+ var _agent$session$get;
24
+ return !!((_agent$session$get = agent.session.get("UIRay.multiSelect.selected")) !== null && _agent$session$get !== void 0 && _agent$session$get.includes(id));
25
+ });
26
+ useOnEvent('sessionChange', _ref2 => {
27
+ let {
28
+ key,
29
+ value
30
+ } = _ref2;
31
+ if (key === 'UIRay.multiSelect.selected') {
32
+ setIsSelected(!!(value !== null && value !== void 0 && value.includes(id)));
33
+ }
34
+ });
25
35
  if (tiles.length === 0) {
26
36
  return /*#__PURE__*/React.createElement(View, {
27
37
  key: id,
@@ -30,14 +40,19 @@ export default function MessageRender(_ref) {
30
40
  }
31
41
  return /*#__PURE__*/React.createElement(View, {
32
42
  key: id,
33
- className: "t-agent-message-list-row-container "
34
- }, showMultSelect && /*#__PURE__*/React.createElement(View, {
43
+ className: "t-agent-message-list-row-container",
44
+ onClick: () => {
45
+ if (showSelect) {
46
+ const prev = agent.session.get("UIRay.multiSelect.selected") || [];
47
+ isSelected ? agent.session.set("UIRay.multiSelect.selected", prev.filter(i => i !== id)) : agent.session.set("UIRay.multiSelect.selected", [...prev, id]);
48
+ }
49
+ }
50
+ }, showSelect && /*#__PURE__*/React.createElement(View, {
35
51
  className: "t-agent-message-list-row-check"
36
52
  }, /*#__PURE__*/React.createElement(View, {
37
- className: "checkbox-container ".concat(select.includes(id) ? 'selected' : ''),
38
- onClick: () => select.includes(id) ? onSelect([...select.filter(v => v !== id)]) : onSelect([...select, id])
53
+ className: "t-agent-message-list-checkbox-container ".concat(isSelected ? 't-agent-message-list-checkbox-selected' : '')
39
54
  }, /*#__PURE__*/React.createElement(View, {
40
- className: "checkbox-check"
55
+ className: "t-agent-message-list-checkbox-check"
41
56
  }))), /*#__PURE__*/React.createElement(View, {
42
57
  className: "t-agent-message-list-row t-agent-message-list-row-".concat(side)
43
58
  }, tiles.map(tile => {
@@ -28,7 +28,7 @@
28
28
  @border-color: rgba(0, 0, 0, 0.3);
29
29
  @active-color: #3678E3;
30
30
 
31
- .checkbox-container {
31
+ .t-agent-message-list-checkbox-container {
32
32
  position: relative;
33
33
  width: @checkbox-size;
34
34
  height: @checkbox-size;
@@ -38,17 +38,17 @@
38
38
  cursor: pointer;
39
39
  transition: all 0.2s ease-in-out;
40
40
 
41
- &.selected {
41
+ &.t-agent-message-list-checkbox-selected {
42
42
  background: @active-color;
43
43
  border-color: transparent;
44
44
 
45
- .checkbox-check {
45
+ .t-agent-message-list-checkbox-check {
46
46
  opacity: 1;
47
47
  }
48
48
  }
49
49
  }
50
50
 
51
- .checkbox-check {
51
+ .t-agent-message-list-checkbox-check {
52
52
  position: absolute;
53
53
  top: 50%;
54
54
  left: 50%;
@@ -58,4 +58,4 @@
58
58
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSI5IiB2aWV3Qm94PSIwIDAgMTIgOSI+PHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRkZGIiBzdHJva2Utd2lkdGg9IjIiIGQ9Ik0xIDRsMy43NSA0TDEwLjMgMSIvPjwvc3ZnPg==");
59
59
  opacity: 0;
60
60
  transition: opacity 0.2s ease-in-out;
61
- }
61
+ }
@@ -1,3 +1,4 @@
1
+ import { Dispatch, SetStateAction } from 'react';
1
2
  import { TTTAction } from '../types';
2
3
  export declare const useChatAgent: () => import("../contexts").UIChatAgent;
3
4
  export declare const useAgentMessage: () => {
@@ -9,3 +10,4 @@ export declare const useOnEvent: (eventName: string, callback: (details: any) =>
9
10
  export declare const useEmitEvent: () => <T extends keyof import("@ray-js/t-agent").UIEventMap>(eventName: T, detail: import("@ray-js/t-agent").UIEventMap[T]) => void;
10
11
  export declare const useTileProps: () => import("../types").TileProps<any, any>;
11
12
  export declare const useSendAction: () => (action: TTTAction) => void;
13
+ export declare const useAgentSessionValue: <S = any>(key: string) => readonly [S, Dispatch<SetStateAction<S>>];
@@ -1,4 +1,5 @@
1
- import { useEffect, useContext, useCallback, useRef } from 'react';
1
+ import "core-js/modules/web.dom-collections.iterator.js";
2
+ import { useEffect, useContext, useCallback, useRef, useState } from 'react';
2
3
  import { TilePropsContext, ChatAgentContext, MessageContext, RenderContext } from '../contexts';
3
4
  export const useChatAgent = () => {
4
5
  return useContext(ChatAgentContext);
@@ -42,4 +43,26 @@ export const useSendAction = () => {
42
43
  agent.plugins.ui.emitEvent('runTTTAction', action);
43
44
  }, [agent]);
44
45
  return emitTileEvent ? tileSendAction : uiSendAction;
46
+ };
47
+ export const useAgentSessionValue = key => {
48
+ const agent = useChatAgent();
49
+ const [value, setValue] = useState(() => agent.session.get(key));
50
+ const set = useCallback(value => {
51
+ if (typeof value === 'function') {
52
+ const prev = agent.session.get(key);
53
+ value = value(prev);
54
+ }
55
+ agent.session.set(key, value);
56
+ setValue(value);
57
+ }, []);
58
+ useOnEvent('sessionChange', _ref => {
59
+ let {
60
+ key: k,
61
+ value
62
+ } = _ref;
63
+ if (k === key) {
64
+ setValue(value);
65
+ }
66
+ });
67
+ return [value, set];
45
68
  };
@@ -3,4 +3,4 @@ export * from './useAttachmentInput';
3
3
  export * from './useIsUnmounted';
4
4
  export * from './useLongPress';
5
5
  export * from './useTranslate';
6
- export * from './useMultSelect';
6
+ export * from './useMultiSelect';
@@ -3,4 +3,4 @@ export * from './useAttachmentInput';
3
3
  export * from './useIsUnmounted';
4
4
  export * from './useLongPress';
5
5
  export * from './useTranslate';
6
- export * from './useMultSelect';
6
+ export * from './useMultiSelect';
@@ -2,7 +2,7 @@ import { ChatMessageObject } from '@ray-js/t-agent';
2
2
  /**
3
3
  * 预定义动作类型
4
4
  */
5
- export type ActionType = 'copy' | 'delete' | 'like' | 'unlike' | 'deleteByChannel' | 'multSelect';
5
+ export type ActionType = 'copy' | 'delete' | 'like' | 'unlike' | 'deleteByChannel' | 'multiSelect';
6
6
  export interface ActionMenuItem {
7
7
  key: string;
8
8
  label: string;
@@ -23,7 +23,7 @@ export interface LongPressActionMenuProps {
23
23
  }
24
24
  export interface UseLongPressOptions {
25
25
  message?: ChatMessageObject;
26
- actions?: ActionType | ActionType[];
26
+ actions?: ActionType | ActionType[] | string[];
27
27
  getMessageContent?: () => string;
28
28
  customActions?: ActionMenuItem[];
29
29
  disabled?: boolean;
@@ -20,7 +20,7 @@ export function useLongPress() {
20
20
  let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
21
21
  const {
22
22
  message,
23
- actions = ['copy', 'multSelect', 'delete'],
23
+ actions = ['copy', 'multiSelect', 'delete'],
24
24
  getMessageContent = () => '',
25
25
  customActions = [],
26
26
  disabled = false
@@ -79,12 +79,12 @@ export function useLongPress() {
79
79
  });
80
80
  }
81
81
  break;
82
- case 'multSelect':
82
+ case 'multiSelect':
83
83
  menuItems.push({
84
- key: 'multSelect',
85
- label: t('t-agent.message.action.multSelect'),
84
+ key: 'multiSelect',
85
+ label: t('t-agent.message.action.multiSelect'),
86
86
  action: () => {
87
- emitEvent('multSelect', {});
87
+ agent.session.set('UIRay.multiSelect.show', !agent.session.get('UIRay.multiSelect.show'));
88
88
  }
89
89
  });
90
90
  break;
@@ -115,32 +115,33 @@ export function useLongPress() {
115
115
  });
116
116
  }
117
117
  break;
118
- case 'deleteByChannel':
119
- menuItems.push({
120
- key: 'deleteByChannel',
121
- label: t('t-agent.message.action.deleteByChannel'),
122
- action: () => {
123
- // const channel = agent.session.get('AIAssistant.channel');
124
- // const { removeMessageByChannel } = agent.plugins.assistant;
125
- // if (typeof removeMessageByChannel === 'function') {
126
- // removeMessageByChannel(channel);
127
- // }
128
- }
129
- });
130
- break;
131
118
  case 'like':
132
119
  menuItems.push({
133
120
  key: 'like',
134
121
  label: t('t-agent.message.action.like'),
135
122
  action: async () => {
136
- // const { feedback } = agent.plugins.assistant;
137
- // if (typeof feedback === 'function') {
138
- // await feedback({ requestId: message.id, type: 'like' });
139
- // ty.showToast({
140
- // title: t('t-agent.message.like.success'),
141
- // icon: 'none',
142
- // });
143
- // }
123
+ try {
124
+ const result = await agent.plugins.ui.callHook('onMessageFeedback', {
125
+ messageId: message.id,
126
+ rate: 'like'
127
+ });
128
+ if (result !== null && result !== void 0 && result.success) {
129
+ ty.showToast({
130
+ title: t('t-agent.message.like.success'),
131
+ icon: 'none'
132
+ });
133
+ } else {
134
+ ty.showToast({
135
+ title: t('t-agent.unknown-error'),
136
+ icon: 'none'
137
+ });
138
+ }
139
+ } catch (error) {
140
+ ty.showToast({
141
+ title: (error === null || error === void 0 ? void 0 : error.message) || t('t-agent.unknown-error'),
142
+ icon: 'none'
143
+ });
144
+ }
144
145
  }
145
146
  });
146
147
  break;
@@ -149,14 +150,28 @@ export function useLongPress() {
149
150
  key: 'unlike',
150
151
  label: t('t-agent.message.action.unlike'),
151
152
  action: async () => {
152
- // const { feedback } = agent.plugins.assistant;
153
- // if (typeof feedback === 'function') {
154
- // await feedback({ requestId: message.id, type: 'unlike' });
155
- // ty.showToast({
156
- // title: t('t-agent.message.unlike.success'),
157
- // icon: 'none',
158
- // });
159
- // }
153
+ try {
154
+ const result = await agent.plugins.ui.callHook('onMessageFeedback', {
155
+ messageId: message.id,
156
+ rate: 'unlike'
157
+ });
158
+ if (result !== null && result !== void 0 && result.success) {
159
+ ty.showToast({
160
+ title: t('t-agent.message.unlike.success'),
161
+ icon: 'none'
162
+ });
163
+ } else {
164
+ ty.showToast({
165
+ title: t('t-agent.unknown-error'),
166
+ icon: 'none'
167
+ });
168
+ }
169
+ } catch (error) {
170
+ ty.showToast({
171
+ title: (error === null || error === void 0 ? void 0 : error.message) || t('t-agent.unknown-error'),
172
+ icon: 'none'
173
+ });
174
+ }
160
175
  }
161
176
  });
162
177
  break;
@@ -217,9 +232,11 @@ export function useLongPress() {
217
232
  isClosing: false,
218
233
  menuPosition: adjustedPosition
219
234
  });
220
- ty.vibrateShort({
221
- type: 'light'
222
- });
235
+ if (ty.getSystemInfoSync().brand !== 'devtools') {
236
+ ty.vibrateShort({
237
+ type: 'light'
238
+ });
239
+ }
223
240
  if (e.origin && e.origin.stopPropagation) {
224
241
  e.origin.stopPropagation();
225
242
  }
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- export declare const useMultSelectMessage: () => {
2
+ export declare const useMultiSelectMessage: () => {
3
3
  show: boolean;
4
4
  select: string[];
5
5
  onSelect: import("react").Dispatch<import("react").SetStateAction<string[]>>;
@@ -1,6 +1,6 @@
1
1
  import "core-js/modules/web.dom-collections.iterator.js";
2
2
  import { useState } from 'react';
3
- export const useMultSelectMessage = () => {
3
+ export const useMultiSelectMessage = () => {
4
4
  const [select, setSelect] = useState([]);
5
5
  const [show, setShow] = useState(false);
6
6
  return {
@@ -25,7 +25,7 @@ declare const _default: {
25
25
  't-agent.message.action.copy': string;
26
26
  't-agent.message.action.delete': string;
27
27
  't-agent.message.action.deleteByChannel': string;
28
- 't-agent.message.action.multSelect': string;
28
+ 't-agent.message.action.multiSelect': string;
29
29
  't-agent.message.like.success': string;
30
30
  't-agent.message.unlike.success': string;
31
31
  't-agent.message.action.like': string;
@@ -66,6 +66,7 @@ declare const _default: {
66
66
  't-agent.expand.scene.one-click': string;
67
67
  't-agent.expand.scene.auto': string;
68
68
  't-agent.expand.no.details': string;
69
+ 't-agent.unknown-error': string;
69
70
  };
70
71
  'zh-Hant': {
71
72
  't-agent.build-in.button.create_scene_manually': string;
@@ -157,7 +158,7 @@ declare const _default: {
157
158
  't-agent.message.action.copy': string;
158
159
  't-agent.message.action.delete': string;
159
160
  't-agent.message.action.deleteByChannel': string;
160
- 't-agent.message.action.multSelect': string;
161
+ 't-agent.message.action.multiSelect': string;
161
162
  't-agent.message.like.success': string;
162
163
  't-agent.message.unlike.success': string;
163
164
  't-agent.message.action.like': string;
@@ -198,6 +199,7 @@ declare const _default: {
198
199
  't-agent.expand.scene.one-click': string;
199
200
  't-agent.expand.scene.auto': string;
200
201
  't-agent.expand.no.details': string;
202
+ 't-agent.unknown-error': string;
201
203
  };
202
204
  ja: {
203
205
  't-agent.build-in.button.create_scene_manually': string;
@@ -25,7 +25,7 @@ export default {
25
25
  't-agent.message.action.copy': '复制消息',
26
26
  't-agent.message.action.delete': '删除消息',
27
27
  't-agent.message.action.deleteByChannel': '删除所有渠道消息',
28
- 't-agent.message.action.multSelect': '多选',
28
+ 't-agent.message.action.multiSelect': '多选',
29
29
  't-agent.message.like.success': '点赞成功',
30
30
  't-agent.message.unlike.success': '取消点赞成功',
31
31
  't-agent.message.action.like': '喜欢消息',
@@ -65,7 +65,8 @@ export default {
65
65
  't-agent.expand.scene.rename': '{oldName}改名成{newName}',
66
66
  't-agent.expand.scene.one-click': '一键执行',
67
67
  't-agent.expand.scene.auto': '自动执行',
68
- 't-agent.expand.no.details': '没有可显示的详情内容'
68
+ 't-agent.expand.no.details': '没有可显示的详情内容',
69
+ 't-agent.unknown-error': '未知错误'
69
70
  },
70
71
  'zh-Hant': {
71
72
  't-agent.build-in.button.create_scene_manually': '手動創建場景',
@@ -160,7 +161,7 @@ export default {
160
161
  't-agent.message.action.copy': 'Copy Message',
161
162
  't-agent.message.action.delete': 'Delete Message',
162
163
  't-agent.message.action.deleteByChannel': 'Delete All Channel Messages',
163
- 't-agent.message.action.multSelect': 'Multiple Selection',
164
+ 't-agent.message.action.multiSelect': 'Multiple Selection',
164
165
  't-agent.message.like.success': 'Like Successful',
165
166
  't-agent.message.unlike.success': 'Unlike Successful',
166
167
  't-agent.message.action.like': 'Like Message',
@@ -200,7 +201,8 @@ export default {
200
201
  't-agent.expand.scene.rename': '{oldName} renamed to {newName}',
201
202
  't-agent.expand.scene.one-click': 'One-click Execution',
202
203
  't-agent.expand.scene.auto': 'Automatic Execution',
203
- 't-agent.expand.no.details': 'No details available'
204
+ 't-agent.expand.no.details': 'No details available',
205
+ 't-agent.unknown-error': 'Unknown Error'
204
206
  },
205
207
  ja: {
206
208
  't-agent.build-in.button.create_scene_manually': 'シーンを手動で作成',
@@ -1,23 +1,21 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
- import "core-js/modules/es.json.stringify.js";
3
2
  import "core-js/modules/esnext.iterator.constructor.js";
4
3
  import "core-js/modules/esnext.iterator.find.js";
5
4
  import "core-js/modules/esnext.iterator.map.js";
6
5
  import "core-js/modules/esnext.iterator.some.js";
7
- import "core-js/modules/web.dom-collections.iterator.js";
8
6
  import './index.less';
9
7
  import { View } from '@ray-js/components';
10
- import React, { useEffect, useState, useCallback, memo } from 'react';
8
+ import React, { useCallback, memo } from 'react';
11
9
  import { Image } from '@ray-js/ray';
12
- import { BubbleTileStatus, ChatMessageStatus, safeParseJSON } from '@ray-js/t-agent';
10
+ import { BubbleTileStatus, ChatMessageStatus } from '@ray-js/t-agent';
13
11
  import TileRender from '../../TileRender';
14
12
  import noticeSvg from './notice.svg';
15
13
  import noticeWarnSvg from './notice-warn.svg';
16
14
  import { useChatAgent, useTranslate, useLongPress, useRenderOptions } from '../../hooks';
17
15
  import RollBack from '../WorkflowTile/RollBack';
18
16
  const BubbleTile = props => {
19
- var _message$meta$request, _workflowTile$data;
20
- const agent = useChatAgent();
17
+ var _workflowTile$data;
18
+ useChatAgent();
21
19
  const {
22
20
  renderLongPressAs
23
21
  } = useRenderOptions();
@@ -38,30 +36,6 @@ const BubbleTile = props => {
38
36
  const bubbleStatus = data.status || BubbleTileStatus.NORMAL;
39
37
  const t = useTranslate();
40
38
  const loading = status === ChatMessageStatus.START || status === ChatMessageStatus.UPDATING;
41
- isLatestMessage && status === ChatMessageStatus.FINISH && role === 'assistant' && ((_message$meta$request = message.meta.requestId) === null || _message$meta$request === void 0 ? void 0 : _message$meta$request.startsWith('AIAssistant')) && bubbleStatus === BubbleTileStatus.NORMAL;
42
- const [feedbackLoaded, setFeedbackLoaded] = useState(false);
43
- const [feedbackValue, setFeedbackValue] = useState(null);
44
- useEffect(() => {
45
- ty.getStorage({
46
- key: 'latestMessageFeedbackValue',
47
- success: res => {
48
- if (res.data) {
49
- try {
50
- const {
51
- requestId,
52
- value
53
- } = safeParseJSON(res.data);
54
- if (requestId === message.meta.requestId) {
55
- setFeedbackValue(value);
56
- }
57
- } catch (e) {
58
- // noop
59
- }
60
- }
61
- setFeedbackLoaded(true);
62
- }
63
- });
64
- }, []);
65
39
  const showInfo = () => {
66
40
  if (data.info) {
67
41
  ty.showToast({
@@ -90,12 +64,7 @@ const BubbleTile = props => {
90
64
  }, [tile]);
91
65
  const longPressRes = useLongPress({
92
66
  message,
93
- // actions: [
94
- // 'copy',
95
- // 'delete',
96
- // ...(isAssistantMessage ? ['like', 'unlike', 'deleteByChannel'] : []),
97
- // ] as ActionType[],
98
- actions: ['copy', 'multSelect', 'delete'],
67
+ actions: ['copy', 'multiSelect', 'delete', 'like', 'unlike'],
99
68
  getMessageContent,
100
69
  disabled: loading
101
70
  });
@@ -1,5 +1,5 @@
1
- import React from 'react';
2
1
  import './index.less';
2
+ import React from 'react';
3
3
  export default function RollBack(props: {
4
4
  nodeId: string;
5
5
  }): React.JSX.Element;
@@ -1,28 +1,22 @@
1
+ import './index.less';
1
2
  import { Image, View } from '@ray-js/ray';
2
3
  import React from 'react';
3
4
  import rollback from './workflow-rollback.png';
4
- import { useChatAgent } from '../../../hooks';
5
- import './index.less';
5
+ import { useTileProps } from '../../../hooks';
6
6
  export default function RollBack(props) {
7
7
  const {
8
8
  nodeId
9
9
  } = props;
10
- const agent = useChatAgent();
10
+ const {
11
+ emitTileEvent
12
+ } = useTileProps();
11
13
  return /*#__PURE__*/React.createElement(View, {
12
14
  className: "t-agent-workflow-rollback-tile",
13
15
  onClick: async () => {
14
- agent.session.get('AIAssistant.channel');
15
- const systemInfo = ty.getSystemInfoSync();
16
- systemInfo.language; // await agent.plugins.assistant.runSkill('hi', 'assistant', {
17
- // channel,
18
- // domain: 'control',
19
- // intent: 'backNode',
20
- // lang,
21
- // 'back.node.id': nodeId,
22
- // device_id: undefined,
23
- // 'text.stream': 'true',
24
- // 'tts.disable': 'true',
25
- // });
16
+ emitTileEvent({
17
+ type: 'rollback',
18
+ nodeId
19
+ });
26
20
  }
27
21
  }, /*#__PURE__*/React.createElement(Image, {
28
22
  src: rollback,
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-2",
3
+ "version": "0.2.0-beta-4",
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": "0784a0f440b67cc1f766a440dbad5350f633dfb1"
43
+ "gitHead": "1728f8a1cac6b2ca53e506e06171808fbf38efdc"
44
44
  }