@rizal_ncc/agent-client 1.4.2 → 1.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +226 -50
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,8 +1,25 @@
1
- # @rizal_ncc/agent-client
1
+ [![Node.js Package](https://github.com/rizalNCC/agent-client/actions/workflows/npm-publish.yml/badge.svg)](https://github.com/rizalNCC/agent-client/actions/workflows/npm-publish.yml)
2
2
 
3
- Frontend UI wrapper + typed helpers for `nems/ai_agent`.
3
+ # Agen Client
4
4
 
5
- `backend-documentation.md` is the source-of-truth contract for backend payload and `tool_results` schema.
5
+ A component (for now support react and vanilla) and headless core for AI agent chat interfaces, designed for seamless integration with a compatible backend API. Provides built-in transport logic, flexible layouts, and tool result handling, while allowing full customization through props and custom transport functions.
6
+
7
+ ## Table of Contents
8
+
9
+ - [Install](#install)
10
+ - [Quick Start (React)](#quick-start-react)
11
+ - [Layouts](#layouts)
12
+ - [AiAgentChat Props](#aiagentchat-props)
13
+ - [Built-in Transport Contract](#built-in-transport-contract)
14
+ - [Headless Core Usage](#headless-core-usage)
15
+ - [Tool Result Helpers](#tool-result-helpers)
16
+ - [Theme and Styling](#theme-and-styling)
17
+ - [Architecture](#architecture)
18
+ - [Testing](#testing)
19
+ - [Development](#development)
20
+ - [Release and Publish](#release-and-publish)
21
+ - [File Map](#file-map)
22
+ - [Known Tradeoffs](#known-tradeoffs)
6
23
 
7
24
  ## Install
8
25
 
@@ -10,7 +27,7 @@ Frontend UI wrapper + typed helpers for `nems/ai_agent`.
10
27
  npm install @rizal_ncc/agent-client
11
28
  ```
12
29
 
13
- ## React Usage
30
+ ## Quick Start (React)
14
31
 
15
32
  ```tsx
16
33
  import { AiAgentChat } from "@rizal_ncc/agent-client/react";
@@ -20,7 +37,7 @@ export function App() {
20
37
  return (
21
38
  <AiAgentChat
22
39
  baseURL="https://example.com/api"
23
- accessToken="your-access-token-here"
40
+ accessToken="your-access-token"
24
41
  agent="home-assistant"
25
42
  primaryColor="#0f766e"
26
43
  primaryForeground="#ffffff"
@@ -33,60 +50,102 @@ export function App() {
33
50
  }
34
51
  ```
35
52
 
36
- Layout examples:
53
+ ## Layouts
54
+
55
+ The component supports three layouts:
56
+
57
+ - `inline`: always open in page flow.
58
+ - `floating`: fixed toggle button + popover panel.
59
+ - `dropdown`: inline toggle bar + expandable panel.
60
+
61
+ Examples:
37
62
 
38
63
  ```tsx
64
+ <AiAgentChat layout="inline" />
39
65
  <AiAgentChat layout="floating" defaultOpen={false} />
40
66
  <AiAgentChat layout="dropdown" defaultOpen={false} panelHeight="560px" />
41
67
  ```
42
68
 
43
- ## Chat Component Props (AiAgentChat)
69
+ Open state control:
70
+
71
+ - Controlled: pass `open` + `onOpenChange`.
72
+ - Uncontrolled: pass `defaultOpen`.
44
73
 
45
- Common props:
74
+ ## AiAgentChat Props
46
75
 
47
- - `baseURL: string` backend base URL
48
- - `accessToken: string | () => string | Promise<string>` bearer token provider
76
+ ### Core
77
+
78
+ - `baseURL?: string` backend base URL (required for built-in transport)
79
+ - `accessToken?: string | () => string | undefined | Promise<string | undefined>` bearer token provider (required for built-in transport)
49
80
  - `agent?: string` default `home-assistant`
50
- - `suggestedMessages?: string[]` clickable prompt chips
51
- - `headerTitle?: string`
52
- - `headerDescription?: string`
53
- - `assistantAvatar?: ReactNode` custom avatar component slot
54
- - `assistantAvatarUrl?: string` avatar URL override (default `/ai-img.svg`)
55
- - `initials?: boolean` show/hide assistant and user initials (default `true`)
56
- - `primaryColor?: string` theme color (default `#1168bb`)
57
- - `primaryForeground?: string` text color on primary surfaces (default `#ffffff`)
58
81
  - `metadata?: { course_id?: number }`
59
82
  - `requestHeaders?: HeadersInit`
60
- - `layout?: "inline" | "floating" | "dropdown"` (default `inline`)
61
- - `open?: boolean` controlled open state for `floating`/`dropdown`
62
- - `defaultOpen?: boolean` uncontrolled initial open state
83
+ - `respondPath?: string` endpoint override
84
+ - `generateResponse?: (request) => Promise<{ content: string }>` custom transport override
85
+
86
+ ### UI
87
+
88
+ - `headerTitle?: string`
89
+ - `headerDescription?: string`
90
+ - `suggestedMessages?: string[]`
91
+ - `assistantAvatar?: ReactNode`
92
+ - `assistantAvatarUrl?: string` default `/ai-img.svg`
93
+ - `assistantInitials?: string` default `AI`
94
+ - `userInitials?: string` default `YOU`
95
+ - `initials?: boolean` default `true`
96
+ - `placeholder?: string` default `Ask the assistant...`
97
+ - `sendLabel?: string` default `Send`
98
+ - `stopLabel?: string` default `Stop`
99
+ - `className?: string`
100
+
101
+ ### Theme
102
+
103
+ - `primaryColor?: string` default `#1168bb`
104
+ - `primaryForeground?: string` default `#ffffff`
105
+ - `panelHeight?: string` optional CSS height override (uses CSS variable fallback if omitted)
106
+ - `zIndex?: number` default `60`
107
+
108
+ ### Layout control
109
+
110
+ - `layout?: "inline" | "floating" | "dropdown"` default `inline`
111
+ - `open?: boolean`
112
+ - `defaultOpen?: boolean`
63
113
  - `onOpenChange?: (open: boolean) => void`
64
- - `panelHeight?: string` panel height (default `"620px"`)
65
- - `floatingPosition?: "bottom-right" | "bottom-left"` (default `bottom-right`)
66
- - `zIndex?: number` (default `60`)
114
+ - `floatingPosition?: "bottom-right" | "bottom-left"` default `bottom-right`
115
+ - `openLabel?: string` default `Open chat`
116
+ - `closeLabel?: string` default `Close chat`
67
117
 
68
- UX behavior:
118
+ ### Events
69
119
 
70
- - Composer uses one combined icon action button:
71
- - idle state: send icon
72
- - loading state: stop icon
120
+ - `onMessage?: (message, messages) => void`
121
+ - `onError?: (error, messages) => void`
73
122
 
74
- Advanced:
123
+ ## Built-in Transport Contract
75
124
 
76
- - `generateResponse?: (request) => Promise<{ content: string }>` custom transport override
77
- - `respondPath?: string` manual endpoint override
78
- - `onMessage?`, `onError?`
125
+ If `generateResponse` is not provided, `AiAgentChat` performs backend requests.
126
+
127
+ Path resolution:
79
128
 
80
- Path behavior (built-in transport):
129
+ - if `baseURL` ends with `/api` -> `POST /v2/ai-agent/respond/`
130
+ - otherwise -> `POST /api/v2/ai-agent/respond/`
81
131
 
82
- - If `baseURL` ends with `/api` -> uses `/v2/ai-agent/respond/`
83
- - Otherwise -> uses `/api/v2/ai-agent/respond/`
132
+ Request body:
84
133
 
85
- Recommendation UI behavior:
134
+ - `agent`
135
+ - `message` (latest user message)
136
+ - `metadata`
86
137
 
87
- - `get_course_recommendation` results are rendered as a horizontal carousel card list.
88
- - If backend returns `next` in recommendation output, a `Load more` button appears below the carousel.
89
- - Clicking `Load more` fetches the `next` URL automatically (with current bearer token) and appends deduplicated results.
138
+ Expected response shape (minimum):
139
+
140
+ - `message: string`
141
+ - `tool_results?: ToolResult[]`
142
+
143
+ Recommendation behavior:
144
+
145
+ - Renders `get_course_recommendation` results as horizontal cards.
146
+ - Uses `next` for pagination when available.
147
+ - `Load more` appends validated incoming items.
148
+ - Duplicate items are currently allowed by design.
90
149
 
91
150
  ## Headless Core Usage
92
151
 
@@ -101,26 +160,87 @@ await bot.sendMessage("Hi");
101
160
  console.log(bot.getState().messages);
102
161
  ```
103
162
 
104
- ## Backend Tool Helpers
163
+ `ChatbotCore` notes:
164
+
165
+ - Ignores empty messages.
166
+ - Aborts previous in-flight request on new send.
167
+ - Throws if `generateResponse` returns empty `content`.
168
+ - Exposes `stop()` for manual cancellation.
105
169
 
106
- Helpers for backend `tool_results`:
170
+ ## Tool Result Helpers
171
+
172
+ Helpers exported from core entry:
107
173
 
108
174
  - `getToolResultsByName(response, toolName)`
175
+ - `getToolErrors(response)`
176
+ - `extractCourseDetail(response)`
109
177
  - `extractRecommendationOutput(response)`
110
178
  - `extractRecommendationItems(response)`
111
- - `extractCourseDetail(response)`
112
- - `getToolErrors(response)`
113
179
 
114
- Tool names follow backend contracts:
180
+ Known backend tool names:
115
181
 
116
182
  - `get_course_recommendation`
117
183
  - `get_course_detail`
118
184
 
119
- ## Exports
185
+ ## Theme and Styling
186
+
187
+ Import styles once:
188
+
189
+ ```tsx
190
+ import "@rizal_ncc/agent-client/style.css";
191
+ ```
192
+
193
+ Runtime CSS variables used by component shell:
194
+
195
+ - `--chat-primary`
196
+ - `--chat-primary-rgb`
197
+ - `--chat-primary-foreground`
198
+ - `--chat-panel-height`
199
+ - `--chat-shell-z-index`
120
200
 
121
- - Core: `@rizal_ncc/agent-client`
122
- - React adapter: `@rizal_ncc/agent-client/react`
123
- - Styles: `@rizal_ncc/agent-client/style.css`
201
+ Important:
202
+
203
+ - Do not redeclare `--chat-primary*` inside `.ai-agent-chat` if you want prop colors to apply.
204
+
205
+ ## Architecture
206
+
207
+ Primary layers:
208
+
209
+ 1. `ChatbotCore` state engine (`src/core/chatbot.ts`)
210
+ 2. React adapter + transport + layout shell (`src/adapters/react.tsx`)
211
+ 3. Tool parsing and pagination helpers (`src/lib/tool-results.ts`, `src/lib/recommendation-pagination.ts`)
212
+ 4. UI styles and layout animations (`src/style.css`)
213
+
214
+ Message lifecycle:
215
+
216
+ 1. User input -> user message append (`isLoading = true`)
217
+ 2. Transport call (custom or built-in)
218
+ 3. Assistant message normalize + append
219
+ 4. Optional recommendation pagination update
220
+ 5. `isLoading = false`
221
+
222
+ ## Testing
223
+
224
+ Stack:
225
+
226
+ - Vitest
227
+ - React Testing Library
228
+ - jsdom
229
+
230
+ Current coverage includes:
231
+
232
+ - core behavior/error flow
233
+ - tool helper parsing
234
+ - recommendation merge behavior
235
+ - dropdown/floating open state
236
+ - typing/stop/error UI states
237
+ - load-more append flow
238
+
239
+ Run tests:
240
+
241
+ ```bash
242
+ npm test
243
+ ```
124
244
 
125
245
  ## Development
126
246
 
@@ -131,12 +251,68 @@ npm test
131
251
  npm run build
132
252
  ```
133
253
 
134
- `npm run dev` starts the root-level Vite playground (`index.html` + `demo/*`).
254
+ `npm run dev` starts Vite playground (`index.html` + `demo/*`).
135
255
 
136
- Demo env:
256
+ Demo env (`.env`):
137
257
 
138
258
  ```bash
139
259
  VITE_API_BASE_URL=http://example.com/
140
260
  VITE_AI_AGENT_TOKEN=<access_token>
141
261
  VITE_AI_AGENT_AGENT=home-assistant
142
262
  ```
263
+
264
+ ## Release and Publish
265
+
266
+ Pre-release validation:
267
+
268
+ ```bash
269
+ npm run release:check
270
+ ```
271
+
272
+ Manual publish:
273
+
274
+ ```bash
275
+ npm publish --access public
276
+ ```
277
+
278
+ Automated publish (GitHub Actions):
279
+
280
+ - Workflow: `.github/workflows/npm-publish.yml`
281
+ - Trigger: push tag matching `v*.*.*`
282
+ - Required secret: `NPM_TOKEN` (npm automation token)
283
+
284
+ Tag-based release flow:
285
+
286
+ ```bash
287
+ npm version patch
288
+ git push --follow-tags
289
+ ```
290
+
291
+ Use `minor` or `major` instead of `patch` when needed.
292
+
293
+ ## File Map
294
+
295
+ - Core
296
+ - `src/core/chatbot.ts`
297
+ - `src/core/types.ts`
298
+ - `src/core/errors.ts`
299
+ - React
300
+ - `src/adapters/react.tsx`
301
+ - `src/react.ts`
302
+ - Helpers
303
+ - `src/lib/tool-results.ts`
304
+ - `src/lib/recommendation-pagination.ts`
305
+ - Styles
306
+ - `src/style.css`
307
+ - Tests
308
+ - `tests/chatbot-core.test.ts`
309
+ - `tests/tool-results.test.ts`
310
+ - `tests/recommendation-pagination.test.ts`
311
+ - `tests/ai-agent-chat-ui.test.tsx`
312
+
313
+ ## Known Tradeoffs
314
+
315
+ 1. Recommendation dedupe is intentionally disabled.
316
+ 2. Built-in transport assumes JSON response (`response.json()`).
317
+ 3. Some layout behavior depends on CSS class contracts.
318
+ 4. Token refresh strategy is caller-managed when using function token provider.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rizal_ncc/agent-client",
3
- "version": "1.4.2",
3
+ "version": "1.4.4",
4
4
  "description": "UI wrapper and helpers for BAWANA AI agent integrations",
5
5
  "author": "Rizal Suryawan - (BAWANA Team)",
6
6
  "license": "MIT",