stream.vue 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. <script setup lang="ts">
  2. import { UserOutlined } from '@ant-design/icons-vue';
  3. import { Flex } from 'ant-design-vue';
  4. import { Bubble, Sender, useXAgent, useXChat } from 'ant-design-x-vue';
  5. import { ref } from 'vue';
  6. defineOptions({ name: 'AXUseXChatStreamSetup' });
  7. const roles: (typeof Bubble.List)['roles'] = {
  8. ai: {
  9. placement: 'start',
  10. avatar: { icon: UserOutlined, style: { background: '#fde3cf' } },
  11. },
  12. local: {
  13. placement: 'end',
  14. avatar: { icon: UserOutlined, style: { background: '#87d068' } },
  15. },
  16. };
  17. const content = ref('');
  18. const senderLoading = ref(false);
  19. // Agent for request
  20. const [ agent ] = useXAgent({
  21. request: async ({ message }, { onSuccess, onUpdate }) => {
  22. senderLoading.value = true;
  23. const fullContent = `Streaming output instead of Bubble typing effect. You typed: ${message}`;
  24. let currentContent = '';
  25. const id = setInterval(() => {
  26. currentContent = fullContent.slice(0, currentContent.length + 2);
  27. onUpdate(currentContent);
  28. if (currentContent === fullContent) {
  29. senderLoading.value = false;
  30. clearInterval(id);
  31. onSuccess(fullContent);
  32. }
  33. }, 100);
  34. },
  35. });
  36. // Chat messages
  37. const { onRequest, messages } = useXChat({
  38. agent: agent.value,
  39. });
  40. </script>
  41. <template>
  42. <Flex
  43. vertical
  44. gap="middle"
  45. >
  46. <Bubble.List
  47. :roles="roles"
  48. :style="{ maxHeight: 300 }"
  49. :items="messages.map(({ id, message, status }) => ({
  50. key: id,
  51. role: status === 'local' ? 'local' : 'ai',
  52. content: message,
  53. }))"
  54. />
  55. <Sender
  56. :loading="senderLoading"
  57. :value="content"
  58. :on-change="(v) => content = v"
  59. :on-submit="(nextContent) => {
  60. onRequest(nextContent);
  61. content = '';
  62. }"
  63. />
  64. </Flex>
  65. </template>