1.0.0 • Published 8 months ago

@blueking/ai-blueking v1.0.0

Weekly downloads
-
License
MIT
Repository
-
Last release
8 months ago

AI 小鲸使用指南

安装

npm i @blueking/ai-blueking

stream 模式

不同框架,组件引入方式不同,具体可参考下面的的例子。这里使用 vue3 项目为例,来展示 stream 模式交互:

<template>
  <AIBlueking
    :loading="loading"
    :messages="messages"
    @clear="handleClear"
    @send="handleSend"
    @stop="handleStop"
  />
</template>

<script lang="ts" setup>
  import { ref } from 'vue';
  import AIBlueking, { ChatHelper, RoleType, MessageStatus } from '@blueking/ai-blueking';
  import '@blueking/ai-blueking/dist/vue3/style.css';

  const loading = ref(false);
  const messages = ref([]);

  // 聊天开始
  const handleStart = (id: number | string) => {
    loading.value = true;
    messages.value.push({
      role: RoleType.Assistant,
      content: '内容正在生成中...',
      status: MessageStatus.Loading,
    });
  };

  // 接收消息
  const handleReceiveMessage = (message: string, id: number | string) => {
    const currentMessage = messages.value.at(-1);
    if (currentMessage.status === MessageStatus.Loading) {
      // 如果是loading状态,直接覆盖
      currentMessage.content = message;
      currentMessage.status = MessageStatus.Success;
    } else if (currentMessage.status === MessageStatus.Success) {
      // 如果是后续消息,就追加消息
      currentMessage.content += message;
    }
  };

  // 聊天结束
  const handleEnd = (id: number | string) => {
    loading.value = false;
    const currentMessage = messages.value.at(-1);
    // loading 情况下终止
    if (currentMessage.status === MessageStatus.Loading) {
      currentMessage.content = '聊天内容已中断';
      currentMessage.status = MessageStatus.Error;
    }
  };

  // 错误处理
  const handleError = (message: string, code: string | number, id: number | string) => {
    if (message.includes('user authentication failed')) {
      // 未登录,跳转登录
      const loginUrl = new URL(process.env.BK_LOGIN_URL);
      loginUrl.searchParams.append('c_url', location.origin);
      window.location.href = loginUrl.href;
    } else {
      // 处理错误消息
      const currentMessage = messages.value.at(-1);
      currentMessage.status = MessageStatus.Error;
      currentMessage.content = message;
      loading.value = false;
    }
  };

  const prefix = process.env.BK_API_URL_TMPL.replace('{api_name}', '<网关名>').replace('http', 'https');
  const chatHelper = new ChatHelper(
    `${prefix}/prod/bk_plugin/plugin_api/assistant/`,
    handleStart,
    handleReceiveMessage,
    handleEnd,
    handleError,
  );

  // 清空消息
  const handleClear = () => {
    messages.value = [];
  };

  // 发送消息
  const handleSend = (message: string) => {
    // 记录当前消息记录
    const chatHistory = [...messages.value];
    // 添加一条消息
    messages.value.push({
      role: 'user',
      content: message,
    });
    // ai 消息,id是唯一标识当前流,调用 chatHelper.stop 的时候需要传入
    chatHelper.stream(
      {
        inputs: {
          input: message,
          chat_history: chatHistory,
        },
      },
      1,
    );
  };

  // 暂停聊天
  const handleStop = () => {
    chatHelper.stop(1);
  };
</script>

vue3 项目内使用(非 stream 模式)

<template>
  <AIBlueking
    :background="background"
    :head-background="headBackground"
    :loading="loading"
    :messages="messages"
    :position-limit="positionLimit"
    :prompts="prompts"
    :scroll-loading="scrollLoading"
    :scroll-loading-end="scrollLoadingEnd"
    :size-limit="sizeLimit"
    :start-position="startPosition"
    @choose-prompt="handleChoosePrompt"
    @clear="handleClear"
    @close="handleClose"
    @scroll-load="handleScrollLoad"
    @send="handleSend"
    @stop="handleStop"
  />
