# growthai-webui

#### Description
Growth AI WebUI Component是一个用于应用在融合AI过程中，专门为应用提供面向AI的交互界面功能组件，它是Growth Store系列中的一个部分。使用该组件后，可以让应用在融合AI后的用户体验获得巨大提升。它提供与AI或AI Agent标准化的交互界面（如对话），以及对原有界面进行融合的组件。

#### 功能与特点：
1. 快速接入，最小化侵入（或零侵入）；通过在原有的界面中引入Growth AI WebUI Component的组件包，并进行简单配置即可使用；
2. 支持多种Web UI技术或框架。包括：Reactive、Vue2/Vue3、H5等。
3. 支持语音输入，自动识别语音指令；
4. 支持应用原有的交互指令。保留应用原有的交互方式，以及通过用户指令模式（AI模型来识别这些指令）来配合工作，用户可以在与AI交互的过程，可以直接使用应用中的相关功能，如菜单、导航、查询、表单等。
5. 根据需要动态扩展数据的展示界面，或数据收集表单；这个是通过业务数据的Schema的表式来生成相应的交互界面。
6. 丰富化AI大模型以及AI Agent交互的方式，不只是对话；

#### 安装

##### npm安装方式
我们有基于npm的方式，可以使用下列的方式进行安装。由于growthai-webui在展示对话内容时使用Markdown方式，所以需要一起安装markdown-it组件。growthai-webui没有将markdown-it组件打包在一起，可以让应用灵活选择。
1. `npm i growthai-webui`
2. `npm i markdown-it`
3. `npm i <markdonw-it的其它插件>`

#####  script标签导入方式
第二种方式，是直接在HTML页面中使用<script/>导入，这个时候需要导入index.umd.js这个文件，
``` JavaScript
...
<script type="text/javascript" src="/assets/growthai-webui/dist/index.umd.js"></script>
<link rel="stylesheet" href="/assets/growthai-webui/dist/css/style.css" />
<script type="text/javascript">
  if (window.GrowthAI) {
    setTimeout(() => {
      new GrowthAI({ ... }).create({})
    }, 500)
  }
</script>
...
```

#### 使用
在应用中创建一个气泡球，通过气泡球可以产生一个小型的AI对话框。在该模式下，AI对话被限制在一个很小的区域进行，对话框悬浮在应用界面之上。
``` JavaScript
import GrowthAI from "growthai-webui";
import "growthai-webui/dist/css/style.css"

new GrowthAI({
    ainame: '小智AI',
    use_websocket: false,
    handleSendMessage: (msg: string) => {
      return {
              "messages":[{"dataId":"apbj7tiDOtJKyIrK93rhFnt2z","hideInUI":false,"role":"user","content": msg}],
              "variables":{"cTime":"2025-07-03 12:06:56 星期四"},
              "chatId": "newchatidwhatisthtis",
              "retainDatasetCite": false, "detail": false, 
              "stream": true
            }
    },
    sse_endpoint: '/api/restapi/com.siline/fastgpt/completions/sse',
  }).create({})

```

如果需要在应用中使用更多的markdown-it的插件，则需要在应用工程中加入相应的插件的导入。
1. `npm i growthai-webui`
2. `npm i markdown-it`
3. `npm i @jsonlee_12138/markdown-it-mermaid`

注意：markdown-it-mermaid是Markdown-it对mermaid图示的支持，markdown-it-mermaid在npmjs仓库中有很多个版本，我们选择使用@jsonlee_12138/markdown-it-mermaid这个版本，可以很好的支持最新版的
markdown-it(14.1.0)和mermaid(v11)。

``` JavaScript
import markdownItMermaid from '@jsonlee_12138/markdown-it-mermaid';
import GrowthAI from "growthai-webui";
import "growthai-webui/dist/css/style.css"

new GrowthAI({
    ainame: '小智AI',
    use_websocket: false,
    markdown_plugins: [markdownItMermaid({delay: 300, securityLevel: 'loose', experimental: ['xychartBeta'], xyChart: {
      yAxis: {
        showTick: true, showAxisLine: true
      },      // 显示刻度线
      xAxis: {
        showTick: true, showAxisLine: true
      }
    },
    suppressErrorRendering: true
    })],
    handleSendMessage: (msg: string) => {
      return {
              "messages":[{"dataId":"apbj7tiDOtJKyIrK93rhFnt2z","hideInUI":false,"role":"user","content": msg}],
              "variables":{"cTime":"2025-07-03 12:06:56 星期四"},
              "chatId": "newchatidwhatisthtis",
              "retainDatasetCite": false, "detail": false, 
              "stream": true
            }
    },
    sse_endpoint: '/api/restapi/com.siline/fastgpt/completions/sse',
  }).create({})

```


#### 创建GrowthAI时的选项说明
在创建GrowthAI实例的时候，我们可以按下列选项来来进行配置GrowthAI的行为。

