knowledge-platform-chat-widget
v0.1.0
Published
Embeddable AI chat widget for Angular and other web applications.
Downloads
20
Maintainers
Readme
Chat Widget Library
Production-oriented TypeScript library for embedding an AI chat assistant into an Angular website or any browser-based application.
Publish to npm
Before publishing, make sure the package name is available on npm and that you are logged in:
npm loginBuild and verify the package:
npm run clean
npm run check
npm run build
npm pack --dry-runPublish it publicly:
npm publish --access publicFor the next release:
npm version patch
npm publish --access publicUse patch for fixes, minor for new backward-compatible features, and major for breaking changes.
Project layout
src/- production TypeScript sourcedocs/implementation-plan.md- architecture and rollout noteslocal-test/mock-ai-server.js- local mock backendlocal-test/chat-widget.js- original quick prototypelocal-test/angular-usage-example.ts- Angular init example
Library API
Package usage:
import { createChatWidget } from "@knowledge-platform/chat-widget";
const widget = createChatWidget({
apiBaseUrl: "https://api.example.com",
endpoints: {
ask: "/knowledge_rag/ask",
history: "/knowledge_rag/get_chat_history",
deleteChat: "/knowledge_rag/delete_chat",
deleteLastQa: "/knowledge_rag/delete_last_qa_pair"
},
rag: {
chatId: "customer-portal-session-123",
knowledgeNames: ["employee-handbook", "policies"],
enableReferences: true
},
getAccessToken: async () => authService.getAccessToken(),
getUserContext: async () => ({
userId: currentUser.id,
displayName: currentUser.name
})
});Browser-global usage after loading the browser bundle:
<script src="https://your-cdn.example.com/browser.iife.js"></script>
<script>
window.ChatWidget.init({
apiBaseUrl: "https://api.example.com",
endpoints: {
ask: "/knowledge_rag/ask",
history: "/knowledge_rag/get_chat_history"
},
rag: {
chatId: "external-client-user-42",
knowledgeNames: ["client-kb-public", "client-kb-private"]
},
getAccessToken: async function () {
return window.appAccessToken;
},
getUserContext: async function () {
return {
userId: window.currentUser?.id,
displayName: window.currentUser?.name
};
}
});
</script>The browser bundle exposes:
window.ChatWidget.init(config)window.ChatWidget.createChatWidget(config)
init() returns a widget instance with methods like open(), close(), toggle(), destroy(), loadChats(), and loadHistory().
Angular integration
There are two supported ways to use this widget in Angular:
- load the browser bundle and call
window.ChatWidget.init(...) - install the npm package and import
createChatWidget(...)
Option 1: Script-based Angular integration
This is the closest match to your current setup.
1. Install or host the built bundle
After npm run build, use:
dist/browser.iife.js
Copy it into your Angular app assets folder, for example:
src/assets/chat-widget/browser.iife.js
2. Add the script in Angular
In angular.json, add the built file under architect > build > options > scripts:
[
"src/assets/chat-widget/browser.iife.js"
]Or add it directly in src/index.html:
<script src="assets/chat-widget/browser.iife.js"></script>3. Initialize it after login
Call it from a component or auth-ready service after the user session is available:
declare global {
interface Window {
ChatWidget?: {
init: (config: any) => any;
};
}
}
window.ChatWidget?.init({
apiBaseUrl: "http://192.168.0.126:8788",
endpoints: {
ask: "/my-chats/:chatId/messages",
history: "/my-chats/:chatId/messages",
listChats: "/my-chats",
createChat: "/my-chats",
updateChat: "/my-chats/:chatId",
deleteChat: "/my-chats/:chatId"
},
rag: {
knowledgeNames: ["sample-kb"],
loadHistoryOnOpen: true
},
getUserContext: async () => ({
userId: "demo-user-8",
email: "[email protected]"
})
});Important:
apiBaseUrlmust be your backend base URL, not the Angular frontend URL- if your backend runs on port
8788, usehttp://192.168.0.126:8788 - if authentication is required, also pass
getAccessToken
Example with token:
window.ChatWidget?.init({
apiBaseUrl: "http://192.168.0.126:8788",
endpoints: {
ask: "/my-chats/:chatId/messages",
history: "/my-chats/:chatId/messages",
listChats: "/my-chats",
createChat: "/my-chats",
updateChat: "/my-chats/:chatId",
deleteChat: "/my-chats/:chatId"
},
rag: {
knowledgeNames: ["sample-kb"],
loadHistoryOnOpen: true
},
getAccessToken: async () => localStorage.getItem("access_token"),
getUserContext: async () => ({
userId: "demo-user-8",
email: "[email protected]"
})
});Option 2: Install from npm in Angular
Install the package:
npm install @knowledge-platform/chat-widgetThen use it in Angular:
import { AfterViewInit, Component, OnDestroy } from "@angular/core";
import { createChatWidget } from "@knowledge-platform/chat-widget";
@Component({
selector: "app-root",
template: ""
})
export class AppComponent implements AfterViewInit, OnDestroy {
private widget?: ReturnType<typeof createChatWidget>;
ngAfterViewInit(): void {
this.widget = createChatWidget({
apiBaseUrl: "http://192.168.0.126:8788",
endpoints: {
ask: "/my-chats/:chatId/messages",
history: "/my-chats/:chatId/messages",
listChats: "/my-chats",
createChat: "/my-chats",
updateChat: "/my-chats/:chatId",
deleteChat: "/my-chats/:chatId"
},
rag: {
knowledgeNames: ["sample-kb"],
loadHistoryOnOpen: true
},
getUserContext: async () => ({
userId: "demo-user-8",
email: "[email protected]"
})
});
}
ngOnDestroy(): void {
this.widget?.destroy();
}
}Configuration reference
These are the main fields you should pass from Angular:
apiBaseUrl: backend base URL, for examplehttp://192.168.0.126:8788endpoints.ask: send-message endpointendpoints.history: fetch-history endpointendpoints.listChats: list sidebar chatsendpoints.createChat: create a new chatendpoints.updateChat: update chat metadata like pin stateendpoints.deleteChat: delete a chatrag.knowledgeNames: knowledge bases to queryrag.loadHistoryOnOpen: whether to load chat history automatically when openedgetAccessToken: function returning bearer tokengetUserContext: function returning user identity information
Example user context:
getUserContext: async () => ({
userId: "demo-user-8",
displayName: "Demo User",
email: "[email protected]",
roles: ["researcher"]
})Recommended Angular timing
Initialize the widget:
- after the user logs in
- after token/user information is available
- once per page/app shell, not on every route change
Destroy the widget when the hosting Angular component is destroyed if you are using the npm import approach.
Knowledge RAG integration
The widget is now aligned to the knowledge_rag endpoints:
POST /knowledge_rag/askGET /knowledge_rag/get_chat_history
Production guidance:
- pass the bearer token with
getAccessToken() - do not hardcode tokens into the shipped widget
- use a stable
rag.chatIdper user/session if you want conversation continuity - provide
rag.knowledgeNamesfrom the host application, not from the widget bundle - version your hosted script URL, for example:
/chat-widget/v1.0.0/browser.iife.js/chat-widget/latest/browser.iife.js
Backend adapter integration
When using the Postgres-backed adapter added in backend/, point the widget to the adapter endpoints instead of the raw RAG endpoints:
createChatWidget({
apiBaseUrl: "http://localhost:8788",
endpoints: {
ask: "/my-chats/:chatId/messages",
history: "/my-chats/:chatId/messages",
listChats: "/my-chats",
createChat: "/my-chats",
updateChat: "/my-chats/:chatId"
},
rag: {
knowledgeNames: ["sample-kb"],
loadHistoryOnOpen: false
},
getAccessToken: async () => authService.getAccessToken(),
getUserContext: async () => ({
userId: "demo-user-1",
displayName: "Demo User",
email: "[email protected]",
roles: ["researcher"]
})
});The widget forwards getUserContext() to the adapter in the X-Chat-User-Context header. In your dummy site you can hardcode that object for testing; in the real client integration they should populate it from their logged-in user/session data.
In the hybrid adapter flow, Postgres stores chat sidebar metadata only. Full message history and chat deletion are proxied to the AI backend.
Build outputs
The library is configured to build:
esmfor app importscjsfor Node/CommonJS consumersiifefor script injection into an already deployed website
Build tooling:
npm install
npm run buildOutput will be generated in dist/.
Local test flow
1. Start the mock backend
node local-test/mock-ai-server.js2. Build the browser bundle
npm install
npm run build3. Inject the built script into an Angular dummy app
Copy the built browser file from dist/ into Angular src/assets/, then add:
<script src="/assets/browser.iife.js"></script>4. Initialize after authentication
window.ChatWidget?.init({
apiBaseUrl: "http://localhost:8787",
endpoints: {
ask: "/knowledge_rag/ask",
history: "/knowledge_rag/get_chat_history"
},
rag: {
chatId: "angular-local-test-user-123",
knowledgeNames: ["sample-kb"]
},
getAccessToken: async () => "dummy-sso-token",
getUserContext: async () => ({
userId: "u-1001",
displayName: "Angular Test User"
})
});Production integration guidance
For the live Angular site:
- host the built
iifebundle on your CDN or app server - load it only after the user is authenticated
- pass access token and user context from the host Angular app
- keep RBAC validation in the AI backend
Do not embed a separate login flow inside the widget.
Chat persistence adapter
This repo now also includes a starter backend adapter in backend/ for storing chat metadata in Postgres and wrapping the existing RAG APIs.
Setup guide:
