@alicloud/appflow-chat 0.0.3-beta.1 → 0.0.4-alpha.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.
- package/dist/appflow-chat.cjs.js +857 -164
- package/dist/appflow-chat.esm.js +19184 -13464
- package/dist/types/index.d.ts +74 -2
- package/package.json +3 -1
- package/src/components/A2UIRenderer/A2UIRenderer.tsx +181 -0
- package/src/components/A2UIRenderer/index.ts +1 -0
- package/src/components/MessageBubble.tsx +22 -2
- package/src/index.ts +6 -0
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,73 @@
|
|
|
1
|
+
import { A2UIViewerProps } from '@a2ui/react';
|
|
2
|
+
import { ComponentRegistry } from '@a2ui/react';
|
|
1
3
|
import { default as default_2 } from 'react';
|
|
4
|
+
import { OnActionCallback } from '@a2ui/react';
|
|
2
5
|
import { Provider } from 'react';
|
|
6
|
+
import { ServerToClientMessage } from '@a2ui/react';
|
|
7
|
+
|
|
8
|
+
/** A2UI 协议消息(v0.8 格式,透传给 @a2ui/react 处理) */
|
|
9
|
+
export declare type A2UIMessage = ServerToClientMessage;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A2UIStaticViewer - A2UI 静态 JSON 渲染组件
|
|
13
|
+
*
|
|
14
|
+
* 用于直接从静态的组件定义和数据渲染 UI,无需流式消息。
|
|
15
|
+
* 适用于已有完整 A2UI 组件树的场景。
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* const components = [
|
|
20
|
+
* { id: 'root', component: { Card: { child: 'text' } } },
|
|
21
|
+
* { id: 'text', component: { Text: { text: { path: '/message' } } } },
|
|
22
|
+
* ];
|
|
23
|
+
*
|
|
24
|
+
* <A2UIStaticViewer
|
|
25
|
+
* root="root"
|
|
26
|
+
* components={components}
|
|
27
|
+
* data={{ message: 'Hello World!' }}
|
|
28
|
+
* onAction={(action) => console.log('Action:', action)}
|
|
29
|
+
* />
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare const A2UIStaticViewer: default_2.FC<A2UIStaticViewerProps>;
|
|
33
|
+
|
|
34
|
+
/** A2UIViewer 的 Props,用于静态 JSON 渲染场景 */
|
|
35
|
+
export declare type A2UIStaticViewerProps = A2UIViewerProps;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A2UISurface - A2UI 声明式 UI 渲染组件(流式消息场景)
|
|
39
|
+
*
|
|
40
|
+
* 接收 Agent 发送的 A2UI 协议消息数组,增量处理并渲染对应的 Surface。
|
|
41
|
+
* 内部封装了 A2UIProvider,可直接作为 BubbleContent 的 children 使用。
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```tsx
|
|
45
|
+
* // 作为 BubbleContent 的 children 使用
|
|
46
|
+
* <BubbleContent content={content} status={status}>
|
|
47
|
+
* <A2UISurface
|
|
48
|
+
* messages={a2uiMessages}
|
|
49
|
+
* surfaceId="main"
|
|
50
|
+
* onAction={(msg) => console.log('用户操作:', msg)}
|
|
51
|
+
* />
|
|
52
|
+
* </BubbleContent>
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare const A2UISurface: default_2.FC<A2UISurfaceProps>;
|
|
56
|
+
|
|
57
|
+
export declare interface A2UISurfaceProps {
|
|
58
|
+
/** A2UI JSON 消息数组(来自 Agent 的响应) */
|
|
59
|
+
messages: A2UIMessage[];
|
|
60
|
+
/** 渲染的 Surface ID(默认 'main') */
|
|
61
|
+
surfaceId?: string;
|
|
62
|
+
/** 用户在 A2UI 组件上的交互回调 */
|
|
63
|
+
onAction?: OnActionCallback;
|
|
64
|
+
/** 自定义组件注册表(可选,默认使用内置组件) */
|
|
65
|
+
registry?: ComponentRegistry;
|
|
66
|
+
/** 自定义类名 */
|
|
67
|
+
className?: string;
|
|
68
|
+
/** 自定义样式 */
|
|
69
|
+
style?: default_2.CSSProperties;
|
|
70
|
+
}
|
|
3
71
|
|
|
4
72
|
/**
|
|
5
73
|
* AssociationPropertyMetadata 类型定义
|
|
@@ -530,14 +598,18 @@ export declare interface MessageBubbleProps {
|
|
|
530
598
|
onReferenceClick?: (item: DocReferenceItem) => void;
|
|
531
599
|
/** 点击网页搜索结果回调(不传则使用默认实现) */
|
|
532
600
|
onWebSearchClick?: (items: DocReferenceItem[]) => void;
|
|
533
|
-
/** 事件类型(用于特殊消息如 humanVerify、historyCard) */
|
|
534
|
-
eventType?: 'humanVerify' | 'historyCard';
|
|
601
|
+
/** 事件类型(用于特殊消息如 humanVerify、historyCard、a2ui) */
|
|
602
|
+
eventType?: 'humanVerify' | 'historyCard' | 'a2ui';
|
|
535
603
|
/** HumanVerify 相关数据 */
|
|
536
604
|
humanVerifyData?: HumanVerifyData;
|
|
537
605
|
/** HistoryCard 相关数据(历史对话中的审核卡片) */
|
|
538
606
|
historyCardData?: HistoryCardData;
|
|
539
607
|
/** HumanVerify 提交回调 */
|
|
540
608
|
onHumanVerifySubmit?: (data: HumanVerifySubmitData) => void;
|
|
609
|
+
/** A2UI 消息数组(Agent 生成的声明式 UI 描述) */
|
|
610
|
+
a2uiMessages?: A2UIMessage[];
|
|
611
|
+
/** A2UI 用户交互回调 */
|
|
612
|
+
onA2UIAction?: (action: any) => void;
|
|
541
613
|
}
|
|
542
614
|
|
|
543
615
|
export declare interface ModelCapabilities {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alicloud/appflow-chat",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4-alpha.1",
|
|
4
4
|
"description": "Appflow-Chat AI聊天机器人组件库,提供聊天服务和UI组件",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/appflow-chat.cjs.js",
|
|
@@ -58,6 +58,8 @@
|
|
|
58
58
|
"vite-plugin-dts": "^4.3.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
+
"@a2ui/react": "^0.8.0",
|
|
62
|
+
"@a2ui/web_core": "^0.8.0",
|
|
61
63
|
"antd": "^5.0.0",
|
|
62
64
|
"react": "^18.0.0",
|
|
63
65
|
"react-dom": "^18.0.0"
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A2UISurface - A2UI 声明式 UI 渲染组件
|
|
3
|
+
*
|
|
4
|
+
* 基于 Google A2UI 协议,将 Agent 生成的声明式 JSON 消息
|
|
5
|
+
* 渲染为原生 React 组件。支持流式增量更新和自定义组件注册。
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import React, { useEffect, useRef, useCallback } from 'react';
|
|
10
|
+
import styled from 'styled-components';
|
|
11
|
+
import {
|
|
12
|
+
A2UIProvider,
|
|
13
|
+
A2UIRenderer,
|
|
14
|
+
A2UIViewer,
|
|
15
|
+
useA2UI,
|
|
16
|
+
initializeDefaultCatalog,
|
|
17
|
+
ComponentRegistry,
|
|
18
|
+
} from '@a2ui/react';
|
|
19
|
+
import type {
|
|
20
|
+
ServerToClientMessage,
|
|
21
|
+
OnActionCallback,
|
|
22
|
+
A2UIViewerProps,
|
|
23
|
+
} from '@a2ui/react';
|
|
24
|
+
|
|
25
|
+
// 初始化默认组件目录(全局只需执行一次)
|
|
26
|
+
initializeDefaultCatalog();
|
|
27
|
+
|
|
28
|
+
// ==================== Types ====================
|
|
29
|
+
|
|
30
|
+
/** A2UI 协议消息(v0.8 格式,透传给 @a2ui/react 处理) */
|
|
31
|
+
export type A2UIMessage = ServerToClientMessage;
|
|
32
|
+
|
|
33
|
+
export interface A2UISurfaceProps {
|
|
34
|
+
/** A2UI JSON 消息数组(来自 Agent 的响应) */
|
|
35
|
+
messages: A2UIMessage[];
|
|
36
|
+
/** 渲染的 Surface ID(默认 'main') */
|
|
37
|
+
surfaceId?: string;
|
|
38
|
+
/** 用户在 A2UI 组件上的交互回调 */
|
|
39
|
+
onAction?: OnActionCallback;
|
|
40
|
+
/** 自定义组件注册表(可选,默认使用内置组件) */
|
|
41
|
+
registry?: ComponentRegistry;
|
|
42
|
+
/** 自定义类名 */
|
|
43
|
+
className?: string;
|
|
44
|
+
/** 自定义样式 */
|
|
45
|
+
style?: React.CSSProperties;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** A2UIViewer 的 Props,用于静态 JSON 渲染场景 */
|
|
49
|
+
export type A2UIStaticViewerProps = A2UIViewerProps;
|
|
50
|
+
|
|
51
|
+
// ==================== Styled Components ====================
|
|
52
|
+
|
|
53
|
+
const A2UIContainer = styled.div`
|
|
54
|
+
margin-top: 12px;
|
|
55
|
+
width: 100%;
|
|
56
|
+
max-width: 100%;
|
|
57
|
+
`;
|
|
58
|
+
|
|
59
|
+
// ==================== Internal Component ====================
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 内部组件:负责消息处理和 Surface 渲染
|
|
63
|
+
* 必须在 A2UIProvider 内部使用,以获取 useA2UI hook 的上下文
|
|
64
|
+
*/
|
|
65
|
+
const A2UISurfaceInner: React.FC<{
|
|
66
|
+
messages: A2UIMessage[];
|
|
67
|
+
surfaceId: string;
|
|
68
|
+
registry?: ComponentRegistry;
|
|
69
|
+
className?: string;
|
|
70
|
+
style?: React.CSSProperties;
|
|
71
|
+
}> = ({ messages, surfaceId, registry, className, style }) => {
|
|
72
|
+
const { processMessages, getSurface } = useA2UI();
|
|
73
|
+
const processedCountRef = useRef(0);
|
|
74
|
+
|
|
75
|
+
// 增量处理新到达的消息(支持流式场景)
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (messages.length > processedCountRef.current) {
|
|
78
|
+
const newMessages = messages.slice(processedCountRef.current);
|
|
79
|
+
processMessages(newMessages);
|
|
80
|
+
processedCountRef.current = messages.length;
|
|
81
|
+
}
|
|
82
|
+
}, [messages, processMessages]);
|
|
83
|
+
|
|
84
|
+
// 当消息被清空时重置计数器
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
if (messages.length === 0) {
|
|
87
|
+
processedCountRef.current = 0;
|
|
88
|
+
}
|
|
89
|
+
}, [messages.length]);
|
|
90
|
+
|
|
91
|
+
const surface = getSurface(surfaceId);
|
|
92
|
+
|
|
93
|
+
if (!surface) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<A2UIContainer className={className} style={style}>
|
|
99
|
+
<A2UIRenderer
|
|
100
|
+
surfaceId={surfaceId}
|
|
101
|
+
registry={registry}
|
|
102
|
+
/>
|
|
103
|
+
</A2UIContainer>
|
|
104
|
+
);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// ==================== Exported Components ====================
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* A2UISurface - A2UI 声明式 UI 渲染组件(流式消息场景)
|
|
111
|
+
*
|
|
112
|
+
* 接收 Agent 发送的 A2UI 协议消息数组,增量处理并渲染对应的 Surface。
|
|
113
|
+
* 内部封装了 A2UIProvider,可直接作为 BubbleContent 的 children 使用。
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```tsx
|
|
117
|
+
* // 作为 BubbleContent 的 children 使用
|
|
118
|
+
* <BubbleContent content={content} status={status}>
|
|
119
|
+
* <A2UISurface
|
|
120
|
+
* messages={a2uiMessages}
|
|
121
|
+
* surfaceId="main"
|
|
122
|
+
* onAction={(msg) => console.log('用户操作:', msg)}
|
|
123
|
+
* />
|
|
124
|
+
* </BubbleContent>
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
export const A2UISurface: React.FC<A2UISurfaceProps> = ({
|
|
128
|
+
messages,
|
|
129
|
+
surfaceId = 'main',
|
|
130
|
+
onAction,
|
|
131
|
+
registry,
|
|
132
|
+
className,
|
|
133
|
+
style,
|
|
134
|
+
}) => {
|
|
135
|
+
const handleAction: OnActionCallback = useCallback((message) => {
|
|
136
|
+
onAction?.(message);
|
|
137
|
+
}, [onAction]);
|
|
138
|
+
|
|
139
|
+
return (
|
|
140
|
+
<A2UIProvider onAction={handleAction}>
|
|
141
|
+
<A2UISurfaceInner
|
|
142
|
+
messages={messages}
|
|
143
|
+
surfaceId={surfaceId}
|
|
144
|
+
registry={registry}
|
|
145
|
+
className={className}
|
|
146
|
+
style={style}
|
|
147
|
+
/>
|
|
148
|
+
</A2UIProvider>
|
|
149
|
+
);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* A2UIStaticViewer - A2UI 静态 JSON 渲染组件
|
|
154
|
+
*
|
|
155
|
+
* 用于直接从静态的组件定义和数据渲染 UI,无需流式消息。
|
|
156
|
+
* 适用于已有完整 A2UI 组件树的场景。
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```tsx
|
|
160
|
+
* const components = [
|
|
161
|
+
* { id: 'root', component: { Card: { child: 'text' } } },
|
|
162
|
+
* { id: 'text', component: { Text: { text: { path: '/message' } } } },
|
|
163
|
+
* ];
|
|
164
|
+
*
|
|
165
|
+
* <A2UIStaticViewer
|
|
166
|
+
* root="root"
|
|
167
|
+
* components={components}
|
|
168
|
+
* data={{ message: 'Hello World!' }}
|
|
169
|
+
* onAction={(action) => console.log('Action:', action)}
|
|
170
|
+
* />
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
export const A2UIStaticViewer: React.FC<A2UIStaticViewerProps> = (props) => {
|
|
174
|
+
return (
|
|
175
|
+
<A2UIContainer>
|
|
176
|
+
<A2UIViewer {...props} />
|
|
177
|
+
</A2UIContainer>
|
|
178
|
+
);
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
export default A2UISurface;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { A2UISurface, A2UIStaticViewer, type A2UISurfaceProps, type A2UIStaticViewerProps, type A2UIMessage } from './A2UIRenderer';
|
|
@@ -11,6 +11,8 @@ import { loadEchartsScript } from '@/utils/loadEcharts';
|
|
|
11
11
|
import { DocReferences, DocReferenceItem } from './DocReferences';
|
|
12
12
|
import { WebSearchPanel } from './WebSearchPanel';
|
|
13
13
|
import { HumanVerify, HistoryCard, CustomParamSchema } from './HumanVerify';
|
|
14
|
+
import { A2UISurface } from './A2UIRenderer';
|
|
15
|
+
import type { A2UIMessage } from './A2UIRenderer';
|
|
14
16
|
import { BubbleContent } from '@/core';
|
|
15
17
|
|
|
16
18
|
/** HumanVerify 提交数据类型 */
|
|
@@ -58,14 +60,21 @@ export interface MessageBubbleProps {
|
|
|
58
60
|
|
|
59
61
|
// ==================== HumanVerify相关Props ====================
|
|
60
62
|
|
|
61
|
-
/** 事件类型(用于特殊消息如 humanVerify、historyCard) */
|
|
62
|
-
eventType?: 'humanVerify' | 'historyCard';
|
|
63
|
+
/** 事件类型(用于特殊消息如 humanVerify、historyCard、a2ui) */
|
|
64
|
+
eventType?: 'humanVerify' | 'historyCard' | 'a2ui';
|
|
63
65
|
/** HumanVerify 相关数据 */
|
|
64
66
|
humanVerifyData?: HumanVerifyData;
|
|
65
67
|
/** HistoryCard 相关数据(历史对话中的审核卡片) */
|
|
66
68
|
historyCardData?: HistoryCardData;
|
|
67
69
|
/** HumanVerify 提交回调 */
|
|
68
70
|
onHumanVerifySubmit?: (data: HumanVerifySubmitData) => void;
|
|
71
|
+
|
|
72
|
+
// ==================== A2UI相关Props ====================
|
|
73
|
+
|
|
74
|
+
/** A2UI 消息数组(Agent 生成的声明式 UI 描述) */
|
|
75
|
+
a2uiMessages?: A2UIMessage[];
|
|
76
|
+
/** A2UI 用户交互回调 */
|
|
77
|
+
onA2UIAction?: (action: any) => void;
|
|
69
78
|
}
|
|
70
79
|
|
|
71
80
|
// 样式隔离容器
|
|
@@ -270,6 +279,9 @@ export const MessageBubble: React.FC<MessageBubbleProps> = ({
|
|
|
270
279
|
humanVerifyData,
|
|
271
280
|
historyCardData,
|
|
272
281
|
onHumanVerifySubmit,
|
|
282
|
+
// A2UI 相关 props
|
|
283
|
+
a2uiMessages,
|
|
284
|
+
onA2UIAction,
|
|
273
285
|
}) => {
|
|
274
286
|
const [modal, contextHolder] = Modal.useModal();
|
|
275
287
|
|
|
@@ -362,6 +374,14 @@ export const MessageBubble: React.FC<MessageBubbleProps> = ({
|
|
|
362
374
|
data={historyCardData}
|
|
363
375
|
/>
|
|
364
376
|
)}
|
|
377
|
+
|
|
378
|
+
{/* A2UI 事件 - Agent 声明式 UI 渲染 */}
|
|
379
|
+
{eventType === 'a2ui' && a2uiMessages && a2uiMessages.length > 0 && (
|
|
380
|
+
<A2UISurface
|
|
381
|
+
messages={a2uiMessages}
|
|
382
|
+
onAction={onA2UIAction}
|
|
383
|
+
/>
|
|
384
|
+
)}
|
|
365
385
|
|
|
366
386
|
{/* 参考资料 */}
|
|
367
387
|
{references && references.length > 0 && status === 'Success' && (
|
package/src/index.ts
CHANGED
|
@@ -76,6 +76,12 @@ export type {
|
|
|
76
76
|
ValidationError,
|
|
77
77
|
} from './components/HumanVerify';
|
|
78
78
|
|
|
79
|
+
// ==================== A2UI 组件导出 ====================
|
|
80
|
+
export { A2UISurface, A2UIStaticViewer } from './components/A2UIRenderer';
|
|
81
|
+
|
|
82
|
+
// ==================== A2UI 组件类型导出 ====================
|
|
83
|
+
export type { A2UISurfaceProps, A2UIStaticViewerProps, A2UIMessage } from './components/A2UIRenderer';
|
|
84
|
+
|
|
79
85
|
// ==================== 工具函数导出 ====================
|
|
80
86
|
export { loadEchartsScript } from './utils/loadEcharts';
|
|
81
87
|
export { loadMermaidScript } from './utils/loadMermaid';
|