esoft-ai-widgets-nexus
v1.0.9
Published
Vue 3 AI Chat Widget components for internal Esoft applications
Readme
esoft-ai-widgets-nexus
A Vue 3 plugin containing two AI chat components (NexusAiChat and NexusAiWidget) for internal Esoft / Softech applications, powered by the Nexus AI backend.
Prerequisites
| Peer Dependency | Version |
| --------------- | --------- |
| vue | ^3.0.0 |
| vue-router | ^4.0.0 |
| axios | ^1.0.0 |
| moment | ^2.29.0 |
Installation
# From npm / internal registry
npm install esoft-ai-widgets-nexus
---
## Setup & Initialization
Register the plugin once in your app entry point (`main.ts` / `main.js`):
```typescript
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import NexusAiPlugin from "esoft-ai-widgets-nexus";
import "esoft-ai-widgets-nexus/style.css"; // Required — include the widget styles
const app = createApp(App);
app.use(router);
app.use(NexusAiPlugin, {
apiBaseUrl: "https://api.your-domain.com", // Required
chatBaseUrl: "https://chat.your-domain.com", // Required
apiKey: "your-server-api-key", // Required — X-Api-Key header
clientToken: "your-jwt-token", // Required — X-Client-Token / Bearer
theme: {
primary: "#f97316", // Optional — accent color
primaryActive: "#ea580c", // Optional — darker shade for hover/active
},
});
app.mount("#app");Plugin Options (NexusAiOptions)
| Property | Type | Required | Description |
| ------------- | -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| apiBaseUrl | string | ✅ Yes | AI Agents API Base URL for /memory/sessions and /memory/history endpoints |
| chatBaseUrl | string | ✅ Yes | AI Agents API Base URL for the chat completion endpoint |
| apiKey | string | ✅ Yes | AI Agents Server API key — sent as X-Api-Key header |
| clientToken | string | ✅ Yes | JWT token used for authenticating your application APIs when invoked via AI Agent HTTP tools. Sent in the X-Client-Token request header. |
| theme | NexusAiTheme | ❌ No | Optional theme overrides (see below) |
Theme Options (NexusAiTheme)
| Property | Type | Default | Description |
| --------------- | -------- | --------- | --------------------------------------------- |
| primary | string | #f97316 | Primary accent color (buttons, active states) |
| primaryActive | string | #ea580c | Darker shade used on hover / active |
| bg | string | #ffffff | Background override |
| text | string | #1e293b | Text color override |
| border | string | #e8ecf1 | Border color override |
Note:
darkModeis no longer set at the plugin level. Use thedarkModeprop on each component for fully reactive dark/light switching (see below).
Components
Both components are globally registered by the plugin. No individual imports needed.
<NexusAiChat>
A full-page chat interface with a sidebar (conversation history) and a main message view.
<template>
<NexusAiChat :darkMode="isDark" />
</template>Props
| Prop | Type | Default | Description |
| ---------- | ----------------- | ------- | ----------------------------------------------------------------------------------------- |
| darkMode | boolean \| null | null | true = dark theme, false = light theme. null (omitted) = use plugin install default |
Routing Setup
Typically rendered on a dedicated route (e.g. /nexus-ai):
// router/index.ts
{
path: '/nexus-ai',
name: 'NexusAi',
component: () => import('@/views/nexus-ai/NexusAiPage.vue'),
}<NexusAiWidget>
A floating chat bubble (fixed bottom-right). Clicking "Expand" navigates to /nexus-ai via vue-router (falls back to window.location.href if router is not available).
<template>
<div>
<main><!-- your app --></main>
<NexusAiWidget :darkMode="isDark" />
</div>
</template>Props
| Prop | Type | Default | Description |
| ---------- | ----------------- | ------- | ----------------------------------------------------------------------------------------- |
| darkMode | boolean \| null | null | true = dark theme, false = light theme. null (omitted) = use plugin install default |
Dark Mode — Reactive Binding
The darkMode prop is fully reactive. Bind it to any computed or store getter and the widget updates instantly when the theme changes — no page refresh needed.
Example: Vuex (Keenthemes / Nucleus Frontend)
<script lang="ts">
import { defineComponent, computed } from "vue";
import { useStore } from "vuex";
export default defineComponent({
setup() {
const store = useStore();
// ThemeModeModule exposes an `isDarkMode` getter
const isDark = computed<boolean>(() => store.getters.isDarkMode);
return { isDark };
},
});
</script>
<template>
<NexusAiChat :darkMode="isDark" />
<NexusAiWidget :darkMode="isDark" />
</template>Example: Pinia
<script setup>
import { computed } from "vue";
import { useThemeStore } from "@/stores/theme";
const theme = useThemeStore();
const isDark = computed(() => theme.mode === "dark");
</script>
<template>
<NexusAiChat :darkMode="isDark" />
</template>Example: data-theme attribute (no store)
<script setup>
import { ref, onMounted } from "vue";
const isDark = ref(
document.documentElement.getAttribute("data-theme") === "dark",
);
// Watch for attribute changes (e.g. Keenthemes layout engine)
const observer = new MutationObserver(() => {
isDark.value = document.documentElement.getAttribute("data-theme") === "dark";
});
onMounted(() => {
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ["data-theme"],
});
});
</script>
<template>
<NexusAiChat :darkMode="isDark" />
</template>Styling
The package ships a self-contained CSS bundle. Import it once in your app entry:
import "esoft-ai-widgets-nexus/style.css";All widget styles are scoped under .nexus-ai-root so they do not leak into your application. Host app styles (Bootstrap, Tailwind, etc.) are prevented from interfering via high-specificity overrides.
Custom Colors
Pass a custom theme object when installing the plugin:
app.use(NexusAiPlugin, {
// ... required options
theme: {
primary: "#40c431", // green accent
primaryActive: "#34a828",
},
});Backend Integration
To use these components, your backend must implement the following endpoints. The components expect a RESTful API structure with JSON payloads.
Required Headers
All requests from the components include these headers:
X-Api-Key: The server API key provided during plugin initialization.X-Client-Token: The JWT/client token provided during plugin initialization.Authorization:Bearer <clientToken>(sent automatically ifclientTokenis provided).
Session Management
1. List Sessions
Retrieve a list of all chat sessions for the authenticated user.
- Endpoint:
GET /memory/sessions - Response Shape:
{
"data": [
{
"sessionId": "uuid-string",
"title": "Conversation Title",
"lastMessageAt": "2024-03-07T10:00:00Z",
"createdAt": "2024-03-07T09:00:00Z"
}
]
}2. Create Session
Initialize a new chat session.
- Endpoint:
POST /memory/sessions - Payload:
{ "agentId": number }(Optional) - Response Shape:
{
"data": {
"sessionId": "uuid-string",
"title": "New Conversation",
"createdAt": "2024-03-07T10:00:00Z"
}
}3. Rename Session
Update the title of an existing session.
- Endpoint:
PATCH /memory/sessions/:id - Payload:
{ "title": "New Title" } - Response Shape:
{ "success": true }
4. Delete Session
Delete a session and its message history.
- Endpoint:
DELETE /memory/sessions/:id - Response Shape:
{ "success": true }
Messaging
1. Fetch Chat History
Fetch all messages within a specific session, ordered chronologically.
- Endpoint:
GET /memory/history?sessionId=<uuid> - Response Shape:
{
"data": [
{
"role": "user",
"content": "Hello AI",
"created_at": "2024-03-07T10:01:00Z"
},
{
"role": "ai",
"content": "Hello! How can I help you?",
"created_at": "2024-03-07T10:01:05Z"
}
]
}2. Send Message
Send a user prompt to the AI and receive a response.
- Endpoint:
POST /chat/:sessionId - Payload:
{ "prompt": "User message text" } - Response Shape:
{
"data": {
"sessionId": "uuid-string",
"response": "AI generated response text"
}
}Changelog
| Version | Notes |
| ------- | ----------------------------------------------------------------------- |
| 1.0.8 | Backend integration documentation added |
| 1.0.7 | Style import path corrected |
| 1.0.6 | darkMode moved to reactive component prop; Boolean coercion bug fixed |
| 1.0.5 | darkMode prop introduced on NexusAiChat and NexusAiWidget |
| 1.0.4 | Explicit dark mode CSS overrides added (!important guards) |
| 1.0.3 | Dark mode CSS custom property system |
| 1.0.0 | Initial release |
