Skip to content

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 navigate 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, such as:

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

ATTENTION

@5.3 is the SDK version number, please ensure that the SDK version you use is consistent with the system version. The system upgrade also requires updating.

Integrating Copilot SDK in Other Systems

We provide sample code for integrating the Copilot SDK into front-end frameworks such as Vue, React, and plain JavaScript. You can choose based on your needs. This requires a certain level of 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">Launch AI Assistant</button>
    <div id="copilot-root" style="display: none;"></div>

    <script>
        const copilotConfig = {
            locale: 'en-US',
            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 = 'Close AI Assistant';
                }
            }
        }

        function destroyCopilot() {
            if (copilotInstance) {
                copilotInstance.destroy();
                copilotInstance = null;
                copilotRoot.style.display = 'none';
                button.textContent = 'Launch 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('Launch AI Assistant');

  const copilotConfig = {
    locale: 'en-US',
    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('Close AI Assistant');
      }
    }
  };

  const destroyCopilot = () => {
    if (copilotInstance) {
      copilotInstance.destroy();
      setCopilotInstance(null);
      setButtonLabel('Launch 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('Launch AI Assistant');

    const copilotConfig = {
      locale: 'en-US',
      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 = 'Close AI Assistant';
        }
      }
    }

    function destroyCopilot() {
      if (copilotInstance.value) {
        copilotInstance.value.destroy();
        copilotInstance.value = null;
        buttonLabel.value = 'Launch 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 provide 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, proceed with using the SDK
  })
  .catch(error => {
    // Login failed, handle the error
  });

Tip

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

Replace 'Your JWT Parameter' with the actual JWT parameter.

Integrating Copilot into Dashboards in the HENGSHI System

The method of invoking 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 the copilot sdk in sync with the system's store data
window.__INITIAL_STATE__ = window._hs_store_.getState();
// 2. Import the 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 the sdk base url
  window.__hs_sdk_base_url__ = undefined;
  // 4. Create the 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 a 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);

Next, you can use a Control Button in the dashboard to trigger Copilot. Add 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 the dialog to be closable
    draggable: { // Enable dialog dragging functionality; set to false or omit if not needed
      enable: true,
      minWidth: 440,
      minHeight: 440,
      position: {
        x: myJS.innerWidth - 480,
        y: 20,
      },
      size: {
        width: 440,
        height: myJS.innerHeight * 0.8,
      },
      // Remember the dragged position and size
      onDragStop: onDragStop,
      onResize: onResize,
    },
    // Set the data source for the dialog
    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 App 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, the chart parameter needs to be defined based on the actual use case
      console.log('Chart selection event', chart);
    },
  },
  chartTheme: 'HAWAII_SEA', // Optional, chart theme, refer to dashboard themes
};

Customizing AI Assistant Styles

If you want to customize the style of the AI assistant, you can achieve this using 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 box */
.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 style of the AI assistant title element */
.hengshi-copilot-sdk .hst-copilot-header {
  color: #fff;
  background-color: darkslategray;
}
/* Set the style of the AI assistant conversation area element */
.hengshi-copilot-sdk .hst-copilot-conversations {
  border-color: #aaa;
  background-color: darkslategray;
  height: calc(100% - 50px);
}
/* Set the style of the AI assistant message element */
.hengshi-copilot-sdk .hst-copilot-msg,
/* Set the style of the icon operation element below the AI assistant message */
.hengshi-copilot-sdk .hst-copilot-msg > .hs-relative > *,
/* Set the style of the AI assistant auxiliary information element */
.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 background style of the icon operation element below the AI assistant message when hovered */
.hengshi-copilot-sdk .hover\:hs-bg-\[\#eee\]:hover {
  --tw-bg-opacity: .2;
}
/* Set the style of the AI assistant bot message bubble element */
.hengshi-copilot-sdk .hst-copilot-msg-bot .hst-copilot-msg-inner,
/* Set the style of the user message bubble element */
.hengshi-copilot-sdk .hst-copilot-msg-user .hst-copilot-msg-inner {
  border-color: darkgray;
  background-color: darkgray;
}
/* Set the background color of the recommended question bubbles in the AI assistant */
.hengshi-copilot-sdk .hst-copilot-msg-inner .hst-copilot-msg-inner {
  background-color: slategray !important;
}
/* Set the style of the input content area element of the AI assistant */
.hengshi-copilot-sdk .hst-copilot-prompt {
  color: #fff;
  background-color: darkslategray;
}
/* Set the style of the input box element of the AI assistant */
.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 property of the Copilot configuration:

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

User Manual for Hengshi Analysis Platform