Skip to content

AI Assistant Integration Embedding Guide

This document will guide you through a few simple steps to integrate or embed the AI Assistant into your system. HENGSHI SENSE AI Assistant offers multiple integration methods, allowing you to embed and integrate the AI Assistant into your system via iframe, JS SDK, ReactJS SDK, or API calls.

1. Integration via iframe

The iframe integration method is the simplest. You only need to add an iframe element to your HTML file (or Vue/React component) and set its src attribute to the URL of the AI Assistant.

html
<iframe
  src="https://develop.hengshi.org/copilot"
  width="100%"
  height="100%">
</iframe>

URL Query String Parameters Description

We provide some optional URL parameters that you can adjust as needed.

Data Source

You can specify the data source when conversing with the AI assistant in the following ways:

  1. Converse with the data source of the chart
?appId={App ID}&chartId={Chart ID}
  1. Converse with the data model of the dataset
?dataAppId={Data Package ID}&datasetId={Dataset ID}
Theme Color

You can specify the theme color of the chart within the AI assistant conversation by:

?chartTheme={Dashboard Theme ID}

The Dashboard Theme ID can be found in the theme dropdown menu while editing the dashboard in your app creation area, as shown in the image below:

Dashboard Theme ID

Display Only Specified Conversations

We also provide the conversationId and chatUid parameters, allowing multiple values to be passed separated by commas, to specify displaying only certain conversations. These two parameters can be used individually or in combination.

?conversationId={conversationID1,conversationID2}&chatUid={uid1,uid2}
Login Authentication

If you need to integrate with other systems, you may need to perform login authentication. You can pass login information through the jwt parameter:

?activeAuth=jwt-param&jwtParam={JWT parameter}

2. Integration via JS SDK

The JS SDK integration method requires you to include the AI assistant's JS file in your HTML file (or Vue/React component) and call the relevant APIs. This will require you to have some JavaScript development experience.

You can go to the Settings->Feature Configuration->AI Assistant->Console page within the system, click Options->Copilot SDK to open the integration page guide. In the drawer popup, you will find the SDK link for integration, for example:

https://develop.hengshi.org/assets/hengshi-copilot@5.3.js

Integrating Copilot SDK in Other Systems

We provide sample code for integrating the Copilot SDK in front-end frameworks such as vue, react, and plain js. You can choose according to your needs, this requires you to have some front-end development experience.

js
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI Assistant</title>
    <script type="text/javascript" src="https://develop.hengshi.org/assets/hengshi-copilot@5.3-SNAPSHOT.js" defer></script>
    <style>
        /* Add styles (if needed) */
    </style>
</head>
<body>
    <button id="trigger-ai">Activate AI Assistant</button>
    <div id="copilot-root" style="display: none;"></div>

    <script>
        const copilotConfig = {
            locale: 'en',
            draggable: {
                enable: true,
                minWidth: 440,
                minHeight: 440,
                position: {
                    x: window.innerWidth - 480,
                    y: 20,
                },
                size: {
                    width: 440,
                    height: window.innerHeight * 0.8,
                },
                onDragStop: onDragStop,
                onResize: onResize,
            },
            userConfig: {
                dataAppId: 130870,
                datasetId: 1,
            },
        };

        let copilotInstance = null;
        const button = document.getElementById('trigger-ai');
        const copilotRoot = document.getElementById('copilot-root');

        button.addEventListener('click', toggleCopilot);

        function onDragStop(event, position) {
            copilotConfig.draggable.position = position;
        }

        function onResize(event, position, size) {
            copilotConfig.draggable.position = position;
            copilotConfig.draggable.size = size;
        }

        function launchCopilot() {
            if (typeof Copilot === 'undefined') {
                (function(fn) {
                    fn(launchCopilot);
                })(requestIdleCallback || setTimeout);
            } else {
                if (!copilotInstance) {
                    copilotInstance = new Copilot(copilotRoot, copilotConfig);
                    copilotRoot.style.display = 'block';
                    button.textContent = 'Deactivate AI Assistant';
                }
            }
        }

        function destroyCopilot() {
            if (copilotInstance) {
                copilotInstance.destroy();
                copilotInstance = null;
                copilotRoot.style.display = 'none';
                button.textContent = 'Activate AI Assistant';
            }
        }

        function toggleCopilot() {
            if (copilotInstance) {
                destroyCopilot();
            } else {
                launchCopilot();
            }
        }
    </script>
