@schmitech/chatbot-api 0.3.1 → 0.4.0

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 CHANGED
@@ -1,76 +1,45 @@
1
- # Chatbot API Client
1
+ # 🤖 Chatbot API Client
2
2
 
3
- A JavaScript/TypeScript client library for interacting with the Chatbot server.
3
+ A JavaScript/TypeScript client for seamless interaction with the Chatbot server, now supporting API key authentication.
4
4
 
5
- ## Installation
5
+ ---
6
6
 
7
- ### Option 1: Using npm link (for local development)
7
+ ## 📥 Installation
8
8
 
9
- To use this library in other projects on your local machine during development:
9
+ ### 📍 Local Development (npm link)
10
10
 
11
- 1. In this library directory, run:
12
- ```bash
13
- npm run build
14
- npm link
15
- ```
11
+ Use during local development:
16
12
 
17
- 2. In your project directory, run:
18
- ```bash
19
- npm link chatbot-api
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
- 3. Now you can import and use the library in your project:
42
- ```javascript
43
- import { streamChat } from 'chatbot-api';
44
- ```
17
+ # In your project directory
18
+ npm link @schmitech/chatbot-api
19
+ ```
45
20
 
46
- ### Option 3: Publishing to npm (for production)
21
+ ### 📂 Local Directory Install
47
22
 
48
- To make this library available to anyone via npm:
23
+ Direct local installation:
49
24
 
50
- 1. Create an account on npmjs.com if you don't have one
51
- 2. Login to npm from the command line:
52
- ```bash
53
- npm login
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
- ### Option 4: Using via CDN (for websites)
30
+ ### 🌐 CDN Integration
62
31
 
63
- You can include the library directly in your website using jsDelivr CDN:
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@0.1.0/dist/api.mjs';
69
-
70
- // Configure the API with your server URL
71
- configureApi('https://your-api-server.com');
72
-
73
- // Use the API functions
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
+ });
42
+
74
43
  async function handleChat() {
75
44
  for await (const response of streamChat('Hello', false)) {
76
45
  console.log(response.text);
@@ -79,315 +48,158 @@ You can include the library directly in your website using jsDelivr CDN:
79
48
  </script>
80
49
  ```
81
50
 
82
- For production use, you can omit the version to always get the latest:
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
- ```
51
+ ---
90
52
 
91
- ## Usage
53
+ ## ⚙️ Usage
92
54
 
93
- ### Configuration (Required)
55
+ ### 🚨 Configuration (Required)
94
56
 
95
- Before using any API functions, you **must** configure the client with your server URL:
57
+ You must configure the API client before usage:
96
58
 
97
59
  ```javascript
98
- import { configureApi, streamChat } from 'chatbot-api';
60
+ import { configureApi, streamChat } from '@schmitech/chatbot-api';
99
61
 
100
- // Configure the API with your server URL
101
- configureApi('https://your-api-server.com');
62
+ configureApi({
63
+ apiUrl: 'https://your-api-server.com',
64
+ apiKey: 'your-api-key'
65
+ });
102
66
  ```
103
67
 
104
- If you don't configure the API before calling other functions, an error will be thrown.
105
-
106
- ### Basic Usage
68
+ ### 📖 Basic Example
107
69
 
108
70
  ```javascript
