Keural Kit
An embed script that places Keural chat, Drive, and prompt screens inside your web service.
Keural Kit places Keural screens on your page with a single script. The screens are drawn inside a Shadow DOM, so they do not mix with your page's CSS. Kit is updated when the Keural web app is deployed. If an old screen still appears after deployment, clear the browser and CDN caches and check the build time with window.KeuralKit.__build.
Kit works with a Keural login session (cookies on the Keural API domain). userInfo is for display only, and user verification is done with the cookie session. To use Kit on your service's domain, coordinate domain registration and login integration (such as SSO) with your Keural contact before adoption.
Loading
Kit loads from the web address of the Keural environment you use. For keural.ai, it is https://keural.ai. For an on-premises or dedicated environment, use that environment's Keural web address. Before the script, set the server addresses that Kit will call in window.__KEURAL_ENV__. All three addresses must belong to the same environment. Get them from your Keural contact during adoption.
<script>
window.__KEURAL_ENV__ = {
NEXT_PUBLIC_API_BASE_URL: '<KEURAL_API_URL>',
NEXT_PUBLIC_FAST_API_BASE_URL: '<KEURAL_AGENT_URL>',
NEXT_PUBLIC_MODE: 'prd',
};
</script>
<script src="<KEURAL_WEB_URL>/plugin/kit/keural.js" async></script>| Value | Description |
|---|---|
<KEURAL_WEB_URL> | Keural web address. Example: https://keural.ai |
<KEURAL_API_URL> | Keural API server address. Example: https://api.keural.ai |
<KEURAL_AGENT_URL> | Keural agent server address |
NEXT_PUBLIC_MODE | prd for production, dev for development |
To use the same Kit on a second domain, set all three values NEXT_PUBLIC_ADDITIONAL_FRONTEND_URL, NEXT_PUBLIC_ADDITIONAL_API_BASE_URL, and NEXT_PUBLIC_ADDITIONAL_FAST_API_BASE_URL. If any one is missing, an error occurs. Each value is an https:// address without a path.
When the script loads, window.KeuralKit is created. In SPAs such as React, use a loader so that the script is loaded only once.
export function loadKeuralKit(src = '<KEURAL_WEB_URL>/plugin/kit/keural.js') {
if (window.KeuralKit) return Promise.resolve(window.KeuralKit);
return new Promise((resolve, reject) => {
const s = document.createElement('script');
s.src = src;
s.async = true;
s.onload = () => resolve(window.KeuralKit);
s.onerror = () => {
s.remove();
reject(new Error('Keural Kit failed to load'));
};
document.head.appendChild(s);
});
}Mount chat
const el = document.getElementById('keural-chat')!;
window.KeuralKit.mountChat(el, {
userInfo: { userId: user.id, name: user.name },
colorMode: 'light',
initialData: { message: "Summarize this quarter's revenue", room_name: 'Quarterly report' },
onSessionCreated: (roomId) => router.push(`/c/${roomId}`),
onError: () => router.push('/'),
});
// When leaving the screen
window.KeuralKit.unmount(el);- To open an existing conversation, put its conversation ID in
sessionId. initialDatais included only when opening a new conversation. If it is included when opening an existing conversation, the same message is sent again.- If
userInfo.userIdis missing, the user is treated as signed out. Mount the chat after the sign-in information is ready.
Methods
| Method | Description |
|---|---|
mountChat(el, options) | Chat screen |
mountDrivePage(el, options) | Drive screen. Receives the files to ask about through onAsk(files) |
mountPromptPage(el, options) | Prompt screen. Receives the selected prompts through onAsk(prompts) |
mountDriveDialog(el, options) / updateDriveDialog | Drive file picker dialog (open required, onClose, onSelect(files), initialSelected) |
mountPromptDialog(el, options) / updatePromptDialog | Prompt picker dialog (open required, onClose, onSelect, onDefaultSelect, selectDefaultPrompt, defaultPromptDismissed) |
unmount(el) | Removes the mounted screen |
The mount* and update* methods take colorMode and userInfo, and unmount(el) takes only the element. update* redraws the same element with new options. To open and close the window, change the open value and call update*. Calling mount* again on the same element reuses the existing screen.
mountChat options
| Option | Type | Description |
|---|---|---|
sessionId | string | Conversation ID to open. If omitted, a new conversation is started |
userInfo | { userId, name?, orgId?, orgName? } | User information. userId is required |
initialData | object | First message of a new conversation. See initialData below |
colorMode | 'light' | 'dark' | Theme. Default light |
initialEffort | 'fast' | 'balanced' | 'high' | 'xhigh' | 'max' | Initial level. Default fast |
initialWebSearch | boolean | Start with web search on. Default true |
initialDeepResearch | boolean | Start with Deep Research on |
hideHomeButton / hideNewChatButton | boolean | Hide header buttons |
hideModePopup | boolean | Hide the mode selection popup |
messageActions | { id, label, onClick(messageId) }[] | Add your own actions to the response menu |
headerLeftActions / headerRightActions | HeaderLeftAction[] | Add your own buttons to the header |
onHeaderLeftMount | (el: HTMLElement) => void | Receives the element when the left header area is drawn |
mobileMenuItems / mobileBottomActions | array | Add menu items or bottom buttons at mobile widths |
onMobileHomeButton | () => void | When the home button is pressed at a mobile width |
chatInputFooter | string | Notice text below the input box |
shareTooltip | string | Tooltip text for the share button |
onSessionCreated | (roomId) => void | When a new conversation is created |
onStreamDone | (roomId) => void | When a response finishes |
onSummaryDone | (roomId) => void | When the conversation title and summary are created |
onRoomInfo | (info) => void | When the conversation information changes |
onShare / onExport | (roomId) => void | When the share or export button is pressed |
onError | (error: Error) => void | When an error occurs |
initialData
| Field | Type | Description |
|---|---|---|
message | string | Required. First message |
files | FileType[] | Drive files to send together (the value received from onSelect of mountDriveDialog) |
prompts | object[] | Prompts to use together |
webSearch | boolean | Web search |
deepResearch | boolean | Deep Research |
effort | 'fast' | 'balanced' | 'high' | 'xhigh' | 'max' | Level |
model | { label, value } | Model that answers |
room_name | string | Conversation name. roomName, title, and name are also accepted. |
folder_id | string | null | Folder to save to |
hideModePopup | boolean | Hide the mode selection popup |
Screen language
Kit screens are displayed in Korean.
Settings and sign-in
- User settings are changed in the Keural web app or app, and the Kit screen follows those settings.
- Your service handles sign-in, and Kit receives only the signed-in user's information.