</body>
</html>
jsx
import React, { useState, useEffect } from 'react';

const CopilotComponent = () => {
  const [copilotInstance, setCopilotInstance] = useState(null);
  const [buttonLabel, setButtonLabel] = useState('Activate AI Assistant');

  const copilotConfig = {
    locale: 'en',
    draggable: {
      enable: true,
      minWidth: 440,
      minHeight: 440,
      position: {
        x: window.innerWidth - 480,
        y: 20,
      },
      size: {
        width: 440,
        height: window.innerHeight * 0.8,
      },
      onDragStop: onDragStop,
      onResize: onResize,
    },
    userConfig: {
      dataAppId: 130870,
      datasetId: 1,
    },
  };

  useEffect(() => {
    // Load SDK
    const script = document.createElement('script');
    script.src = 'https://develop.hengshi.org/assets/hengshi-copilot@5.3-SNAPSHOT.js';
    script.async = true;
    document.body.appendChild(script);

    return () => {
      document.body.removeChild(script); // Clean up loaded script
    };
  }, []);

  function onDragStop(event, position) {
    copilotConfig.draggable.position = position;
  }

  function onResize(event, position, size) {
    copilotConfig.draggable.position = position;
    copilotConfig.draggable.size = size;
  }

  const launchCopilot = () => {
    if (typeof Copilot === 'undefined') {
      (function(fn) {
        fn(launchCopilot);
      })(requestIdleCallback || setTimeout);
    } else {
      if (!copilotInstance) {
        const copilotRoot = document.getElementById('copilot-root');
        const instance = new Copilot(copilotRoot, copilotConfig);
        setCopilotInstance(instance);
        setButtonLabel('Deactivate AI Assistant');
      }
    }
  };

  const destroyCopilot = () => {
    if (copilotInstance) {
      copilotInstance.destroy();
      setCopilotInstance(null);
      setButtonLabel('Activate AI Assistant');
    }
  };

  const toggleCopilot = () => {
    if (copilotInstance) {
      destroyCopilot();
    } else {
      launchCopilot();
    }
  };

  return (
    <div>
      <button onClick={toggleCopilot}>{buttonLabel}</button>
      {copilotInstance && <div id="copilot-root"></div>}
    </div>
  );
};

export default CopilotComponent;
vue
<template>
  <div>
    <button @click="toggleCopilot">{{ buttonLabel }}</button>
    <div id="copilot-root" v-if="copilotInstance"></div>
  </div>
</template>

<script>
import { ref, onMounted, onBeforeUnmount } from 'vue';

export default {
  setup() {
    const copilotInstance = ref(null);
    const buttonLabel = ref('Activate AI Assistant');

    const copilotConfig = {
      locale: 'en',
      draggable: {
        enable: true,
        minWidth: 440,
        minHeight: 440,
        position: {
          x: window.innerWidth - 480,
          y: 20,
        },
        size: {
          width: 440,
          height: window.innerHeight * 0.8,
        },
        onDragStop: onDragStop,
        onResize: onResize,
      },
      userConfig: {
        dataAppId: 130870,
        datasetId: 1,
      },
    };

    function onDragStop(event, position) {
      copilotConfig.draggable.position = position;
    }

    function onResize(event, position, size) {
      copilotConfig.draggable.position = position;
      copilotConfig.draggable.size = size;
    }

    function launchCopilot() {
      if (typeof Copilot === 'undefined') {
        (function(fn) {
          fn(launchCopilot);
        })(requestIdleCallback || setTimeout);
      } else {
        if (!copilotInstance.value) {
          copilotInstance.value = new Copilot(document.getElementById('copilot-root'), copilotConfig);
          buttonLabel.value = 'Deactivate AI Assistant';
        }
      }
    }

    function destroyCopilot() {
      if (copilotInstance.value) {
        copilotInstance.value.destroy();
        copilotInstance.value = null;
        buttonLabel.value = 'Activate AI Assistant';
      }
    }

    function toggleCopilot() {
      if (copilotInstance.value) {
        destroyCopilot();
      } else {
        launchCopilot();
      }
    }

    return {
      copilotInstance,
      buttonLabel,
      toggleCopilot,
    };
  },
};
</script>

