@ray-js/t-agent-ui-ray 0.2.8-beta.2 → 0.2.8-beta.3
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/README-zh_CN.md +337 -87
- package/README.md +916 -706
- package/dist/PrivateImage/index.js +7 -10
- package/dist/tiles/BubbleTile/index.d.ts +15 -1
- package/dist/tiles/BubbleTile/index.js +60 -68
- package/dist/tiles/BubbleToolTile/audio-play.svg +1 -0
- package/dist/tiles/BubbleToolTile/audio-playing.svg +24 -0
- package/dist/tiles/BubbleToolTile/copy.svg +1 -0
- package/dist/tiles/BubbleToolTile/index.d.ts +10 -0
- package/dist/tiles/BubbleToolTile/index.js +63 -0
- package/dist/tiles/BubbleToolTile/index.less +46 -0
- package/dist/tiles/TimeTile/index.js +17 -16
- package/dist/tiles/map.js +3 -3
- package/dist/utils/getMessageContent.d.ts +11 -0
- package/dist/utils/getMessageContent.js +49 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +2 -1
- package/package.json +2 -3
- package/dist/tiles/WorkflowTile/RollBack/index.d.ts +0 -5
- package/dist/tiles/WorkflowTile/RollBack/index.js +0 -27
- package/dist/tiles/WorkflowTile/RollBack/index.less +0 -20
- package/dist/tiles/WorkflowTile/RollBack/workflow-rollback.png +0 -0
- package/dist/tiles/WorkflowTile/index.d.ts +0 -21
- package/dist/tiles/WorkflowTile/index.js +0 -32
- package/dist/tiles/WorkflowTile/index.less +0 -31
|
@@ -3,8 +3,8 @@ import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutPr
|
|
|
3
3
|
const _excluded = ["src", "bizType"];
|
|
4
4
|
import "core-js/modules/web.dom-collections.iterator.js";
|
|
5
5
|
import React, { useMemo, useRef, useState } from 'react';
|
|
6
|
-
import { Image
|
|
7
|
-
import { getUrlByCloudKey, isLinkExpired, parseCloudKey
|
|
6
|
+
import { Image } from '@ray-js/ray';
|
|
7
|
+
import { getUrlByCloudKey, isLinkExpired, parseCloudKey } from '../utils/file';
|
|
8
8
|
import logger from '../logger';
|
|
9
9
|
const PrivateImage = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
10
10
|
const {
|
|
@@ -73,13 +73,10 @@ const PrivateImage = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
73
73
|
// }
|
|
74
74
|
// }, [expired, url, bizType]);
|
|
75
75
|
|
|
76
|
-
if (loading || !url || !isFullLink(url)) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
style: rest.style
|
|
81
|
-
});
|
|
82
|
-
}
|
|
76
|
+
// if (loading || !url || !isFullLink(url)) {
|
|
77
|
+
// return <View key={url} className={rest.className} style={rest.style} />;
|
|
78
|
+
// }
|
|
79
|
+
|
|
83
80
|
return /*#__PURE__*/React.createElement(Image, _extends({
|
|
84
81
|
ref: ref,
|
|
85
82
|
key: url,
|
|
@@ -107,7 +104,7 @@ const PrivateImage = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
107
104
|
}
|
|
108
105
|
(_props$onError = props.onError) === null || _props$onError === void 0 || _props$onError.call(props, event);
|
|
109
106
|
},
|
|
110
|
-
src:
|
|
107
|
+
src: src
|
|
111
108
|
}, rest));
|
|
112
109
|
});
|
|
113
110
|
export default PrivateImage;
|
|
@@ -2,5 +2,19 @@ import './index.less';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { BubbleTileData } from '@ray-js/t-agent';
|
|
4
4
|
import { TileProps } from '../../types';
|
|
5
|
-
|
|
5
|
+
/** Unified props passed to every overridable slot component of BubbleTile. */
|
|
6
|
+
type BubbleTileSlotProps = TileProps<BubbleTileData>;
|
|
7
|
+
export interface BubbleTileProps extends TileProps<BubbleTileData> {
|
|
8
|
+
/** Rendered at the top of the bubble content, before the children. */
|
|
9
|
+
Header?: React.ComponentType<BubbleTileSlotProps>;
|
|
10
|
+
/** Rendered at the bottom of the bubble content, after the children. */
|
|
11
|
+
Footer?: React.ComponentType<BubbleTileSlotProps>;
|
|
12
|
+
/** Overrides the default error / warning side icon. */
|
|
13
|
+
ErrorNotice?: React.ComponentType<BubbleTileSlotProps>;
|
|
14
|
+
/** Overrides the default loading indicator. */
|
|
15
|
+
LoadingIndicator?: React.ComponentType<BubbleTileSlotProps>;
|
|
16
|
+
/** Overrides the standalone error-alert bubble (empty assistant error message). */
|
|
17
|
+
ErrorBubble?: React.ComponentType<BubbleTileSlotProps>;
|
|
18
|
+
}
|
|
19
|
+
declare const _default: React.MemoExoticComponent<(props: BubbleTileProps) => React.JSX.Element>;
|
|
6
20
|
export default _default;
|
|
@@ -1,26 +1,31 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import "core-js/modules/esnext.iterator.constructor.js";
|
|
3
|
-
import "core-js/modules/esnext.iterator.find.js";
|
|
4
3
|
import "core-js/modules/esnext.iterator.map.js";
|
|
5
|
-
import "core-js/modules/esnext.iterator.some.js";
|
|
6
4
|
import './index.less';
|
|
7
5
|
import { View } from '@ray-js/components';
|
|
8
|
-
import React, { memo,
|
|
6
|
+
import React, { memo, useMemo } from 'react';
|
|
9
7
|
import { BubbleTileStatus, ChatMessageStatus } from '@ray-js/t-agent';
|
|
10
8
|
import TileRender from '../../TileRender';
|
|
11
9
|
import { useLongPress, useRenderOptions, useTranslate } from '../../hooks';
|
|
12
|
-
import
|
|
10
|
+
import { getMessageContent as _getMessageContent } from '../../utils';
|
|
11
|
+
import { useStableCallback } from '../../hooks/useStableCallback';
|
|
12
|
+
|
|
13
|
+
/** Unified props passed to every overridable slot component of BubbleTile. */
|
|
14
|
+
|
|
13
15
|
const BubbleTile = props => {
|
|
14
|
-
var _workflowTile$data;
|
|
15
16
|
const {
|
|
16
|
-
renderLongPressAs
|
|
17
|
-
formatErrorMessageAs
|
|
17
|
+
renderLongPressAs
|
|
18
18
|
} = useRenderOptions();
|
|
19
19
|
const {
|
|
20
20
|
message,
|
|
21
21
|
tile,
|
|
22
22
|
isLatestMessage,
|
|
23
|
-
side
|
|
23
|
+
side,
|
|
24
|
+
Header,
|
|
25
|
+
Footer,
|
|
26
|
+
ErrorNotice = DefaultErrorNotice,
|
|
27
|
+
LoadingIndicator = DefaultLoadingIndicator,
|
|
28
|
+
ErrorBubble = DefaultErrorBubble
|
|
24
29
|
} = props;
|
|
25
30
|
const {
|
|
26
31
|
status,
|
|
@@ -33,24 +38,7 @@ const BubbleTile = props => {
|
|
|
33
38
|
const bubbleStatus = data.status || BubbleTileStatus.NORMAL;
|
|
34
39
|
const t = useTranslate();
|
|
35
40
|
const loading = status === ChatMessageStatus.START || status === ChatMessageStatus.UPDATING;
|
|
36
|
-
|
|
37
|
-
// 获取消息内容的函数
|
|
38
|
-
const getMessageContent = useCallback(() => {
|
|
39
|
-
let messageContent = '';
|
|
40
|
-
if (tile.children && tile.children.length > 0) {
|
|
41
|
-
// 查找文本类型的tile
|
|
42
|
-
const textTile = tile.children.find(child => child.type === 'text');
|
|
43
|
-
if (textTile && textTile.data && typeof textTile.data === 'object' && 'text' in textTile.data) {
|
|
44
|
-
messageContent = textTile.data.text;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// 如果是文本类型的tile,直接获取文本内容
|
|
49
|
-
if (tile.type === 'text' && tile.data && typeof tile.data === 'object' && 'text' in tile.data) {
|
|
50
|
-
messageContent = tile.data.text;
|
|
51
|
-
}
|
|
52
|
-
return messageContent;
|
|
53
|
-
}, [tile]);
|
|
41
|
+
const getMessageContent = useStableCallback(() => _getMessageContent(message));
|
|
54
42
|
const longPressRes = useLongPress({
|
|
55
43
|
message,
|
|
56
44
|
actions: role === 'assistant' ? ['copy', 'multiSelect', 'delete', 'like', 'unlike'] : ['copy', 'multiSelect', 'delete'],
|
|
@@ -58,6 +46,7 @@ const BubbleTile = props => {
|
|
|
58
46
|
disabled: loading
|
|
59
47
|
});
|
|
60
48
|
const longPressBlock = renderLongPressAs(longPressRes);
|
|
49
|
+
const slotProps = props;
|
|
61
50
|
const isErrorBubble = useMemo(() => {
|
|
62
51
|
let empty = true;
|
|
63
52
|
for (let i = 0; i < children.length; i++) {
|
|
@@ -76,38 +65,13 @@ const BubbleTile = props => {
|
|
|
76
65
|
}
|
|
77
66
|
return empty && role === 'assistant' && bubbleStatus === BubbleTileStatus.ERROR && status === ChatMessageStatus.FINISH;
|
|
78
67
|
}, [status, role, bubbleStatus, children]);
|
|
79
|
-
if (isErrorBubble) {
|
|
80
|
-
return /*#__PURE__*/React.createElement(View, _extends({
|
|
81
|
-
className: "t-agent-bubble-tile t-agent-bubble-tile-error-alert",
|
|
82
|
-
"data-testid": "t-agent-bubble-tile"
|
|
83
|
-
}, longPressRes.longPressProps), /*#__PURE__*/React.createElement(View, {
|
|
84
|
-
className: "t-agent-bubble-tile-error",
|
|
85
|
-
"data-testid": "t-agent-bubble-tile-error"
|
|
86
|
-
}), /*#__PURE__*/React.createElement(View, {
|
|
87
|
-
className: "t-agent-bubble-tile-error-alert-text"
|
|
88
|
-
}, formatErrorMessageAs(data.info, data.code) || t('t-agent.error.unknown-error')), longPressBlock);
|
|
89
|
-
}
|
|
90
|
-
const showInfo = () => {
|
|
91
|
-
if (data.info) {
|
|
92
|
-
ty.showToast({
|
|
93
|
-
title: formatErrorMessageAs(data.info, data.code),
|
|
94
|
-
icon: 'none'
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
68
|
const showAbortedMessage = bubbleStatus === BubbleTileStatus.ABORTED;
|
|
99
|
-
const showRollBack = side === 'start' && children.some(child => child.type === 'workflow');
|
|
100
|
-
const workflowTile = children.find(child => child.type === 'workflow');
|
|
101
|
-
const workflowNode = workflowTile === null || workflowTile === void 0 || (_workflowTile$data = workflowTile.data) === null || _workflowTile$data === void 0 ? void 0 : _workflowTile$data.nodeId;
|
|
102
69
|
return /*#__PURE__*/React.createElement(View, _extends({
|
|
103
|
-
className: "t-agent-bubble-tile t-agent-bubble-tile-".concat(side),
|
|
70
|
+
className: "t-agent-bubble-tile t-agent-bubble-tile-".concat(side, " ").concat(isErrorBubble ? 't-agent-bubble-tile-error-alert' : ''),
|
|
104
71
|
"data-testid": "t-agent-bubble-tile"
|
|
105
|
-
}, longPressRes.longPressProps), side === 'end' && /*#__PURE__*/React.createElement(ErrorNotice, {
|
|
106
|
-
bubbleStatus: bubbleStatus,
|
|
107
|
-
showInfo: showInfo
|
|
108
|
-
}), /*#__PURE__*/React.createElement(View, {
|
|
72
|
+
}, longPressRes.longPressProps), isErrorBubble ? /*#__PURE__*/React.createElement(ErrorBubble, slotProps) : /*#__PURE__*/React.createElement(React.Fragment, null, side === 'end' && /*#__PURE__*/React.createElement(ErrorNotice, slotProps), /*#__PURE__*/React.createElement(View, {
|
|
109
73
|
className: "t-agent-bubble-tile-bubble ".concat(loading ? 't-agent-bubble-tile-bubble-loading' : '')
|
|
110
|
-
}, (() => {
|
|
74
|
+
}, Header && /*#__PURE__*/React.createElement(Header, slotProps), (() => {
|
|
111
75
|
return children.map(t => /*#__PURE__*/React.createElement(TileRender, {
|
|
112
76
|
side: side,
|
|
113
77
|
tile: t,
|
|
@@ -116,22 +80,47 @@ const BubbleTile = props => {
|
|
|
116
80
|
isLatestMessage: isLatestMessage,
|
|
117
81
|
notifyHeightChanged: props.notifyHeightChanged
|
|
118
82
|
}));
|
|
119
|
-
})(), /*#__PURE__*/React.createElement(LoadingIndicator, {
|
|
120
|
-
status: status
|
|
121
|
-
}), showAbortedMessage && /*#__PURE__*/React.createElement(View, {
|
|
83
|
+
})(), /*#__PURE__*/React.createElement(LoadingIndicator, slotProps), showAbortedMessage && /*#__PURE__*/React.createElement(View, {
|
|
122
84
|
className: "t-agent-bubble-tile-aborted"
|
|
123
|
-
}, t('t-agent.message.bubble.aborted'))), side === 'start' && /*#__PURE__*/React.createElement(ErrorNotice,
|
|
124
|
-
bubbleStatus: bubbleStatus,
|
|
125
|
-
showInfo: showInfo
|
|
126
|
-
}), longPressBlock, showRollBack && !isLatestMessage && workflowNode && /*#__PURE__*/React.createElement(RollBack, {
|
|
127
|
-
nodeId: workflowNode
|
|
128
|
-
}));
|
|
85
|
+
}, t('t-agent.message.bubble.aborted')), Footer && /*#__PURE__*/React.createElement(Footer, slotProps)), side === 'start' && /*#__PURE__*/React.createElement(ErrorNotice, slotProps)), longPressBlock);
|
|
129
86
|
};
|
|
130
|
-
const
|
|
87
|
+
const DefaultErrorBubble = /*#__PURE__*/memo(_ref => {
|
|
131
88
|
let {
|
|
132
|
-
|
|
133
|
-
showInfo
|
|
89
|
+
tile
|
|
134
90
|
} = _ref;
|
|
91
|
+
const {
|
|
92
|
+
formatErrorMessageAs
|
|
93
|
+
} = useRenderOptions();
|
|
94
|
+
const t = useTranslate();
|
|
95
|
+
const {
|
|
96
|
+
data
|
|
97
|
+
} = tile;
|
|
98
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(View, {
|
|
99
|
+
className: "t-agent-bubble-tile-error",
|
|
100
|
+
"data-testid": "t-agent-bubble-tile-error"
|
|
101
|
+
}), /*#__PURE__*/React.createElement(View, {
|
|
102
|
+
className: "t-agent-bubble-tile-error-alert-text"
|
|
103
|
+
}, formatErrorMessageAs(data.info, data.code) || t('t-agent.error.unknown-error')));
|
|
104
|
+
});
|
|
105
|
+
const DefaultErrorNotice = /*#__PURE__*/memo(_ref2 => {
|
|
106
|
+
let {
|
|
107
|
+
tile
|
|
108
|
+
} = _ref2;
|
|
109
|
+
const {
|
|
110
|
+
formatErrorMessageAs
|
|
111
|
+
} = useRenderOptions();
|
|
112
|
+
const {
|
|
113
|
+
data
|
|
114
|
+
} = tile;
|
|
115
|
+
const bubbleStatus = data.status || BubbleTileStatus.NORMAL;
|
|
116
|
+
const showInfo = () => {
|
|
117
|
+
if (data.info) {
|
|
118
|
+
ty.showToast({
|
|
119
|
+
title: formatErrorMessageAs(data.info, data.code),
|
|
120
|
+
icon: 'none'
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
};
|
|
135
124
|
if (bubbleStatus === BubbleTileStatus.ERROR) {
|
|
136
125
|
return /*#__PURE__*/React.createElement(View, {
|
|
137
126
|
onClick: showInfo,
|
|
@@ -148,10 +137,13 @@ const ErrorNotice = /*#__PURE__*/memo(_ref => {
|
|
|
148
137
|
}
|
|
149
138
|
return null;
|
|
150
139
|
});
|
|
151
|
-
const
|
|
140
|
+
const DefaultLoadingIndicator = /*#__PURE__*/memo(_ref3 => {
|
|
152
141
|
let {
|
|
142
|
+
message
|
|
143
|
+
} = _ref3;
|
|
144
|
+
const {
|
|
153
145
|
status
|
|
154
|
-
} =
|
|
146
|
+
} = message;
|
|
155
147
|
if (status === ChatMessageStatus.START) {
|
|
156
148
|
return /*#__PURE__*/React.createElement(View, {
|
|
157
149
|
className: "t-agent-bubble-tile-bubble-loader"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="14.666666984558105" height="11.259817123413086" viewBox="0 0 14.666666984558105 11.259817123413086"><path d="M3.7352133,4.2966166L6,2.4435894L6,8.8162832L3.7352133,6.9632831L1.3333334,6.9632831L1.3333334,4.2966166L3.7352133,4.2966166ZM0.66666669,8.2966156L3.2592599,8.2966156L6.7889338,11.184483C6.8484669,11.233217,6.9230666,11.259817,7,11.259817C7.1840668,11.259817,7.3333335,11.110617,7.3333335,10.926483L7.3333335,0.33334273C7.3333335,0.256396,7.3067336,0.18181595,7.2580004,0.12226264C7.1414003,-0.020217419,6.9314003,-0.041217327,6.7889338,0.075356007L3.2592599,2.9632626L0.66666669,2.9632626C0.29848003,2.9632626,0,3.2617359,0,3.6299293L0,7.6299496C0,7.9981494,0.29848003,8.2966156,0.66666669,8.2966156ZM14.666667,5.6298828C14.666667,7.8245497,13.7026,9.7940826,12.1748,11.138016L11.229667,10.192817C12.5172,9.09235,13.333334,7.4564166,13.333334,5.6298828C13.333334,3.8033233,12.5172,2.1674094,11.229667,1.0669293L12.1748,0.12174273C13.7026,1.4656695,14.666667,3.4351826,14.666667,5.6298828ZM11.333334,5.6298828C11.333334,4.3554163,10.737334,3.2202029,9.8088665,2.4877026L8.8561335,3.440443C9.547533,3.9222496,10,4.7232165,10,5.6298828C10,6.5365496,9.547533,7.3374834,8.8561335,7.8192825L9.8088665,8.7720165C10.737334,8.0395498,11.333334,6.904283,11.333334,5.6298828Z" fill="#427FF7" fill-opacity="1" style="mix-blend-mode:passthrough"/></svg>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
|
2
|
+
<g fill="#427ff7">
|
|
3
|
+
<rect x="2.4" width="2.4" rx="1.2" y="9" height="6">
|
|
4
|
+
<animate attributeName="height" values="6;18;6" dur="0.9s" begin="0s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.5;1" keySplines="0.4 0 0.6 1;0.4 0 0.6 1" />
|
|
5
|
+
<animate attributeName="y" values="9;3;9" dur="0.9s" begin="0s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.5;1" keySplines="0.4 0 0.6 1;0.4 0 0.6 1" />
|
|
6
|
+
</rect>
|
|
7
|
+
<rect x="6.6" width="2.4" rx="1.2" y="6" height="12">
|
|
8
|
+
<animate attributeName="height" values="6;18;6" dur="0.9s" begin="-0.3s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.5;1" keySplines="0.4 0 0.6 1;0.4 0 0.6 1" />
|
|
9
|
+
<animate attributeName="y" values="9;3;9" dur="0.9s" begin="-0.3s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.5;1" keySplines="0.4 0 0.6 1;0.4 0 0.6 1" />
|
|
10
|
+
</rect>
|
|
11
|
+
<rect x="10.8" width="2.4" rx="1.2" y="3" height="18">
|
|
12
|
+
<animate attributeName="height" values="6;18;6" dur="0.9s" begin="-0.6s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.5;1" keySplines="0.4 0 0.6 1;0.4 0 0.6 1" />
|
|
13
|
+
<animate attributeName="y" values="9;3;9" dur="0.9s" begin="-0.6s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.5;1" keySplines="0.4 0 0.6 1;0.4 0 0.6 1" />
|
|
14
|
+
</rect>
|
|
15
|
+
<rect x="15" width="2.4" rx="1.2" y="6" height="12">
|
|
16
|
+
<animate attributeName="height" values="6;18;6" dur="0.9s" begin="-0.15s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.5;1" keySplines="0.4 0 0.6 1;0.4 0 0.6 1" />
|
|
17
|
+
<animate attributeName="y" values="9;3;9" dur="0.9s" begin="-0.15s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.5;1" keySplines="0.4 0 0.6 1;0.4 0 0.6 1" />
|
|
18
|
+
</rect>
|
|
19
|
+
<rect x="19.2" width="2.4" rx="1.2" y="9" height="6">
|
|
20
|
+
<animate attributeName="height" values="6;18;6" dur="0.9s" begin="-0.45s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.5;1" keySplines="0.4 0 0.6 1;0.4 0 0.6 1" />
|
|
21
|
+
<animate attributeName="y" values="9;3;9" dur="0.9s" begin="-0.45s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.5;1" keySplines="0.4 0 0.6 1;0.4 0 0.6 1" />
|
|
22
|
+
</rect>
|
|
23
|
+
</g>
|
|
24
|
+
</svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><defs><clipPath id="master_svg0_1631_18176"><rect x="0" y="0" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_1631_18176)"><path d="M4.6665335,4.000002576464844L4.6665335,2.0000025664648438C4.6665335,1.6318159064648436,4.9650133,1.3333358764648438,5.3332002,1.3333358764648438L13.3332,1.3333358764648438C13.7014,1.3333358764648438,13.999866,1.6318159064648436,13.999866,2.0000025664648438L13.999866,11.333335876464844C13.999866,11.701535876464844,13.7014,12.000002876464844,13.3332,12.000002876464844L11.3332005,12.000002876464844L11.3332005,13.999402876464844C11.3332005,14.367936876464844,11.033267,14.666669876464844,10.6620007,14.666669876464844L2.6711067,14.666669876464844C2.3003932799999998,14.666669876464844,2,14.370269876464844,2,13.999402876464844L2.0017333031,4.667249476464844C2.0018000603,4.298742776464843,2.30176005,4.000002576464844,2.67294663,4.000002576464844L4.6665335,4.000002576464844ZM3.3349466000000003,5.333335876464844L3.3334599000000003,13.333335876464844L9.9998665,13.333335876464844L9.9998665,5.333335876464844L3.3349466000000003,5.333335876464844ZM5.9998664999999995,4.000002576464844L11.3332005,4.000002576464844L11.3332005,10.666669876464844L12.666533,10.666669876464844L12.666533,2.6666692764648436L5.9998664999999995,2.6666692764648436L5.9998664999999995,4.000002576464844Z" fill="#427FF7" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></svg>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import './index.less';
|
|
3
|
+
import { TileProps } from '../../types';
|
|
4
|
+
export interface BubbleToolTileData {
|
|
5
|
+
/** 播放所需的音频参数,由 aistream 插件下发时写入 */
|
|
6
|
+
audio?: Record<string, any>;
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
}
|
|
9
|
+
declare const _default: React.MemoExoticComponent<(props: TileProps<BubbleToolTileData>) => React.JSX.Element | null>;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import "core-js/modules/web.dom-collections.iterator.js";
|
|
2
|
+
import React, { useEffect } from 'react';
|
|
3
|
+
import { View } from '@ray-js/components';
|
|
4
|
+
import './index.less';
|
|
5
|
+
import { useAgentSessionValue, useTranslate } from '../../hooks';
|
|
6
|
+
import { getMessageContent } from '../../utils';
|
|
7
|
+
const BubbleToolTile = props => {
|
|
8
|
+
const {
|
|
9
|
+
message,
|
|
10
|
+
isLatestMessage,
|
|
11
|
+
notifyHeightChanged
|
|
12
|
+
} = props;
|
|
13
|
+
// playing 不是 tile 的本地状态,而是从 session 的全局播放状态派生:
|
|
14
|
+
// 真正的播放/停止由 withBuildIn 处理,并把 “是否正在播放 / 正在播放的消息 id”
|
|
15
|
+
// 写入 session,UI 通过 sessionChange 事件感知变化。
|
|
16
|
+
const [audioPlaying] = useAgentSessionValue('AIStream.audioPlaying');
|
|
17
|
+
const [playingMessageId] = useAgentSessionValue('AIStream.playingMessageId');
|
|
18
|
+
const playing = !!audioPlaying && playingMessageId === message.id;
|
|
19
|
+
|
|
20
|
+
// UI 只负责发指令
|
|
21
|
+
|
|
22
|
+
const show = message.role === 'assistant' && isLatestMessage;
|
|
23
|
+
const t = useTranslate();
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!show) {
|
|
26
|
+
notifyHeightChanged();
|
|
27
|
+
}
|
|
28
|
+
}, [show]);
|
|
29
|
+
if (!show) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
33
|
+
className: "t-agent-bubble-tool-tile"
|
|
34
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
35
|
+
className: "t-agent-bubble-tool-tile-divider"
|
|
36
|
+
}), /*#__PURE__*/React.createElement(View, {
|
|
37
|
+
className: "t-agent-bubble-tool-tile-actions"
|
|
38
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
39
|
+
className: "t-agent-bubble-tool-tile-button ".concat(playing ? 't-agent-bubble-tool-tile-play-active' : 't-agent-bubble-tool-tile-play'),
|
|
40
|
+
"data-testid": "t-agent-bubble-tool-tile-play",
|
|
41
|
+
onClick: () => {
|
|
42
|
+
props.emitTileEvent({
|
|
43
|
+
action: 'toggle'
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}), /*#__PURE__*/React.createElement(View, {
|
|
47
|
+
className: "t-agent-bubble-tool-tile-button t-agent-bubble-tool-tile-copy",
|
|
48
|
+
"data-testid": "t-agent-bubble-tool-tile-copy",
|
|
49
|
+
onClick: () => {
|
|
50
|
+
const text = getMessageContent(message);
|
|
51
|
+
ty.setClipboardData({
|
|
52
|
+
data: text,
|
|
53
|
+
success() {
|
|
54
|
+
ty.showToast({
|
|
55
|
+
title: t('t-agent.message.copy.success'),
|
|
56
|
+
icon: 'none'
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
})));
|
|
62
|
+
};
|
|
63
|
+
export default /*#__PURE__*/React.memo(BubbleToolTile);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
.t-agent-bubble-tool-tile {
|
|
2
|
+
}
|
|
3
|
+
|
|
4
|
+
.t-agent-bubble-tool-tile-divider {
|
|
5
|
+
flex: 1;
|
|
6
|
+
height: 1px;
|
|
7
|
+
background-color: var(--app-B3-N1);
|
|
8
|
+
opacity: 0.12;
|
|
9
|
+
margin: 16rpx 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.t-agent-bubble-tool-tile-actions {
|
|
13
|
+
display: flex;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.t-agent-bubble-tool-tile-button {
|
|
17
|
+
flex: 0 0 auto;
|
|
18
|
+
width: 48rpx;
|
|
19
|
+
height: 48rpx;
|
|
20
|
+
border-radius: 8rpx;
|
|
21
|
+
background-color: var(--app-B1);
|
|
22
|
+
background-repeat: no-repeat;
|
|
23
|
+
background-position: center center;
|
|
24
|
+
background-size: 28rpx 28rpx;
|
|
25
|
+
margin-right: 16rpx;
|
|
26
|
+
|
|
27
|
+
:first-child {
|
|
28
|
+
margin-right: 0;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.t-agent-bubble-tool-tile-play {
|
|
33
|
+
background-image: url("./audio-play.svg");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.t-agent-bubble-tool-tile-play-active {
|
|
37
|
+
background-image: url("./audio-playing.svg");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.t-agent-bubble-tool-tile-copy {
|
|
41
|
+
background-image: url("./copy.svg");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.t-agent-bubble-tool-tile-play-active {
|
|
45
|
+
opacity: 0.6;
|
|
46
|
+
}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import "core-js/modules/web.dom-collections.iterator.js";
|
|
2
2
|
import { View } from '@ray-js/components';
|
|
3
3
|
import React, { useEffect, useMemo, useState } from 'react';
|
|
4
|
-
import dayjs from 'dayjs';
|
|
5
4
|
import './index.less';
|
|
5
|
+
function formatDate(timestamp) {
|
|
6
|
+
const d = new Date(timestamp);
|
|
7
|
+
return [d.getFullYear(), String(d.getMonth() + 1).padStart(2, '0'), String(d.getDate()).padStart(2, '0')].join('-');
|
|
8
|
+
}
|
|
9
|
+
function formatTime(timestamp) {
|
|
10
|
+
const d = new Date(timestamp);
|
|
11
|
+
return [String(d.getHours()).padStart(2, '0'), String(d.getMinutes()).padStart(2, '0')].join(':');
|
|
12
|
+
}
|
|
6
13
|
export default function TimeTile(props) {
|
|
7
14
|
const {
|
|
8
15
|
tile
|
|
@@ -10,25 +17,19 @@ export default function TimeTile(props) {
|
|
|
10
17
|
const {
|
|
11
18
|
timestamp
|
|
12
19
|
} = tile.data;
|
|
13
|
-
const [
|
|
14
|
-
return dayjs(timestamp).format('YYYY-MM-DD');
|
|
15
|
-
});
|
|
20
|
+
const [today, setToday] = useState(() => formatDate(Date.now()));
|
|
16
21
|
useEffect(() => {
|
|
17
|
-
|
|
22
|
+
const now = new Date();
|
|
23
|
+
const nextDay = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);
|
|
18
24
|
const timer = setTimeout(() => {
|
|
19
|
-
|
|
20
|
-
},
|
|
21
|
-
return () =>
|
|
22
|
-
clearTimeout(timer);
|
|
23
|
-
};
|
|
25
|
+
setToday(formatDate(Date.now()));
|
|
26
|
+
}, nextDay.getTime() - now.getTime());
|
|
27
|
+
return () => clearTimeout(timer);
|
|
24
28
|
}, []);
|
|
25
29
|
const time = useMemo(() => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
return dayjs(timestamp).format('YYYY-MM-DD HH:mm');
|
|
31
|
-
}, [timestamp, date]);
|
|
30
|
+
const tsDate = formatDate(timestamp);
|
|
31
|
+
return tsDate === today ? formatTime(timestamp) : "".concat(tsDate, " ").concat(formatTime(timestamp));
|
|
32
|
+
}, [timestamp, today]);
|
|
32
33
|
return /*#__PURE__*/React.createElement(View, {
|
|
33
34
|
className: "t-agent-time-tile"
|
|
34
35
|
}, time);
|
package/dist/tiles/map.js
CHANGED
|
@@ -7,12 +7,12 @@ import VideoTile from './VideoTile';
|
|
|
7
7
|
import ButtonGroupTile from './ButtonsTile';
|
|
8
8
|
import RecommendationsTile from './RecommendationsTile';
|
|
9
9
|
import CardTile from './CardTile';
|
|
10
|
-
import WorkflowTile from './WorkflowTile';
|
|
11
10
|
import DocumentsTile from './DocumentsTile';
|
|
12
11
|
import OperateCardTile from './OperateCardTile';
|
|
13
12
|
import ExecuteCardTile from './ExecuteCardTile';
|
|
14
13
|
import DividerTile from './DividerTile';
|
|
15
14
|
import FileTile from './FileTile';
|
|
15
|
+
import BubbleToolTile from './BubbleToolTile';
|
|
16
16
|
export const tileMap = {
|
|
17
17
|
bubble: BubbleTile,
|
|
18
18
|
image: ImageTile,
|
|
@@ -23,10 +23,10 @@ export const tileMap = {
|
|
|
23
23
|
buttons: ButtonGroupTile,
|
|
24
24
|
recommendations: RecommendationsTile,
|
|
25
25
|
card: CardTile,
|
|
26
|
-
workflow: WorkflowTile,
|
|
27
26
|
documents: DocumentsTile,
|
|
28
27
|
operateCard: OperateCardTile,
|
|
29
28
|
executeCard: ExecuteCardTile,
|
|
30
29
|
divider: DividerTile,
|
|
31
|
-
file: FileTile
|
|
30
|
+
file: FileTile,
|
|
31
|
+
bubbleTool: BubbleToolTile
|
|
32
32
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ChatMessageObject } from '@ray-js/t-agent';
|
|
2
|
+
/**
|
|
3
|
+
* 从 message 中提取文本内容。
|
|
4
|
+
*
|
|
5
|
+
* 遍历 message 的所有 tile,取第一个能解析出文本的 tile:
|
|
6
|
+
* - 若 tile 自身为 `text` 类型,返回其文本;
|
|
7
|
+
* - 否则查找其 children 中的第一个 `text` 类型 tile 并返回文本。
|
|
8
|
+
*
|
|
9
|
+
* 可在任意 tile 中复用,例如长按复制消息内容。
|
|
10
|
+
*/
|
|
11
|
+
export declare function getMessageContent(message?: ChatMessageObject): string;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import "core-js/modules/esnext.iterator.constructor.js";
|
|
2
|
+
import "core-js/modules/esnext.iterator.find.js";
|
|
3
|
+
const getTileText = data => {
|
|
4
|
+
if (data && typeof data === 'object' && 'text' in data) {
|
|
5
|
+
return data.text || '';
|
|
6
|
+
}
|
|
7
|
+
return '';
|
|
8
|
+
};
|
|
9
|
+
const getTextFromTile = tile => {
|
|
10
|
+
if (!tile) {
|
|
11
|
+
return '';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// 如果是文本类型的 tile,直接获取文本内容
|
|
15
|
+
if (tile.type === 'text') {
|
|
16
|
+
return getTileText(tile.data);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// 查找子 tile 中的文本类型 tile
|
|
20
|
+
if (tile.children && tile.children.length > 0) {
|
|
21
|
+
const textTile = tile.children.find(child => child.type === 'text');
|
|
22
|
+
if (textTile) {
|
|
23
|
+
return getTileText(textTile.data);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return '';
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 从 message 中提取文本内容。
|
|
31
|
+
*
|
|
32
|
+
* 遍历 message 的所有 tile,取第一个能解析出文本的 tile:
|
|
33
|
+
* - 若 tile 自身为 `text` 类型,返回其文本;
|
|
34
|
+
* - 否则查找其 children 中的第一个 `text` 类型 tile 并返回文本。
|
|
35
|
+
*
|
|
36
|
+
* 可在任意 tile 中复用,例如长按复制消息内容。
|
|
37
|
+
*/
|
|
38
|
+
export function getMessageContent(message) {
|
|
39
|
+
if (!message || !message.tiles || message.tiles.length === 0) {
|
|
40
|
+
return '';
|
|
41
|
+
}
|
|
42
|
+
for (let i = 0; i < message.tiles.length; i++) {
|
|
43
|
+
const content = getTextFromTile(message.tiles[i]);
|
|
44
|
+
if (content) {
|
|
45
|
+
return content;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return '';
|
|
49
|
+
}
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ray-js/t-agent-ui-ray",
|
|
3
|
-
"version": "0.2.8-beta.
|
|
3
|
+
"version": "0.2.8-beta.3",
|
|
4
4
|
"author": "Tuya.inc",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"clsx": "^1.2.1",
|
|
30
|
-
"dayjs": "^1.10.4",
|
|
31
30
|
"echarts": "^5.5.0",
|
|
32
31
|
"markdown-it": "^14.1.0",
|
|
33
32
|
"markdown-it-emoji": "^3.0.0",
|
|
@@ -42,5 +41,5 @@
|
|
|
42
41
|
"@types/echarts": "^4.9.22",
|
|
43
42
|
"@types/markdown-it": "^14.1.1"
|
|
44
43
|
},
|
|
45
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "938bc0c7da7d23dbbad8c3c14c97e5f4007f06f7"
|
|
46
45
|
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import './index.less';
|
|
2
|
-
import { Image, View } from '@ray-js/ray';
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import rollback from './workflow-rollback.png';
|
|
5
|
-
import { useTileProps } from '../../../hooks';
|
|
6
|
-
export default function RollBack(props) {
|
|
7
|
-
const {
|
|
8
|
-
nodeId
|
|
9
|
-
} = props;
|
|
10
|
-
const {
|
|
11
|
-
emitTileEvent
|
|
12
|
-
} = useTileProps();
|
|
13
|
-
return /*#__PURE__*/React.createElement(View, {
|
|
14
|
-
className: "t-agent-workflow-rollback-tile",
|
|
15
|
-
onClick: async () => {
|
|
16
|
-
emitTileEvent({
|
|
17
|
-
type: 'rollback',
|
|
18
|
-
nodeId
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
}, /*#__PURE__*/React.createElement(Image, {
|
|
22
|
-
src: rollback,
|
|
23
|
-
className: "t-agent-workflow-rollback-tile-image"
|
|
24
|
-
}), /*#__PURE__*/React.createElement(View, {
|
|
25
|
-
className: "t-agent-workflow-rollback-tile-text"
|
|
26
|
-
}, "\u91CD\u9009"));
|
|
27
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
.t-agent-workflow-rollback-tile {
|
|
2
|
-
color: var(--app-B3-N1);
|
|
3
|
-
background-color: var(--app-B3);
|
|
4
|
-
border-radius: 9999px;
|
|
5
|
-
height: 36px;
|
|
6
|
-
margin-top: 8px;
|
|
7
|
-
width: fit-content;
|
|
8
|
-
line-height: 36px;
|
|
9
|
-
padding: 0 12px;
|
|
10
|
-
display: flex;
|
|
11
|
-
align-items: center;
|
|
12
|
-
justify-content: center;
|
|
13
|
-
.t-agent-workflow-rollback-tile-image {
|
|
14
|
-
width: 20px;
|
|
15
|
-
height: 20px;
|
|
16
|
-
margin-right: 6px;
|
|
17
|
-
}
|
|
18
|
-
.t-agent-workflow-rollback-tile-text {
|
|
19
|
-
}
|
|
20
|
-
}
|
|
Binary file
|