109
- import { configureApi, streamChat } from 'chatbot-api';
110
-
111
71
  async function chat() {
112
- // Configure the API with your server URL (required first step)
113
- configureApi('https://your-api-server.com');
114
-
115
- // Stream chat responses
116
- for await (const response of streamChat('Hello, how can I help you?', false)) {
117
- // Access the text response
72
+ configureApi({ apiUrl: 'https://your-api-server.com', apiKey: 'your-api-key' });
73
+
74
+ for await (const response of streamChat('Hello, how can I help?', false)) {
118
75
  console.log(response.text);
119
-
120
- // Check if this is the final response
121
- if (response.done) {
122
- console.log('Chat complete!');
123
- }
76
+ if (response.done) console.log('Chat complete!');
124
77
  }
125
78
  }
126
79
 
127
80
  chat();
128
81
  ```
129
82
 
130
- ### With Voice Enabled
83
+ ### 🎙️ Voice-enabled Example
131
84
 
132
85
  ```javascript
133
- import { configureApi, streamChat } from 'chatbot-api';
134
-
135
86
  async function chatWithVoice() {
136
- // Configure the API with your server URL
137
- configureApi('https://your-api-server.com');
138
-
139
- // Stream chat responses with voice enabled (second parameter true)
87
+ configureApi({ apiUrl: 'https://your-api-server.com', apiKey: 'your-api-key' });
88
+
140
89
  for await (const response of streamChat('Tell me a joke', true)) {
141
- // Process text responses
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)
90
+ if (response.type === 'audio') {
149
91
  console.log('Received audio content');
150
- // You can decode and play the audio here
151
- }
152
-
153
- if (response.done) {
154
- console.log('Chat complete!');
92
+ } else {
93
+ console.log(response.text);
155
94
  }
95
+ if (response.done) console.log('Chat complete!');
156
96
  }
157
97
  }
158
98
 
159
99
  chatWithVoice();
160
100
  ```
161
101
 
162
- ### React Example
102
+ ---
103
+
104
+ ## ⚛️ React Integration
105
+
106
+ Configure once globally:
163
107
 
164
108
  ```jsx
165
- import React, { useState, useEffect } from 'react';
166
- import { configureApi, streamChat } from 'chatbot-api';
109
+ import React, { useState } from 'react';
110
+ import { configureApi, streamChat } from '@schmitech/chatbot-api';
167
111
 
168
- // Configure the API once at the application startup
169
- configureApi('https://your-api-server.com');
112
+ configureApi({
113
+ apiUrl: 'https://your-api-server.com',
114
+ apiKey: 'your-api-key'
115
+ });
170
116
 
171
117
  function ChatComponent() {
172
118
  const [messages, setMessages] = useState([]);
173
119
  const [input, setInput] = useState('');
174
- const [isLoading, setIsLoading] = useState(false);
175
120
 
176
121
  const handleSubmit = async (e) => {
177
122
  e.preventDefault();
178
- if (!input.trim()) return;
179
-
180
- const userMessage = input;
181
- setInput('');
182
- setMessages(prev => [...prev, { text: userMessage, isUser: true }]);
183
- setIsLoading(true);
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);
123
+ setMessages(prev => [...prev, { text: input, isUser: true }]);
124
+
125
+ let responseText = '';
126
+ for await (const response of streamChat(input, false)) {
127
+ responseText += response.text;
128
+ setMessages(prev => [...prev, { text: responseText, isUser: false }]);
129
+ if (response.done) break;
211
130
  }
131
+ setInput('');
212
132
  };
213
133
 