<style>
/* Add styles (if needed) */
</style>

Login Authentication

When integrating the SDK, you may need to perform login authentication. We offer two methods:

  1. SSO Single Sign-On: If your system is already integrated with the HENGSHI system, no additional login is required.
  2. JWT Authentication: Use the following code to perform login authentication with JWT:
js
fetch('https://develop.hengshi.org/api/auth/login-info?activeAuth=jwt-param&jwtParam=your JWT parameter')
  .then(response => {
    // Login successful, continue using the SDK
  })
  .catch(error => {
    // Login failed, handle the error
  });

Tip

Ensure that you have configured JWT in 'Settings->Organization Management->Authentication Method->JWT Request Parameters'.

Replace 'your JWT parameter' with the actual JWT parameter.

Integrating Copilot into Dashboards in the HENGSHI System

The method to invoke Copilot in the HENGSHI system is similar to the aforementioned HTML method.

First, load the Copilot SDK through code in the global JS file:

js
// 1. Keep copilot sdk in sync with the system's store data
window.__INITIAL_STATE__ = window._hs_store_.getState();
// 2. Introduce copilot sdk code
var script = document.createElement('script');
script.src = 'https://develop.hengshi.org/assets/hengshi-copilot@5.3-SNAPSHOT.js';
script.async = true;
script.onload = function() {
  // 3. Reset sdk base url
  window.__hs_sdk_base_url__ = undefined;
  // 4. Create sdk container
  var copilotRoot = document.createElement('div');
  copilotRoot.id = 'copilot-root';
  copilotRoot.style.width = '100%';
  copilotRoot.style.height = '100%';
  copilotRoot.style.position = 'fixed';
  copilotRoot.style.inset = '0';
  copilotRoot.style.zIndex = '9999';
  copilotRoot.style.pointerEvents = 'none';
  document.body.appendChild(copilotRoot);
  // 5. Assign to custom sandbox variable for use in custom js
  window.myJS = window.myJS || {};
  window.myJS.innerWidth = window.innerWidth;
  window.myJS.innerHeight = window.innerHeight;
  window.myJS.Copilot = Copilot;
  window.myJS.CopilotRoot = copilotRoot;
};
document.body.appendChild(script);

Then, you can use the Control Button in the dashboard to invoke Copilot by adding a click event in the button control settings to execute the corresponding JS code.

js
if (!myJS) {
  throw new Error('hengshi copilot sdk not loaded yet');
}
if (!myJS.copilotConfig) {
  var stylesheet = `html.hengshi-copilot-sdk, html.hengshi-copilot-sdk body {width:100% !important; height: 100% !important;}
    html.hengshi-copilot-sdk body.hst {background: transparent;}
    .react-draggable {pointer-events: all;}`;
  myJS.copilotConfig = {
    locale: 'zh-CN',
    stylesheet: stylesheet,
    closable: true, // Set dialog to be closable
    draggable: { // Set dialog dragging feature, can be set to false or not set if dragging is not needed
      enable: true,
      minWidth: 440,
      minHeight: 440,
      position: {
        x: myJS.innerWidth - 480,
        y: 20,
      },
      size: {
        width: 440,
        height: myJS.innerHeight * 0.8,
      },
      // Set to remember the dragged position and size
      onDragStop: onDragStop,
      onResize: onResize,
    },
    // Set dialog data source
    userConfig: {
      dataAppId: 354, // Data package id
      datasetId: 26, // Dataset id
    },
  };
}
function onDragStop(event, position) {
  myJS.copilotConfig.draggable.position = position;
}
function onResize(event, position, size) {
  myJS.copilotConfig.draggable.position = position;
  myJS.copilotConfig.draggable.size = size;
}
function launchCopilot() {
  if (typeof myJS.Copilot === 'undefined') {
    (function (fn) {
      fn(launchCopilot);
    })(requestIdleCallback || setTimeout);
  } else {
    myJS.copilot = new myJS.Copilot(myJS.CopilotRoot, myJS.copilotConfig);
  }
}
if (myJS.copilot) {
  myJS.copilot.destroy();
  myJS.copilot = null;
} else {
  launchCopilot();
}