``` JavaScript
interface GrowthAIConfigOptions {
    welcome?: string;                       // 显示欢迎词
    growth_id?: string;                     // 用于标识这个GrowthAI对话框，可以使用它来确保只有一个GrowthAI实例被创建
    ball_image?: string;                    // 显示Ball的图片URL，最好是png，或者svg
    ball_style?: string;                    // 显示Ball的一些附加的Style，因为缺省的Ball样式是圆形的，如果你想修改成其它样式，则可以自行定义它
    disable_rotation?: boolean;             // 是否禁止Ball的旋转
    ainame?: string;                        // 显示的AI Assistant名称
    username?: string;                      // 显示的用户的名称
    websocket_endpoint?: string;            // 如果使用WebSocket方法来请求对话，则需要填写对应的Growth Store的WebSocket端口，这个只支持GrowthStore的WebSocket能力
    sse_endpoint?: string;                  // 如果使用HTTP Streamable方法来请求对话，则需要填写对应的Growth Store的Completion端口 
    use_websocket: boolean;                 // 是否使用WebSocket来进行Chat对话，这个时候，将需要提供websocket_endpoint，否则应该提供sse_endpoint
    aiavatar?: string;                      // 显示AI Assistant的头像
    useravatar?: string;                    // 显示用户的头像
    frame_placement?: string;               // 最大化时，用于将对话框嵌入到界面的Selector
    attach_on_create?: boolean;             // 启动时自动显示，并偿试最大化
    window_width?: number;                  // 窗口模型下的宽
    window_height?: number;                 // 窗口模型下的高
    ball_right?: number;                    // 150px
    ball_bottom?: number;                   // 20px
    ball_width?: number;                    // 100px;
    space_recording?: boolean;              // 允许按下Space键来进行语音识别，按下Space键后达到将近1秒，录音功能才会正式启动，同时，如果录音时长没有达到1秒，即松开了按键，则直接取消录音，但不会语音识别。
    allow_images?: boolean;                 // 允许上传（并识别图片）
    allow_documents?: boolean;              // 允许使用文档
    hidden_ball_maximum?: boolean;          // 最大化时隐藏Ball
    image_width?: number;                   // 上传图片时，处理的最大宽度
    image_height?: number;                  // 上传图片时，处理的最大高度，image_width和image_height取最小值。如果不设置，则不进行图片缩放处理
    sse_client?: SSEEndpointClient;         // 提供一个自定义的SSEEndpointClient
    markdown_plugins?: Array<any>;          // Markdown-it的可以使用的插件
    authorization?: string;                 // 提供基于Bearer （或其它的形式的Authorization）
    upload_endpoint?: string;               // 提供用于上传文件的Endpoint
    voiceasr_endpoint?: string;             // 提供用于语音识别的Endpoint
    upload_filefield?: string;              // 文件上传时用于附带文件的名称，缺省为file
    voiceasr_filefield?: string;            // 语音识别是用于上传语音文件的名称，，缺省为file
    pass_file_asbase64?: boolean;           // 向AI发送文件时，使用Base64格式，否则发送可以在外网访问的URL。
    adjust_frame_height?: number;           // 调整加入到最大化TAG时的高度值，calc(100vh - xx);
    uploadAttachment?: (file: File, onprogress?: (progress: number) => void) => Promise<any>; // 提供用于上传文件的处理方法，如果提供了这个函数，则upload_endpoint无须提供
    voiceRecognize?: (data: Blob) => Promise<any>;   // 提供用于上传语音以及返回识别结果的函数，如果提供了这个函数，则voiceasr_endpoint无须提供
    handleReceivedMessage?: (rec: any) => string | null;   // 从接收到消息中获取相应的内容
    handleSendMessage?: (msg: string, attachs?: Array<any>) => object;
    routeHandler?: (route: any) => void;
    notifyHandle?: (msg: string, level?: string) => void;   // 提供一个应用级的通知处理程序，用于显示提示消息，如果没有提供，则使用alert
    previewImageHandle?: (image_src: string, image_list?: string[]) => void;       // 预览图片
    handleUploadResult?: (resp: any) => string;                 // 处理返回时的结果，如果返回值为空，或以ERR/ERROR开头，则表示出现了错误
    handleVoiceRecoginzResult?: (resp: any) => string;          // 返回语音识别结果，如果返回值为空，或以ERR/ERROR开头，则表示出现了错误
    handleRefineFileURL?: (image_url: string) => string;       // 对远程ImageURL/FileURL进行重新处理，主要用于加入相应的访问Token，以防无法访问
}

interface SSEEndpointClient {
    sendCompletions: (msg: any, options: any) => Promise<any>;    // 往AI服务器发送Completion请求
    onError?: (e: any) => void;                                   // 出现错误时的处理
}

```

