@ray-js/t-agent-ui-ray 0.0.8 → 0.0.9-beta-2
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.
- package/dist/CustomCardRender/index.js +21 -3
- package/dist/MarkdownRender/index.less +0 -4
- package/dist/MarkdownRender/theme/light.less +2 -1
- package/dist/MessageInput/AsrInput.d.ts +1 -0
- package/dist/MessageInput/AsrInput.js +9 -5
- package/dist/MessageInput/icons/stop.svg +1 -0
- package/dist/MessageInput/index.js +34 -7
- package/dist/MessageInput/index.less +6 -2
- package/dist/TileRender/index.js +1 -1
- package/dist/contexts.js +2 -1
- package/dist/tiles/BubbleTile/index.js +4 -1
- package/dist/tiles/BubbleTile/index.less +8 -0
- package/dist/tiles/CardTile/index.js +2 -1
- package/dist/types.d.ts +9 -3
- package/package.json +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import './index.less';
|
|
2
2
|
import { View } from '@ray-js/components';
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import { useRenderOptions } from '../hooks';
|
|
3
|
+
import React, { useCallback, useEffect, useRef } from 'react';
|
|
4
|
+
import { useRenderOptions, useTileProps } from '../hooks';
|
|
5
5
|
export default function CustomCardRender(_ref) {
|
|
6
6
|
let {
|
|
7
7
|
card
|
|
@@ -9,6 +9,23 @@ export default function CustomCardRender(_ref) {
|
|
|
9
9
|
const {
|
|
10
10
|
customCardMap
|
|
11
11
|
} = useRenderOptions();
|
|
12
|
+
const {
|
|
13
|
+
emitEvent
|
|
14
|
+
} = useTileProps();
|
|
15
|
+
const ref = useRef(card);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
ref.current = card;
|
|
18
|
+
});
|
|
19
|
+
const setCardState = useCallback((state, options) => {
|
|
20
|
+
if (typeof state === 'function') {
|
|
21
|
+
state = state(ref.current.cardState);
|
|
22
|
+
}
|
|
23
|
+
emitEvent({
|
|
24
|
+
type: '@buildIn/setCardState',
|
|
25
|
+
state,
|
|
26
|
+
options: options || {}
|
|
27
|
+
});
|
|
28
|
+
}, [emitEvent]);
|
|
12
29
|
const Card = customCardMap[card.cardCode];
|
|
13
30
|
if (!Card) {
|
|
14
31
|
return null;
|
|
@@ -16,6 +33,7 @@ export default function CustomCardRender(_ref) {
|
|
|
16
33
|
return /*#__PURE__*/React.createElement(View, {
|
|
17
34
|
className: "t-agent-custom-card-render"
|
|
18
35
|
}, /*#__PURE__*/React.createElement(Card, {
|
|
19
|
-
card: card
|
|
36
|
+
card: card,
|
|
37
|
+
setCardState: setCardState
|
|
20
38
|
}));
|
|
21
39
|
}
|
|
@@ -12,7 +12,8 @@ export default function AsrInput(props) {
|
|
|
12
12
|
closeMore,
|
|
13
13
|
hasMore,
|
|
14
14
|
text,
|
|
15
|
-
setText
|
|
15
|
+
setText,
|
|
16
|
+
onAbort
|
|
16
17
|
} = props;
|
|
17
18
|
const {
|
|
18
19
|
state,
|
|
@@ -65,16 +66,19 @@ export default function AsrInput(props) {
|
|
|
65
66
|
onTouchCancel: release,
|
|
66
67
|
onTouchEnd: release
|
|
67
68
|
}), /*#__PURE__*/React.createElement(Button, {
|
|
68
|
-
disabled: sendDisabled
|
|
69
|
+
disabled: sendDisabled,
|
|
69
70
|
"data-testid": "t-agent-message-input-asr-button-right",
|
|
70
71
|
className: cx('t-agent-message-input-button', {
|
|
71
72
|
't-agent-message-input-button-voice-send': state === 'pending',
|
|
72
|
-
't-agent-message-input-button-hide': state === 'recording' || !hasMore && state !== 'pending',
|
|
73
|
+
't-agent-message-input-button-hide': (state === 'recording' || !hasMore && state !== 'pending') && !responding,
|
|
73
74
|
't-agent-message-input-button-more': state === 'init' && hasMore,
|
|
74
|
-
't-agent-message-input-button-more-open': state === 'init' && moreOpen
|
|
75
|
+
't-agent-message-input-button-more-open': state === 'init' && moreOpen,
|
|
76
|
+
't-agent-message-input-button-stop': state === 'init' && responding
|
|
75
77
|
}),
|
|
76
78
|
onClick: () => {
|
|
77
|
-
if (
|
|
79
|
+
if (responding) {
|
|
80
|
+
onAbort();
|
|
81
|
+
} else if (state === 'init' && hasMore) {
|
|
78
82
|
onMoreClick();
|
|
79
83
|
} else {
|
|
80
84
|
props.onSend();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#7b7c7e" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square"><rect width="18" height="18" x="3" y="3" rx="2"/></svg>
|
|
@@ -4,9 +4,9 @@ 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 { Button, View } from '@ray-js/components';
|
|
7
|
-
import React, { useState } from 'react';
|
|
7
|
+
import React, { useRef, useState } from 'react';
|
|
8
8
|
import { Image, Input, ScrollView } from '@ray-js/ray';
|
|
9
|
-
import { Asr } from '@ray-js/t-agent-plugin-assistant';
|
|
9
|
+
import { Asr, AbortController } from '@ray-js/t-agent-plugin-assistant';
|
|
10
10
|
import cx from 'clsx';
|
|
11
11
|
import PrivateImage from '../PrivateImage';
|
|
12
12
|
import imageSvg from './icons/image.svg';
|
|
@@ -29,6 +29,7 @@ export default function MessageInput(props) {
|
|
|
29
29
|
setUploaded,
|
|
30
30
|
upload
|
|
31
31
|
} = attachmentInput;
|
|
32
|
+
const acRef = useRef(null);
|
|
32
33
|
const [responding, setResponding] = useState(false);
|
|
33
34
|
const [mode, setMode] = useState('text');
|
|
34
35
|
const agent = useChatAgent();
|
|
@@ -51,8 +52,16 @@ export default function MessageInput(props) {
|
|
|
51
52
|
setUploaded([]);
|
|
52
53
|
setText('');
|
|
53
54
|
setResponding(true);
|
|
55
|
+
const ac = new AbortController();
|
|
56
|
+
acRef.current = ac;
|
|
57
|
+
ac.signal.addEventListener('abort', () => {
|
|
58
|
+
if (acRef.current === ac) {
|
|
59
|
+
acRef.current = null;
|
|
60
|
+
}
|
|
61
|
+
setResponding(false);
|
|
62
|
+
});
|
|
54
63
|
try {
|
|
55
|
-
await agent.pushInputBlocks(inputBlocks);
|
|
64
|
+
await agent.pushInputBlocks(inputBlocks, ac.signal);
|
|
56
65
|
} finally {
|
|
57
66
|
if (!isUnmounted()) {
|
|
58
67
|
setResponding(false);
|
|
@@ -70,8 +79,16 @@ export default function MessageInput(props) {
|
|
|
70
79
|
setMoreOpen(false);
|
|
71
80
|
setUploaded([]);
|
|
72
81
|
setResponding(true);
|
|
82
|
+
const ac = new AbortController();
|
|
83
|
+
acRef.current = ac;
|
|
84
|
+
ac.signal.addEventListener('abort', () => {
|
|
85
|
+
if (acRef.current === ac) {
|
|
86
|
+
acRef.current = null;
|
|
87
|
+
}
|
|
88
|
+
setResponding(false);
|
|
89
|
+
});
|
|
73
90
|
try {
|
|
74
|
-
await agent.pushInputBlocks(blocks);
|
|
91
|
+
await agent.pushInputBlocks(blocks, ac.signal);
|
|
75
92
|
} finally {
|
|
76
93
|
if (!isUnmounted()) {
|
|
77
94
|
setResponding(false);
|
|
@@ -154,15 +171,20 @@ export default function MessageInput(props) {
|
|
|
154
171
|
},
|
|
155
172
|
className: "t-agent-message-input-button t-agent-message-input-button-voice"
|
|
156
173
|
})), /*#__PURE__*/React.createElement(Button, {
|
|
157
|
-
disabled: !isMore &&
|
|
174
|
+
disabled: !isMore && uploading,
|
|
158
175
|
className: cx('t-agent-message-input-button', {
|
|
159
176
|
't-agent-message-input-button-more': isMore,
|
|
160
177
|
't-agent-message-input-button-more-open': moreOpen && isMore,
|
|
161
|
-
't-agent-message-input-button-send': !isMore
|
|
178
|
+
't-agent-message-input-button-send': !isMore && !responding,
|
|
179
|
+
't-agent-message-input-button-stop': responding
|
|
162
180
|
}),
|
|
163
181
|
"data-testid": "t-agent-message-input-button-main",
|
|
164
182
|
onClick: async () => {
|
|
165
|
-
if (
|
|
183
|
+
if (responding) {
|
|
184
|
+
if (acRef.current) {
|
|
185
|
+
acRef.current.abort('User abort');
|
|
186
|
+
}
|
|
187
|
+
} else if (isMore) {
|
|
166
188
|
openMoreClick();
|
|
167
189
|
} else if (text) {
|
|
168
190
|
await send([...attachmentInput.blocks, {
|
|
@@ -180,6 +202,11 @@ export default function MessageInput(props) {
|
|
|
180
202
|
setText('');
|
|
181
203
|
setMode('text');
|
|
182
204
|
},
|
|
205
|
+
onAbort: () => {
|
|
206
|
+
if (acRef.current) {
|
|
207
|
+
acRef.current.abort('User abort');
|
|
208
|
+
}
|
|
209
|
+
},
|
|
183
210
|
moreOpen: moreOpen,
|
|
184
211
|
closeMore: () => setMoreOpen(false),
|
|
185
212
|
onMoreClick: openMoreClick,
|
|
@@ -98,6 +98,7 @@
|
|
|
98
98
|
.t-agent-message-input-button {
|
|
99
99
|
--button-size: 68rpx;
|
|
100
100
|
background: transparent;
|
|
101
|
+
transition: all ease-in-out 0.2s;
|
|
101
102
|
|
|
102
103
|
border-radius: 50%;
|
|
103
104
|
width: var(--button-size);
|
|
@@ -123,7 +124,6 @@
|
|
|
123
124
|
.t-agent-message-input-button-more {
|
|
124
125
|
background: transparent url('icons/plus.svg') no-repeat center;
|
|
125
126
|
border: 2rpx solid var(--t-agent-input-border-color);
|
|
126
|
-
transition: all ease-in-out 0.2s;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
.t-agent-message-input-button-more-open {
|
|
@@ -132,7 +132,6 @@
|
|
|
132
132
|
|
|
133
133
|
.t-agent-message-input-button-send {
|
|
134
134
|
background: var(--app-M1) url('icons/send.svg') no-repeat center;
|
|
135
|
-
transition: all ease-in-out 0.2s;
|
|
136
135
|
}
|
|
137
136
|
|
|
138
137
|
.t-agent-message-input-button-voice-send {
|
|
@@ -147,6 +146,11 @@
|
|
|
147
146
|
right: 10rpx;
|
|
148
147
|
}
|
|
149
148
|
|
|
149
|
+
.t-agent-message-input-button-stop {
|
|
150
|
+
background: rgba(0,0,0,0) url('icons/stop.svg') no-repeat center;
|
|
151
|
+
border: 2rpx solid var(--t-agent-input-border-color);
|
|
152
|
+
}
|
|
153
|
+
|
|
150
154
|
.t-agent-message-input-panel {
|
|
151
155
|
overflow: hidden;
|
|
152
156
|
height: 168rpx;
|
package/dist/TileRender/index.js
CHANGED
|
@@ -10,7 +10,7 @@ const TileRender = _ref => {
|
|
|
10
10
|
side
|
|
11
11
|
} = _ref;
|
|
12
12
|
const agent = useChatAgent();
|
|
13
|
-
const emitEvent = useCallback(async payload => agent.emitTileEvent(tile.id, payload), [tile.id]);
|
|
13
|
+
const emitEvent = useCallback(async payload => agent.emitTileEvent(tile.id, payload), [agent, tile.id]);
|
|
14
14
|
const {
|
|
15
15
|
renderTileAs
|
|
16
16
|
} = useRenderOptions();
|
package/dist/contexts.js
CHANGED
|
@@ -9,7 +9,8 @@ export const RenderContext = /*#__PURE__*/createContext({
|
|
|
9
9
|
renderCardAs: () => null,
|
|
10
10
|
customBlockTypes: [],
|
|
11
11
|
customCardMap: {},
|
|
12
|
-
getStaticResourceBizType: () => ''
|
|
12
|
+
getStaticResourceBizType: () => '',
|
|
13
|
+
i18nTranslate: key => key
|
|
13
14
|
});
|
|
14
15
|
export const ChatAgentContext = /*#__PURE__*/createContext({});
|
|
15
16
|
export const TilePropsContext = /*#__PURE__*/createContext({});
|
|
@@ -85,6 +85,7 @@ const BubbleTile = props => {
|
|
|
85
85
|
}
|
|
86
86
|
return /*#__PURE__*/React.createElement(View, {
|
|
87
87
|
className: "t-agent-bubble-tile t-agent-bubble-tile-".concat(side),
|
|
88
|
+
"data-testid": "t-agent-bubble-tile",
|
|
88
89
|
onLongPress: () => {}
|
|
89
90
|
}, side === 'end' && errorNode, /*#__PURE__*/React.createElement(View, {
|
|
90
91
|
className: "t-agent-bubble-tile-bubble ".concat(loading ? 't-agent-bubble-tile-bubble-loading' : '')
|
|
@@ -127,6 +128,8 @@ const BubbleTile = props => {
|
|
|
127
128
|
icon: 'none'
|
|
128
129
|
});
|
|
129
130
|
}
|
|
130
|
-
})
|
|
131
|
+
}), bubbleStatus === BubbleTileStatus.ABORTED && /*#__PURE__*/React.createElement(View, {
|
|
132
|
+
className: "t-agent-bubble-tile-aborted"
|
|
133
|
+
}, t('t-agent.message.bubble.aborted'))), side === 'start' && errorNode);
|
|
131
134
|
};
|
|
132
135
|
export default /*#__PURE__*/React.memo(BubbleTile);
|
|
@@ -14,7 +14,8 @@ const CardTile = props => {
|
|
|
14
14
|
return null;
|
|
15
15
|
}
|
|
16
16
|
return /*#__PURE__*/React.createElement(View, {
|
|
17
|
-
className: "t-agent-card-tile"
|
|
17
|
+
className: "t-agent-card-tile",
|
|
18
|
+
"data-testid": "t-agent-bubble-tile"
|
|
18
19
|
}, node);
|
|
19
20
|
};
|
|
20
21
|
export default /*#__PURE__*/React.memo(CardTile);
|
package/dist/types.d.ts
CHANGED
|
@@ -14,14 +14,20 @@ export interface MarkdownBlock {
|
|
|
14
14
|
children: string;
|
|
15
15
|
map: [number, number];
|
|
16
16
|
}
|
|
17
|
+
export type ChatCardComponent<T = any, S = any> = React.ComponentType<{
|
|
18
|
+
card: ChatCardObject<T, S>;
|
|
19
|
+
setCardState: ChatCardComponentSetCardState<S>;
|
|
20
|
+
}>;
|
|
21
|
+
export interface ChatCardComponentSetCardStateOptions {
|
|
22
|
+
persist?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export type ChatCardComponentSetCardState<S = any> = (state: S | ((prev: S | undefined) => S), options?: ChatCardComponentSetCardStateOptions) => void;
|
|
17
25
|
export interface RenderOptions {
|
|
18
26
|
renderTileAs: (props: TileProps) => React.ReactNode;
|
|
19
27
|
renderCustomBlockAs: (block: MarkdownBlock) => React.ReactNode;
|
|
20
28
|
renderCardAs: (card: ChatCardObject) => React.ReactNode;
|
|
21
29
|
customBlockTypes: string[];
|
|
22
|
-
customCardMap: Record<string,
|
|
23
|
-
card: ChatCardObject;
|
|
24
|
-
}>>;
|
|
30
|
+
customCardMap: Record<string, ChatCardComponent>;
|
|
25
31
|
getStaticResourceBizType: (src: string, scene?: string, data?: any) => string;
|
|
26
32
|
i18nTranslate: (key: string) => string;
|
|
27
33
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ray-js/t-agent-ui-ray",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9-beta-2",
|
|
4
4
|
"author": "Tuya.inc",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"@types/echarts": "^4.9.22",
|
|
42
42
|
"@types/markdown-it": "^14.1.1"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "45f4f153fe2ce1e218a74f9bd3df726cf4e06d63"
|
|
45
45
|
}
|