@schmitech/chatbot-api 0.3.1 → 0.4.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 +128 -287
- package/api.d.ts +26 -1
- package/dist/api.cjs +2 -2
- package/dist/api.cjs.map +1 -1
- package/dist/api.mjs +151 -85
- package/dist/api.mjs.d.ts +1 -9
- package/dist/api.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,76 +1,46 @@
|
|
|
1
|
-
# Chatbot API Client
|
|
1
|
+
# 🤖 Chatbot API Client
|
|
2
2
|
|
|
3
|
-
A JavaScript/TypeScript client
|
|
3
|
+
A JavaScript/TypeScript client for seamless interaction with the Chatbot server, now supporting API key authentication and session tracking.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## 📥 Installation
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
### 📍 Local Development (npm link)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
```bash
|
|
13
|
-
npm run build
|
|
14
|
-
npm link
|
|
15
|
-
```
|
|
11
|
+
Use during local development:
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
3. Now you can import and use the library in your project:
|
|
23
|
-
```javascript
|
|
24
|
-
import { streamChat } from 'chatbot-api';
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
### Option 2: Installing from a local directory
|
|
28
|
-
|
|
29
|
-
You can also install the package directly from the local directory:
|
|
30
|
-
|
|
31
|
-
1. In this library directory, run:
|
|
32
|
-
```bash
|
|
33
|
-
npm run build
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
2. In your project directory, run:
|
|
37
|
-
```bash
|
|
38
|
-
npm install /path/to/qa-chatbot-server/api
|
|
39
|
-
```
|
|
13
|
+
```bash
|
|
14
|
+
npm run build
|
|
15
|
+
npm link
|
|
40
16
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
```
|
|
17
|
+
# In your project directory
|
|
18
|
+
npm link @schmitech/chatbot-api
|
|
19
|
+
```
|
|
45
20
|
|
|
46
|
-
###
|
|
21
|
+
### 📂 Local Directory Install
|
|
47
22
|
|
|
48
|
-
|
|
23
|
+
Direct local installation:
|
|
49
24
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
```
|
|
55
|
-
3. Update the package name in package.json to ensure it's unique
|
|
56
|
-
4. Publish the package:
|
|
57
|
-
```bash
|
|
58
|
-
npm publish
|
|
59
|
-
```
|
|
25
|
+
```bash
|
|
26
|
+
npm run build
|
|
27
|
+
npm install /path/to/qa-chatbot-server/api
|
|
28
|
+
```
|
|
60
29
|
|
|
61
|
-
###
|
|
30
|
+
### 🌐 CDN Integration
|
|
62
31
|
|
|
63
|
-
|
|
32
|
+
Integrate directly into websites via CDN:
|
|
64
33
|
|
|
65
34
|
```html
|
|
66
|
-
<!-- For ESM (modern browsers) -->
|
|
67
35
|
<script type="module">
|
|
68
|
-
import { configureApi, streamChat } from 'https://cdn.jsdelivr.net/npm/@schmitech/chatbot-api
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
36
|
+
import { configureApi, streamChat } from 'https://cdn.jsdelivr.net/npm/@schmitech/chatbot-api/dist/api.mjs';
|
|
37
|
+
|
|
38
|
+
configureApi({
|
|
39
|
+
apiUrl: 'https://your-api-server.com',
|
|
40
|
+
apiKey: 'your-api-key',
|
|
41
|
+
sessionId: 'your-session-id' // Optional
|
|
42
|
+
});
|
|
43
|
+
|
|
74
44
|
async function handleChat() {
|
|
75
45
|
for await (const response of streamChat('Hello', false)) {
|
|
76
46
|
console.log(response.text);
|
|
@@ -79,315 +49,186 @@ You can include the library directly in your website using jsDelivr CDN:
|
|
|
79
49
|
</script>
|
|
80
50
|
```
|
|
81
51
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
```html
|
|
85
|
-
<script type="module">
|
|
86
|
-
import { configureApi, streamChat } from 'https://cdn.jsdelivr.net/npm/@schmitech/chatbot-api/dist/api.mjs';
|
|
87
|
-
// ...
|
|
88
|
-
</script>
|
|
89
|
-
```
|
|
52
|
+
---
|
|
90
53
|
|
|
91
|
-
## Usage
|
|
54
|
+
## ⚙️ Usage
|
|
92
55
|
|
|
93
|
-
### Configuration (Required)
|
|
56
|
+
### 🚨 Configuration (Required)
|
|
94
57
|
|
|
95
|
-
|
|
58
|
+
You must configure the API client before usage:
|
|
96
59
|
|
|
97
60
|
```javascript
|
|
98
|
-
import { configureApi, streamChat } from 'chatbot-api';
|
|
61
|
+
import { configureApi, streamChat } from '@schmitech/chatbot-api';
|
|
99
62
|
|
|
100
|
-
|
|
101
|
-
|
|
63
|
+
configureApi({
|
|
64
|
+
apiUrl: 'https://your-api-server.com',
|
|
65
|
+
apiKey: 'your-api-key',
|
|
66
|
+
sessionId: 'your-session-id' // Optional
|
|
67
|
+
});
|
|
102
68
|
```
|
|
103
69
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
### Basic Usage
|
|
70
|
+
### 📖 Basic Example
|
|
107
71
|
|
|
108
72
|
```javascript
|
|
109
|
-
import { configureApi, streamChat } from 'chatbot-api';
|
|
110
|
-
|
|
111
73
|
async function chat() {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
74
|
+
configureApi({
|
|
75
|
+
apiUrl: 'https://your-api-server.com',
|
|
76
|
+
apiKey: 'your-api-key',
|
|
77
|
+
sessionId: 'user_123_session_456' // Optional
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
for await (const response of streamChat('Hello, how can I help?', false)) {
|
|
118
81
|
console.log(response.text);
|
|
119
|
-
|
|
120
|
-
// Check if this is the final response
|
|
121
|
-
if (response.done) {
|
|
122
|
-
console.log('Chat complete!');
|
|
123
|
-
}
|
|
82
|
+
if (response.done) console.log('Chat complete!');
|
|
124
83
|
}
|
|
125
84
|
}
|
|
126
85
|
|
|
127
86
|
chat();
|
|
128
87
|
```
|
|
129
88
|
|
|
130
|
-
###
|
|
89
|
+
### 🎙️ Voice-enabled Example
|
|
131
90
|
|
|
132
91
|
```javascript
|
|
133
|
-
import { configureApi, streamChat } from 'chatbot-api';
|
|
134
|
-
|
|
135
92
|
async function chatWithVoice() {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
93
|
+
configureApi({
|
|
94
|
+
apiUrl: 'https://your-api-server.com',
|
|
95
|
+
apiKey: 'your-api-key',
|
|
96
|
+
sessionId: 'user_123_session_456' // Optional
|
|
97
|
+
});
|
|
98
|
+
|
|
140
99
|
for await (const response of streamChat('Tell me a joke', true)) {
|
|
141
|
-
|
|
142
|
-
if (response.text) {
|
|
143
|
-
console.log(response.text);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Handle audio content when available
|
|
147
|
-
if (response.type === 'audio' && response.content) {
|
|
148
|
-
// Process audio content (base64 encoded)
|
|
100
|
+
if (response.type === 'audio') {
|
|
149
101
|
console.log('Received audio content');
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if (response.done) {
|
|
154
|
-
console.log('Chat complete!');
|
|
102
|
+
} else {
|
|
103
|
+
console.log(response.text);
|
|
155
104
|
}
|
|
105
|
+
if (response.done) console.log('Chat complete!');
|
|
156
106
|
}
|
|
157
107
|
}
|
|
158
108
|
|
|
159
109
|
chatWithVoice();
|
|
160
110
|
```
|
|
161
111
|
|
|
162
|
-
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## ⚛️ React Integration
|
|
115
|
+
|
|
116
|
+
Configure once globally:
|
|
163
117
|
|
|
164
118
|
```jsx
|
|
165
|
-
import React, { useState
|
|
166
|
-
import { configureApi, streamChat } from 'chatbot-api';
|
|
119
|
+
import React, { useState } from 'react';
|
|
120
|
+
import { configureApi, streamChat } from '@schmitech/chatbot-api';
|
|
167
121
|
|
|
168
|
-
|
|
169
|
-
|
|
122
|
+
configureApi({
|
|
123
|
+
apiUrl: 'https://your-api-server.com',
|
|
124
|
+
apiKey: 'your-api-key',
|
|
125
|
+
sessionId: 'user_123_session_456' // Optional
|
|
126
|
+
});
|
|
170
127
|
|
|
171
128
|
function ChatComponent() {
|
|
172
129
|
const [messages, setMessages] = useState([]);
|
|
173
130
|
const [input, setInput] = useState('');
|
|
174
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
175
131
|
|
|
176
132
|
const handleSubmit = async (e) => {
|
|
177
133
|
e.preventDefault();
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
let fullResponse = '';
|
|
186
|
-
|
|
187
|
-
try {
|
|
188
|
-
for await (const response of streamChat(userMessage, false)) {
|
|
189
|
-
if (response.text) {
|
|
190
|
-
fullResponse += response.text;
|
|
191
|
-
// Update the UI with each chunk of text as it arrives
|
|
192
|
-
setMessages(prev => [
|
|
193
|
-
...prev.slice(0, -1),
|
|
194
|
-
{ text: userMessage, isUser: true },
|
|
195
|
-
{ text: fullResponse, isUser: false, isComplete: response.done }
|
|
196
|
-
]);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (response.done) {
|
|
200
|
-
setIsLoading(false);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
} catch (error) {
|
|
204
|
-
console.error('Chat error:', error);
|
|
205
|
-
setMessages(prev => [...prev, {
|
|
206
|
-
text: `Error: ${error.message}`,
|
|
207
|
-
isUser: false,
|
|
208
|
-
isError: true
|
|
209
|
-
}]);
|
|
210
|
-
setIsLoading(false);
|
|
134
|
+
setMessages(prev => [...prev, { text: input, isUser: true }]);
|
|
135
|
+
|
|
136
|
+
let responseText = '';
|
|
137
|
+
for await (const response of streamChat(input, false)) {
|
|
138
|
+
responseText += response.text;
|
|
139
|
+
setMessages(prev => [...prev, { text: responseText, isUser: false }]);
|
|
140
|
+
if (response.done) break;
|
|
211
141
|
}
|
|
142
|
+
setInput('');
|
|
212
143
|
};
|
|
213
144
|
|
|
214
145
|
return (
|
|
215
|
-
<
|
|
216
|
-
<
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
{msg.text}
|
|
220
|
-
</div>
|
|
221
|
-
))}
|
|
222
|
-
{isLoading && <div className="loading">...</div>}
|
|
223
|
-
</div>
|
|
224
|
-
|
|
225
|
-
<form onSubmit={handleSubmit}>
|
|
226
|
-
<input
|
|
227
|
-
value={input}
|
|
228
|
-
onChange={(e) => setInput(e.target.value)}
|
|
229
|
-
placeholder="Type your message..."
|
|
230
|
-
disabled={isLoading}
|
|
231
|
-
/>
|
|
232
|
-
<button type="submit" disabled={isLoading}>Send</button>
|
|
233
|
-
</form>
|
|
234
|
-
</div>
|
|
146
|
+
<form onSubmit={handleSubmit}>
|
|
147
|
+
<input value={input} onChange={(e) => setInput(e.target.value)} />
|
|
148
|
+
<button type="submit">Send</button>
|
|
149
|
+
</form>
|
|
235
150
|
);
|
|
236
151
|
}
|
|
237
152
|
|
|
238
153
|
export default ChatComponent;
|
|
239
154
|
```
|
|
240
155
|
|
|
241
|
-
|
|
156
|
+
---
|
|
242
157
|
|
|
243
|
-
|
|
158
|
+
## 📱 Mobile Usage
|
|
244
159
|
|
|
245
|
-
|
|
160
|
+
### 📲 React Native
|
|
246
161
|
|
|
247
162
|
```javascript
|
|
248
|
-
|
|
163
|
+
configureApi({
|
|
164
|
+
apiUrl: 'https://your-api-server.com',
|
|
165
|
+
apiKey: 'your-api-key',
|
|
166
|
+
sessionId: 'user_123_session_456' // Optional
|
|
167
|
+
});
|
|
249
168
|
|
|
250
|
-
// Configure API
|
|
251
|
-
configureApi('https://your-api-server.com');
|
|
252
|
-
|
|
253
|
-
// Usage in React Native component
|
|
254
169
|
async function handleChat(message) {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
// Update UI with response.text
|
|
258
|
-
}
|
|
259
|
-
} catch (error) {
|
|
260
|
-
console.error('Chat error:', error);
|
|
170
|
+
for await (const response of streamChat(message, false)) {
|
|
171
|
+
// Handle response
|
|
261
172
|
}
|
|
262
173
|
}
|
|
263
174
|
```
|
|
264
175
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
For pure native iOS, you'll need to create a Swift wrapper:
|
|
268
|
-
|
|
269
|
-
```swift
|
|
270
|
-
// ChatService.swift
|
|
271
|
-
import Foundation
|
|
272
|
-
|
|
273
|
-
class ChatService {
|
|
274
|
-
private let apiUrl: String
|
|
275
|
-
|
|
276
|
-
init(apiUrl: String) {
|
|
277
|
-
self.apiUrl = apiUrl
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
func sendMessage(_ message: String, voiceEnabled: Bool,
|
|
281
|
-
onResponse: @escaping (String, Bool) -> Void,
|
|
282
|
-
onError: @escaping (Error) -> Void) {
|
|
283
|
-
|
|
284
|
-
guard let url = URL(string: "\(apiUrl)/chat") else {
|
|
285
|
-
onError(NSError(domain: "Invalid URL", code: 0))
|
|
286
|
-
return
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
var request = URLRequest(url: url)
|
|
290
|
-
request.httpMethod = "POST"
|
|
291
|
-
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
|
292
|
-
|
|
293
|
-
let body: [String: Any] = ["message": message, "voiceEnabled": voiceEnabled]
|
|
294
|
-
request.httpBody = try? JSONSerialization.data(withJSONObject: body)
|
|
295
|
-
|
|
296
|
-
let task = URLSession.shared.dataTask(with: request) { data, response, error in
|
|
297
|
-
// Handle streaming responses
|
|
298
|
-
// ...
|
|
299
|
-
}
|
|
300
|
-
task.resume()
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
### Native Android (Kotlin)
|
|
306
|
-
|
|
307
|
-
For pure native Android, you'd implement:
|
|
308
|
-
|
|
309
|
-
```kotlin
|
|
310
|
-
// ChatService.kt
|
|
311
|
-
class ChatService(private val apiUrl: String) {
|
|
312
|
-
fun sendMessage(
|
|
313
|
-
message: String,
|
|
314
|
-
voiceEnabled: Boolean,
|
|
315
|
-
onResponse: (text: String, isDone: Boolean) -> Unit,
|
|
316
|
-
onError: (error: Throwable) -> Unit
|
|
317
|
-
) {
|
|
318
|
-
val client = OkHttpClient()
|
|
319
|
-
|
|
320
|
-
val requestBody = JSONObject().apply {
|
|
321
|
-
put("message", message)
|
|
322
|
-
put("voiceEnabled", voiceEnabled)
|
|
323
|
-
}.toString().toRequestBody("application/json".toMediaType())
|
|
324
|
-
|
|
325
|
-
val request = Request.Builder()
|
|
326
|
-
.url("$apiUrl/chat")
|
|
327
|
-
.post(requestBody)
|
|
328
|
-
.build()
|
|
329
|
-
|
|
330
|
-
// Set up streaming response handling
|
|
331
|
-
// ...
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
```
|
|
176
|
+
---
|
|
335
177
|
|
|
336
|
-
|
|
178
|
+
## 📚 API Reference
|
|
337
179
|
|
|
338
|
-
|
|
339
|
-
2. **WebView**: Embed a web component in your app that uses the JS client
|
|
340
|
-
3. **Capacitor/Cordova**: Create a hybrid app, use the npm package directly
|
|
180
|
+
### `configureApi(config)`
|
|
341
181
|
|
|
342
|
-
|
|
182
|
+
| Parameter | Description | Required |
|
|
183
|
+
|-----------|-------------|----------|
|
|
184
|
+
| `apiUrl` | Chatbot API URL | ✅ Yes |
|
|
185
|
+
| `apiKey` | API key for authentication | ✅ Yes |
|
|
186
|
+
| `sessionId` | Session ID for tracking conversations | ❌ No |
|
|
343
187
|
|
|
344
|
-
|
|
188
|
+
---
|
|
345
189
|
|
|
346
|
-
|
|
190
|
+
## 📤 Publish to npm
|
|
347
191
|
|
|
348
|
-
|
|
349
|
-
- **Returns**: void
|
|
192
|
+
**Build package:**
|
|
350
193
|
|
|
351
|
-
|
|
194
|
+
```bash
|
|
195
|
+
npm run build
|
|
196
|
+
```
|
|
352
197
|
|
|
353
|
-
|
|
198
|
+
**Test locally (optional):**
|
|
354
199
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
200
|
+
```bash
|
|
201
|
+
npm pack --dry-run
|
|
202
|
+
```
|
|
358
203
|
|
|
359
|
-
|
|
204
|
+
**Update version:**
|
|
360
205
|
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
text?: string; // The text response
|
|
364
|
-
content?: string; // Alternative property for text content
|
|
365
|
-
done?: boolean; // Whether this is the final response
|
|
366
|
-
type?: string; // Type of response (e.g., 'text', 'audio')
|
|
367
|
-
}
|
|
206
|
+
```bash
|
|
207
|
+
npm version [patch|minor|major]
|
|
368
208
|
```
|
|
369
209
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
### Building the Library
|
|
210
|
+
**Publish:**
|
|
373
211
|
|
|
374
212
|
```bash
|
|
375
|
-
npm
|
|
213
|
+
npm publish --access public
|
|
376
214
|
```
|
|
377
215
|
|
|
378
|
-
|
|
216
|
+
---
|
|
379
217
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
218
|
+
## 🛠️ Development
|
|
219
|
+
|
|
220
|
+
### 🧪 Testing
|
|
383
221
|
|
|
384
|
-
|
|
385
|
-
|
|
222
|
+
```bash
|
|
223
|
+
# Test single query
|
|
224
|
+
npm run test-query "your query" "http://your-api-server.com" "your-api-key" ["your-session-id"]
|
|
386
225
|
|
|
387
|
-
# Test
|
|
388
|
-
npm run test-query
|
|
226
|
+
# Test multiple queries from JSON file
|
|
227
|
+
npm run test-query-from-pairs questions.json "http://your-api-server.com" "your-api-key" [number_of_questions] ["your-session-id"]
|
|
389
228
|
```
|
|
390
229
|
|
|
391
|
-
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## 📃 License
|
|
392
233
|
|
|
393
|
-
MIT
|
|
234
|
+
MIT License - See [LICENSE](LICENSE).
|
package/api.d.ts
CHANGED
|
@@ -5,5 +5,30 @@ export interface StreamResponse {
|
|
|
5
5
|
export interface ChatResponse {
|
|
6
6
|
response: string;
|
|
7
7
|
}
|
|
8
|
-
|
|
8
|
+
interface MCPResponse {
|
|
9
|
+
jsonrpc: "2.0";
|
|
10
|
+
id: string;
|
|
11
|
+
result?: {
|
|
12
|
+
type?: "start" | "chunk" | "complete";
|
|
13
|
+
chunk?: {
|
|
14
|
+
content: string;
|
|
15
|
+
};
|
|
16
|
+
output?: {
|
|
17
|
+
messages: Array<{
|
|
18
|
+
role: string;
|
|
19
|
+
content: string;
|
|
20
|
+
}>;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
error?: {
|
|
24
|
+
code: number;
|
|
25
|
+
message: string;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export declare const configureApi: (apiUrl: string, apiKey: string, sessionId: string) => void;
|
|
9
29
|
export declare function streamChat(message: string, stream?: boolean): AsyncGenerator<StreamResponse>;
|
|
30
|
+
export declare function sendToolsRequest(tools: Array<{
|
|
31
|
+
name: string;
|
|
32
|
+
parameters: Record<string, any>;
|
|
33
|
+
}>): Promise<MCPResponse>;
|
|
34
|
+
export {};
|
package/dist/api.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let
|
|
2
|
-
`);a=
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let m=null,A=null,P=null;const $=(t,e,r)=>{if(!t||typeof t!="string")throw new Error("API URL must be a valid string");if(!e||typeof e!="string")throw new Error("API key must be a valid string");if(!r||typeof r!="string")throw new Error("Session ID must be a valid string");m=t,A=e,P=r},D=()=>{if(!m)throw new Error("API URL not configured. Please call configureApi() with your server URL before using any API functions.");return m},q=()=>{if(!A)throw new Error("API key not configured. Please call configureApi() with your API key before using any API functions.");return A},L=()=>{if(!P)throw new Error("Session ID not configured. Please call configureApi() with your session ID before using any API functions.");return P},R=(t,e={})=>{t.startsWith("https:");const n={Connection:"keep-alive","X-Request-ID":Date.now().toString(36)+Math.random().toString(36).substring(2),"X-API-Key":q(),"X-Session-ID":L()};return{...e,headers:{...e.headers,...n}}},x=(t,e=!0)=>({jsonrpc:"2.0",method:"tools/call",params:{name:"chat",arguments:{messages:[{role:"user",content:t}],stream:e}},id:Date.now().toString(36)+Math.random().toString(36).substring(2)}),J=t=>({jsonrpc:"2.0",method:"tools/call",params:{name:"tools",arguments:{tools:t}},id:Date.now().toString(36)+Math.random().toString(36).substring(2)});async function*T(t,e=!0){var r,n,u,b,k,E,S,I,v;try{const i=D(),C=new AbortController,j=setTimeout(()=>C.abort(),1e4),l=await fetch(`${i}/v1/chat`,{...R(i,{method:"POST",headers:{"Content-Type":"application/json",Accept:e?"text/event-stream":"application/json"},body:JSON.stringify(x(t,e))}),signal:C.signal});if(clearTimeout(j),!l.ok){const o=await l.text();throw new Error(`Network response was not ok: ${l.status} ${o}`)}if(!e){const o=await l.json();if(o.error)throw new Error(`MCP Error: ${o.error.message}`);(b=(u=(n=(r=o.result)==null?void 0:r.output)==null?void 0:n.messages)==null?void 0:u[0])!=null&&b.content&&(yield{text:o.result.output.messages[0].content,done:!0});return}const p=(k=l.body)==null?void 0:k.getReader();if(!p)throw new Error("No reader available");const M=new TextDecoder;let a="",w="";try{for(;;){const{done:o,value:c}=await p.read();if(o)break;const f=M.decode(c,{stream:!0});a+=f;const N=a.split(`
|
|
2
|
+
`);a=N.pop()||"";for(const d of N)if(d.trim()&&d.startsWith("data: "))try{const h=d.slice(6).trim();if(h==="[DONE]"){yield{text:"",done:!0};break}const s=JSON.parse(h);if(s.result){let g="";if(s.result.type==="start")continue;if(s.result.type==="chunk"&&s.result.chunk?g=s.result.chunk.content:s.result.type==="complete"&&((S=(E=s.result.output)==null?void 0:E.messages)!=null&&S[0])&&(g=s.result.output.messages[0].content),g){const y=O(g,w);y?(w+=y,yield{text:y,done:s.result.type==="complete"}):s.result.type==="complete"&&(yield{text:"",done:!0})}}}catch(h){console.warn("Error parsing JSON chunk:",d,"Error:",h)}}}finally{p.releaseLock()}if(a&&a.startsWith("data: "))try{const o=a.slice(6).trim();if(o!=="[DONE]"){const c=JSON.parse(o);if((v=(I=c.result)==null?void 0:I.chunk)!=null&&v.content){const f=O(c.result.chunk.content,w);f&&(yield{text:f,done:c.result.type==="complete"})}}}catch(o){console.warn("Error parsing final JSON buffer:",a,"Error:",o)}}catch(i){i.name==="AbortError"?yield{text:"Connection timed out. Please check if the server is running.",done:!0}:i.name==="TypeError"&&i.message.includes("Failed to fetch")?yield{text:"Could not connect to the server. Please check if the server is running.",done:!0}:yield{text:`Error: ${i.message}`,done:!0}}}function O(t,e){if(!e)return t;if(e.endsWith(t))return"";if(t.length>e.length){if(t.startsWith(e))return t.slice(e.length);let r=0;const n=Math.min(e.length,t.length);for(;r<n&&e[r]===t[r];)r++;if(r>e.length/2)return t.slice(r)}return t}async function U(t){const e=D(),r=await fetch(`${e}/v1/chat`,R(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(J(t))}));if(!r.ok){const u=await r.text();throw new Error(`Network response was not ok: ${r.status} ${u}`)}const n=await r.json();if(n.error)throw new Error(`MCP Error: ${n.error.message}`);return n}exports.configureApi=$;exports.sendToolsRequest=U;exports.streamChat=T;
|
|
3
3
|
//# sourceMappingURL=api.cjs.map
|
package/dist/api.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.cjs","sources":["../api.ts"],"sourcesContent":["// For Node.js environments, we can use http.Agent for connection pooling\nlet httpAgent: any = null;\nlet httpsAgent: any = null;\n\n// Define the StreamResponse interface\nexport interface StreamResponse {\n text: string;\n done: boolean;\n}\n\nexport interface ChatResponse {\n response: string;\n}\n\n// Store the configured API URL and key\nlet configuredApiUrl: string | null = null;\nlet configuredApiKey: string | null = null;\n\n// Configure the API with a custom URL and API key\nexport const configureApi = (apiUrl: string, apiKey: string): void => {\n if (!apiUrl || typeof apiUrl !== 'string') {\n throw new Error('API URL must be a valid string');\n }\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('API key must be a valid string');\n }\n configuredApiUrl = apiUrl;\n configuredApiKey = apiKey;\n}\n\n// Get the configured API URL or throw an error if not configured\nconst getApiUrl = (): string => {\n if (!configuredApiUrl) {\n throw new Error('API URL not configured. Please call configureApi() with your server URL before using any API functions.');\n }\n return configuredApiUrl;\n};\n\n// Get the configured API key or throw an error if not configured\nconst getApiKey = (): string => {\n if (!configuredApiKey) {\n throw new Error('API key not configured. Please call configureApi() with your API key before using any API functions.');\n }\n return configuredApiKey;\n};\n\n// Helper to get fetch options with connection pooling if available\nconst getFetchOptions = (apiUrl: string, options: RequestInit = {}): RequestInit | any => {\n const isHttps = apiUrl.startsWith('https:');\n \n // Only use agents in Node.js environment\n if (typeof window === 'undefined') {\n if (isHttps && httpsAgent) {\n // Using 'any' type to bypass TypeScript limitations with Node.js http.Agent\n return { ...options, agent: httpsAgent } as any;\n } else if (httpAgent) {\n return { ...options, agent: httpAgent } as any;\n }\n }\n \n // Browser environment\n const requestId = Date.now().toString(36) + Math.random().toString(36).substring(2);\n \n // Use keep-alive header in browser environments\n return {\n ...options,\n headers: {\n ...options.headers,\n 'Connection': 'keep-alive',\n 'X-Request-ID': requestId, // Add unique ID to track requests\n 'X-API-Key': getApiKey() // Add API key to headers\n }\n };\n};\n\nexport async function* streamChat(\n message: string,\n stream: boolean = true\n): AsyncGenerator<StreamResponse> {\n try {\n const API_URL = getApiUrl();\n \n const response = await fetch(`${API_URL}/chat`, getFetchOptions(API_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': stream ? 'text/event-stream' : 'application/json'\n },\n body: JSON.stringify({ message, stream }),\n }));\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(`API request failed: ${response.status} ${errorText}`);\n throw new Error(`Network response was not ok: ${response.status} ${errorText}`);\n }\n\n if (!stream) {\n // Handle non-streaming response\n const data = await response.json() as ChatResponse;\n yield {\n text: data.response,\n done: true\n };\n return;\n }\n \n const reader = response.body?.getReader();\n if (!reader) throw new Error('No reader available');\n\n const decoder = new TextDecoder();\n let buffer = '';\n let currentFullText = ''; // Track full response to detect duplicates\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n buffer += chunk;\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.trim() && line.startsWith('data: ')) {\n try {\n // Properly extract the JSON part by trimming whitespace after 'data:'\n const jsonText = line.slice(6).trim();\n const data = JSON.parse(jsonText);\n \n if (data.text) {\n // Check if this is a duplicate or overlapping chunk\n const newText = extractNewText(data.text, currentFullText);\n \n // Only yield if we have new text\n if (newText) {\n currentFullText += newText;\n yield {\n text: newText,\n done: data.done || false\n };\n } else if (data.done) {\n // Always send done signal even if no new text\n yield {\n text: '',\n done: true\n };\n }\n } else {\n // Pass through as-is if no text property\n yield {\n text: data.text || '',\n done: data.done || false\n };\n }\n } catch (error) {\n console.warn('Error parsing JSON chunk:', line, 'Error:', error);\n }\n }\n }\n }\n\n if (buffer && buffer.startsWith('data: ')) {\n try {\n // Properly extract the JSON part by trimming whitespace after 'data:'\n const jsonText = buffer.slice(6).trim();\n const data = JSON.parse(jsonText);\n \n if (data.text) {\n // Check for duplicates in final chunk\n const newText = extractNewText(data.text, currentFullText);\n if (newText || data.done) {\n yield {\n text: newText || '',\n done: data.done || false\n };\n }\n } else {\n yield {\n text: data.text || '',\n done: data.done || false\n };\n }\n } catch (error) {\n console.warn('Error parsing final JSON buffer:', buffer, 'Error:', error);\n }\n }\n } catch (error: any) {\n console.error('Chat API error:', error.message);\n yield { \n text: `Error connecting to chat server: ${error.message}`, \n done: true \n };\n }\n}\n\n// Helper function to extract only new text from incoming chunks\nfunction extractNewText(incomingText: string, currentText: string): string {\n // If we have no current text, all text is new\n if (!currentText) return incomingText;\n \n // Handle exact duplicates\n if (currentText.endsWith(incomingText)) return '';\n\n // If incoming text is larger, check if it's an expanded version\n if (incomingText.length > currentText.length) {\n // If incoming text contains all of current text at the beginning,\n // only return the new part\n if (incomingText.startsWith(currentText)) {\n return incomingText.slice(currentText.length);\n }\n \n // Sometimes the FastAPI server might send growing chunks like \"Hel\" -> \"Hello\" -> \"Hello wo\" -> \"Hello world\"\n // Find the longest common prefix\n let i = 0;\n const minLength = Math.min(currentText.length, incomingText.length);\n while (i < minLength && currentText[i] === incomingText[i]) {\n i++;\n }\n \n // If there's significant overlap, extract only the new part\n if (i > currentText.length / 2) {\n return incomingText.slice(i);\n }\n }\n \n // Default: return the full text (this handles non-overlapping chunks)\n return incomingText;\n}"],"names":["configuredApiUrl","configuredApiKey","configureApi","apiUrl","apiKey","getApiUrl","getApiKey","getFetchOptions","options","requestId","streamChat","message","stream","API_URL","response","errorText","reader","_a","decoder","buffer","currentFullText","done","value","chunk","lines","line","jsonText","data","newText","extractNewText","error","incomingText","currentText","i","minLength"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api.cjs","sources":["../api.ts"],"sourcesContent":["// For Node.js environments, we can use http.Agent for connection pooling\nlet httpAgent: any = null;\nlet httpsAgent: any = null;\n\n// Define the StreamResponse interface\nexport interface StreamResponse {\n text: string;\n done: boolean;\n}\n\nexport interface ChatResponse {\n response: string;\n}\n\n// MCP Protocol interfaces\ninterface MCPRequest {\n jsonrpc: \"2.0\";\n method: string;\n params: {\n name: string;\n arguments: {\n messages?: Array<{\n role: string;\n content: string;\n }>;\n stream?: boolean;\n tools?: Array<{\n name: string;\n parameters: Record<string, any>;\n }>;\n };\n };\n id: string;\n}\n\ninterface MCPResponse {\n jsonrpc: \"2.0\";\n id: string;\n result?: {\n type?: \"start\" | \"chunk\" | \"complete\";\n chunk?: {\n content: string;\n };\n output?: {\n messages: Array<{\n role: string;\n content: string;\n }>;\n };\n };\n error?: {\n code: number;\n message: string;\n };\n}\n\n// Store the configured API URL, key, and session ID\nlet configuredApiUrl: string | null = null;\nlet configuredApiKey: string | null = null;\nlet configuredSessionId: string | null = null;\n\n// Configure the API with a custom URL, API key, and session ID\nexport const configureApi = (apiUrl: string, apiKey: string, sessionId: string): void => {\n if (!apiUrl || typeof apiUrl !== 'string') {\n throw new Error('API URL must be a valid string');\n }\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('API key must be a valid string');\n }\n if (!sessionId || typeof sessionId !== 'string') {\n throw new Error('Session ID must be a valid string');\n }\n configuredApiUrl = apiUrl;\n configuredApiKey = apiKey;\n configuredSessionId = sessionId;\n}\n\n// Get the configured API URL or throw an error if not configured\nconst getApiUrl = (): string => {\n if (!configuredApiUrl) {\n throw new Error('API URL not configured. Please call configureApi() with your server URL before using any API functions.');\n }\n return configuredApiUrl;\n};\n\n// Get the configured API key or throw an error if not configured\nconst getApiKey = (): string => {\n if (!configuredApiKey) {\n throw new Error('API key not configured. Please call configureApi() with your API key before using any API functions.');\n }\n return configuredApiKey;\n};\n\n// Get the configured session ID or throw an error if not configured\nconst getSessionId = (): string => {\n if (!configuredSessionId) {\n throw new Error('Session ID not configured. Please call configureApi() with your session ID before using any API functions.');\n }\n return configuredSessionId;\n};\n\n// Helper to get fetch options with connection pooling if available\nconst getFetchOptions = (apiUrl: string, options: RequestInit = {}): RequestInit | any => {\n const isHttps = apiUrl.startsWith('https:');\n \n // Only use agents in Node.js environment\n if (typeof window === 'undefined') {\n if (isHttps && httpsAgent) {\n return { ...options, agent: httpsAgent } as any;\n } else if (httpAgent) {\n return { ...options, agent: httpAgent } as any;\n }\n }\n \n // Browser environment\n const requestId = Date.now().toString(36) + Math.random().toString(36).substring(2);\n \n // Use keep-alive header in browser environments\n const headers: Record<string, string> = {\n 'Connection': 'keep-alive',\n 'X-Request-ID': requestId,\n 'X-API-Key': getApiKey(),\n 'X-Session-ID': getSessionId()\n };\n \n return {\n ...options,\n headers: {\n ...options.headers,\n ...headers\n }\n };\n};\n\n// Create MCP request\nconst createMCPRequest = (message: string, stream: boolean = true): MCPRequest => {\n return {\n jsonrpc: \"2.0\",\n method: \"tools/call\",\n params: {\n name: \"chat\",\n arguments: {\n messages: [\n { role: \"user\", content: message }\n ],\n stream\n }\n },\n id: Date.now().toString(36) + Math.random().toString(36).substring(2)\n };\n};\n\n// Create MCP tools request\nconst createMCPToolsRequest = (tools: Array<{ name: string; parameters: Record<string, any> }>): MCPRequest => {\n return {\n jsonrpc: \"2.0\",\n method: \"tools/call\",\n params: {\n name: \"tools\",\n arguments: {\n tools\n }\n },\n id: Date.now().toString(36) + Math.random().toString(36).substring(2)\n };\n};\n\nexport async function* streamChat(\n message: string,\n stream: boolean = true\n): AsyncGenerator<StreamResponse> {\n try {\n const API_URL = getApiUrl();\n \n // Add timeout to the fetch request\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout\n\n const response = await fetch(`${API_URL}/v1/chat`, {\n ...getFetchOptions(API_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': stream ? 'text/event-stream' : 'application/json'\n },\n body: JSON.stringify(createMCPRequest(message, stream)),\n }),\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Network response was not ok: ${response.status} ${errorText}`);\n }\n\n if (!stream) {\n // Handle non-streaming response\n const data = await response.json() as MCPResponse;\n if (data.error) {\n throw new Error(`MCP Error: ${data.error.message}`);\n }\n if (data.result?.output?.messages?.[0]?.content) {\n yield {\n text: data.result.output.messages[0].content,\n done: true\n };\n }\n return;\n }\n \n const reader = response.body?.getReader();\n if (!reader) throw new Error('No reader available');\n\n const decoder = new TextDecoder();\n let buffer = '';\n let currentFullText = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n buffer += chunk;\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.trim() && line.startsWith('data: ')) {\n try {\n const jsonText = line.slice(6).trim();\n if (jsonText === '[DONE]') {\n yield { text: '', done: true };\n break;\n }\n\n const data = JSON.parse(jsonText) as MCPResponse;\n \n if (data.result) {\n let content = '';\n \n if (data.result.type === 'start') {\n continue;\n } else if (data.result.type === 'chunk' && data.result.chunk) {\n content = data.result.chunk.content;\n } else if (data.result.type === 'complete' && data.result.output?.messages?.[0]) {\n content = data.result.output.messages[0].content;\n }\n\n if (content) {\n const newText = extractNewText(content, currentFullText);\n if (newText) {\n currentFullText += newText;\n yield {\n text: newText,\n done: data.result.type === 'complete'\n };\n } else if (data.result.type === 'complete') {\n yield { text: '', done: true };\n }\n }\n }\n } catch (error) {\n console.warn('Error parsing JSON chunk:', line, 'Error:', error);\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n // Handle any remaining buffer\n if (buffer && buffer.startsWith('data: ')) {\n try {\n const jsonText = buffer.slice(6).trim();\n if (jsonText !== '[DONE]') {\n const data = JSON.parse(jsonText) as MCPResponse;\n if (data.result?.chunk?.content) {\n const newText = extractNewText(data.result.chunk.content, currentFullText);\n if (newText) {\n yield {\n text: newText,\n done: data.result.type === 'complete'\n };\n }\n }\n }\n } catch (error) {\n console.warn('Error parsing final JSON buffer:', buffer, 'Error:', error);\n }\n }\n } catch (error: any) {\n if (error.name === 'AbortError') {\n yield { \n text: 'Connection timed out. Please check if the server is running.', \n done: true \n };\n } else if (error.name === 'TypeError' && error.message.includes('Failed to fetch')) {\n yield { \n text: 'Could not connect to the server. Please check if the server is running.', \n done: true \n };\n } else {\n yield { \n text: `Error: ${error.message}`, \n done: true \n };\n }\n }\n}\n\n// Helper function to extract only new text from incoming chunks\nfunction extractNewText(incomingText: string, currentText: string): string {\n if (!currentText) return incomingText;\n if (currentText.endsWith(incomingText)) return '';\n \n if (incomingText.length > currentText.length) {\n if (incomingText.startsWith(currentText)) {\n return incomingText.slice(currentText.length);\n }\n \n let i = 0;\n const minLength = Math.min(currentText.length, incomingText.length);\n while (i < minLength && currentText[i] === incomingText[i]) {\n i++;\n }\n \n if (i > currentText.length / 2) {\n return incomingText.slice(i);\n }\n }\n \n return incomingText;\n}\n\n// New function to send tools request\nexport async function sendToolsRequest(tools: Array<{ name: string; parameters: Record<string, any> }>): Promise<MCPResponse> {\n const API_URL = getApiUrl();\n \n const response = await fetch(`${API_URL}/v1/chat`, getFetchOptions(API_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(createMCPToolsRequest(tools)),\n }));\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Network response was not ok: ${response.status} ${errorText}`);\n }\n\n const data = await response.json() as MCPResponse;\n if (data.error) {\n throw new Error(`MCP Error: ${data.error.message}`);\n }\n\n return data;\n}"],"names":["configuredApiUrl","configuredApiKey","configuredSessionId","configureApi","apiUrl","apiKey","sessionId","getApiUrl","getApiKey","getSessionId","getFetchOptions","options","headers","createMCPRequest","message","stream","createMCPToolsRequest","tools","streamChat","API_URL","controller","timeoutId","response","errorText","data","_d","_c","_b","_a","reader","_e","decoder","buffer","currentFullText","done","value","chunk","lines","line","jsonText","content","_g","_f","newText","extractNewText","error","_i","_h","incomingText","currentText","i","minLength","sendToolsRequest"],"mappings":"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"}
|
package/dist/api.mjs
CHANGED
|
@@ -1,130 +1,196 @@
|
|
|
1
|
-
let
|
|
2
|
-
const
|
|
1
|
+
let m = null, k = null, A = null;
|
|
2
|
+
const J = (t, e, r) => {
|
|
3
3
|
if (!t || typeof t != "string")
|
|
4
4
|
throw new Error("API URL must be a valid string");
|
|
5
5
|
if (!e || typeof e != "string")
|
|
6
6
|
throw new Error("API key must be a valid string");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
if (!r || typeof r != "string")
|
|
8
|
+
throw new Error("Session ID must be a valid string");
|
|
9
|
+
m = t, k = e, A = r;
|
|
10
|
+
}, O = () => {
|
|
11
|
+
if (!m)
|
|
10
12
|
throw new Error("API URL not configured. Please call configureApi() with your server URL before using any API functions.");
|
|
11
|
-
return
|
|
12
|
-
},
|
|
13
|
-
if (!
|
|
13
|
+
return m;
|
|
14
|
+
}, M = () => {
|
|
15
|
+
if (!k)
|
|
14
16
|
throw new Error("API key not configured. Please call configureApi() with your API key before using any API functions.");
|
|
15
|
-
return
|
|
16
|
-
},
|
|
17
|
+
return k;
|
|
18
|
+
}, x = () => {
|
|
19
|
+
if (!A)
|
|
20
|
+
throw new Error("Session ID not configured. Please call configureApi() with your session ID before using any API functions.");
|
|
21
|
+
return A;
|
|
22
|
+
}, R = (t, e = {}) => {
|
|
17
23
|
t.startsWith("https:");
|
|
18
|
-
const
|
|
24
|
+
const n = {
|
|
25
|
+
Connection: "keep-alive",
|
|
26
|
+
"X-Request-ID": Date.now().toString(36) + Math.random().toString(36).substring(2),
|
|
27
|
+
"X-API-Key": M(),
|
|
28
|
+
"X-Session-ID": x()
|
|
29
|
+
};
|
|
19
30
|
return {
|
|
20
31
|
...e,
|
|
21
32
|
headers: {
|
|
22
33
|
...e.headers,
|
|
23
|
-
|
|
24
|
-
"X-Request-ID": r,
|
|
25
|
-
// Add unique ID to track requests
|
|
26
|
-
"X-API-Key": b()
|
|
27
|
-
// Add API key to headers
|
|
34
|
+
...n
|
|
28
35
|
}
|
|
29
36
|
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
}, L = (t, e = !0) => ({
|
|
38
|
+
jsonrpc: "2.0",
|
|
39
|
+
method: "tools/call",
|
|
40
|
+
params: {
|
|
41
|
+
name: "chat",
|
|
42
|
+
arguments: {
|
|
43
|
+
messages: [
|
|
44
|
+
{ role: "user", content: t }
|
|
45
|
+
],
|
|
46
|
+
stream: e
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
id: Date.now().toString(36) + Math.random().toString(36).substring(2)
|
|
50
|
+
}), q = (t) => ({
|
|
51
|
+
jsonrpc: "2.0",
|
|
52
|
+
method: "tools/call",
|
|
53
|
+
params: {
|
|
54
|
+
name: "tools",
|
|
55
|
+
arguments: {
|
|
56
|
+
tools: t
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
id: Date.now().toString(36) + Math.random().toString(36).substring(2)
|
|
60
|
+
});
|
|
61
|
+
async function* U(t, e = !0) {
|
|
62
|
+
var r, n, u, E, P, b, I, S, v;
|
|
33
63
|
try {
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
64
|
+
const i = O(), N = new AbortController(), j = setTimeout(() => N.abort(), 1e4), l = await fetch(`${i}/v1/chat`, {
|
|
65
|
+
...R(i, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
headers: {
|
|
68
|
+
"Content-Type": "application/json",
|
|
69
|
+
Accept: e ? "text/event-stream" : "application/json"
|
|
70
|
+
},
|
|
71
|
+
body: JSON.stringify(L(t, e))
|
|
72
|
+
}),
|
|
73
|
+
signal: N.signal
|
|
74
|
+
});
|
|
75
|
+
if (clearTimeout(j), !l.ok) {
|
|
76
|
+
const o = await l.text();
|
|
77
|
+
throw new Error(`Network response was not ok: ${l.status} ${o}`);
|
|
45
78
|
}
|
|
46
79
|
if (!e) {
|
|
47
|
-
|
|
48
|
-
|
|
80
|
+
const o = await l.json();
|
|
81
|
+
if (o.error)
|
|
82
|
+
throw new Error(`MCP Error: ${o.error.message}`);
|
|
83
|
+
(E = (u = (n = (r = o.result) == null ? void 0 : r.output) == null ? void 0 : n.messages) == null ? void 0 : u[0]) != null && E.content && (yield {
|
|
84
|
+
text: o.result.output.messages[0].content,
|
|
49
85
|
done: !0
|
|
50
|
-
};
|
|
86
|
+
});
|
|
51
87
|
return;
|
|
52
88
|
}
|
|
53
|
-
const
|
|
54
|
-
if (!
|
|
55
|
-
const
|
|
56
|
-
let a = "",
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
89
|
+
const p = (P = l.body) == null ? void 0 : P.getReader();
|
|
90
|
+
if (!p) throw new Error("No reader available");
|
|
91
|
+
const $ = new TextDecoder();
|
|
92
|
+
let a = "", w = "";
|
|
93
|
+
try {
|
|
94
|
+
for (; ; ) {
|
|
95
|
+
const { done: o, value: c } = await p.read();
|
|
96
|
+
if (o) break;
|
|
97
|
+
const f = $.decode(c, { stream: !0 });
|
|
98
|
+
a += f;
|
|
99
|
+
const C = a.split(`
|
|
63
100
|
`);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
101
|
+
a = C.pop() || "";
|
|
102
|
+
for (const d of C)
|
|
103
|
+
if (d.trim() && d.startsWith("data: "))
|
|
104
|
+
try {
|
|
105
|
+
const h = d.slice(6).trim();
|
|
106
|
+
if (h === "[DONE]") {
|
|
107
|
+
yield { text: "", done: !0 };
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
const s = JSON.parse(h);
|
|
111
|
+
if (s.result) {
|
|
112
|
+
let g = "";
|
|
113
|
+
if (s.result.type === "start")
|
|
114
|
+
continue;
|
|
115
|
+
if (s.result.type === "chunk" && s.result.chunk ? g = s.result.chunk.content : s.result.type === "complete" && ((I = (b = s.result.output) == null ? void 0 : b.messages) != null && I[0]) && (g = s.result.output.messages[0].content), g) {
|
|
116
|
+
const y = D(g, w);
|
|
117
|
+
y ? (w += y, yield {
|
|
118
|
+
text: y,
|
|
119
|
+
done: s.result.type === "complete"
|
|
120
|
+
}) : s.result.type === "complete" && (yield { text: "", done: !0 });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
} catch (h) {
|
|
124
|
+
console.warn("Error parsing JSON chunk:", d, "Error:", h);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
} finally {
|
|
128
|
+
p.releaseLock();
|
|
86
129
|
}
|
|
87
130
|
if (a && a.startsWith("data: "))
|
|
88
131
|
try {
|
|
89
|
-
const o = a.slice(6).trim()
|
|
90
|
-
if (
|
|
91
|
-
const c =
|
|
92
|
-
(c
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
};
|
|
132
|
+
const o = a.slice(6).trim();
|
|
133
|
+
if (o !== "[DONE]") {
|
|
134
|
+
const c = JSON.parse(o);
|
|
135
|
+
if ((v = (S = c.result) == null ? void 0 : S.chunk) != null && v.content) {
|
|
136
|
+
const f = D(c.result.chunk.content, w);
|
|
137
|
+
f && (yield {
|
|
138
|
+
text: f,
|
|
139
|
+
done: c.result.type === "complete"
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
101
143
|
} catch (o) {
|
|
102
144
|
console.warn("Error parsing final JSON buffer:", a, "Error:", o);
|
|
103
145
|
}
|
|
104
|
-
} catch (
|
|
105
|
-
|
|
106
|
-
text:
|
|
146
|
+
} catch (i) {
|
|
147
|
+
i.name === "AbortError" ? yield {
|
|
148
|
+
text: "Connection timed out. Please check if the server is running.",
|
|
149
|
+
done: !0
|
|
150
|
+
} : i.name === "TypeError" && i.message.includes("Failed to fetch") ? yield {
|
|
151
|
+
text: "Could not connect to the server. Please check if the server is running.",
|
|
152
|
+
done: !0
|
|
153
|
+
} : yield {
|
|
154
|
+
text: `Error: ${i.message}`,
|
|
107
155
|
done: !0
|
|
108
156
|
};
|
|
109
157
|
}
|
|
110
158
|
}
|
|
111
|
-
function
|
|
159
|
+
function D(t, e) {
|
|
112
160
|
if (!e) return t;
|
|
113
161
|
if (e.endsWith(t)) return "";
|
|
114
162
|
if (t.length > e.length) {
|
|
115
163
|
if (t.startsWith(e))
|
|
116
164
|
return t.slice(e.length);
|
|
117
165
|
let r = 0;
|
|
118
|
-
const
|
|
119
|
-
for (; r <
|
|
166
|
+
const n = Math.min(e.length, t.length);
|
|
167
|
+
for (; r < n && e[r] === t[r]; )
|
|
120
168
|
r++;
|
|
121
169
|
if (r > e.length / 2)
|
|
122
170
|
return t.slice(r);
|
|
123
171
|
}
|
|
124
172
|
return t;
|
|
125
173
|
}
|
|
174
|
+
async function W(t) {
|
|
175
|
+
const e = O(), r = await fetch(`${e}/v1/chat`, R(e, {
|
|
176
|
+
method: "POST",
|
|
177
|
+
headers: {
|
|
178
|
+
"Content-Type": "application/json"
|
|
179
|
+
},
|
|
180
|
+
body: JSON.stringify(q(t))
|
|
181
|
+
}));
|
|
182
|
+
if (!r.ok) {
|
|
183
|
+
const u = await r.text();
|
|
184
|
+
throw new Error(`Network response was not ok: ${r.status} ${u}`);
|
|
185
|
+
}
|
|
186
|
+
const n = await r.json();
|
|
187
|
+
if (n.error)
|
|
188
|
+
throw new Error(`MCP Error: ${n.error.message}`);
|
|
189
|
+
return n;
|
|
190
|
+
}
|
|
126
191
|
export {
|
|
127
|
-
|
|
128
|
-
|
|
192
|
+
J as configureApi,
|
|
193
|
+
W as sendToolsRequest,
|
|
194
|
+
U as streamChat
|
|
129
195
|
};
|
|
130
196
|
//# sourceMappingURL=api.mjs.map
|
package/dist/api.mjs.d.ts
CHANGED
|
@@ -1,9 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
text?: string;
|
|
3
|
-
content?: string;
|
|
4
|
-
done?: boolean;
|
|
5
|
-
type?: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function configureApi(apiUrl: string, apiKey?: string): void;
|
|
9
|
-
export function streamChat(message: string, voiceEnabled: boolean): AsyncGenerator<StreamResponse>;
|
|
1
|
+
export * from "../api.d.ts";
|
package/dist/api.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.mjs","sources":["../api.ts"],"sourcesContent":["// For Node.js environments, we can use http.Agent for connection pooling\nlet httpAgent: any = null;\nlet httpsAgent: any = null;\n\n// Define the StreamResponse interface\nexport interface StreamResponse {\n text: string;\n done: boolean;\n}\n\nexport interface ChatResponse {\n response: string;\n}\n\n// Store the configured API URL and key\nlet configuredApiUrl: string | null = null;\nlet configuredApiKey: string | null = null;\n\n// Configure the API with a custom URL and API key\nexport const configureApi = (apiUrl: string, apiKey: string): void => {\n if (!apiUrl || typeof apiUrl !== 'string') {\n throw new Error('API URL must be a valid string');\n }\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('API key must be a valid string');\n }\n configuredApiUrl = apiUrl;\n configuredApiKey = apiKey;\n}\n\n// Get the configured API URL or throw an error if not configured\nconst getApiUrl = (): string => {\n if (!configuredApiUrl) {\n throw new Error('API URL not configured. Please call configureApi() with your server URL before using any API functions.');\n }\n return configuredApiUrl;\n};\n\n// Get the configured API key or throw an error if not configured\nconst getApiKey = (): string => {\n if (!configuredApiKey) {\n throw new Error('API key not configured. Please call configureApi() with your API key before using any API functions.');\n }\n return configuredApiKey;\n};\n\n// Helper to get fetch options with connection pooling if available\nconst getFetchOptions = (apiUrl: string, options: RequestInit = {}): RequestInit | any => {\n const isHttps = apiUrl.startsWith('https:');\n \n // Only use agents in Node.js environment\n if (typeof window === 'undefined') {\n if (isHttps && httpsAgent) {\n // Using 'any' type to bypass TypeScript limitations with Node.js http.Agent\n return { ...options, agent: httpsAgent } as any;\n } else if (httpAgent) {\n return { ...options, agent: httpAgent } as any;\n }\n }\n \n // Browser environment\n const requestId = Date.now().toString(36) + Math.random().toString(36).substring(2);\n \n // Use keep-alive header in browser environments\n return {\n ...options,\n headers: {\n ...options.headers,\n 'Connection': 'keep-alive',\n 'X-Request-ID': requestId, // Add unique ID to track requests\n 'X-API-Key': getApiKey() // Add API key to headers\n }\n };\n};\n\nexport async function* streamChat(\n message: string,\n stream: boolean = true\n): AsyncGenerator<StreamResponse> {\n try {\n const API_URL = getApiUrl();\n \n const response = await fetch(`${API_URL}/chat`, getFetchOptions(API_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': stream ? 'text/event-stream' : 'application/json'\n },\n body: JSON.stringify({ message, stream }),\n }));\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(`API request failed: ${response.status} ${errorText}`);\n throw new Error(`Network response was not ok: ${response.status} ${errorText}`);\n }\n\n if (!stream) {\n // Handle non-streaming response\n const data = await response.json() as ChatResponse;\n yield {\n text: data.response,\n done: true\n };\n return;\n }\n \n const reader = response.body?.getReader();\n if (!reader) throw new Error('No reader available');\n\n const decoder = new TextDecoder();\n let buffer = '';\n let currentFullText = ''; // Track full response to detect duplicates\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n buffer += chunk;\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.trim() && line.startsWith('data: ')) {\n try {\n // Properly extract the JSON part by trimming whitespace after 'data:'\n const jsonText = line.slice(6).trim();\n const data = JSON.parse(jsonText);\n \n if (data.text) {\n // Check if this is a duplicate or overlapping chunk\n const newText = extractNewText(data.text, currentFullText);\n \n // Only yield if we have new text\n if (newText) {\n currentFullText += newText;\n yield {\n text: newText,\n done: data.done || false\n };\n } else if (data.done) {\n // Always send done signal even if no new text\n yield {\n text: '',\n done: true\n };\n }\n } else {\n // Pass through as-is if no text property\n yield {\n text: data.text || '',\n done: data.done || false\n };\n }\n } catch (error) {\n console.warn('Error parsing JSON chunk:', line, 'Error:', error);\n }\n }\n }\n }\n\n if (buffer && buffer.startsWith('data: ')) {\n try {\n // Properly extract the JSON part by trimming whitespace after 'data:'\n const jsonText = buffer.slice(6).trim();\n const data = JSON.parse(jsonText);\n \n if (data.text) {\n // Check for duplicates in final chunk\n const newText = extractNewText(data.text, currentFullText);\n if (newText || data.done) {\n yield {\n text: newText || '',\n done: data.done || false\n };\n }\n } else {\n yield {\n text: data.text || '',\n done: data.done || false\n };\n }\n } catch (error) {\n console.warn('Error parsing final JSON buffer:', buffer, 'Error:', error);\n }\n }\n } catch (error: any) {\n console.error('Chat API error:', error.message);\n yield { \n text: `Error connecting to chat server: ${error.message}`, \n done: true \n };\n }\n}\n\n// Helper function to extract only new text from incoming chunks\nfunction extractNewText(incomingText: string, currentText: string): string {\n // If we have no current text, all text is new\n if (!currentText) return incomingText;\n \n // Handle exact duplicates\n if (currentText.endsWith(incomingText)) return '';\n\n // If incoming text is larger, check if it's an expanded version\n if (incomingText.length > currentText.length) {\n // If incoming text contains all of current text at the beginning,\n // only return the new part\n if (incomingText.startsWith(currentText)) {\n return incomingText.slice(currentText.length);\n }\n \n // Sometimes the FastAPI server might send growing chunks like \"Hel\" -> \"Hello\" -> \"Hello wo\" -> \"Hello world\"\n // Find the longest common prefix\n let i = 0;\n const minLength = Math.min(currentText.length, incomingText.length);\n while (i < minLength && currentText[i] === incomingText[i]) {\n i++;\n }\n \n // If there's significant overlap, extract only the new part\n if (i > currentText.length / 2) {\n return incomingText.slice(i);\n }\n }\n \n // Default: return the full text (this handles non-overlapping chunks)\n return incomingText;\n}"],"names":["configuredApiUrl","configuredApiKey","configureApi","apiUrl","apiKey","getApiUrl","getApiKey","getFetchOptions","options","requestId","streamChat","message","stream","_a","API_URL","response","errorText","reader","decoder","buffer","currentFullText","done","value","chunk","lines","line","jsonText","data","newText","extractNewText","error","incomingText","currentText","i","minLength"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"api.mjs","sources":["../api.ts"],"sourcesContent":["// For Node.js environments, we can use http.Agent for connection pooling\nlet httpAgent: any = null;\nlet httpsAgent: any = null;\n\n// Define the StreamResponse interface\nexport interface StreamResponse {\n text: string;\n done: boolean;\n}\n\nexport interface ChatResponse {\n response: string;\n}\n\n// MCP Protocol interfaces\ninterface MCPRequest {\n jsonrpc: \"2.0\";\n method: string;\n params: {\n name: string;\n arguments: {\n messages?: Array<{\n role: string;\n content: string;\n }>;\n stream?: boolean;\n tools?: Array<{\n name: string;\n parameters: Record<string, any>;\n }>;\n };\n };\n id: string;\n}\n\ninterface MCPResponse {\n jsonrpc: \"2.0\";\n id: string;\n result?: {\n type?: \"start\" | \"chunk\" | \"complete\";\n chunk?: {\n content: string;\n };\n output?: {\n messages: Array<{\n role: string;\n content: string;\n }>;\n };\n };\n error?: {\n code: number;\n message: string;\n };\n}\n\n// Store the configured API URL, key, and session ID\nlet configuredApiUrl: string | null = null;\nlet configuredApiKey: string | null = null;\nlet configuredSessionId: string | null = null;\n\n// Configure the API with a custom URL, API key, and session ID\nexport const configureApi = (apiUrl: string, apiKey: string, sessionId: string): void => {\n if (!apiUrl || typeof apiUrl !== 'string') {\n throw new Error('API URL must be a valid string');\n }\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('API key must be a valid string');\n }\n if (!sessionId || typeof sessionId !== 'string') {\n throw new Error('Session ID must be a valid string');\n }\n configuredApiUrl = apiUrl;\n configuredApiKey = apiKey;\n configuredSessionId = sessionId;\n}\n\n// Get the configured API URL or throw an error if not configured\nconst getApiUrl = (): string => {\n if (!configuredApiUrl) {\n throw new Error('API URL not configured. Please call configureApi() with your server URL before using any API functions.');\n }\n return configuredApiUrl;\n};\n\n// Get the configured API key or throw an error if not configured\nconst getApiKey = (): string => {\n if (!configuredApiKey) {\n throw new Error('API key not configured. Please call configureApi() with your API key before using any API functions.');\n }\n return configuredApiKey;\n};\n\n// Get the configured session ID or throw an error if not configured\nconst getSessionId = (): string => {\n if (!configuredSessionId) {\n throw new Error('Session ID not configured. Please call configureApi() with your session ID before using any API functions.');\n }\n return configuredSessionId;\n};\n\n// Helper to get fetch options with connection pooling if available\nconst getFetchOptions = (apiUrl: string, options: RequestInit = {}): RequestInit | any => {\n const isHttps = apiUrl.startsWith('https:');\n \n // Only use agents in Node.js environment\n if (typeof window === 'undefined') {\n if (isHttps && httpsAgent) {\n return { ...options, agent: httpsAgent } as any;\n } else if (httpAgent) {\n return { ...options, agent: httpAgent } as any;\n }\n }\n \n // Browser environment\n const requestId = Date.now().toString(36) + Math.random().toString(36).substring(2);\n \n // Use keep-alive header in browser environments\n const headers: Record<string, string> = {\n 'Connection': 'keep-alive',\n 'X-Request-ID': requestId,\n 'X-API-Key': getApiKey(),\n 'X-Session-ID': getSessionId()\n };\n \n return {\n ...options,\n headers: {\n ...options.headers,\n ...headers\n }\n };\n};\n\n// Create MCP request\nconst createMCPRequest = (message: string, stream: boolean = true): MCPRequest => {\n return {\n jsonrpc: \"2.0\",\n method: \"tools/call\",\n params: {\n name: \"chat\",\n arguments: {\n messages: [\n { role: \"user\", content: message }\n ],\n stream\n }\n },\n id: Date.now().toString(36) + Math.random().toString(36).substring(2)\n };\n};\n\n// Create MCP tools request\nconst createMCPToolsRequest = (tools: Array<{ name: string; parameters: Record<string, any> }>): MCPRequest => {\n return {\n jsonrpc: \"2.0\",\n method: \"tools/call\",\n params: {\n name: \"tools\",\n arguments: {\n tools\n }\n },\n id: Date.now().toString(36) + Math.random().toString(36).substring(2)\n };\n};\n\nexport async function* streamChat(\n message: string,\n stream: boolean = true\n): AsyncGenerator<StreamResponse> {\n try {\n const API_URL = getApiUrl();\n \n // Add timeout to the fetch request\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout\n\n const response = await fetch(`${API_URL}/v1/chat`, {\n ...getFetchOptions(API_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': stream ? 'text/event-stream' : 'application/json'\n },\n body: JSON.stringify(createMCPRequest(message, stream)),\n }),\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Network response was not ok: ${response.status} ${errorText}`);\n }\n\n if (!stream) {\n // Handle non-streaming response\n const data = await response.json() as MCPResponse;\n if (data.error) {\n throw new Error(`MCP Error: ${data.error.message}`);\n }\n if (data.result?.output?.messages?.[0]?.content) {\n yield {\n text: data.result.output.messages[0].content,\n done: true\n };\n }\n return;\n }\n \n const reader = response.body?.getReader();\n if (!reader) throw new Error('No reader available');\n\n const decoder = new TextDecoder();\n let buffer = '';\n let currentFullText = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n buffer += chunk;\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.trim() && line.startsWith('data: ')) {\n try {\n const jsonText = line.slice(6).trim();\n if (jsonText === '[DONE]') {\n yield { text: '', done: true };\n break;\n }\n\n const data = JSON.parse(jsonText) as MCPResponse;\n \n if (data.result) {\n let content = '';\n \n if (data.result.type === 'start') {\n continue;\n } else if (data.result.type === 'chunk' && data.result.chunk) {\n content = data.result.chunk.content;\n } else if (data.result.type === 'complete' && data.result.output?.messages?.[0]) {\n content = data.result.output.messages[0].content;\n }\n\n if (content) {\n const newText = extractNewText(content, currentFullText);\n if (newText) {\n currentFullText += newText;\n yield {\n text: newText,\n done: data.result.type === 'complete'\n };\n } else if (data.result.type === 'complete') {\n yield { text: '', done: true };\n }\n }\n }\n } catch (error) {\n console.warn('Error parsing JSON chunk:', line, 'Error:', error);\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n // Handle any remaining buffer\n if (buffer && buffer.startsWith('data: ')) {\n try {\n const jsonText = buffer.slice(6).trim();\n if (jsonText !== '[DONE]') {\n const data = JSON.parse(jsonText) as MCPResponse;\n if (data.result?.chunk?.content) {\n const newText = extractNewText(data.result.chunk.content, currentFullText);\n if (newText) {\n yield {\n text: newText,\n done: data.result.type === 'complete'\n };\n }\n }\n }\n } catch (error) {\n console.warn('Error parsing final JSON buffer:', buffer, 'Error:', error);\n }\n }\n } catch (error: any) {\n if (error.name === 'AbortError') {\n yield { \n text: 'Connection timed out. Please check if the server is running.', \n done: true \n };\n } else if (error.name === 'TypeError' && error.message.includes('Failed to fetch')) {\n yield { \n text: 'Could not connect to the server. Please check if the server is running.', \n done: true \n };\n } else {\n yield { \n text: `Error: ${error.message}`, \n done: true \n };\n }\n }\n}\n\n// Helper function to extract only new text from incoming chunks\nfunction extractNewText(incomingText: string, currentText: string): string {\n if (!currentText) return incomingText;\n if (currentText.endsWith(incomingText)) return '';\n \n if (incomingText.length > currentText.length) {\n if (incomingText.startsWith(currentText)) {\n return incomingText.slice(currentText.length);\n }\n \n let i = 0;\n const minLength = Math.min(currentText.length, incomingText.length);\n while (i < minLength && currentText[i] === incomingText[i]) {\n i++;\n }\n \n if (i > currentText.length / 2) {\n return incomingText.slice(i);\n }\n }\n \n return incomingText;\n}\n\n// New function to send tools request\nexport async function sendToolsRequest(tools: Array<{ name: string; parameters: Record<string, any> }>): Promise<MCPResponse> {\n const API_URL = getApiUrl();\n \n const response = await fetch(`${API_URL}/v1/chat`, getFetchOptions(API_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(createMCPToolsRequest(tools)),\n }));\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Network response was not ok: ${response.status} ${errorText}`);\n }\n\n const data = await response.json() as MCPResponse;\n if (data.error) {\n throw new Error(`MCP Error: ${data.error.message}`);\n }\n\n return data;\n}"],"names":["configuredApiUrl","configuredApiKey","configuredSessionId","configureApi","apiUrl","apiKey","sessionId","getApiUrl","getApiKey","getSessionId","getFetchOptions","options","headers","createMCPRequest","message","stream","createMCPToolsRequest","tools","streamChat","_a","_b","_c","_d","_e","_f","_g","_h","_i","API_URL","controller","timeoutId","response","errorText","data","reader","decoder","buffer","currentFullText","done","value","chunk","lines","line","jsonText","content","newText","extractNewText","error","incomingText","currentText","i","minLength","sendToolsRequest"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schmitech/chatbot-api",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
5
|
-
"description": "API client for the
|
|
4
|
+
"version": "0.4.1",
|
|
5
|
+
"description": "API client for the ORBIT MCP server",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/api.cjs",
|
|
8
8
|
"module": "./dist/api.mjs",
|