@ragbits/api-client 0.0.1 → 0.0.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.
- package/README.md +252 -58
- package/dist/index.cjs +220 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +189 -0
- package/dist/types.d.ts +238 -0
- package/package.json +5 -4
- package/eslint.config.js +0 -21
- package/prettier.config.js +0 -6
- package/src/index.ts +0 -213
- package/src/test/RagbitsClient.test.ts +0 -484
- package/src/test/mocks/handlers.ts +0 -98
- package/src/test/setup.ts +0 -23
- package/src/test/types.test.ts +0 -35
- package/src/test/utils.ts +0 -28
- package/src/types.ts +0 -259
- package/tsconfig.json +0 -16
- package/vitest.config.ts +0 -20
package/README.md
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @ragbits/api-client
|
|
2
2
|
|
|
3
|
-
A TypeScript client for communicating with the Ragbits API. This client provides methods for both regular HTTP requests and server-sent events (streaming) functionality.
|
|
3
|
+
A TypeScript client for communicating with the Ragbits API. This client provides type-safe methods for both regular HTTP requests and server-sent events (streaming) functionality.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Type-safe API calls** - Full TypeScript support with predefined endpoints
|
|
8
|
+
- **Streaming support** - Real-time server-sent events with proper error handling
|
|
9
|
+
- **Modern JavaScript** - ES modules and CommonJS support
|
|
10
|
+
- **Abortable requests** - Cancel ongoing requests and streams
|
|
11
|
+
- **Error handling** - Comprehensive error handling with detailed error messages
|
|
12
|
+
- **Zero dependencies** - Lightweight with no runtime dependencies
|
|
4
13
|
|
|
5
14
|
## Installation
|
|
6
15
|
|
|
7
16
|
```bash
|
|
8
|
-
npm install ragbits
|
|
17
|
+
npm install @ragbits/api-client
|
|
9
18
|
```
|
|
10
19
|
|
|
11
|
-
##
|
|
20
|
+
## Quick Start
|
|
12
21
|
|
|
13
22
|
```typescript
|
|
14
|
-
import { RagbitsClient
|
|
23
|
+
import { RagbitsClient } from '@ragbits/api-client'
|
|
15
24
|
|
|
16
25
|
// Initialize the client
|
|
17
26
|
const client = new RagbitsClient({
|
|
@@ -19,20 +28,21 @@ const client = new RagbitsClient({
|
|
|
19
28
|
})
|
|
20
29
|
|
|
21
30
|
// Get API configuration
|
|
22
|
-
const config = await client.
|
|
31
|
+
const config = await client.makeRequest('/api/config')
|
|
23
32
|
|
|
24
33
|
// Send a chat message with streaming response
|
|
25
|
-
const cleanup = client.
|
|
34
|
+
const cleanup = client.makeStreamRequest(
|
|
35
|
+
'/api/chat',
|
|
26
36
|
{
|
|
27
37
|
message: 'Hello!',
|
|
28
38
|
history: [],
|
|
29
39
|
context: {}, // Optional
|
|
30
40
|
},
|
|
31
41
|
{
|
|
32
|
-
onMessage: (data
|
|
42
|
+
onMessage: (data) => {
|
|
33
43
|
console.log('Received message:', data)
|
|
34
44
|
},
|
|
35
|
-
onError: (error
|
|
45
|
+
onError: (error) => {
|
|
36
46
|
console.error('Error:', error)
|
|
37
47
|
},
|
|
38
48
|
onClose: () => {
|
|
@@ -45,10 +55,13 @@ const cleanup = client.sendChatMessage(
|
|
|
45
55
|
cleanup()
|
|
46
56
|
|
|
47
57
|
// Send feedback
|
|
48
|
-
await client.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
58
|
+
await client.makeRequest('/api/feedback', {
|
|
59
|
+
method: 'POST',
|
|
60
|
+
body: {
|
|
61
|
+
message_id: 'message-123',
|
|
62
|
+
feedback: 'like',
|
|
63
|
+
payload: { reason: 'helpful' },
|
|
64
|
+
},
|
|
52
65
|
})
|
|
53
66
|
```
|
|
54
67
|
|
|
@@ -61,86 +74,267 @@ The main client class for interacting with the Ragbits API.
|
|
|
61
74
|
#### Constructor
|
|
62
75
|
|
|
63
76
|
```typescript
|
|
64
|
-
new RagbitsClient(config?:
|
|
77
|
+
new RagbitsClient(config?: ClientConfig)
|
|
65
78
|
```
|
|
66
79
|
|
|
80
|
+
**Parameters:**
|
|
81
|
+
|
|
67
82
|
- `config.baseUrl` (optional): Base URL for the API. Defaults to 'http://127.0.0.1:8000'
|
|
68
83
|
|
|
84
|
+
**Throws:** `Error` if the base URL is invalid
|
|
85
|
+
|
|
69
86
|
#### Methods
|
|
70
87
|
|
|
71
|
-
##### `
|
|
88
|
+
##### `getBaseUrl(): string`
|
|
89
|
+
|
|
90
|
+
Get the base URL used by this client.
|
|
91
|
+
|
|
92
|
+
**Returns:** The configured base URL
|
|
93
|
+
|
|
94
|
+
##### `makeRequest<T>(endpoint, options?): Promise<T>`
|
|
95
|
+
|
|
96
|
+
Make a type-safe API request to predefined endpoints.
|
|
97
|
+
|
|
98
|
+
**Parameters:**
|
|
72
99
|
|
|
73
|
-
|
|
100
|
+
- `endpoint`: Predefined API endpoint path (e.g., '/api/config', '/api/feedback')
|
|
101
|
+
- `options` (optional): Request options
|
|
102
|
+
- `method`: HTTP method (defaults to endpoint's predefined method)
|
|
103
|
+
- `body`: Request body (typed based on endpoint)
|
|
104
|
+
- `headers`: Additional headers
|
|
105
|
+
- `signal`: AbortSignal for cancelling the request
|
|
74
106
|
|
|
75
|
-
|
|
107
|
+
**Returns:** Promise with the typed response
|
|
76
108
|
|
|
77
|
-
|
|
109
|
+
**Example:**
|
|
78
110
|
|
|
79
|
-
|
|
111
|
+
```typescript
|
|
112
|
+
// GET request
|
|
113
|
+
const config = await client.makeRequest('/api/config')
|
|
114
|
+
|
|
115
|
+
// POST request
|
|
116
|
+
const feedback = await client.makeRequest('/api/feedback', {
|
|
117
|
+
method: 'POST',
|
|
118
|
+
body: {
|
|
119
|
+
message_id: 'msg-123',
|
|
120
|
+
feedback: 'like',
|
|
121
|
+
payload: { rating: 5 },
|
|
122
|
+
},
|
|
123
|
+
})
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
##### `makeStreamRequest<T>(endpoint, data, callbacks, signal?): () => void`
|
|
80
127
|
|
|
81
|
-
-
|
|
82
|
-
- `chatRequest`: ChatRequest
|
|
83
|
-
- `message`: string - User message
|
|
84
|
-
- `history`: Array<{ role: string; content: string; id?: string }> - Chat history
|
|
85
|
-
- `context`: Record<string, unknown> (optional) - Additional context
|
|
86
|
-
- `callbacks`: StreamCallbacks
|
|
87
|
-
- `onMessage`: (data: ChatResponse) => void | Promise<void> - Called when a message chunk is received
|
|
88
|
-
- `onError`: (error: string) => void | Promise<void> - Called when an error occurs
|
|
89
|
-
- `onClose`: () => void | Promise<void> (optional) - Called when the stream closes
|
|
90
|
-
- Returns: `() => void` - Cleanup function to cancel the stream
|
|
128
|
+
Make a type-safe streaming request to predefined streaming endpoints.
|
|
91
129
|
|
|
92
|
-
|
|
130
|
+
**Parameters:**
|
|
93
131
|
|
|
94
|
-
|
|
132
|
+
- `endpoint`: Predefined streaming endpoint path (e.g., '/api/chat')
|
|
133
|
+
- `data`: Request data (typed based on endpoint)
|
|
134
|
+
- `callbacks`: Stream callbacks
|
|
135
|
+
- `onMessage`: Called when a message chunk is received
|
|
136
|
+
- `onError`: Called when an error occurs
|
|
137
|
+
- `onClose`: Called when the stream closes (optional)
|
|
138
|
+
- `signal` (optional): AbortSignal for cancelling the stream
|
|
95
139
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
140
|
+
**Returns:** Cleanup function to cancel the stream
|
|
141
|
+
|
|
142
|
+
**Example:**
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
const cleanup = client.makeStreamRequest(
|
|
146
|
+
'/api/chat',
|
|
147
|
+
{
|
|
148
|
+
message: 'Tell me about AI',
|
|
149
|
+
history: [
|
|
150
|
+
{ role: 'user', content: 'Hello', id: 'msg-1' },
|
|
151
|
+
{ role: 'assistant', content: 'Hi there!', id: 'msg-2' },
|
|
152
|
+
],
|
|
153
|
+
context: { user_id: 'user-123' },
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
onMessage: (data) => {
|
|
157
|
+
switch (data.type) {
|
|
158
|
+
case 'text':
|
|
159
|
+
console.log('Text:', data.content)
|
|
160
|
+
break
|
|
161
|
+
case 'reference':
|
|
162
|
+
console.log('Reference:', data.content.title)
|
|
163
|
+
break
|
|
164
|
+
case 'message_id':
|
|
165
|
+
console.log('Message ID:', data.content)
|
|
166
|
+
break
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
onError: (error) => {
|
|
170
|
+
console.error('Stream error:', error)
|
|
171
|
+
},
|
|
172
|
+
onClose: () => {
|
|
173
|
+
console.log('Stream completed')
|
|
174
|
+
},
|
|
175
|
+
}
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
// Cancel stream
|
|
179
|
+
cleanup()
|
|
180
|
+
```
|
|
102
181
|
|
|
103
182
|
## Types
|
|
104
183
|
|
|
105
|
-
###
|
|
184
|
+
### Core Types
|
|
185
|
+
|
|
186
|
+
#### `ClientConfig`
|
|
106
187
|
|
|
107
188
|
```typescript
|
|
108
|
-
{
|
|
109
|
-
|
|
110
|
-
content: any
|
|
189
|
+
interface ClientConfig {
|
|
190
|
+
baseUrl?: string
|
|
111
191
|
}
|
|
112
192
|
```
|
|
113
193
|
|
|
114
|
-
|
|
194
|
+
#### `Message`
|
|
115
195
|
|
|
116
196
|
```typescript
|
|
117
|
-
{
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
197
|
+
interface Message {
|
|
198
|
+
role: MessageRole
|
|
199
|
+
content: string
|
|
200
|
+
id?: string
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
enum MessageRole {
|
|
204
|
+
USER = 'user',
|
|
205
|
+
ASSISTANT = 'assistant',
|
|
206
|
+
SYSTEM = 'system',
|
|
125
207
|
}
|
|
126
208
|
```
|
|
127
209
|
|
|
128
|
-
|
|
210
|
+
#### `ChatRequest`
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
interface ChatRequest {
|
|
214
|
+
message: string
|
|
215
|
+
history: Message[]
|
|
216
|
+
context?: Record<string, unknown>
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
#### `TypedChatResponse`
|
|
221
|
+
|
|
222
|
+
Union type for all possible chat response types:
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
type TypedChatResponse =
|
|
226
|
+
| { type: 'text'; content: string }
|
|
227
|
+
| { type: 'reference'; content: Reference }
|
|
228
|
+
| { type: 'message_id'; content: string }
|
|
229
|
+
| { type: 'conversation_id'; content: string }
|
|
230
|
+
| { type: 'state_update'; content: ServerState }
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
#### `FeedbackRequest`
|
|
129
234
|
|
|
130
235
|
```typescript
|
|
131
|
-
{
|
|
236
|
+
interface FeedbackRequest {
|
|
132
237
|
message_id: string
|
|
133
|
-
feedback:
|
|
238
|
+
feedback: FeedbackType
|
|
134
239
|
payload: Record<string, unknown> | null
|
|
135
240
|
}
|
|
241
|
+
|
|
242
|
+
enum FeedbackType {
|
|
243
|
+
LIKE = 'like',
|
|
244
|
+
DISLIKE = 'dislike',
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
#### `ConfigResponse`
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
interface ConfigResponse {
|
|
252
|
+
feedback: {
|
|
253
|
+
like: { enabled: boolean; form: RJSFSchema | null }
|
|
254
|
+
dislike: { enabled: boolean; form: RJSFSchema | null }
|
|
255
|
+
}
|
|
256
|
+
customization: UICustomization | null
|
|
257
|
+
}
|
|
136
258
|
```
|
|
137
259
|
|
|
138
|
-
|
|
260
|
+
#### `StreamCallbacks<T, E>`
|
|
139
261
|
|
|
140
262
|
```typescript
|
|
141
|
-
{
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
263
|
+
interface StreamCallbacks<T, E = Error> {
|
|
264
|
+
onMessage: (data: T) => void | Promise<void>
|
|
265
|
+
onError: (error: E) => void | Promise<void>
|
|
266
|
+
onClose?: () => void | Promise<void>
|
|
145
267
|
}
|
|
146
268
|
```
|
|
269
|
+
|
|
270
|
+
### Advanced Types
|
|
271
|
+
|
|
272
|
+
The package provides extensive TypeScript support with predefined endpoint types:
|
|
273
|
+
|
|
274
|
+
- `ApiEndpointPath` - Union of all available API endpoints
|
|
275
|
+
- `StreamingEndpointPath` - Union of all available streaming endpoints
|
|
276
|
+
- `ApiEndpointResponse<T>` - Response type for a specific endpoint
|
|
277
|
+
- `StreamingEndpointStream<T>` - Stream response type for a specific endpoint
|
|
278
|
+
|
|
279
|
+
## Error Handling
|
|
280
|
+
|
|
281
|
+
The client provides comprehensive error handling:
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
try {
|
|
285
|
+
const config = await client.makeRequest('/api/config')
|
|
286
|
+
} catch (error) {
|
|
287
|
+
if (error instanceof Error) {
|
|
288
|
+
console.error('API Error:', error.message)
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Common error scenarios:
|
|
294
|
+
|
|
295
|
+
- **Network errors** - Connection failures, timeouts
|
|
296
|
+
- **HTTP errors** - 4xx/5xx status codes
|
|
297
|
+
- **Invalid URLs** - Malformed base URL
|
|
298
|
+
- **Stream errors** - Connection drops, parsing errors
|
|
299
|
+
|
|
300
|
+
## Aborting Requests
|
|
301
|
+
|
|
302
|
+
Both regular requests and streams can be aborted:
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
// Abort regular request
|
|
306
|
+
const controller = new AbortController()
|
|
307
|
+
const request = client.makeRequest('/api/config', {
|
|
308
|
+
signal: controller.signal,
|
|
309
|
+
})
|
|
310
|
+
controller.abort() // Cancels the request
|
|
311
|
+
|
|
312
|
+
// Abort stream
|
|
313
|
+
const cleanup = client.makeStreamRequest(
|
|
314
|
+
'/api/chat',
|
|
315
|
+
data,
|
|
316
|
+
callbacks,
|
|
317
|
+
controller.signal
|
|
318
|
+
)
|
|
319
|
+
controller.abort() // Cancels the stream
|
|
320
|
+
cleanup() // Also cancels the stream
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## Browser Support
|
|
324
|
+
|
|
325
|
+
This package supports all modern browsers with fetch API support:
|
|
326
|
+
|
|
327
|
+
- Chrome 42+
|
|
328
|
+
- Firefox 39+
|
|
329
|
+
- Safari 10.1+
|
|
330
|
+
- Edge 14+
|
|
331
|
+
|
|
332
|
+
## Node.js Support
|
|
333
|
+
|
|
334
|
+
For Node.js environments, you'll need:
|
|
335
|
+
|
|
336
|
+
- Node.js 18+
|
|
337
|
+
|
|
338
|
+
## License
|
|
339
|
+
|
|
340
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ChatResponseType: () => ChatResponseType,
|
|
24
|
+
FeedbackType: () => FeedbackType,
|
|
25
|
+
LiveUpdateType: () => LiveUpdateType,
|
|
26
|
+
MessageRole: () => MessageRole,
|
|
27
|
+
RagbitsClient: () => RagbitsClient
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(index_exports);
|
|
30
|
+
|
|
31
|
+
// src/types.ts
|
|
32
|
+
var MessageRole = /* @__PURE__ */ ((MessageRole2) => {
|
|
33
|
+
MessageRole2["USER"] = "user";
|
|
34
|
+
MessageRole2["ASSISTANT"] = "assistant";
|
|
35
|
+
MessageRole2["SYSTEM"] = "system";
|
|
36
|
+
return MessageRole2;
|
|
37
|
+
})(MessageRole || {});
|
|
38
|
+
var ChatResponseType = /* @__PURE__ */ ((ChatResponseType2) => {
|
|
39
|
+
ChatResponseType2["MESSAGE"] = "message";
|
|
40
|
+
ChatResponseType2["REFERENCE"] = "reference";
|
|
41
|
+
ChatResponseType2["STATE_UPDATE"] = "state_update";
|
|
42
|
+
ChatResponseType2["TEXT"] = "text";
|
|
43
|
+
ChatResponseType2["MESSAGE_ID"] = "message_id";
|
|
44
|
+
ChatResponseType2["CONVERSATION_ID"] = "conversation_id";
|
|
45
|
+
ChatResponseType2["LIVE_UPDATE"] = "live_update";
|
|
46
|
+
ChatResponseType2["FOLLOWUP_MESSAGES"] = "followup_messages";
|
|
47
|
+
return ChatResponseType2;
|
|
48
|
+
})(ChatResponseType || {});
|
|
49
|
+
var FeedbackType = /* @__PURE__ */ ((FeedbackType2) => {
|
|
50
|
+
FeedbackType2["LIKE"] = "like";
|
|
51
|
+
FeedbackType2["DISLIKE"] = "dislike";
|
|
52
|
+
return FeedbackType2;
|
|
53
|
+
})(FeedbackType || {});
|
|
54
|
+
var LiveUpdateType = /* @__PURE__ */ ((LiveUpdateType2) => {
|
|
55
|
+
LiveUpdateType2["START"] = "START";
|
|
56
|
+
LiveUpdateType2["FINISH"] = "FINISH";
|
|
57
|
+
return LiveUpdateType2;
|
|
58
|
+
})(LiveUpdateType || {});
|
|
59
|
+
|
|
60
|
+
// src/index.ts
|
|
61
|
+
var RagbitsClient = class {
|
|
62
|
+
/**
|
|
63
|
+
* @param config - Configuration object
|
|
64
|
+
*/
|
|
65
|
+
constructor(config = {}) {
|
|
66
|
+
this.baseUrl = config.baseUrl || "http://127.0.0.1:8000";
|
|
67
|
+
try {
|
|
68
|
+
new URL(this.baseUrl);
|
|
69
|
+
} catch {
|
|
70
|
+
throw new Error(
|
|
71
|
+
`Invalid base URL: ${this.baseUrl}. Please provide a valid URL.`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
if (this.baseUrl.endsWith("/")) {
|
|
75
|
+
this.baseUrl = this.baseUrl.slice(0, -1);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get the base URL used by this client
|
|
80
|
+
*/
|
|
81
|
+
getBaseUrl() {
|
|
82
|
+
return this.baseUrl;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Build full API URL from path
|
|
86
|
+
* @private
|
|
87
|
+
*/
|
|
88
|
+
_buildApiUrl(path) {
|
|
89
|
+
return `${this.baseUrl}${path}`;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Make a request to the API
|
|
93
|
+
* @private
|
|
94
|
+
*/
|
|
95
|
+
async _makeRequest(url, options = {}) {
|
|
96
|
+
const defaultOptions = {
|
|
97
|
+
headers: {
|
|
98
|
+
"Content-Type": "application/json"
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
const response = await fetch(url, { ...defaultOptions, ...options });
|
|
102
|
+
if (!response.ok) {
|
|
103
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
104
|
+
}
|
|
105
|
+
return response;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Method to make API requests to known endpoints only
|
|
109
|
+
* @param endpoint - API endpoint path (must be predefined)
|
|
110
|
+
* @param options - Typed request options for the specific endpoint
|
|
111
|
+
*/
|
|
112
|
+
async makeRequest(endpoint, options) {
|
|
113
|
+
const {
|
|
114
|
+
method = "GET",
|
|
115
|
+
body,
|
|
116
|
+
headers = {},
|
|
117
|
+
...restOptions
|
|
118
|
+
} = options || {};
|
|
119
|
+
const requestOptions = {
|
|
120
|
+
method,
|
|
121
|
+
headers,
|
|
122
|
+
...restOptions
|
|
123
|
+
// This will include signal and other fetch options
|
|
124
|
+
};
|
|
125
|
+
if (body && method !== "GET") {
|
|
126
|
+
requestOptions.body = typeof body === "string" ? body : JSON.stringify(body);
|
|
127
|
+
}
|
|
128
|
+
const response = await this._makeRequest(
|
|
129
|
+
this._buildApiUrl(endpoint),
|
|
130
|
+
requestOptions
|
|
131
|
+
);
|
|
132
|
+
return response.json();
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Method for streaming requests to known endpoints only
|
|
136
|
+
* @param endpoint - Streaming endpoint path (must be predefined)
|
|
137
|
+
* @param data - Request data
|
|
138
|
+
* @param callbacks - Stream callbacks
|
|
139
|
+
* @param signal - Optional AbortSignal for cancelling the request
|
|
140
|
+
*/
|
|
141
|
+
makeStreamRequest(endpoint, data, callbacks, signal) {
|
|
142
|
+
let isCancelled = false;
|
|
143
|
+
const processStream = async (response) => {
|
|
144
|
+
const reader = response.body?.pipeThrough(new TextDecoderStream()).getReader();
|
|
145
|
+
if (!reader) {
|
|
146
|
+
throw new Error("Response body is null");
|
|
147
|
+
}
|
|
148
|
+
while (!isCancelled && !signal?.aborted) {
|
|
149
|
+
try {
|
|
150
|
+
const { value, done } = await reader.read();
|
|
151
|
+
if (done) {
|
|
152
|
+
callbacks.onClose?.();
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
const lines = value.split("\n");
|
|
156
|
+
for (const line of lines) {
|
|
157
|
+
if (!line.startsWith("data: ")) continue;
|
|
158
|
+
try {
|
|
159
|
+
const jsonString = line.replace("data: ", "").trim();
|
|
160
|
+
const parsedData = JSON.parse(
|
|
161
|
+
jsonString
|
|
162
|
+
);
|
|
163
|
+
await callbacks.onMessage(parsedData);
|
|
164
|
+
} catch (parseError) {
|
|
165
|
+
console.error("Error parsing JSON:", parseError);
|
|
166
|
+
await callbacks.onError(
|
|
167
|
+
new Error("Error processing server response")
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
} catch (streamError) {
|
|
172
|
+
console.error("Stream error:", streamError);
|
|
173
|
+
await callbacks.onError(new Error("Error reading stream"));
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
const startStream = async () => {
|
|
179
|
+
try {
|
|
180
|
+
const response = await fetch(this._buildApiUrl(endpoint), {
|
|
181
|
+
method: "POST",
|
|
182
|
+
headers: {
|
|
183
|
+
"Content-Type": "application/json",
|
|
184
|
+
Accept: "text/event-stream"
|
|
185
|
+
},
|
|
186
|
+
body: JSON.stringify(data),
|
|
187
|
+
signal
|
|
188
|
+
});
|
|
189
|
+
if (!response.ok) {
|
|
190
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
191
|
+
}
|
|
192
|
+
await processStream(response);
|
|
193
|
+
} catch (error) {
|
|
194
|
+
if (signal?.aborted) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
console.error("Request error:", error);
|
|
198
|
+
const errorMessage = error instanceof Error ? error.message : "Error connecting to server";
|
|
199
|
+
await callbacks.onError(new Error(errorMessage));
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
try {
|
|
203
|
+
startStream();
|
|
204
|
+
} catch (error) {
|
|
205
|
+
const errorMessage = error instanceof Error ? error.message : "Failed to start stream";
|
|
206
|
+
callbacks.onError(new Error(errorMessage));
|
|
207
|
+
}
|
|
208
|
+
return () => {
|
|
209
|
+
isCancelled = true;
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
214
|
+
0 && (module.exports = {
|
|
215
|
+
ChatResponseType,
|
|
216
|
+
FeedbackType,
|
|
217
|
+
LiveUpdateType,
|
|
218
|
+
MessageRole,
|
|
219
|
+
RagbitsClient
|
|
220
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ClientConfig, StreamCallbacks, ApiEndpointPath, ApiEndpointResponse, TypedApiRequestOptions, StreamingEndpointPath, StreamingEndpointRequest, StreamingEndpointStream } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Client for communicating with the Ragbits API
|
|
4
|
+
*/
|
|
5
|
+
export declare class RagbitsClient {
|
|
6
|
+
private readonly baseUrl;
|
|
7
|
+
/**
|
|
8
|
+
* @param config - Configuration object
|
|
9
|
+
*/
|
|
10
|
+
constructor(config?: ClientConfig);
|
|
11
|
+
/**
|
|
12
|
+
* Get the base URL used by this client
|
|
13
|
+
*/
|
|
14
|
+
getBaseUrl(): string;
|
|
15
|
+
/**
|
|
16
|
+
* Build full API URL from path
|
|
17
|
+
* @private
|
|
18
|
+
*/
|
|
19
|
+
private _buildApiUrl;
|
|
20
|
+
/**
|
|
21
|
+
* Make a request to the API
|
|
22
|
+
* @private
|
|
23
|
+
*/
|
|
24
|
+
private _makeRequest;
|
|
25
|
+
/**
|
|
26
|
+
* Method to make API requests to known endpoints only
|
|
27
|
+
* @param endpoint - API endpoint path (must be predefined)
|
|
28
|
+
* @param options - Typed request options for the specific endpoint
|
|
29
|
+
*/
|
|
30
|
+
makeRequest<T extends ApiEndpointPath>(endpoint: T, options?: TypedApiRequestOptions<T>): Promise<ApiEndpointResponse<T>>;
|
|
31
|
+
/**
|
|
32
|
+
* Method for streaming requests to known endpoints only
|
|
33
|
+
* @param endpoint - Streaming endpoint path (must be predefined)
|
|
34
|
+
* @param data - Request data
|
|
35
|
+
* @param callbacks - Stream callbacks
|
|
36
|
+
* @param signal - Optional AbortSignal for cancelling the request
|
|
37
|
+
*/
|
|
38
|
+
makeStreamRequest<T extends StreamingEndpointPath>(endpoint: T, data: StreamingEndpointRequest<T>, callbacks: StreamCallbacks<StreamingEndpointStream<T>>, signal?: AbortSignal): () => void;
|
|
39
|
+
}
|
|
40
|
+
export * from './types';
|