@rizal_ncc/agent-client 1.4.2 → 1.4.3

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