</template>
<script setup lang="ts">
  import { ref } from 'vue';

  import AIBlueking, { type IPrompt, type IMessage, RoleType, MessageStatus } from '@blueking/ai-blueking';

  import '@blueking/ai-blueking/dist/vue3/style.css';

  // 展示的消息,其中 time 可以不传
  const messages = ref<IMessage[]>([
    {
      content: '1+1=?',
      time: '2023-08-12 10:28',
      role: RoleType.User,
    },
    {
      content: '1+1=3',
      time: '2024-08-07 14:29',
      role: RoleType.Assistant,
      status: MessageStatus.Error,
    },
    {
      content: '不对',
      time: '2024-08-12 09:29',
      role: RoleType.User,
    },
    {
      content: '1+1=2',
      time: '2024-08-12 09:31',
      role: RoleType.Assistant,
      status: MessageStatus.Loading,
    },
    {
      content: '对了',
      time: '2024-08-13 10:20',
      role: RoleType.User,
    },
    {
      content: '好的,任务已完成',
      time: '2024-08-13 10:23',
      role: RoleType.Assistant,
    },
  ]);
  // 内置 prompt
  const prompts = [
    {
      id: 1,
      content: '帮我计算1+1的结果',
    },
    {
      id: 2,
      content: '帮我计算2+2的结果',
    },
  ];

  // 处理ai消息的loading状态
  const loading = ref(false);
  // 聊天背景色
  const background = '#f5f7fa';
  // 头部背景色
  const headBackground = 'linear-gradient(267deg, #2dd1f4 0%, #1482ff 95%)';
  // 弹框位于屏幕四边的最小距离
  const positionLimit = {
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
  };
  // 组件最小尺寸
  const sizeLimit = {
    height: 320,
    width: 400,
  };
  // 初始位置
  const startPosition = {
    top: window.innerHeight - 560,
    bottom: 0,
    left: window.innerWidth - 400,
    right: 0,
  };
  // 向上滚动加载
  const scrollLoading = ref(false);
  const scrollLoadingEnd = ref(false);

  const handleClear = () => {
    console.log('trigger clear');
  };

  const handleSend = (val: string) => {
    console.log('trigger send', val);
  };

  const handleStop = () => {
    console.log('trigger stop');
  };

  const handleScrollLoad = () => {
    scrollLoading.value = true;
    setTimeout(() => {
      // 模拟异步请求
      messages.value.unshift(
        ...[
          {
            content: '1+1=?',
            time: '2023-08-12 9:28',
            role: RoleType.User,
          },
          {
            content: '2',
            time: '2023-08-12 9:30',
            role: RoleType.Assistant,
          },
        ],
      );
      // 设置状态
      scrollLoading.value = false;
      scrollLoadingEnd.value = true;
    }, 1000);
  };

  const handleClose = () => {
    console.log('trigger close');
  };

  const handleChoosePrompt = (prompt: IPrompt) => {
    console.log('choose prompt', prompt);
  };
</script>

vue2 项目内使用(非 stream 模式)

vue2 下,需要安装 npm 包,里面是 vue3 资源

npm i @blueking/bkui-library
<template>
  <AIBlueking
    :background="background"
    :head-background="headBackground"
    :loading="loading"
    :messages="messages"
    :position-limit="positionLimit"
    :prompts="prompts"
    :size-limit="sizeLimit"
    :start-position="startPosition"
    @choose-prompt="handleChoosePrompt"
    @clear="handleClear"
    @close="handleClose"
    @send="handleSend"
    @scroll="handleScroll"
    @stop="handleStop"
  />
</template>
<script lang="ts">
  import { ref } from 'vue';

  import AIBlueking from '@blueking/ai-blueking/vue2';
  import '@blueking/ai-blueking/dist/vue2/style.css';

  export default {
    components: {
      AIBlueking,
    },
    data() {
      return {
        messages: [
          {
            content: '你好呀',
            role: 'assistant',
          },
          {
            content: '1+1=?',
            role: 'user',
          },
          {
            content: '1+1=3',
            role: 'assistant',
            status: 'error',
          },
          {
            content: '不对',
            role: 'user',
          },
          {
            content: '1+1=2',
            role: 'assistant',
            status: 'loading',
          },
          {
            content: '对了',
            role: 'user',
          },
          {
            content: '好的,任务已完成',
            role: 'assistant',
          },
        ],
        prompts: [
          {
            id: 1,
            content: '帮我计算1+1的结果',
          },
          {
            id: 2,
            content: '帮我计算2+2的结果',
          },
        ],
        loading: false,
        background: '#f5f7fa',
        headBackground: 'linear-gradient(267deg, #2dd1f4 0%, #1482ff 95%)',
        positionLimit: {
          top: 0,
          bottom: 0,
          left: 0,
          right: 0,
        },
        sizeLimit: {
          height: 320,
          width: 400,
        },
        startPosition: {
          top: window.innerHeight - 560,
          bottom: 0,
          left: window.innerWidth - 400,
          right: 0,
        },
      };
    },
    methods: {
      handleClear() {
        console.log('trigger clear');
      },
      handleSend(val: string) {
        console.log('trigger send', val);
      },
      handleClose() {
        console.log('trigger close');
      },
      handleChoosePrompt(prompt) {
        console.log('choose prompt', prompt);
      },
      handleScroll(event: Event) {
        console.log('trigger scroll', event);
      },
      handleStop() {
        console.log('trigger stop');
      },
    },
  };
</script>
0.4.5-beta.1

10 months ago

0.2.15

1 year ago

0.2.14

1 year ago

0.2.13

1 year ago

0.2.12

1 year ago