Copilot Configuration Options

You can adjust the configuration options as needed:

ts
// Copilot Configuration Definition
interface ICopilotConfig {
  userConfig: {
    appId: number;
    chartId?: number;
    dataAppId: number;
    datasetId?: number;
  };
  closable?: boolean;
  draggable?: boolean | {
    enable: boolean;
    minWidth: number;
    minHeight: number;
    bounds: 'window' | 'parent';
    position: {
      x: number;
      y: number;
    };
    size: {
      width: number;
      height: number;
    };
  };
  locale?: string;
  stylesheet?: string;
  className?: string;
  style?: React.CSSProperties;
  bodyClassName?: string;
  bodyStyle?: React.CSSProperties;
  header?: string | React.ReactElement;
  systemMsg?: string;
  parser?: {
    selectText: string;
    onSelect: (chart: any) => void;
  };
  chartTheme?: string | Theme;
}
interface Theme {
  base?: string | number;
  background?: string;
  color?: string;
  fontSize?: number;
  fontFamily?: any;
  fontWeight?: string;
  textAlign?: string;
  borderColor?: string;
  borderWidth?: number;
  borderStyle?: string;
  borderRadius?: number;
  boxShadow?: string;
  chartBackground?: string;
  chartPadding?: number;
  schema?: string[];
  mapTheme?: string;
}

// Create Copilot Configuration Object
const copilotConfig: ICopilotConfig = {
  userConfig: {
    // Either appId and datasetId or chartId must be provided
    // Example: appId: 130870, datasetId: 1 // Data package id + Dataset id
    // or
    // appId: 130870, chartId: 1 // App id + Chart id
  },
  closable: true, // Optional, whether to display the close button, default is false
  draggable: {
    enable: false,
    minWidth: 400,
    minHeight: 400,
    bounds: 'window',
    position: {
      x: window.innerWidth - 480,
      y: 20,
    },
    size: {
      width: 440,
      height: window.innerHeight * 0.8,
    },
  },
  locale: 'zh-CN', // Optional, language setting, default is Simplified Chinese
  stylesheet: '', // Optional, custom CSS styles
  className: '', // Optional, custom class name
  style: {}, // Optional, custom styles
  bodyClassName: '', // Optional, class name for the dialog content container
  bodyStyle: {}, // Optional, styles for the dialog content container
  header: '', // Optional, additional content in the title
  systemMsg: 'Welcome to the Intelligent Analysis Assistant', // Optional, welcome message, default value
  parser: {
    selectText: 'Select Chart', // Button text
    onSelect: (chart) => {
      // Event triggered when the button is clicked, chart parameter needs to be defined according to the actual use case
      console.log('Chart selection event', chart);
    },
  },
  chartTheme: 'HAWAII_SEA', // Optional, chart theme, refer to Dashboard theme
};

Customizing AI Assistant Styles

If you want to customize the style of the AI assistant, you can achieve this with the following CSS code:

