@jivaai/agent-chat-typescript 0.1.0 → 0.1.1
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.
- package/README.md +873 -793
- package/dist/api.d.ts +11 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +66 -1
- package/dist/api.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,793 +1,873 @@
|
|
|
1
|
-
# Jiva.ai Agent Chat - TypeScript SDK
|
|
2
|
-
|
|
3
|
-
A comprehensive TypeScript SDK for integrating with Jiva.ai's agentic workflows. This library provides a simple, type-safe interface for building conversational AI applications powered by Jiva.ai's agentic workflow engine.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- 🤖 **Full Agentic Workflow Integration** - Seamlessly interact with Jiva.ai's agentic workflows
|
|
8
|
-
- 💬 **Conversational Interface** - Support for multi-turn conversations with context
|
|
9
|
-
- 📤 **Asset Upload Support** - Upload files, text, and tables to satisfy agent requirements
|
|
10
|
-
- 🔄 **Automatic Polling** - Handles async workflow execution with automatic polling
|
|
11
|
-
- 📡 **Real-Time Updates** - Subscribe to live agent updates via Server-Sent Events (SSE)
|
|
12
|
-
- 🎯 **Type-Safe** - Full TypeScript support with comprehensive type definitions
|
|
13
|
-
- 📝 **Built-in Logging** - Configurable logging for debugging and monitoring
|
|
14
|
-
|
|
15
|
-
## Quick Start
|
|
16
|
-
|
|
17
|
-
### 1. Installation
|
|
18
|
-
|
|
19
|
-
If you're using this package from npm:
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
npm install @jivaai/agent-chat-typescript
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
If you're using this package directly from the repository:
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
cd agent-chat/typescript
|
|
29
|
-
npm install
|
|
30
|
-
npm run build
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### 2. Get Your Credentials
|
|
34
|
-
|
|
35
|
-
Before you can use the SDK, you'll need to obtain the following from your Jiva.ai platform project:
|
|
36
|
-
|
|
37
|
-
1. **Main Chat Workflow ID** - The workflow ID for your agent chat backend
|
|
38
|
-
2. **API Key** - Your API key for authentication
|
|
39
|
-
3. **Upload Cache Workflow IDs** - Workflow IDs for:
|
|
40
|
-
- File Upload Cache
|
|
41
|
-
- Text Upload Cache
|
|
42
|
-
- Table Upload Cache
|
|
43
|
-
|
|
44
|
-
These can be found in your Jiva.ai platform project settings. The upload cache workflows are typically created alongside your main chat workflow.
|
|
45
|
-
|
|
46
|
-
### 3. Create a Client Instance
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
import { JivaApiClient } from '@jivaai/agent-chat-typescript';
|
|
50
|
-
|
|
51
|
-
const client = new JivaApiClient({
|
|
52
|
-
// Required: Main chat workflow configuration
|
|
53
|
-
apiKey: 'your-api-key',
|
|
54
|
-
workflowId: 'your-workflow-id',
|
|
55
|
-
workflowVersion: '0', // Optional, defaults to "0"
|
|
56
|
-
|
|
57
|
-
// Required: Upload cache workflow IDs
|
|
58
|
-
fileUploadCacheWorkflowId: 'file-cache-workflow-id',
|
|
59
|
-
textUploadCacheWorkflowId: 'text-cache-workflow-id',
|
|
60
|
-
tableUploadCacheWorkflowId: 'table-cache-workflow-id',
|
|
61
|
-
|
|
62
|
-
// Optional: Upload cache versions (default to workflowVersion or "0")
|
|
63
|
-
fileUploadCacheVersion: '0',
|
|
64
|
-
textUploadCacheVersion: '0',
|
|
65
|
-
tableUploadCacheVersion: '0',
|
|
66
|
-
|
|
67
|
-
// Optional: Separate API keys for upload caches (default to apiKey)
|
|
68
|
-
fileUploadCacheApiKey: 'file-cache-api-key',
|
|
69
|
-
textUploadCacheApiKey: 'text-cache-api-key',
|
|
70
|
-
tableUploadCacheApiKey: 'table-cache-api-key',
|
|
71
|
-
|
|
72
|
-
// Optional: Custom base URLs (for testing or different environments)
|
|
73
|
-
baseUrl: 'https://api.jiva.ai/public-api/workflow',
|
|
74
|
-
socketBaseUrl: 'https://api.jiva.ai/public-api',
|
|
75
|
-
|
|
76
|
-
// Optional: Logging configuration
|
|
77
|
-
logging: {
|
|
78
|
-
level: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'silent'
|
|
79
|
-
enabled: true,
|
|
80
|
-
},
|
|
81
|
-
});
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### 4. Start a Conversation
|
|
85
|
-
|
|
86
|
-
```typescript
|
|
87
|
-
// Initiate a conversation with the agent
|
|
88
|
-
const response = await client.initiateConversation({
|
|
89
|
-
sessionId: 'user-123-thread-1', // Unique session ID per user/thread
|
|
90
|
-
message: 'create a professional RFQ document', // obviously, this needs to be relevant to your agent
|
|
91
|
-
mode: 'CHAT_REQUEST',
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
// Handle the response
|
|
95
|
-
if (response.error) {
|
|
96
|
-
console.error('Error:', response.error);
|
|
97
|
-
} else if (response.data) {
|
|
98
|
-
const conversationData = response.data.json.default;
|
|
99
|
-
|
|
100
|
-
if (conversationData.state === 'OK') {
|
|
101
|
-
console.log('Success:', conversationData.message);
|
|
102
|
-
|
|
103
|
-
// Process execution results
|
|
104
|
-
if (conversationData.executions) {
|
|
105
|
-
conversationData.executions.forEach((exec) => {
|
|
106
|
-
console.log(`Execution: ${exec.response} (${exec.type})`);
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
} else if (conversationData.state === 'ERROR') {
|
|
110
|
-
console.error('Error:', response.data.errorMessages);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
That's it! The SDK automatically handles:
|
|
116
|
-
- ✅ Async workflow execution (polling when state is `RUNNING`)
|
|
117
|
-
- ✅ Error handling
|
|
118
|
-
- ✅ Response parsing
|
|
119
|
-
|
|
120
|
-
## How the API Works
|
|
121
|
-
|
|
122
|
-
### Architecture Overview
|
|
123
|
-
|
|
124
|
-
The Jiva.ai Agent Chat SDK communicates with Jiva.ai's agentic workflow engine through REST APIs and Server-Sent Events (SSE):
|
|
125
|
-
|
|
126
|
-
1. **Main Chat Workflow** - Handles conversation requests and agent interactions
|
|
127
|
-
2. **Upload Cache Workflows** - Store uploaded assets (files, text, tables) that agents can reference
|
|
128
|
-
3. **EventSource (SSE)** - Provides real-time updates during agent processing
|
|
129
|
-
|
|
130
|
-
### Request Flow
|
|
131
|
-
|
|
132
|
-
```
|
|
133
|
-
┌─────────────┐
|
|
134
|
-
│ Your App │
|
|
135
|
-
└──────┬──────┘
|
|
136
|
-
│
|
|
137
|
-
│ 1. initiateConversation()
|
|
138
|
-
▼
|
|
139
|
-
┌─────────────────────────┐
|
|
140
|
-
│ JivaApiClient │
|
|
141
|
-
│ - Validates request │
|
|
142
|
-
│ - Sends POST request │
|
|
143
|
-
└──────┬──────────────────┘
|
|
144
|
-
│
|
|
145
|
-
│ 2. POST /workflow/{workflowId}/{version}/invoke
|
|
146
|
-
▼
|
|
147
|
-
┌─────────────────────────┐
|
|
148
|
-
│ Jiva.ai API │
|
|
149
|
-
│ - Processes request │
|
|
150
|
-
│ - Returns state: │
|
|
151
|
-
│ • OK (immediate) │
|
|
152
|
-
│ • RUNNING (async) │
|
|
153
|
-
│ • ERROR │
|
|
154
|
-
└──────┬──────────────────┘
|
|
155
|
-
│
|
|
156
|
-
│ 3. If RUNNING, auto-poll
|
|
157
|
-
▼
|
|
158
|
-
┌─────────────────────────┐
|
|
159
|
-
│ Polling (automatic) │
|
|
160
|
-
│ - Polls every 1s │
|
|
161
|
-
│ - Max 30 attempts │
|
|
162
|
-
│ - Returns when complete │
|
|
163
|
-
└─────────────────────────┘
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### Response States
|
|
167
|
-
|
|
168
|
-
The API returns responses with different states:
|
|
169
|
-
|
|
170
|
-
- **OK** - Request processed immediately, result is available
|
|
171
|
-
- **RUNNING** - Request is being processed asynchronously (SDK automatically polls)
|
|
172
|
-
- **PARTIAL_OK** - Partial results are available
|
|
173
|
-
- **ERROR** - Request failed with an error
|
|
174
|
-
|
|
175
|
-
### Response Modes
|
|
176
|
-
|
|
177
|
-
- **CHAT_RESPONSE** - Normal response with execution results
|
|
178
|
-
- **SCREEN_RESPONSE** - Response indicating that assets are required (check `screens` array)
|
|
179
|
-
|
|
180
|
-
## Usage Guide
|
|
181
|
-
|
|
182
|
-
### Basic Conversation
|
|
183
|
-
|
|
184
|
-
The simplest way to interact with the agent:
|
|
185
|
-
|
|
186
|
-
```typescript
|
|
187
|
-
const response = await client.initiateConversation({
|
|
188
|
-
sessionId: 'user-123-thread-1',
|
|
189
|
-
message: 'Hello, what can you help me with?',
|
|
190
|
-
mode: 'CHAT_REQUEST',
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
if (response.data?.json.default.state === 'OK') {
|
|
194
|
-
console.log('Agent response:', response.data.json.default.message);
|
|
195
|
-
}
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### Conversations with Context
|
|
199
|
-
|
|
200
|
-
Provide conversation history for context-aware interactions:
|
|
201
|
-
|
|
202
|
-
```typescript
|
|
203
|
-
const response = await client.initiateConversation(
|
|
204
|
-
[
|
|
205
|
-
{
|
|
206
|
-
sessionId: 'user-123-thread-1',
|
|
207
|
-
message: 'RFQs are generally single-pagers',
|
|
208
|
-
mode: 'CHAT_REQUEST',
|
|
209
|
-
},
|
|
210
|
-
{
|
|
211
|
-
sessionId: 'user-123-thread-1',
|
|
212
|
-
message: 'ok',
|
|
213
|
-
mode: 'CHAT_RESPONSE',
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
sessionId: 'user-123-thread-1',
|
|
217
|
-
message: 'create a professional RFQ document',
|
|
218
|
-
mode: 'CHAT_REQUEST',
|
|
219
|
-
},
|
|
220
|
-
],
|
|
221
|
-
{
|
|
222
|
-
maxAttempts: 30, // Optional: max polling attempts (default: 30)
|
|
223
|
-
pollInterval: 1000, // Optional: polling interval in ms (default: 1000)
|
|
224
|
-
}
|
|
225
|
-
);
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
**Important Notes:**
|
|
229
|
-
- All messages must have the same `sessionId`
|
|
230
|
-
- `CHAT_REQUEST` and `CHAT_RESPONSE` must alternate in the array
|
|
231
|
-
- The first message can be either `CHAT_REQUEST` or `CHAT_RESPONSE`
|
|
232
|
-
|
|
233
|
-
### Handling Screen Responses
|
|
234
|
-
|
|
235
|
-
Sometimes the agent requires additional assets (like files) to complete a request. When this happens, the response will have `mode: 'SCREEN_RESPONSE'` and include a `screens` array.
|
|
236
|
-
|
|
237
|
-
```typescript
|
|
238
|
-
const response = await client.initiateConversation({
|
|
239
|
-
sessionId: 'session-123',
|
|
240
|
-
message: 'create a professional RFQ document',
|
|
241
|
-
mode: 'CHAT_REQUEST',
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
if (response.data?.json.default.mode === 'SCREEN_RESPONSE') {
|
|
245
|
-
const screens = response.data.json.default.screens;
|
|
246
|
-
|
|
247
|
-
screens?.forEach((screen) => {
|
|
248
|
-
console.log(`Screen ${screen.nodeId}: ${screen.asset.message}`);
|
|
249
|
-
console.log(`Asset type: ${screen.asset.type}`);
|
|
250
|
-
|
|
251
|
-
if (screen.asset.type === 'FILE_UPLOAD') {
|
|
252
|
-
// Upload file and satisfy the screen (see below)
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
### Uploading Assets
|
|
259
|
-
|
|
260
|
-
The SDK provides methods to upload files, text, and tables. These methods return an `assetId` that can be used to satisfy screen responses.
|
|
261
|
-
|
|
262
|
-
#### Uploading a File
|
|
263
|
-
|
|
264
|
-
```typescript
|
|
265
|
-
// In browser environments, you can upload File or Blob objects
|
|
266
|
-
const file = new File(['file content'], 'document.pdf', {
|
|
267
|
-
type: 'application/pdf'
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
const uploadResponse = await client.uploadFile(file);
|
|
271
|
-
|
|
272
|
-
if (uploadResponse.data) {
|
|
273
|
-
const assetId = uploadResponse.data.strings.default;
|
|
274
|
-
console.log('File uploaded, assetId:', assetId);
|
|
275
|
-
// Cache this assetId for later use with the same sessionId
|
|
276
|
-
}
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
```typescript
|
|
280
|
-
// In Node.js environments, provide base64 string directly
|
|
281
|
-
const base64String = 'base64-encoded-file-content';
|
|
282
|
-
const uploadResponse = await client.uploadFile(base64String);
|
|
283
|
-
|
|
284
|
-
const assetId = uploadResponse.data?.strings.default;
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
#### Uploading Text
|
|
288
|
-
|
|
289
|
-
```typescript
|
|
290
|
-
const textResponse = await client.uploadText(
|
|
291
|
-
'This is the text content to upload'
|
|
292
|
-
);
|
|
293
|
-
|
|
294
|
-
const assetId = textResponse.data?.strings.default;
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
#### Uploading Table Data
|
|
298
|
-
|
|
299
|
-
```typescript
|
|
300
|
-
const tableData = [
|
|
301
|
-
{ name: 'John', age: 30, city: 'New York' },
|
|
302
|
-
{ name: 'Jane', age: 25, city: 'Boston' },
|
|
303
|
-
{ name: 'Bob', age: 35, city: 'Chicago' },
|
|
304
|
-
];
|
|
305
|
-
|
|
306
|
-
const tableResponse = await client.uploadTable(tableData);
|
|
307
|
-
|
|
308
|
-
const assetId = tableResponse.data?.strings.default;
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
### Satisfying Screen Responses
|
|
312
|
-
|
|
313
|
-
After uploading assets and receiving an `assetId`, you can satisfy the screen by including `nodeId`, `field`, and `assetId` in your follow-up request:
|
|
314
|
-
|
|
315
|
-
```typescript
|
|
316
|
-
// 1. Make initial request
|
|
317
|
-
const response = await client.initiateConversation({
|
|
318
|
-
sessionId: 'session-123',
|
|
319
|
-
message: 'create a professional RFQ document',
|
|
320
|
-
mode: 'CHAT_REQUEST',
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
// 2. Check for screen response
|
|
324
|
-
if (response.data?.json.default.mode === 'SCREEN_RESPONSE') {
|
|
325
|
-
const screen = response.data.json.default.screens?.[0];
|
|
326
|
-
|
|
327
|
-
if (screen?.asset.type === 'FILE_UPLOAD') {
|
|
328
|
-
// 3. Upload the file
|
|
329
|
-
const file = /* get file from user */;
|
|
330
|
-
const uploadResponse = await client.uploadFile(file);
|
|
331
|
-
|
|
332
|
-
if (uploadResponse.data) {
|
|
333
|
-
const assetId = uploadResponse.data.strings.default;
|
|
334
|
-
|
|
335
|
-
// 4. Satisfy the screen with the uploaded asset
|
|
336
|
-
const followUp = await client.initiateConversation({
|
|
337
|
-
sessionId: 'session-123',
|
|
338
|
-
message: 'create a professional RFQ document',
|
|
339
|
-
mode: 'CHAT_REQUEST',
|
|
340
|
-
nodeId: screen.nodeId,
|
|
341
|
-
field: screen.field,
|
|
342
|
-
assetId: assetId,
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
**Important Notes:**
|
|
350
|
-
- All three fields (`nodeId`, `field`, `assetId`) must be provided together when satisfying a screen
|
|
351
|
-
- The `nodeId` and `field` come from the `screens` array in the `SCREEN_RESPONSE`
|
|
352
|
-
- The `assetId` comes from uploading to File Upload Cache, Text Upload Cache, or Table Upload Cache endpoints
|
|
353
|
-
- Asset IDs should be cached on your backend - they can be reused for the same `sessionId`
|
|
354
|
-
- Asset semantics are session-specific: an asset for one `sessionId` may not be valid for another
|
|
355
|
-
|
|
356
|
-
### Real-Time Updates with EventSource
|
|
357
|
-
|
|
358
|
-
Subscribe to real-time updates from the agent using Server-Sent Events (SSE). This allows you to receive live updates as the agent processes requests, including thinking messages, execution results, and progress updates.
|
|
359
|
-
|
|
360
|
-
```typescript
|
|
361
|
-
// Subscribe to real-time updates for a session
|
|
362
|
-
const es = client.subscribeToSocket(
|
|
363
|
-
'session-123', // Session ID
|
|
364
|
-
{
|
|
365
|
-
onOpen: () => {
|
|
366
|
-
console.log('EventSource connected');
|
|
367
|
-
},
|
|
368
|
-
onMessage: (message) => {
|
|
369
|
-
console.log('Message:', message.message);
|
|
370
|
-
console.log('Types:', message.types);
|
|
371
|
-
|
|
372
|
-
// Handle different message types
|
|
373
|
-
if (message.types.includes('AGENT_THINKING')) {
|
|
374
|
-
console.log('Agent is thinking...');
|
|
375
|
-
} else if (message.types.includes('AGENT_COMPLETED')) {
|
|
376
|
-
console.log('Agent completed successfully');
|
|
377
|
-
} else if (message.types.includes('CONTENT_DELTA')) {
|
|
378
|
-
// Streaming content
|
|
379
|
-
process.stdout.write(message.message);
|
|
380
|
-
} else if (message.types.includes('FINAL_RESULT')) {
|
|
381
|
-
console.log('Final result:', message.message);
|
|
382
|
-
}
|
|
383
|
-
},
|
|
384
|
-
onClose: (event) => {
|
|
385
|
-
console.log('EventSource closed:', event.reason);
|
|
386
|
-
},
|
|
387
|
-
onError: (error) => {
|
|
388
|
-
console.error('EventSource error:', error);
|
|
389
|
-
},
|
|
390
|
-
onReconnect: (attempt) => {
|
|
391
|
-
console.log(`Reconnecting... (attempt ${attempt})`);
|
|
392
|
-
},
|
|
393
|
-
},
|
|
394
|
-
{
|
|
395
|
-
autoReconnect: true, // Automatically reconnect on disconnect
|
|
396
|
-
reconnectInterval: 3000, // Wait 3 seconds between reconnection attempts
|
|
397
|
-
maxReconnectAttempts: 10, // Maximum number of reconnection attempts
|
|
398
|
-
}
|
|
399
|
-
);
|
|
400
|
-
|
|
401
|
-
// Close the connection when done
|
|
402
|
-
es.close();
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
#### Socket Message Types
|
|
406
|
-
|
|
407
|
-
The socket can send various message types. Here are some common ones:
|
|
408
|
-
|
|
409
|
-
- **AGENT_STARTED** - Agent has begun processing
|
|
410
|
-
- **AGENT_THINKING** - Agent is analyzing and planning
|
|
411
|
-
- **AGENT_COMPLETED** - Agent finished successfully
|
|
412
|
-
- **AGENT_FAILED** - Agent encountered an error
|
|
413
|
-
- **CONTENT_DELTA** - Incremental text content (streaming)
|
|
414
|
-
- **CONTENT_COMPLETE** - Full text content block
|
|
415
|
-
- **EXECUTION_CALL_STARTED** - Agent is invoking a pipeline
|
|
416
|
-
- **EXECUTION_CALL_RESULT** - Result from an execution
|
|
417
|
-
- **FINAL_RESULT** - Final output from the pipeline
|
|
418
|
-
- **PROGRESS_UPDATE** - Progress percentage or status
|
|
419
|
-
- **TOKEN_USAGE** - Token consumption metrics
|
|
420
|
-
- **ERROR** - Error message with details
|
|
421
|
-
- **KEEPALIVE** - Heartbeat to keep connection alive
|
|
422
|
-
|
|
423
|
-
And many more. See the full list in the type definitions.
|
|
424
|
-
|
|
425
|
-
#### Socket Options
|
|
426
|
-
|
|
427
|
-
- **autoReconnect** (default: `true`) - Automatically attempt to reconnect on disconnect
|
|
428
|
-
- **reconnectInterval** (default: `3000`) - Delay in milliseconds between reconnection attempts
|
|
429
|
-
- **maxReconnectAttempts** (default: `10`) - Maximum number of reconnection attempts before giving up
|
|
430
|
-
|
|
431
|
-
#### Example: Real-Time Chat with EventSource
|
|
432
|
-
|
|
433
|
-
```typescript
|
|
434
|
-
// Start a conversation
|
|
435
|
-
const response = await client.initiateConversation({
|
|
436
|
-
sessionId: 'session-123',
|
|
437
|
-
message: 'create a professional RFQ document',
|
|
438
|
-
mode: 'CHAT_REQUEST',
|
|
439
|
-
});
|
|
440
|
-
|
|
441
|
-
// Subscribe to real-time updates
|
|
442
|
-
const es = client.subscribeToSocket('session-123', {
|
|
443
|
-
onMessage: (message) => {
|
|
444
|
-
if (message.types.includes('CONTENT_DELTA')) {
|
|
445
|
-
// Stream content to user
|
|
446
|
-
updateUI(message.message);
|
|
447
|
-
} else if (message.types.includes('AGENT_COMPLETED')) {
|
|
448
|
-
console.log('Agent finished processing');
|
|
449
|
-
es.close();
|
|
450
|
-
} else if (message.types.includes('ERROR')) {
|
|
451
|
-
console.error('Error:', message.message);
|
|
452
|
-
es.close();
|
|
453
|
-
}
|
|
454
|
-
},
|
|
455
|
-
});
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
**Note:**
|
|
459
|
-
- The EventSource URL is constructed from the `socketBaseUrl` (defaults to `https://api.jiva.ai/public-api`) and follows the pattern: `{socketBaseUrl}/workflow-chat/{workflowId}/{sessionId}`
|
|
460
|
-
- API endpoints follow the pattern: `{baseUrl}/{workflowId}/{version}/invoke` where version defaults to "0"
|
|
461
|
-
- For test environments, you can set custom `baseUrl` and version numbers in the client configuration
|
|
462
|
-
|
|
463
|
-
### Manual Polling
|
|
464
|
-
|
|
465
|
-
If you need to manually poll for a result (e.g., for multiple IDs simultaneously), you can use the `poll()` method:
|
|
466
|
-
|
|
467
|
-
```typescript
|
|
468
|
-
// Poll for a specific execution ID
|
|
469
|
-
const pollResponse = await client.poll(
|
|
470
|
-
{
|
|
471
|
-
sessionId: 'user-123-thread-1', // Required: session ID from original request
|
|
472
|
-
id: 'exec-456', // Required: ID from the RUNNING response
|
|
473
|
-
mode: 'POLL_REQUEST', // Required: must be POLL_REQUEST
|
|
474
|
-
},
|
|
475
|
-
(data) => {
|
|
476
|
-
// Success callback (optional)
|
|
477
|
-
console.log('State:', data.json.default.state);
|
|
478
|
-
if (data.json.default.logs) {
|
|
479
|
-
console.log('Logs:', data.json.default.logs);
|
|
480
|
-
}
|
|
481
|
-
if (data.json.default.executions) {
|
|
482
|
-
data.json.default.executions.forEach((exec) => {
|
|
483
|
-
console.log(`Execution state: ${exec.output.state}`);
|
|
484
|
-
console.log(`Output: ${exec.output.response} (${exec.output.type})`);
|
|
485
|
-
});
|
|
486
|
-
}
|
|
487
|
-
},
|
|
488
|
-
(error) => {
|
|
489
|
-
// Error callback (optional)
|
|
490
|
-
console.error('Error:', error);
|
|
491
|
-
}
|
|
492
|
-
);
|
|
493
|
-
|
|
494
|
-
// Handle the response
|
|
495
|
-
if (pollResponse.error) {
|
|
496
|
-
console.error('Poll failed:', pollResponse.error);
|
|
497
|
-
} else if (pollResponse.data) {
|
|
498
|
-
const pollData = pollResponse.data.json.default;
|
|
499
|
-
|
|
500
|
-
if (pollData.state === 'OK') {
|
|
501
|
-
console.log('Processing complete!');
|
|
502
|
-
} else if (pollData.state === 'RUNNING') {
|
|
503
|
-
console.log('Still processing...');
|
|
504
|
-
// Poll again after recommended 1 second delay
|
|
505
|
-
} else if (pollData.state === 'PARTIAL_OK') {
|
|
506
|
-
console.log('Partial results available');
|
|
507
|
-
} else if (pollData.state === 'ERROR') {
|
|
508
|
-
console.error('Error:', pollResponse.data.errorMessages);
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
**Note**: Only 1 sessionId can be polled per call. If you need to poll multiple IDs, make separate API calls simultaneously. The recommended polling frequency is 1 second to avoid being blacklisted.
|
|
514
|
-
|
|
515
|
-
###
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
```typescript
|
|
520
|
-
//
|
|
521
|
-
const
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
```typescript
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
}
|
|
601
|
-
```
|
|
602
|
-
|
|
603
|
-
###
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
```
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
- `
|
|
782
|
-
- `
|
|
783
|
-
- `
|
|
784
|
-
- `ConversationResponse
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
- `
|
|
791
|
-
- `
|
|
792
|
-
|
|
793
|
-
|
|
1
|
+
# Jiva.ai Agent Chat - TypeScript SDK
|
|
2
|
+
|
|
3
|
+
A comprehensive TypeScript SDK for integrating with Jiva.ai's agentic workflows. This library provides a simple, type-safe interface for building conversational AI applications powered by Jiva.ai's agentic workflow engine.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🤖 **Full Agentic Workflow Integration** - Seamlessly interact with Jiva.ai's agentic workflows
|
|
8
|
+
- 💬 **Conversational Interface** - Support for multi-turn conversations with context
|
|
9
|
+
- 📤 **Asset Upload Support** - Upload files, text, and tables to satisfy agent requirements
|
|
10
|
+
- 🔄 **Automatic Polling** - Handles async workflow execution with automatic polling
|
|
11
|
+
- 📡 **Real-Time Updates** - Subscribe to live agent updates via Server-Sent Events (SSE)
|
|
12
|
+
- 🎯 **Type-Safe** - Full TypeScript support with comprehensive type definitions
|
|
13
|
+
- 📝 **Built-in Logging** - Configurable logging for debugging and monitoring
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
### 1. Installation
|
|
18
|
+
|
|
19
|
+
If you're using this package from npm:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @jivaai/agent-chat-typescript
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
If you're using this package directly from the repository:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cd agent-chat/typescript
|
|
29
|
+
npm install
|
|
30
|
+
npm run build
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Get Your Credentials
|
|
34
|
+
|
|
35
|
+
Before you can use the SDK, you'll need to obtain the following from your Jiva.ai platform project:
|
|
36
|
+
|
|
37
|
+
1. **Main Chat Workflow ID** - The workflow ID for your agent chat backend
|
|
38
|
+
2. **API Key** - Your API key for authentication
|
|
39
|
+
3. **Upload Cache Workflow IDs** - Workflow IDs for:
|
|
40
|
+
- File Upload Cache
|
|
41
|
+
- Text Upload Cache
|
|
42
|
+
- Table Upload Cache
|
|
43
|
+
|
|
44
|
+
These can be found in your Jiva.ai platform project settings. The upload cache workflows are typically created alongside your main chat workflow.
|
|
45
|
+
|
|
46
|
+
### 3. Create a Client Instance
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { JivaApiClient } from '@jivaai/agent-chat-typescript';
|
|
50
|
+
|
|
51
|
+
const client = new JivaApiClient({
|
|
52
|
+
// Required: Main chat workflow configuration
|
|
53
|
+
apiKey: 'your-api-key',
|
|
54
|
+
workflowId: 'your-workflow-id',
|
|
55
|
+
workflowVersion: '0', // Optional, defaults to "0"
|
|
56
|
+
|
|
57
|
+
// Required: Upload cache workflow IDs
|
|
58
|
+
fileUploadCacheWorkflowId: 'file-cache-workflow-id',
|
|
59
|
+
textUploadCacheWorkflowId: 'text-cache-workflow-id',
|
|
60
|
+
tableUploadCacheWorkflowId: 'table-cache-workflow-id',
|
|
61
|
+
|
|
62
|
+
// Optional: Upload cache versions (default to workflowVersion or "0")
|
|
63
|
+
fileUploadCacheVersion: '0',
|
|
64
|
+
textUploadCacheVersion: '0',
|
|
65
|
+
tableUploadCacheVersion: '0',
|
|
66
|
+
|
|
67
|
+
// Optional: Separate API keys for upload caches (default to apiKey)
|
|
68
|
+
fileUploadCacheApiKey: 'file-cache-api-key',
|
|
69
|
+
textUploadCacheApiKey: 'text-cache-api-key',
|
|
70
|
+
tableUploadCacheApiKey: 'table-cache-api-key',
|
|
71
|
+
|
|
72
|
+
// Optional: Custom base URLs (for testing or different environments)
|
|
73
|
+
baseUrl: 'https://api.jiva.ai/public-api/workflow',
|
|
74
|
+
socketBaseUrl: 'https://api.jiva.ai/public-api',
|
|
75
|
+
|
|
76
|
+
// Optional: Logging configuration
|
|
77
|
+
logging: {
|
|
78
|
+
level: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'silent'
|
|
79
|
+
enabled: true,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 4. Start a Conversation
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
// Initiate a conversation with the agent
|
|
88
|
+
const response = await client.initiateConversation({
|
|
89
|
+
sessionId: 'user-123-thread-1', // Unique session ID per user/thread
|
|
90
|
+
message: 'create a professional RFQ document', // obviously, this needs to be relevant to your agent
|
|
91
|
+
mode: 'CHAT_REQUEST',
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Handle the response
|
|
95
|
+
if (response.error) {
|
|
96
|
+
console.error('Error:', response.error);
|
|
97
|
+
} else if (response.data) {
|
|
98
|
+
const conversationData = response.data.json.default;
|
|
99
|
+
|
|
100
|
+
if (conversationData.state === 'OK') {
|
|
101
|
+
console.log('Success:', conversationData.message);
|
|
102
|
+
|
|
103
|
+
// Process execution results
|
|
104
|
+
if (conversationData.executions) {
|
|
105
|
+
conversationData.executions.forEach((exec) => {
|
|
106
|
+
console.log(`Execution: ${exec.response} (${exec.type})`);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
} else if (conversationData.state === 'ERROR') {
|
|
110
|
+
console.error('Error:', response.data.errorMessages);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
That's it! The SDK automatically handles:
|
|
116
|
+
- ✅ Async workflow execution (polling when state is `RUNNING`)
|
|
117
|
+
- ✅ Error handling
|
|
118
|
+
- ✅ Response parsing
|
|
119
|
+
|
|
120
|
+
## How the API Works
|
|
121
|
+
|
|
122
|
+
### Architecture Overview
|
|
123
|
+
|
|
124
|
+
The Jiva.ai Agent Chat SDK communicates with Jiva.ai's agentic workflow engine through REST APIs and Server-Sent Events (SSE):
|
|
125
|
+
|
|
126
|
+
1. **Main Chat Workflow** - Handles conversation requests and agent interactions
|
|
127
|
+
2. **Upload Cache Workflows** - Store uploaded assets (files, text, tables) that agents can reference
|
|
128
|
+
3. **EventSource (SSE)** - Provides real-time updates during agent processing
|
|
129
|
+
|
|
130
|
+
### Request Flow
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
┌─────────────┐
|
|
134
|
+
│ Your App │
|
|
135
|
+
└──────┬──────┘
|
|
136
|
+
│
|
|
137
|
+
│ 1. initiateConversation()
|
|
138
|
+
▼
|
|
139
|
+
┌─────────────────────────┐
|
|
140
|
+
│ JivaApiClient │
|
|
141
|
+
│ - Validates request │
|
|
142
|
+
│ - Sends POST request │
|
|
143
|
+
└──────┬──────────────────┘
|
|
144
|
+
│
|
|
145
|
+
│ 2. POST /workflow/{workflowId}/{version}/invoke
|
|
146
|
+
▼
|
|
147
|
+
┌─────────────────────────┐
|
|
148
|
+
│ Jiva.ai API │
|
|
149
|
+
│ - Processes request │
|
|
150
|
+
│ - Returns state: │
|
|
151
|
+
│ • OK (immediate) │
|
|
152
|
+
│ • RUNNING (async) │
|
|
153
|
+
│ • ERROR │
|
|
154
|
+
└──────┬──────────────────┘
|
|
155
|
+
│
|
|
156
|
+
│ 3. If RUNNING, auto-poll
|
|
157
|
+
▼
|
|
158
|
+
┌─────────────────────────┐
|
|
159
|
+
│ Polling (automatic) │
|
|
160
|
+
│ - Polls every 1s │
|
|
161
|
+
│ - Max 30 attempts │
|
|
162
|
+
│ - Returns when complete │
|
|
163
|
+
└─────────────────────────┘
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Response States
|
|
167
|
+
|
|
168
|
+
The API returns responses with different states:
|
|
169
|
+
|
|
170
|
+
- **OK** - Request processed immediately, result is available
|
|
171
|
+
- **RUNNING** - Request is being processed asynchronously (SDK automatically polls)
|
|
172
|
+
- **PARTIAL_OK** - Partial results are available
|
|
173
|
+
- **ERROR** - Request failed with an error
|
|
174
|
+
|
|
175
|
+
### Response Modes
|
|
176
|
+
|
|
177
|
+
- **CHAT_RESPONSE** - Normal response with execution results
|
|
178
|
+
- **SCREEN_RESPONSE** - Response indicating that assets are required (check `screens` array)
|
|
179
|
+
|
|
180
|
+
## Usage Guide
|
|
181
|
+
|
|
182
|
+
### Basic Conversation
|
|
183
|
+
|
|
184
|
+
The simplest way to interact with the agent:
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
const response = await client.initiateConversation({
|
|
188
|
+
sessionId: 'user-123-thread-1',
|
|
189
|
+
message: 'Hello, what can you help me with?',
|
|
190
|
+
mode: 'CHAT_REQUEST',
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
if (response.data?.json.default.state === 'OK') {
|
|
194
|
+
console.log('Agent response:', response.data.json.default.message);
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Conversations with Context
|
|
199
|
+
|
|
200
|
+
Provide conversation history for context-aware interactions:
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
const response = await client.initiateConversation(
|
|
204
|
+
[
|
|
205
|
+
{
|
|
206
|
+
sessionId: 'user-123-thread-1',
|
|
207
|
+
message: 'RFQs are generally single-pagers',
|
|
208
|
+
mode: 'CHAT_REQUEST',
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
sessionId: 'user-123-thread-1',
|
|
212
|
+
message: 'ok',
|
|
213
|
+
mode: 'CHAT_RESPONSE',
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
sessionId: 'user-123-thread-1',
|
|
217
|
+
message: 'create a professional RFQ document',
|
|
218
|
+
mode: 'CHAT_REQUEST',
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
{
|
|
222
|
+
maxAttempts: 30, // Optional: max polling attempts (default: 30)
|
|
223
|
+
pollInterval: 1000, // Optional: polling interval in ms (default: 1000)
|
|
224
|
+
}
|
|
225
|
+
);
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Important Notes:**
|
|
229
|
+
- All messages must have the same `sessionId`
|
|
230
|
+
- `CHAT_REQUEST` and `CHAT_RESPONSE` must alternate in the array
|
|
231
|
+
- The first message can be either `CHAT_REQUEST` or `CHAT_RESPONSE`
|
|
232
|
+
|
|
233
|
+
### Handling Screen Responses
|
|
234
|
+
|
|
235
|
+
Sometimes the agent requires additional assets (like files) to complete a request. When this happens, the response will have `mode: 'SCREEN_RESPONSE'` and include a `screens` array.
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
const response = await client.initiateConversation({
|
|
239
|
+
sessionId: 'session-123',
|
|
240
|
+
message: 'create a professional RFQ document',
|
|
241
|
+
mode: 'CHAT_REQUEST',
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
if (response.data?.json.default.mode === 'SCREEN_RESPONSE') {
|
|
245
|
+
const screens = response.data.json.default.screens;
|
|
246
|
+
|
|
247
|
+
screens?.forEach((screen) => {
|
|
248
|
+
console.log(`Screen ${screen.nodeId}: ${screen.asset.message}`);
|
|
249
|
+
console.log(`Asset type: ${screen.asset.type}`);
|
|
250
|
+
|
|
251
|
+
if (screen.asset.type === 'FILE_UPLOAD') {
|
|
252
|
+
// Upload file and satisfy the screen (see below)
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Uploading Assets
|
|
259
|
+
|
|
260
|
+
The SDK provides methods to upload files, text, and tables. These methods return an `assetId` that can be used to satisfy screen responses.
|
|
261
|
+
|
|
262
|
+
#### Uploading a File
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
// In browser environments, you can upload File or Blob objects
|
|
266
|
+
const file = new File(['file content'], 'document.pdf', {
|
|
267
|
+
type: 'application/pdf'
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
const uploadResponse = await client.uploadFile(file);
|
|
271
|
+
|
|
272
|
+
if (uploadResponse.data) {
|
|
273
|
+
const assetId = uploadResponse.data.strings.default;
|
|
274
|
+
console.log('File uploaded, assetId:', assetId);
|
|
275
|
+
// Cache this assetId for later use with the same sessionId
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
// In Node.js environments, provide base64 string directly
|
|
281
|
+
const base64String = 'base64-encoded-file-content';
|
|
282
|
+
const uploadResponse = await client.uploadFile(base64String);
|
|
283
|
+
|
|
284
|
+
const assetId = uploadResponse.data?.strings.default;
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
#### Uploading Text
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
const textResponse = await client.uploadText(
|
|
291
|
+
'This is the text content to upload'
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
const assetId = textResponse.data?.strings.default;
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
#### Uploading Table Data
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
const tableData = [
|
|
301
|
+
{ name: 'John', age: 30, city: 'New York' },
|
|
302
|
+
{ name: 'Jane', age: 25, city: 'Boston' },
|
|
303
|
+
{ name: 'Bob', age: 35, city: 'Chicago' },
|
|
304
|
+
];
|
|
305
|
+
|
|
306
|
+
const tableResponse = await client.uploadTable(tableData);
|
|
307
|
+
|
|
308
|
+
const assetId = tableResponse.data?.strings.default;
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Satisfying Screen Responses
|
|
312
|
+
|
|
313
|
+
After uploading assets and receiving an `assetId`, you can satisfy the screen by including `nodeId`, `field`, and `assetId` in your follow-up request:
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
// 1. Make initial request
|
|
317
|
+
const response = await client.initiateConversation({
|
|
318
|
+
sessionId: 'session-123',
|
|
319
|
+
message: 'create a professional RFQ document',
|
|
320
|
+
mode: 'CHAT_REQUEST',
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// 2. Check for screen response
|
|
324
|
+
if (response.data?.json.default.mode === 'SCREEN_RESPONSE') {
|
|
325
|
+
const screen = response.data.json.default.screens?.[0];
|
|
326
|
+
|
|
327
|
+
if (screen?.asset.type === 'FILE_UPLOAD') {
|
|
328
|
+
// 3. Upload the file
|
|
329
|
+
const file = /* get file from user */;
|
|
330
|
+
const uploadResponse = await client.uploadFile(file);
|
|
331
|
+
|
|
332
|
+
if (uploadResponse.data) {
|
|
333
|
+
const assetId = uploadResponse.data.strings.default;
|
|
334
|
+
|
|
335
|
+
// 4. Satisfy the screen with the uploaded asset
|
|
336
|
+
const followUp = await client.initiateConversation({
|
|
337
|
+
sessionId: 'session-123',
|
|
338
|
+
message: 'create a professional RFQ document',
|
|
339
|
+
mode: 'CHAT_REQUEST',
|
|
340
|
+
nodeId: screen.nodeId,
|
|
341
|
+
field: screen.field,
|
|
342
|
+
assetId: assetId,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**Important Notes:**
|
|
350
|
+
- All three fields (`nodeId`, `field`, `assetId`) must be provided together when satisfying a screen
|
|
351
|
+
- The `nodeId` and `field` come from the `screens` array in the `SCREEN_RESPONSE`
|
|
352
|
+
- The `assetId` comes from uploading to File Upload Cache, Text Upload Cache, or Table Upload Cache endpoints
|
|
353
|
+
- Asset IDs should be cached on your backend - they can be reused for the same `sessionId`
|
|
354
|
+
- Asset semantics are session-specific: an asset for one `sessionId` may not be valid for another
|
|
355
|
+
|
|
356
|
+
### Real-Time Updates with EventSource
|
|
357
|
+
|
|
358
|
+
Subscribe to real-time updates from the agent using Server-Sent Events (SSE). This allows you to receive live updates as the agent processes requests, including thinking messages, execution results, and progress updates.
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
// Subscribe to real-time updates for a session
|
|
362
|
+
const es = client.subscribeToSocket(
|
|
363
|
+
'session-123', // Session ID
|
|
364
|
+
{
|
|
365
|
+
onOpen: () => {
|
|
366
|
+
console.log('EventSource connected');
|
|
367
|
+
},
|
|
368
|
+
onMessage: (message) => {
|
|
369
|
+
console.log('Message:', message.message);
|
|
370
|
+
console.log('Types:', message.types);
|
|
371
|
+
|
|
372
|
+
// Handle different message types
|
|
373
|
+
if (message.types.includes('AGENT_THINKING')) {
|
|
374
|
+
console.log('Agent is thinking...');
|
|
375
|
+
} else if (message.types.includes('AGENT_COMPLETED')) {
|
|
376
|
+
console.log('Agent completed successfully');
|
|
377
|
+
} else if (message.types.includes('CONTENT_DELTA')) {
|
|
378
|
+
// Streaming content
|
|
379
|
+
process.stdout.write(message.message);
|
|
380
|
+
} else if (message.types.includes('FINAL_RESULT')) {
|
|
381
|
+
console.log('Final result:', message.message);
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
onClose: (event) => {
|
|
385
|
+
console.log('EventSource closed:', event.reason);
|
|
386
|
+
},
|
|
387
|
+
onError: (error) => {
|
|
388
|
+
console.error('EventSource error:', error);
|
|
389
|
+
},
|
|
390
|
+
onReconnect: (attempt) => {
|
|
391
|
+
console.log(`Reconnecting... (attempt ${attempt})`);
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
autoReconnect: true, // Automatically reconnect on disconnect
|
|
396
|
+
reconnectInterval: 3000, // Wait 3 seconds between reconnection attempts
|
|
397
|
+
maxReconnectAttempts: 10, // Maximum number of reconnection attempts
|
|
398
|
+
}
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
// Close the connection when done
|
|
402
|
+
es.close();
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
#### Socket Message Types
|
|
406
|
+
|
|
407
|
+
The socket can send various message types. Here are some common ones:
|
|
408
|
+
|
|
409
|
+
- **AGENT_STARTED** - Agent has begun processing
|
|
410
|
+
- **AGENT_THINKING** - Agent is analyzing and planning
|
|
411
|
+
- **AGENT_COMPLETED** - Agent finished successfully
|
|
412
|
+
- **AGENT_FAILED** - Agent encountered an error
|
|
413
|
+
- **CONTENT_DELTA** - Incremental text content (streaming)
|
|
414
|
+
- **CONTENT_COMPLETE** - Full text content block
|
|
415
|
+
- **EXECUTION_CALL_STARTED** - Agent is invoking a pipeline
|
|
416
|
+
- **EXECUTION_CALL_RESULT** - Result from an execution
|
|
417
|
+
- **FINAL_RESULT** - Final output from the pipeline
|
|
418
|
+
- **PROGRESS_UPDATE** - Progress percentage or status
|
|
419
|
+
- **TOKEN_USAGE** - Token consumption metrics
|
|
420
|
+
- **ERROR** - Error message with details
|
|
421
|
+
- **KEEPALIVE** - Heartbeat to keep connection alive
|
|
422
|
+
|
|
423
|
+
And many more. See the full list in the type definitions.
|
|
424
|
+
|
|
425
|
+
#### Socket Options
|
|
426
|
+
|
|
427
|
+
- **autoReconnect** (default: `true`) - Automatically attempt to reconnect on disconnect
|
|
428
|
+
- **reconnectInterval** (default: `3000`) - Delay in milliseconds between reconnection attempts
|
|
429
|
+
- **maxReconnectAttempts** (default: `10`) - Maximum number of reconnection attempts before giving up
|
|
430
|
+
|
|
431
|
+
#### Example: Real-Time Chat with EventSource
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
// Start a conversation
|
|
435
|
+
const response = await client.initiateConversation({
|
|
436
|
+
sessionId: 'session-123',
|
|
437
|
+
message: 'create a professional RFQ document',
|
|
438
|
+
mode: 'CHAT_REQUEST',
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
// Subscribe to real-time updates
|
|
442
|
+
const es = client.subscribeToSocket('session-123', {
|
|
443
|
+
onMessage: (message) => {
|
|
444
|
+
if (message.types.includes('CONTENT_DELTA')) {
|
|
445
|
+
// Stream content to user
|
|
446
|
+
updateUI(message.message);
|
|
447
|
+
} else if (message.types.includes('AGENT_COMPLETED')) {
|
|
448
|
+
console.log('Agent finished processing');
|
|
449
|
+
es.close();
|
|
450
|
+
} else if (message.types.includes('ERROR')) {
|
|
451
|
+
console.error('Error:', message.message);
|
|
452
|
+
es.close();
|
|
453
|
+
}
|
|
454
|
+
},
|
|
455
|
+
});
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
**Note:**
|
|
459
|
+
- The EventSource URL is constructed from the `socketBaseUrl` (defaults to `https://api.jiva.ai/public-api`) and follows the pattern: `{socketBaseUrl}/workflow-chat/{workflowId}/{sessionId}`
|
|
460
|
+
- API endpoints follow the pattern: `{baseUrl}/{workflowId}/{version}/invoke` where version defaults to "0"
|
|
461
|
+
- For test environments, you can set custom `baseUrl` and version numbers in the client configuration
|
|
462
|
+
|
|
463
|
+
### Manual Polling
|
|
464
|
+
|
|
465
|
+
If you need to manually poll for a result (e.g., for multiple IDs simultaneously), you can use the `poll()` method:
|
|
466
|
+
|
|
467
|
+
```typescript
|
|
468
|
+
// Poll for a specific execution ID
|
|
469
|
+
const pollResponse = await client.poll(
|
|
470
|
+
{
|
|
471
|
+
sessionId: 'user-123-thread-1', // Required: session ID from original request
|
|
472
|
+
id: 'exec-456', // Required: ID from the RUNNING response
|
|
473
|
+
mode: 'POLL_REQUEST', // Required: must be POLL_REQUEST
|
|
474
|
+
},
|
|
475
|
+
(data) => {
|
|
476
|
+
// Success callback (optional)
|
|
477
|
+
console.log('State:', data.json.default.state);
|
|
478
|
+
if (data.json.default.logs) {
|
|
479
|
+
console.log('Logs:', data.json.default.logs);
|
|
480
|
+
}
|
|
481
|
+
if (data.json.default.executions) {
|
|
482
|
+
data.json.default.executions.forEach((exec) => {
|
|
483
|
+
console.log(`Execution state: ${exec.output.state}`);
|
|
484
|
+
console.log(`Output: ${exec.output.response} (${exec.output.type})`);
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
(error) => {
|
|
489
|
+
// Error callback (optional)
|
|
490
|
+
console.error('Error:', error);
|
|
491
|
+
}
|
|
492
|
+
);
|
|
493
|
+
|
|
494
|
+
// Handle the response
|
|
495
|
+
if (pollResponse.error) {
|
|
496
|
+
console.error('Poll failed:', pollResponse.error);
|
|
497
|
+
} else if (pollResponse.data) {
|
|
498
|
+
const pollData = pollResponse.data.json.default;
|
|
499
|
+
|
|
500
|
+
if (pollData.state === 'OK') {
|
|
501
|
+
console.log('Processing complete!');
|
|
502
|
+
} else if (pollData.state === 'RUNNING') {
|
|
503
|
+
console.log('Still processing...');
|
|
504
|
+
// Poll again after recommended 1 second delay
|
|
505
|
+
} else if (pollData.state === 'PARTIAL_OK') {
|
|
506
|
+
console.log('Partial results available');
|
|
507
|
+
} else if (pollData.state === 'ERROR') {
|
|
508
|
+
console.error('Error:', pollResponse.data.errorMessages);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
**Note**: Only 1 sessionId can be polled per call. If you need to poll multiple IDs, make separate API calls simultaneously. The recommended polling frequency is 1 second to avoid being blacklisted.
|
|
514
|
+
|
|
515
|
+
### Checking Completion Status
|
|
516
|
+
|
|
517
|
+
When polling for workflow execution results, you can use `checkCompletionStatus()` to determine if all executions within a poll response have completed. This is useful for custom polling logic where you want to check if all sub-executions are finished.
|
|
518
|
+
|
|
519
|
+
```typescript
|
|
520
|
+
// Poll for a specific execution ID
|
|
521
|
+
const pollResponse = await client.poll({
|
|
522
|
+
sessionId: 'user-123-thread-1',
|
|
523
|
+
id: 'exec-456',
|
|
524
|
+
mode: 'POLL_REQUEST',
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
if (pollResponse.data) {
|
|
528
|
+
// Check if all executions are complete
|
|
529
|
+
const isComplete = client.checkCompletionStatus(pollResponse.data);
|
|
530
|
+
|
|
531
|
+
if (isComplete) {
|
|
532
|
+
console.log('All executions have completed');
|
|
533
|
+
// Process final results
|
|
534
|
+
} else {
|
|
535
|
+
console.log('Some executions are still pending');
|
|
536
|
+
// Continue polling
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
**How it works:**
|
|
542
|
+
- Returns `true` if all executions are complete (not in `PENDING` state)
|
|
543
|
+
- Returns `false` if any execution is still `PENDING` or if the response structure is invalid
|
|
544
|
+
- Handles both response formats:
|
|
545
|
+
- Newer format: `json.default.data[0].executions` (array format with data property)
|
|
546
|
+
- Older format: `json.default.executions` (direct format)
|
|
547
|
+
- If no executions array is found, it considers the response complete (returns `true`)
|
|
548
|
+
|
|
549
|
+
**Example with custom polling loop:**
|
|
550
|
+
|
|
551
|
+
```typescript
|
|
552
|
+
async function pollUntilComplete(sessionId: string, executionId: string) {
|
|
553
|
+
let isComplete = false;
|
|
554
|
+
let attempts = 0;
|
|
555
|
+
const maxAttempts = 30;
|
|
556
|
+
|
|
557
|
+
while (!isComplete && attempts < maxAttempts) {
|
|
558
|
+
const pollResponse = await client.poll({
|
|
559
|
+
sessionId,
|
|
560
|
+
id: executionId,
|
|
561
|
+
mode: 'POLL_REQUEST',
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
if (pollResponse.error) {
|
|
565
|
+
throw new Error(pollResponse.error);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
if (pollResponse.data) {
|
|
569
|
+
isComplete = client.checkCompletionStatus(pollResponse.data);
|
|
570
|
+
|
|
571
|
+
if (!isComplete) {
|
|
572
|
+
// Wait before next poll
|
|
573
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
attempts++;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
if (!isComplete) {
|
|
581
|
+
throw new Error('Polling timeout: executions did not complete');
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
return pollResponse.data;
|
|
585
|
+
}
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
### Using Promises (without callbacks)
|
|
589
|
+
|
|
590
|
+
All methods return promises, so you can use async/await or `.then()`:
|
|
591
|
+
|
|
592
|
+
```typescript
|
|
593
|
+
// The methods return promises, so you can use async/await or .then()
|
|
594
|
+
const response = await client.post({ message: 'Hello' });
|
|
595
|
+
|
|
596
|
+
if (response.error) {
|
|
597
|
+
console.error('Error:', response.error);
|
|
598
|
+
} else {
|
|
599
|
+
console.log('Data:', response.data);
|
|
600
|
+
}
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
### Logging
|
|
604
|
+
|
|
605
|
+
The SDK includes built-in logging with different log levels. By default, logging is enabled and uses:
|
|
606
|
+
- **Production**: `warn` level (warnings and errors only)
|
|
607
|
+
- **Development**: `debug` level (all messages)
|
|
608
|
+
|
|
609
|
+
You can configure logging in the client initialization:
|
|
610
|
+
|
|
611
|
+
```typescript
|
|
612
|
+
const client = new JivaApiClient({
|
|
613
|
+
apiKey: 'your-api-key',
|
|
614
|
+
workflowId: 'your-workflow-id',
|
|
615
|
+
// ... other config ...
|
|
616
|
+
logging: {
|
|
617
|
+
level: 'debug', // 'debug' | 'info' | 'warn' | 'error' | 'silent'
|
|
618
|
+
enabled: true, // Enable/disable logging
|
|
619
|
+
},
|
|
620
|
+
});
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
**Log Levels:**
|
|
624
|
+
- `debug`: Detailed information (URLs, payloads, responses) - most verbose
|
|
625
|
+
- `info`: General flow information (method calls, state changes)
|
|
626
|
+
- `warn`: Warnings (retries, fallbacks, timeouts)
|
|
627
|
+
- `error`: Errors (API errors, network errors)
|
|
628
|
+
- `silent`: No logging output
|
|
629
|
+
|
|
630
|
+
**Using a Custom Logger:**
|
|
631
|
+
|
|
632
|
+
You can provide your own logger implementation:
|
|
633
|
+
|
|
634
|
+
```typescript
|
|
635
|
+
import { Logger } from '@jivaai/agent-chat-typescript';
|
|
636
|
+
|
|
637
|
+
const customLogger: Logger = {
|
|
638
|
+
debug(message: string, ...args: unknown[]): void {
|
|
639
|
+
// Your custom debug logging
|
|
640
|
+
},
|
|
641
|
+
info(message: string, ...args: unknown[]): void {
|
|
642
|
+
// Your custom info logging
|
|
643
|
+
},
|
|
644
|
+
warn(message: string, ...args: unknown[]): void {
|
|
645
|
+
// Your custom warn logging
|
|
646
|
+
},
|
|
647
|
+
error(message: string, ...args: unknown[]): void {
|
|
648
|
+
// Your custom error logging
|
|
649
|
+
},
|
|
650
|
+
};
|
|
651
|
+
|
|
652
|
+
const client = new JivaApiClient({
|
|
653
|
+
apiKey: 'your-api-key',
|
|
654
|
+
workflowId: 'your-workflow-id',
|
|
655
|
+
// ... other config ...
|
|
656
|
+
logging: {
|
|
657
|
+
logger: customLogger,
|
|
658
|
+
level: 'info',
|
|
659
|
+
},
|
|
660
|
+
});
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
**Disable Logging:**
|
|
664
|
+
|
|
665
|
+
```typescript
|
|
666
|
+
const client = new JivaApiClient({
|
|
667
|
+
apiKey: 'your-api-key',
|
|
668
|
+
workflowId: 'your-workflow-id',
|
|
669
|
+
// ... other config ...
|
|
670
|
+
logging: {
|
|
671
|
+
enabled: false, // Disable all logging
|
|
672
|
+
},
|
|
673
|
+
});
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
### Using Custom Base URL (for testing)
|
|
677
|
+
|
|
678
|
+
```typescript
|
|
679
|
+
const testClient = new JivaApiClient({
|
|
680
|
+
apiKey: 'test-api-key',
|
|
681
|
+
workflowId: 'test-workflow-id',
|
|
682
|
+
fileUploadCacheWorkflowId: 'test-file-cache-workflow-id',
|
|
683
|
+
textUploadCacheWorkflowId: 'test-text-cache-workflow-id',
|
|
684
|
+
tableUploadCacheWorkflowId: 'test-table-cache-workflow-id',
|
|
685
|
+
baseUrl: 'https://test-api.example.com/workflow',
|
|
686
|
+
socketBaseUrl: 'https://test-api.example.com',
|
|
687
|
+
});
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
## Development
|
|
691
|
+
|
|
692
|
+
### Build
|
|
693
|
+
|
|
694
|
+
```bash
|
|
695
|
+
npm run build
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
This compiles TypeScript to JavaScript in the `dist/` directory.
|
|
699
|
+
|
|
700
|
+
### Test
|
|
701
|
+
|
|
702
|
+
```bash
|
|
703
|
+
npm test
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
Run tests in watch mode:
|
|
707
|
+
|
|
708
|
+
```bash
|
|
709
|
+
npm run test:watch
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
Run only end-to-end tests:
|
|
713
|
+
|
|
714
|
+
```bash
|
|
715
|
+
npm test -- e2e.test.ts
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
Run integration tests (requires local Jiva.ai instance):
|
|
719
|
+
|
|
720
|
+
```bash
|
|
721
|
+
# Remove .skip from describe block in integration.test.ts first
|
|
722
|
+
npm test -- integration.test.ts
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
Run integration tests (they are skipped by default):
|
|
726
|
+
|
|
727
|
+
```bash
|
|
728
|
+
# On Unix/Linux/Mac:
|
|
729
|
+
RUN_INTEGRATION_TESTS=true npm test -- integration.test.ts
|
|
730
|
+
|
|
731
|
+
# On Windows (PowerShell):
|
|
732
|
+
$env:RUN_INTEGRATION_TESTS="true"; npm test -- integration.test.ts
|
|
733
|
+
|
|
734
|
+
# On Windows (CMD):
|
|
735
|
+
set RUN_INTEGRATION_TESTS=true && npm test -- integration.test.ts
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
**Note**: Integration tests are skipped by default and require a running local Jiva.ai instance. They will only run when `RUN_INTEGRATION_TESTS=true` is explicitly set.
|
|
739
|
+
|
|
740
|
+
### Lint
|
|
741
|
+
|
|
742
|
+
```bash
|
|
743
|
+
npm run lint
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
## Project Structure
|
|
747
|
+
|
|
748
|
+
```
|
|
749
|
+
typescript/
|
|
750
|
+
├── src/ # Source code
|
|
751
|
+
│ ├── __tests__/ # Test files
|
|
752
|
+
│ ├── api.ts # Main API client implementation
|
|
753
|
+
│ ├── types.ts # TypeScript type definitions
|
|
754
|
+
│ ├── logger.ts # Logging utilities
|
|
755
|
+
│ └── index.ts # Main entry point
|
|
756
|
+
├── dist/ # Compiled output (generated)
|
|
757
|
+
├── package.json # Dependencies and scripts
|
|
758
|
+
├── tsconfig.json # TypeScript configuration
|
|
759
|
+
└── jest.config.js # Jest test configuration
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
## API Reference
|
|
763
|
+
|
|
764
|
+
### JivaApiClient
|
|
765
|
+
|
|
766
|
+
Main client class for interacting with the Jiva.ai Agent Chat API.
|
|
767
|
+
|
|
768
|
+
#### Constructor
|
|
769
|
+
|
|
770
|
+
```typescript
|
|
771
|
+
new JivaApiClient(config: ApiConfig)
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
#### Methods
|
|
775
|
+
|
|
776
|
+
##### `initiateConversation(request, options?, onSuccess?, onError?)`
|
|
777
|
+
|
|
778
|
+
Initiates a conversation with the Jiva.ai agent.
|
|
779
|
+
|
|
780
|
+
- **request**: `InitiateConversationRequest | InitiateConversationWithContext` - Single message or array of messages
|
|
781
|
+
- **options**: `PollingOptions` (optional) - Polling configuration
|
|
782
|
+
- **onSuccess**: `SuccessCallback<ConversationResponse>` (optional) - Success callback
|
|
783
|
+
- **onError**: `ErrorCallback` (optional) - Error callback
|
|
784
|
+
- **Returns**: `Promise<ApiResponse<ConversationResponse>>`
|
|
785
|
+
|
|
786
|
+
##### `poll(request, onSuccess?, onError?)`
|
|
787
|
+
|
|
788
|
+
Manually polls for the status of a running conversation.
|
|
789
|
+
|
|
790
|
+
- **request**: `PollRequest` - Poll request with sessionId, id, and mode
|
|
791
|
+
- **onSuccess**: `SuccessCallback<PollResponse>` (optional) - Success callback
|
|
792
|
+
- **onError**: `ErrorCallback` (optional) - Error callback
|
|
793
|
+
- **Returns**: `Promise<ApiResponse<PollResponse>>`
|
|
794
|
+
|
|
795
|
+
##### `uploadFile(file, onSuccess?, onError?)`
|
|
796
|
+
|
|
797
|
+
Uploads a file to the File Upload Cache.
|
|
798
|
+
|
|
799
|
+
- **file**: `File | Blob | string` - File to upload (File/Blob in browser, base64 string in Node.js)
|
|
800
|
+
- **onSuccess**: `SuccessCallback<UploadResponse>` (optional) - Success callback
|
|
801
|
+
- **onError**: `ErrorCallback` (optional) - Error callback
|
|
802
|
+
- **Returns**: `Promise<ApiResponse<UploadResponse>>`
|
|
803
|
+
|
|
804
|
+
##### `uploadText(text, onSuccess?, onError?)`
|
|
805
|
+
|
|
806
|
+
Uploads text to the Text Upload Cache.
|
|
807
|
+
|
|
808
|
+
- **text**: `string` - Text content to upload
|
|
809
|
+
- **onSuccess**: `SuccessCallback<UploadResponse>` (optional) - Success callback
|
|
810
|
+
- **onError**: `ErrorCallback` (optional) - Error callback
|
|
811
|
+
- **Returns**: `Promise<ApiResponse<UploadResponse>>`
|
|
812
|
+
|
|
813
|
+
##### `uploadTable(tableData, onSuccess?, onError?)`
|
|
814
|
+
|
|
815
|
+
Uploads table data to the Table Upload Cache.
|
|
816
|
+
|
|
817
|
+
- **tableData**: `Record<string, unknown>[]` - Table data to upload
|
|
818
|
+
- **onSuccess**: `SuccessCallback<UploadResponse>` (optional) - Success callback
|
|
819
|
+
- **onError**: `ErrorCallback` (optional) - Error callback
|
|
820
|
+
- **Returns**: `Promise<ApiResponse<UploadResponse>>`
|
|
821
|
+
|
|
822
|
+
##### `subscribeToSocket(sessionId, callbacks?, options?)`
|
|
823
|
+
|
|
824
|
+
Creates a Server-Sent Events (SSE) connection to subscribe to real-time agent updates.
|
|
825
|
+
|
|
826
|
+
- **sessionId**: `string` - Session ID to subscribe to
|
|
827
|
+
- **callbacks**: `SocketCallbacks` (optional) - Event callbacks
|
|
828
|
+
- **options**: `SocketOptions` (optional) - Socket connection options
|
|
829
|
+
- **Returns**: `{ url: string; close: () => void; readyState: number }`
|
|
830
|
+
|
|
831
|
+
##### `get(endpoint?, onSuccess?, onError?)`
|
|
832
|
+
|
|
833
|
+
Makes a GET request to the API.
|
|
834
|
+
|
|
835
|
+
- **endpoint**: `string` (optional) - Endpoint path
|
|
836
|
+
- **onSuccess**: `SuccessCallback` (optional) - Success callback
|
|
837
|
+
- **onError**: `ErrorCallback` (optional) - Error callback
|
|
838
|
+
- **Returns**: `Promise<ApiResponse<T>>`
|
|
839
|
+
|
|
840
|
+
##### `post(payload?, endpoint?, onSuccess?, onError?)`
|
|
841
|
+
|
|
842
|
+
Makes a POST request to the API.
|
|
843
|
+
|
|
844
|
+
- **payload**: `Record<string, unknown>` (optional) - JSON payload
|
|
845
|
+
- **endpoint**: `string` (optional) - Endpoint path
|
|
846
|
+
- **onSuccess**: `SuccessCallback` (optional) - Success callback
|
|
847
|
+
- **onError**: `ErrorCallback` (optional) - Error callback
|
|
848
|
+
- **Returns**: `Promise<ApiResponse<T>>`
|
|
849
|
+
|
|
850
|
+
## Type Definitions
|
|
851
|
+
|
|
852
|
+
All TypeScript types are exported from the main entry point. Key types include:
|
|
853
|
+
|
|
854
|
+
- `ApiConfig` - Client configuration
|
|
855
|
+
- `InitiateConversationRequest` - Single conversation message
|
|
856
|
+
- `InitiateConversationWithContext` - Array of conversation messages
|
|
857
|
+
- `ConversationResponse` - Response from conversation request
|
|
858
|
+
- `PollRequest` - Poll request payload
|
|
859
|
+
- `PollResponse` - Poll response payload
|
|
860
|
+
- `UploadResponse` - Upload response payload
|
|
861
|
+
- `SocketMessage` - Real-time socket message
|
|
862
|
+
- `SocketCallbacks` - Socket event callbacks
|
|
863
|
+
- `SocketOptions` - Socket connection options
|
|
864
|
+
- `Logger` - Custom logger interface
|
|
865
|
+
|
|
866
|
+
See `src/types.ts` for complete type definitions.
|
|
867
|
+
|
|
868
|
+
# Installing on npm
|
|
869
|
+
|
|
870
|
+
```
|
|
871
|
+
npm login
|
|
872
|
+
npm publish
|
|
873
|
+
```
|