1.1.0-beta.2

8 months ago

1.1.0-beta.1

8 months ago

0.3.0

1 year ago

1.1.0-beta.3

8 months ago

0.3.6

1 year ago

0.3.5

1 year ago

0.3.8

1 year ago

0.3.7

1 year ago

0.3.2

1 year ago

0.3.1

1 year ago

0.3.4

1 year ago

0.3.3

1 year ago

0.4.4-beta.1

11 months ago

0.5.0-beta.1

11 months ago

0.5.5-beta.2

9 months ago

0.5.5-beta.1

9 months ago

0.5.3-beta.4

10 months ago

0.5.3-beta.3

10 months ago

0.5.3-beta.2

10 months ago

0.5.3-beta.1

10 months ago

0.5.3-beta.7

10 months ago

0.5.0-beta.8

10 months ago

0.5.3-beta.6

10 months ago

0.5.0-beta.7

10 months ago

0.5.3-beta.5

10 months ago

0.5.0-beta.6

10 months ago

0.5.0-beta.5

10 months ago

0.5.0-beta.4

10 months ago

0.5.0-beta.3

10 months ago

0.5.0-beta.2

11 months ago

0.2.15-beta.3

1 year ago

0.2.15-beta.2

1 year ago

0.2.15-beta.1

1 year ago

0.4.4

10 months ago

0.4.1

11 months ago

0.4.0

11 months ago

0.4.3

11 months ago

0.4.2

11 months ago

1.0.0

8 months ago

0.3.25-beta.0

12 months ago

0.3.29

11 months ago

0.3.20

1 year ago

0.3.28

11 months ago

0.3.27

11 months ago

0.3.26

12 months ago

0.3.25

12 months ago

0.3.24

12 months ago

0.3.23

12 months ago

0.3.22

1 year ago

0.3.21

1 year ago

1.0.0-beta.11

9 months ago

1.0.0-beta.12

9 months ago

1.0.0-beta.10

9 months ago

0.3.19

1 year ago

0.3.18

1 year ago

0.5.4

9 months ago

0.5.3

9 months ago

0.5.6

9 months ago

0.5.5

9 months ago

0.5.0

10 months ago

1.0.0-beta.13

9 months ago

0.5.2

10 months ago

0.5.1

10 months ago

0.3.9

1 year ago

0.3.17

1 year ago

0.3.16

1 year ago

0.3.15

1 year ago

0.3.14

1 year ago

0.3.13

1 year ago

0.3.12

1 year ago

0.3.11

1 year ago

0.3.10

1 year ago

1.0.0-beta.2

9 months ago

1.0.0-beta.3

9 months ago

1.0.0-beta.4

9 months ago

1.0.0-beta.5

9 months ago

1.0.0-beta.1

9 months ago

1.0.0-beta.6

9 months ago

1.0.0-beta.7

9 months ago

1.0.0-beta.8

9 months ago

1.0.0-beta.9

9 months ago

0.2.11

1 year ago

0.2.10

1 year ago

0.2.8-beta.1

1 year ago

0.2.8-beta.2

1 year ago

0.2.9

1 year ago

0.2.1

1 year ago

0.2.7

1 year ago

0.2.6

1 year ago

0.2.3

1 year ago

0.2.2

1 year ago

0.2.5

1 year ago

0.2.4

1 year ago

0.2.0-beta.17

1 year ago

0.2.0-beta.16

1 year ago

0.2.0-beta.15

1 year ago

0.2.0-beta.14

1 year ago

0.2.0-beta.13

1 year ago

0.2.0-beta.12

1 year ago

0.2.0-beta.11

1 year ago

0.2.0-beta.10

1 year ago

0.2.0-beta.9

1 year ago

0.2.0-beta.8

1 year ago

0.2.0-beta.7

1 year ago

0.2.0-beta.6

1 year ago

0.2.0-beta.4

1 year ago

0.2.0-beta.3

1 year ago

0.2.0-beta.2

1 year ago

0.2.0-beta.1

1 year ago

0.1.7

1 year ago

0.1.6

1 year ago

0.1.6-beta.4

1 year ago

0.1.6-beta.3

1 year ago

0.1.6-beta.2

1 year ago

0.1.6-beta.1

1 year ago

0.1.5

1 year ago

0.1.5-beta.1

1 year ago

0.1.4

1 year ago

0.1.4-beta.1

1 year ago

0.1.3

1 year ago

0.1.3-beta.1

1 year ago

0.1.2

1 year ago

0.1.2-beta.2

1 year ago

0.1.2-beta.1

1 year ago

0.1.1

1 year ago

0.1.1-beta.2

1 year ago

0.1.1-beta.1

1 year ago

0.1.0

2 years ago

0.1.0-beta.2

2 years ago

0.1.0-beta.1

2 years ago

0.0.6

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago

0.0.0

2 years ago