123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- <script setup lang="ts">
- import { SmileOutlined, UserOutlined } from '@ant-design/icons-vue';
- import { Flex } from 'ant-design-vue';
- import { Bubble, Prompts, Sender, useXAgent, useXChat, type BubbleListProps } from 'ant-design-x-vue';
- import { ref, h } from 'vue';
- defineOptions({ name: 'AXUseXChatSuggestionsSetup' });
- const sleep = () => new Promise((resolve) => setTimeout(resolve, 1000));
- const roles: BubbleListProps['roles'] = {
- user: {
- placement: 'end',
- avatar: { icon: UserOutlined, style: { background: '#87d068' } },
- },
- text: {
- placement: 'start',
- avatar: { icon: UserOutlined, style: { background: '#fde3cf' } },
- typing: true,
- },
- suggestion: {
- placement: 'start',
- avatar: { icon: UserOutlined, style: { visibility: 'hidden' } },
- variant: 'borderless',
- messageRender: (content) => h(Prompts, {
- vertical: true,
- items: (content as any as string[]).map((text) => ({
- key: text,
- icon: h(SmileOutlined, { style: { color: '#FAAD14' } }),
- description: text,
- }))
- }),
- },
- };
- type AgentUserMessage = {
- type: 'user';
- content: string;
- };
- type AgentAIMessage = {
- type: 'ai';
- content?: string;
- list?: (
- | {
- type: 'text';
- content: string;
- }
- | {
- type: 'suggestion';
- content: string[];
- }
- )[];
- };
- type AgentMessage = AgentUserMessage | AgentAIMessage;
- type BubbleMessage = {
- role: string;
- };
- const content = ref('');
- const senderLoading = ref(false);
- // Agent for request
- const [ agent ] = useXAgent<AgentMessage>({
- request: async ({ message }, { onSuccess }) => {
- senderLoading.value = true;
- await sleep();
- const { content } = message || {};
- senderLoading.value = false;
- onSuccess({
- type: 'ai',
- list: [
- {
- type: 'text',
- content: `Do you want?`,
- },
- {
- type: 'suggestion',
- content: [`Look at: ${content}`, `Search: ${content}`, `Try: ${content}`],
- },
- ],
- });
- },
- });
- // Chat messages
- const { onRequest, parsedMessages } = useXChat<AgentMessage, BubbleMessage>({
- agent: agent.value,
- defaultMessages: [
- {
- id: 'init',
- message: {
- type: 'ai',
- content: 'Hello, what can I do for you?',
- },
- status: 'success',
- },
- ],
- requestPlaceholder: {
- type: 'ai',
- content: 'Waiting...',
- },
- // Convert AgentMessage to BubbleMessage
- parser: (agentMessages) => {
- const list = agentMessages.content ? [agentMessages] : (agentMessages as AgentAIMessage).list;
- return (list || []).map((msg) => ({
- role: msg.type,
- content: msg.content,
- }));
- },
- });
- </script>
- <template>
- <Flex
- vertical
- gap="middle"
- >
- <Bubble.List
- :roles="roles"
- :style="{ maxHeight: 300 }"
- :items="parsedMessages.map(({ id, message, status }) => ({
- key: id,
- loading: status === 'loading',
- ...message,
- }))"
- />
- <Sender
- :loading="senderLoading"
- :value="content"
- :on-change="(v) => content = v"
- :on-submit="(nextContent) => {
- onRequest({
- type: 'user',
- content: nextContent,
- });
- content = '';
- }"
- />
- </Flex>
- </template>
|