css
/* Example: Use CSS to batch customize skin styles */
*, ::before, ::after {
  --brand: #4CAF50; // This is the overall brand color of the system
}
/* Set the root element style of the AI assistant dialog */
.hengshi-copilot-sdk .hst-copilot {
  position: fixed;
  // z-index: 1; // Set as needed
  top: 10vh;
  right: 50px;
  width: 440px;
  height: 80vh;
  border-width: 1px;
}
/* Set the AI assistant title element style */
.hengshi-copilot-sdk .hst-copilot-header {
  color: #fff;
  background-color: darkslategray;
}
/* Set the AI assistant conversation area element style */
.hengshi-copilot-sdk .hst-copilot-conversations {
  border-color: #aaa;
  background-color: darkslategray;
  height: calc(100% - 50px);
}
/* Set the AI assistant message element style */
.hengshi-copilot-sdk .hst-copilot-msg,
/* Set the AI assistant message icon operation element style */
.hengshi-copilot-sdk .hst-copilot-msg > .hs-relative > *,
/* Set the AI assistant auxiliary information element style */
.hengshi-copilot-sdk .hst-copilot-mark {
  color: #fff;
}
.hengshi-copilot-sdk .hst-copilot-mark .hs-bg-\[color\:var\(--hs-bg-lighter\)\] {
  background-color: transparent;
}
/* Set the AI assistant message icon operation hover background style */
.hengshi-copilot-sdk .hover\:hs-bg-\[\#eee\]:hover {
  --tw-bg-opacity: .2;
}
/* Set the AI assistant AI message bubble element style */
.hengshi-copilot-sdk .hst-copilot-msg-bot .hst-copilot-msg-inner,
/* Set the AI assistant user message bubble element style */
.hengshi-copilot-sdk .hst-copilot-msg-user .hst-copilot-msg-inner {
  border-color: darkgray;
  background-color: darkgray;
}
/* Set the background color of the AI assistant recommended question bubble */
.hengshi-copilot-sdk .hst-copilot-msg-inner .hst-copilot-msg-inner {
  background-color: slategray !important;
}
/* Set the AI assistant input area element style */
.hengshi-copilot-sdk .hst-copilot-prompt {
  color: #fff;
  background-color: darkslategray;
}
/* Set the AI assistant input box element style */
.hengshi-copilot-sdk .hst-copilot-prompt textarea {
  color: #fff;
  border-color: darkgray !important;
}
.hengshi-copilot-sdk .hst-copilot-prompt .hs-from-\[\#f1f1f1\],
.hengshi-copilot-sdk .hst-copilot-prompt .hs-to-\[\#f1f1f1\] {
  --tw-gradient-to: darkslategray;
}

Pass the above CSS as a string in the stylesheet of the Copilot configuration:

ts
// Create Copilot configuration object
const copilotConfig: ICopilotConfig = {
  ...
  stylesheet: css, 
  ...
};

3. Integration via ReactJS SDK

The ReactJS SDK allows you to easily integrate visualization features into your existing chat application.

Quick Start

Installation and Introduction

Since the ReactJS SDK does not provide an npm package, please contact support@hengshi.com for inquiries.

Example Directory Structure:

plaintext
<Your Project>/
├── src/
|   ├── hengshi/   <-- For example, place the SDK here in your project source
│   ├── index.ejs
│   └── index.js
└── package.json

Example index.js:

jsx
import React from "react";
import { createRoot } from "react-dom/client";

import Completion from "./hengshi/ai";

function ReactApp() {
  const chat = {
    "meta": "refineQuestion,answer,chart,chartConfig",
    "conversationId": 226,
    "uid": "00747081-9cc3-4c7c-b3de-735244498fd6",
    "prompt": "Distribution of bug issues across modules",
    "answer": "Bug issues are distributed fairly evenly across modules, with the most having 4 bugs, and most other modules having 2-3 bugs.",
    "refineQuestion": "Please provide the distribution of bug issues across modules",
    "charts": [
      {
        "appId": 134683,
        "datasetId": 1,
        "options": {
          "axes": [
            {
              "op": "{{41}}.{title}",
              "uid": "uid1",
              "kind": "formula"
            },
            {
              "op": "count({{33}}.{issue_id})",
              "uid": "uid2",
              "kind": "formula"
            }
          ],
          "limit": 100
        }
      }
    ]
  };

  return <Completion {...chat} />;
}

const root = createRoot(document.getElementById("root"));
root.render(<ReactApp />);

Rendered as shown in the figure:

react-sdk-example

Shadow DOM Description

To avoid style conflicts, the component uses Shadow DOM for rendering, ensuring that the component's styles do not affect or are not affected by external applications.

SDK Directory Structure

plaintext
hengshi/
├── ai.css        # Stylesheet file
├── ai.js         # Main SDK entry
├── font/         # Font resources
│   ├── fontello.eot
│   ├── fontello.ttf
│   ├── fontello.woff
│   └── fontello.woff2
└── locales/      # Language packs
    ├── en-US.json
    ├── zh-CN.json

Component API Reference

As shown in the previous example, the Completion component accepts chat data as a parameter. This object is the data content of a HENGSHI conversation round and can be obtained through the GET /api/conversations/${conversationId}/chats/${uid} interface. The data structure is referenced in chat.

In addition to all the attributes of the chat object, the Completion component also accepts the following parameters:

ParameterTypeDescription
metaSTRINGAny combination of strings such as 'refineQuestion', 'answer', 'chart', 'chartSwitcher', 'chartConfig', separated by commas (','), can be used to customize the display content
disableEllipsisBOOLWhen true, the answer and data retrieval logic tags will not be collapsed or omitted
showWhenNoDataBOOLWhether to display the chart component when there is no data, default is false
chartThemeSTRINGDashboard theme ID, refer to Theme Colors
stylesheetsSTRING or STRING ARRAYStylesheet link or stylesheet content for custom styles
localeSTRINGMultilingual, default is 'zh-CN', supports 'zh-CN', 'en-US', 'zh-TW', 'ja-JP'
onChangeChartTypeFUNCTIONCallback function for chart type switching. After passing this parameter, an icon button for switching chart types will appear above the chart
parserOBJECTConfiguration options
parser.onSelectFUNCTIONAfter passing this parameter, a plus icon button will appear in the upper right corner of the chart, clicking the button will trigger this function
parser.selectedTextSTRINGThe string will be used as the Tooltip content of the plus icon button
onReadyFUNCTIONCallback function for initial rendering

Frequently Asked Questions

Q: Prompted as not logged in, how to resolve?

A: Refer to the Login Authentication section. You need to complete login authentication before the component renders.

Q: How to customize styles?

A: Since Shadow DOM is used, you need to modify styles by passing parameters through stylesheets. Stylesheets accept a string or an array of strings, and support both stylesheet links and stylesheet content, for example:

jsx
<Chart
  {...chat}
  stylesheets={[
    'https://cdn.example.com/custom.css',
    `.custom-class { color: red; }`,
  ]} />

4. API Integration

API integration can be done in two ways: frontend and backend. The frontend method directly calls the js API provided by the Copilot SDK, while the backend method uses the HTTP interface.

JS SDK API

1. Intervening via JS

The Copilot SDK provides a headless mode, which means you don't need a UI and can interact with the backend through HTTP interfaces by calling the JS API. This allows you to integrate the Copilot SDK into your existing front-end projects (such as your own AI assistant) by simply calling the JS API where needed.

Pass headless: true in CopilotConfig to enable headless mode. In this mode, the Copilot UI will not render on the page, and you can control Copilot's behavior by calling the JS API.

Similar to the loading method in UI mode, the copilot instance returned after new Copilot provides the following Copilot states, data, and functions:

js
{
  api: {...},
  // Copilot state
  isLoading: false,
  // Current conversation list, data format reference
  // https://api.hengshi.com/conversation.html#conversation
  conversations: [],
  setConversations: () => {},
  currentConversationId: null,
  setCurrentConversationId: () => {},
  runningChatUid: null,
  setRunningChatUid: () => {},
  setChat: (id, chatUid, chat) => {},
  // Fetch historical conversation list
  onFetchConversations: (offset = 0, limit = 10) => {},
  // Create conversation
  onCreateConversation: prompt => {},
  onFetchConversation: id => {},
  onClearConversations: () => {},
  onFetchPreviousConversations: () => {},
  // Create Q&A
  onCreateChat: body => {},
  onDeleteChat: (id, chatUid) => {},
  onFetchSuggestions: refresh => {},
  onFetchFavorites: () => {},
  onCancelChatFavorite: (id, chatUid) => {},
  // Render chart
  renderChart: (container, { id, chart, chartTheme }) => {},
}

2. Call HTTP API via JS

In the copilot example above, the api object provides methods to call all HTTP APIs, allowing you to interact with the backend, such as:

js
// 1. Create a conversation
const { body: { data: conversation }} = await copilot.api.requestCreateConversation({
  body: {
    title: 'This is the title of the conversation',
  },
}).value;
/**
conversation = {
  "id": 135,
  "title": "This is the title of the conversation",
  "createdBy": 268,
  "createdAt": "2024-09-14 15:47:23",
  "updatedBy": 268,
  "updatedAt": "2024-09-14 15:47:23"
}
*/
// 2. Create a Q&A
const { body: { data: chat }} = await copilot.api.requestCreateChat({
  id: conversation.id,
  body: {
    prompt: 'Which director has the highest-grossing films', // This is the user's question
    userConfig: { // Refer to the userConfig in the copilotConfig above
      dataAppId: 129150,
      datasetId: 1,
    }
  },
  qs: {
    sync: true, // Whether to execute synchronously
    timeout: 1000 * 60, // Timeout in milliseconds
  },
}).value;
/**
chat = {
    "conversationId": 135,
    "prompt": "Which director has the highest-grossing films",
    "answer": "Christopher Nolan has the highest-grossing films.",
    "model": "gpt-4o",
    "uid": "08ff93ca-1972-4916-b884-35fab6f91c64",
    "temperature": 0,
    "createdBy": 268,
    "createdAt": "2024-09-14 15:47:23",
    "updatedBy": 268,
    "updatedAt": "2024-09-14 15:47:23",
    "responseAt": "2024-09-14 15:47:30",
    "isDelete": false,
    "isContextEnd": false,
    "suggestQuestions": [],
    "statusList": [
        "PENDING",
        "ANALYZE_REQUEST",
        "HQL_SELECT_FIELDS",
        "HQL_SELECT_FUNCTIONS",
        "GENERATE_HQL_QUERY",
        "DOING_HQL_QUERY",
        "DOING_SUMMARY",
        "DOING_QUESTION_SUGGESTING",
        "DONE"
    ],
    "userConfig": {
        "datasetId": 1,
        "dataAppId": 129150
    },
    "autoConfig": {
        "agentType": "HQL_AGENT"
    },
    "isCurrent": true,
    "usage": [
        {
            "completion_tokens": 24,
            "prompt_tokens": 4063,
            "total_tokens": 4087
        },
        {
            "completion_tokens": 5,
            "prompt_tokens": 1424,
            "total_tokens": 1429
        },
        {
            "completion_tokens": 49,
            "prompt_tokens": 3906,
            "total_tokens": 3955
        },
        {
            "completion_tokens": 16,
            "prompt_tokens": 299,
            "total_tokens": 315
        }
    ],
    "chartCreatedAt": "2024-09-14 15:47:30",
    "refineQuestion": "Which director has the highest-grossing films",
    "favorite": false,
    "charts": [
        {
            "appId": 129150,
            "datasetId": 1,
            "options": {
                "axes": [
                    {
                        "op": "{{1}}.{director}",
                        "uid": "uid1",
                        "fieldName": "director",
                        "kind": "formula",
                        "datasetId": 1,
                        "labelOrigin": "director",
                        "label": "director",
                        "isAggregate": false,
                        "value": "{{coffe_产品表}}.{director}",
                        "dataset": 1,
                        "fieldType": "string"
                    },
                    {
                        "op": "max({{1}}.{votes})",
                        "uid": "uid2",
                        "fieldName": "votes",
                        "kind": "formula",
                        "datasetId": 1,
                        "labelOrigin": "votes",
                        "label": "votes",
                        "isAggregate": true,
                        "value": "max({{coffe_产品表}}.{votes})",
                        "dataset": 1,
                        "fieldType": "number"
                    }
                ],
                "name": "Bar",
                "limit": 1,
                "sort": [
                    {
                        "op": "uid2",
                        "kind": "reference",
                        "direction": "desc"
                    },
                    {
                        "op": "uid1",
                        "kind": "reference",
                        "direction": "asc"
                    }
                ]
            },
            "dataAppId": 129150,
            "datasetIds": [
                1
            ]
        }
    ]
}
*/

Backend HTTP API Integration

For backend HTTP API integration, please refer to the API documentation: Complete API Call Example from User Query to Data Retrieval

HENGSHI SENSE Platform User Manual