214
134
  return (
215
- <div className="chat-container">
216
- <div className="messages">
217
- {messages.map((msg, i) => (
218
- <div key={i} className={`message ${msg.isUser ? 'user' : 'bot'}`}>
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>
135
+ <form onSubmit={handleSubmit}>
136
+ <input value={input} onChange={(e) => setInput(e.target.value)} />
137
+ <button type="submit">Send</button>
138
+ </form>
235
139
  );
236
140
  }
237
141
 
238
142
  export default ChatComponent;
239
143
  ```
240
144
 
241
- ## Usage with Native Mobile Platforms
145
+ ---
242
146
 
243
- ### React Native
147
+ ## 📱 Mobile Usage
244
148
 
245
- If using React Native, you can use the npm package directly:
149
+ ### 📲 React Native
246
150
 
247
151
  ```javascript
248
- import { configureApi, streamChat } from '@schmitech/chatbot-api';
152
+ configureApi({ apiUrl: 'https://your-api-server.com', apiKey: 'your-api-key' });
249
153
 
250
- // Configure API
251
- configureApi('https://your-api-server.com');
252
-
253
- // Usage in React Native component
254
154
  async function handleChat(message) {
255
- try {
256
- for await (const response of streamChat(message, false)) {
257
- // Update UI with response.text
258
- }
259
- } catch (error) {
260
- console.error('Chat error:', error);
155
+ for await (const response of streamChat(message, false)) {
156
+ // Handle response
261
157
  }
262
158
  }
263
159
  ```
264
160
 
265
- ### Native iOS (Swift)
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
- ```
335
-
336
- ### Alternative Approaches
337
-
338
- 1. **Flutter**: Create Dart implementation using http package
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
341
-
342
- ## API Reference
343
-
344
- ### configureApi(apiUrl)
345
-
346
- Configures the API client with your server URL.
161
+ ---
347
162
 
348
- - **apiUrl** (string): The URL of your Chatbot server
349
- - **Returns**: void
163
+ ## 📚 API Reference
350
164
 
351
- ### streamChat(message, voiceEnabled)
165
+ ### `configureApi(config)`
352
166
 
353
- Streams chat responses from the server.
167
+ | Parameter | Description | Required |
168
+ |-----------|-------------|----------|
169
+ | `apiUrl` | Chatbot API URL | ✅ Yes |
170
+ | `apiKey` | API key for authentication | ✅ Yes |
354
171
 
355
- - **message** (string): The message to send to the chatbot
356
- - **voiceEnabled** (boolean): Whether to enable voice responses
357
- - **Returns**: AsyncGenerator that yields StreamResponse objects
172
+ ### `streamChat(message, voiceEnabled)`
358
173
 
359
- ### StreamResponse Interface
174
+ Streams responses from the server:
175
+ - `message`: Message string
176
+ - `voiceEnabled`: Boolean, enables audio response
360
177
 
178
+ Returns an async generator yielding:
361
179
  ```typescript
362
180
  interface StreamResponse {
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')
181
+ text?: string;
182
+ content?: string;
183
+ done?: boolean;
184
+ type?: string;
367
185
  }
368
186
  ```
369
187
 
370
- ## Development
188
+ ---
371
189
 
372
- ### Building the Library
190
+ ## 🛠️ Development
373
191
 
374
- ```bash
375
- npm run build
376
- ```
377
-
378
- ### Running Tests
192
+ ### 🧪 Testing
379
193
 
380
194
  ```bash
381
- # Run tests once
195
+ npm run build
382
196
  npm test
383
-
384
- # Run tests in watch mode
385
197
  npm run test:watch
386
-
387
- # Test a specific query
388
- npm run test-query "how much is the fee?" "http://your-api-server.com"
198
+ npm run test-query "your query" "http://your-api-server.com" "your-api-key"
389
199
  ```
390
200
 
391
- ## License
201
+ ---
202
+
203
+ ## 📃 License
392
204
 
393
- MIT
205
+ 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
+ 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
+ }
8
28
  export declare const configureApi: (apiUrl: string, apiKey: 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 w=null,g=null;const b=(t,e)=>{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");w=t,g=e},I=()=>{if(!w)throw new Error("API URL not configured. Please call configureApi() with your server URL before using any API functions.");return w},E=()=>{if(!g)throw new Error("API key not configured. Please call configureApi() with your API key before using any API functions.");return g},k=(t,e={})=>{t.startsWith("https:");const r=Date.now().toString(36)+Math.random().toString(36).substring(2);return{...e,headers:{...e.headers,Connection:"keep-alive","X-Request-ID":r,"X-API-Key":E()}}};async function*S(t,e=!0){var r;try{const s=I(),i=await fetch(`${s}/chat`,k(s,{method:"POST",headers:{"Content-Type":"application/json",Accept:e?"text/event-stream":"application/json"},body:JSON.stringify({message:t,stream:e})}));if(!i.ok){const o=await i.text();throw console.error(`API request failed: ${i.status} ${o}`),new Error(`Network response was not ok: ${i.status} ${o}`)}if(!e){yield{text:(await i.json()).response,done:!0};return}const y=(r=i.body)==null?void 0:r.getReader();if(!y)throw new Error("No reader available");const P=new TextDecoder;let a="",f="";for(;;){const{done:o,value:n}=await y.read();if(o)break;const c=P.decode(n,{stream:!0});a+=c;const p=a.split(`
2
- `);a=p.pop()||"";for(const d of p)if(d.trim()&&d.startsWith("data: "))try{const u=d.slice(6).trim(),l=JSON.parse(u);if(l.text){const h=A(l.text,f);h?(f+=h,yield{text:h,done:l.done||!1}):l.done&&(yield{text:"",done:!0})}else yield{text:l.text||"",done:l.done||!1}}catch(u){console.warn("Error parsing JSON chunk:",d,"Error:",u)}}if(a&&a.startsWith("data: "))try{const o=a.slice(6).trim(),n=JSON.parse(o);if(n.text){const c=A(n.text,f);(c||n.done)&&(yield{text:c||"",done:n.done||!1})}else yield{text:n.text||"",done:n.done||!1}}catch(o){console.warn("Error parsing final JSON buffer:",a,"Error:",o)}}catch(s){console.error("Chat API error:",s.message),yield{text:`Error connecting to chat server: ${s.message}`,done:!0}}}function A(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 s=Math.min(e.length,t.length);for(;r<s&&e[r]===t[r];)r++;if(r>e.length/2)return t.slice(r)}return t}exports.configureApi=b;exports.streamChat=S;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let y=null,m=null;const j=(t,e)=>{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");y=t,m=e},v=()=>{if(!y)throw new Error("API URL not configured. Please call configureApi() with your server URL before using any API functions.");return y},C=()=>{if(!m)throw new Error("API key not configured. Please call configureApi() with your API key before using any API functions.");return m},R=(t,e={})=>{t.startsWith("https:");const r=Date.now().toString(36)+Math.random().toString(36).substring(2);return{...e,headers:{...e.headers,Connection:"keep-alive","X-Request-ID":r,"X-API-Key":C()}}},M=(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)}),q=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*D(t,e=!0){var r,n,u,A,P,k,E,b,S;try{const c=v(),i=await fetch(`${c}/v1/chat`,R(c,{method:"POST",headers:{"Content-Type":"application/json",Accept:e?"text/event-stream":"application/json"},body:JSON.stringify(M(t,e))}));if(!i.ok){const o=await i.text();throw console.error(`API request failed: ${i.status} ${o}`),new Error(`Network response was not ok: ${i.status} ${o}`)}if(!e){const o=await i.json();if(o.error)throw new Error(`MCP Error: ${o.error.message}`);(A=(u=(n=(r=o.result)==null?void 0:r.output)==null?void 0:n.messages)==null?void 0:u[0])!=null&&A.content&&(yield{text:o.result.output.messages[0].content,done:!0});return}const I=(P=i.body)==null?void 0:P.getReader();if(!I)throw new Error("No reader available");const $=new TextDecoder;let a="",g="";for(;;){const{done:o,value:l}=await I.read();if(o)break;const f=$.decode(l,{stream:!0});a+=f;const N=a.split(`
2
+ `);a=N.pop()||"";for(const h of N)if(h.trim()&&h.startsWith("data: "))try{const d=h.slice(6).trim();if(d==="[DONE]"){yield{text:"",done:!0};break}const s=JSON.parse(d);if(s.result){let p="";if(s.result.type==="start")continue;if(s.result.type==="chunk"&&s.result.chunk?p=s.result.chunk.content:s.result.type==="complete"&&((E=(k=s.result.output)==null?void 0:k.messages)!=null&&E[0])&&(p=s.result.output.messages[0].content),p){const w=O(p,g);w?(g+=w,yield{text:w,done:s.result.type==="complete"}):s.result.type==="complete"&&(yield{text:"",done:!0})}}}catch(d){console.warn("Error parsing JSON chunk:",h,"Error:",d)}}if(a&&a.startsWith("data: "))try{const o=a.slice(6).trim();if(o!=="[DONE]"){const l=JSON.parse(o);if((S=(b=l.result)==null?void 0:b.chunk)!=null&&S.content){const f=O(l.result.chunk.content,g);f&&(yield{text:f,done:l.result.type==="complete"})}}}catch(o){console.warn("Error parsing final JSON buffer:",a,"Error:",o)}}catch(c){console.error("Chat API error:",c.message),yield{text:`Error connecting to chat server: ${c.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 J(t){const e=v(),r=await fetch(`${e}/v1/chat`,R(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(q(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=j;exports.sendToolsRequest=J;exports.streamChat=D;
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 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 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,\n 'X-API-Key': getApiKey()\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 const response = await fetch(`${API_URL}/v1/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(createMCPRequest(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 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 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 // Handle different response types\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\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 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 (!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","configureApi","apiUrl","apiKey","getApiUrl","getApiKey","getFetchOptions","options","requestId","createMCPRequest","message","stream","createMCPToolsRequest","tools","streamChat","API_URL","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,174 @@
1
- let w = null, g = null;
2
- const k = (t, e) => {
3
- if (!t || typeof t != "string")
4
- throw new Error("API URL must be a valid string");
1
+ let y = null, m = null;
2
+ const D = (e, t) => {
5
3
  if (!e || typeof e != "string")
4
+ throw new Error("API URL must be a valid string");
5
+ if (!t || typeof t != "string")
6
6
  throw new Error("API key must be a valid string");
7
- w = t, g = e;
8
- }, I = () => {
9
- if (!w)
7
+ y = e, m = t;
8
+ }, $ = () => {
9
+ if (!y)
10
10
  throw new Error("API URL not configured. Please call configureApi() with your server URL before using any API functions.");
11
- return w;
12
- }, b = () => {
13
- if (!g)
11
+ return y;
12
+ }, j = () => {
13
+ if (!m)
14
14
  throw new Error("API key not configured. Please call configureApi() with your API key before using any API functions.");
15
- return g;
16
- }, E = (t, e = {}) => {
17
- t.startsWith("https:");
15
+ return m;
16
+ }, v = (e, t = {}) => {
17
+ e.startsWith("https:");
18
18
  const r = Date.now().toString(36) + Math.random().toString(36).substring(2);
19
19
  return {
20
- ...e,
20
+ ...t,
21
21
  headers: {
22
- ...e.headers,
22
+ ...t.headers,
23
23
  Connection: "keep-alive",
24
24
  "X-Request-ID": r,
25
- // Add unique ID to track requests
26
- "X-API-Key": b()
27
- // Add API key to headers
25
+ "X-API-Key": j()
28
26
  }
29
27
  };
30
- };
31
- async function* x(t, e = !0) {
32
- var r;
28
+ }, C = (e, t = !0) => ({
29
+ jsonrpc: "2.0",
30
+ method: "tools/call",
31
+ params: {
32
+ name: "chat",
33
+ arguments: {
34
+ messages: [
35
+ { role: "user", content: e }
36
+ ],
37
+ stream: t
38
+ }
39
+ },
40
+ id: Date.now().toString(36) + Math.random().toString(36).substring(2)
41
+ }), M = (e) => ({
42
+ jsonrpc: "2.0",
43
+ method: "tools/call",
44
+ params: {
45
+ name: "tools",
46
+ arguments: {
47
+ tools: e
48
+ }
49
+ },
50
+ id: Date.now().toString(36) + Math.random().toString(36).substring(2)
51
+ });
52
+ async function* q(e, t = !0) {
53
+ var r, s, u, A, P, k, E, b, I;
33
54
  try {
34
- const s = I(), i = await fetch(`${s}/chat`, E(s, {
55
+ const c = $(), i = await fetch(`${c}/v1/chat`, v(c, {
35
56
  method: "POST",
36
57
  headers: {
37
58
  "Content-Type": "application/json",
38
- Accept: e ? "text/event-stream" : "application/json"
59
+ Accept: t ? "text/event-stream" : "application/json"
39
60
  },
40
- body: JSON.stringify({ message: t, stream: e })
61
+ body: JSON.stringify(C(e, t))
41
62
  }));
42
63
  if (!i.ok) {
43
64
  const o = await i.text();
44
65
  throw console.error(`API request failed: ${i.status} ${o}`), new Error(`Network response was not ok: ${i.status} ${o}`);
45
66
  }
46
- if (!e) {
47
- yield {
48
- text: (await i.json()).response,
67
+ if (!t) {
68
+ const o = await i.json();
69
+ if (o.error)
70
+ throw new Error(`MCP Error: ${o.error.message}`);
71
+ (A = (u = (s = (r = o.result) == null ? void 0 : r.output) == null ? void 0 : s.messages) == null ? void 0 : u[0]) != null && A.content && (yield {
72
+ text: o.result.output.messages[0].content,
49
73
  done: !0
50
- };
74
+ });
51
75
  return;
52
76
  }
53
- const y = (r = i.body) == null ? void 0 : r.getReader();
54
- if (!y) throw new Error("No reader available");
55
- const P = new TextDecoder();
56
- let a = "", f = "";
77
+ const S = (P = i.body) == null ? void 0 : P.getReader();
78
+ if (!S) throw new Error("No reader available");
79
+ const R = new TextDecoder();
80
+ let a = "", w = "";
57
81
  for (; ; ) {
58
- const { done: o, value: n } = await y.read();
82
+ const { done: o, value: l } = await S.read();
59
83
  if (o) break;
60
- const c = P.decode(n, { stream: !0 });
61
- a += c;
62
- const p = a.split(`
84
+ const f = R.decode(l, { stream: !0 });
85
+ a += f;
86
+ const N = a.split(`
63
87
  `);
64
- a = p.pop() || "";
65
- for (const d of p)
66
- if (d.trim() && d.startsWith("data: "))
88
+ a = N.pop() || "";
89
+ for (const h of N)
90
+ if (h.trim() && h.startsWith("data: "))
67
91
  try {
68
- const h = d.slice(6).trim(), l = JSON.parse(h);
69
- if (l.text) {
70
- const u = A(l.text, f);
71
- u ? (f += u, yield {
72
- text: u,
73
- done: l.done || !1
74
- }) : l.done && (yield {
75
- text: "",
76
- done: !0
77
- });
78
- } else
79
- yield {
80
- text: l.text || "",
81
- done: l.done || !1
82
- };
83
- } catch (h) {
84
- console.warn("Error parsing JSON chunk:", d, "Error:", h);
92
+ const d = h.slice(6).trim();
93
+ if (d === "[DONE]") {
94
+ yield { text: "", done: !0 };
95
+ break;
96
+ }
97
+ const n = JSON.parse(d);
98
+ if (n.result) {
99
+ let p = "";
100
+ if (n.result.type === "start")
101
+ continue;
102
+ if (n.result.type === "chunk" && n.result.chunk ? p = n.result.chunk.content : n.result.type === "complete" && ((E = (k = n.result.output) == null ? void 0 : k.messages) != null && E[0]) && (p = n.result.output.messages[0].content), p) {
103
+ const g = O(p, w);
104
+ g ? (w += g, yield {
105
+ text: g,
106
+ done: n.result.type === "complete"
107
+ }) : n.result.type === "complete" && (yield { text: "", done: !0 });
108
+ }
109
+ }
110
+ } catch (d) {
111
+ console.warn("Error parsing JSON chunk:", h, "Error:", d);
85
112
  }
86
113
  }
87
114
  if (a && a.startsWith("data: "))
88
115
  try {
89
- const o = a.slice(6).trim(), n = JSON.parse(o);
90
- if (n.text) {
91
- const c = A(n.text, f);
92
- (c || n.done) && (yield {
93
- text: c || "",
94
- done: n.done || !1
95
- });
96
- } else
97
- yield {
98
- text: n.text || "",
99
- done: n.done || !1
100
- };
116
+ const o = a.slice(6).trim();
117
+ if (o !== "[DONE]") {
118
+ const l = JSON.parse(o);
119
+ if ((I = (b = l.result) == null ? void 0 : b.chunk) != null && I.content) {
120
+ const f = O(l.result.chunk.content, w);
121
+ f && (yield {
122
+ text: f,
123
+ done: l.result.type === "complete"
124
+ });
125
+ }
126
+ }
101
127
  } catch (o) {
102
128
  console.warn("Error parsing final JSON buffer:", a, "Error:", o);
103
129
  }
104
- } catch (s) {
105
- console.error("Chat API error:", s.message), yield {
106
- text: `Error connecting to chat server: ${s.message}`,
130
+ } catch (c) {
131
+ console.error("Chat API error:", c.message), yield {
132
+ text: `Error connecting to chat server: ${c.message}`,
107
133
  done: !0
108
134
  };
109
135
  }
110
136
  }
111
- function A(t, e) {
112
- if (!e) return t;
113
- if (e.endsWith(t)) return "";
114
- if (t.length > e.length) {
115
- if (t.startsWith(e))
116
- return t.slice(e.length);
137
+ function O(e, t) {
138
+ if (!t) return e;
139
+ if (t.endsWith(e)) return "";
140
+ if (e.length > t.length) {
141
+ if (e.startsWith(t))
142
+ return e.slice(t.length);
117
143
  let r = 0;
118
- const s = Math.min(e.length, t.length);
119
- for (; r < s && e[r] === t[r]; )
144
+ const s = Math.min(t.length, e.length);
145
+ for (; r < s && t[r] === e[r]; )
120
146
  r++;
121
- if (r > e.length / 2)
122
- return t.slice(r);
147
+ if (r > t.length / 2)
148
+ return e.slice(r);
149
+ }
150
+ return e;
151
+ }
152
+ async function J(e) {
153
+ const t = $(), r = await fetch(`${t}/v1/chat`, v(t, {
154
+ method: "POST",
155
+ headers: {
156
+ "Content-Type": "application/json"
157
+ },
158
+ body: JSON.stringify(M(e))
159
+ }));
160
+ if (!r.ok) {
161
+ const u = await r.text();
162
+ throw new Error(`Network response was not ok: ${r.status} ${u}`);
123
163
  }
124
- return t;
164
+ const s = await r.json();
165
+ if (s.error)
166
+ throw new Error(`MCP Error: ${s.error.message}`);
167
+ return s;
125
168
  }
126
169
  export {
127
- k as configureApi,
128
- x as streamChat
170
+ D as configureApi,
171
+ J as sendToolsRequest,
172
+ q as streamChat
129
173
  };
130
174
  //# sourceMappingURL=api.mjs.map
package/dist/api.mjs.d.ts CHANGED
@@ -1,9 +1 @@
1
- export interface StreamResponse {
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 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 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,\n 'X-API-Key': getApiKey()\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 const response = await fetch(`${API_URL}/v1/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(createMCPRequest(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 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 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 // Handle different response types\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\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 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 (!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","configureApi","apiUrl","apiKey","getApiUrl","getApiKey","getFetchOptions","options","requestId","createMCPRequest","message","stream","createMCPToolsRequest","tools","streamChat","_a","_b","_c","_d","_e","_f","_g","_h","_i","API_URL","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,7 +1,7 @@
1
1
  {
2
2
  "name": "@schmitech/chatbot-api",
3
3
  "private": false,
4
- "version": "0.3.1",
4
+ "version": "0.4.0",
5
5
  "description": "API client for the Chatbot server",
6
6
  "type": "module",
7
7
  "main": "./dist/api.cjs",