@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 CHANGED
@@ -1,76 +1,46 @@
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 and session tracking.
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
+ 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
- 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
- ```
52
+ ---
90
53
 
91
- ## Usage
54
+ ## ⚙️ Usage
92
55
 
93
- ### Configuration (Required)
56
+ ### 🚨 Configuration (Required)
94
57
 
95
- Before using any API functions, you **must** configure the client with your server URL:
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
- // Configure the API with your server URL
101
- configureApi('https://your-api-server.com');
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
- If you don't configure the API before calling other functions, an error will be thrown.
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
- // 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
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
- ### With Voice Enabled
89
+ ### 🎙️ Voice-enabled Example
131
90
 
132
91
  ```javascript
133
- import { configureApi, streamChat } from 'chatbot-api';
134
-
135
92
  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)
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
- // 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)
100
+ if (response.type === 'audio') {
149
101
  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!');
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
- ### React Example
112
+ ---
113
+
114
+ ## ⚛️ React Integration
115
+
116
+ Configure once globally:
163
117
 
164
118
  ```jsx
165
- import React, { useState, useEffect } from 'react';
166
- import { configureApi, streamChat } from 'chatbot-api';
119
+ import React, { useState } from 'react';
120
+ import { configureApi, streamChat } from '@schmitech/chatbot-api';
167
121
 
168
- // Configure the API once at the application startup
169
- configureApi('https://your-api-server.com');
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
- 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);
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
- <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>
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
- ## Usage with Native Mobile Platforms
156
+ ---
242
157
 
243
- ### React Native
158
+ ## 📱 Mobile Usage
244
159
 
245
- If using React Native, you can use the npm package directly:
160
+ ### 📲 React Native
246
161
 
247
162
  ```javascript
248
- import { configureApi, streamChat } from '@schmitech/chatbot-api';
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
- 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);
170
+ for await (const response of streamChat(message, false)) {
171
+ // Handle response
261
172
  }
262
173
  }
263
174
  ```
264
175
 
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
- ```
176
+ ---
335
177
 
336
- ### Alternative Approaches
178
+ ## 📚 API Reference
337
179
 
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
180
+ ### `configureApi(config)`
341
181
 
342
- ## API Reference
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
- ### configureApi(apiUrl)
188
+ ---
345
189
 
346
- Configures the API client with your server URL.
190
+ ## 📤 Publish to npm
347
191
 
348
- - **apiUrl** (string): The URL of your Chatbot server
349
- - **Returns**: void
192
+ **Build package:**
350
193
 
351
- ### streamChat(message, voiceEnabled)
194
+ ```bash
195
+ npm run build
196
+ ```
352
197
 
353
- Streams chat responses from the server.
198
+ **Test locally (optional):**
354
199
 
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
200
+ ```bash
201
+ npm pack --dry-run
202
+ ```
358
203
 
359
- ### StreamResponse Interface
204
+ **Update version:**
360
205
 
361
- ```typescript
362
- 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')
367
- }
206
+ ```bash
207
+ npm version [patch|minor|major]
368
208
  ```
369
209
 
370
- ## Development
371
-
372
- ### Building the Library
210
+ **Publish:**
373
211
 
374
212
  ```bash
375
- npm run build
213
+ npm publish --access public
376
214
  ```
377
215
 
378
- ### Running Tests
216
+ ---
379
217
 
380
- ```bash
381
- # Run tests once
382
- npm test
218
+ ## 🛠️ Development
219
+
220
+ ### 🧪 Testing
383
221
 
384
- # Run tests in watch mode
385
- npm run test:watch
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 a specific query
388
- npm run test-query "how much is the fee?" "http://your-api-server.com"
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
- ## License
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
- export declare const configureApi: (apiUrl: string, apiKey: string) => void;
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 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 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 w = null, g = null;
2
- const k = (t, e) => {
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
- w = t, g = e;
8
- }, I = () => {
9
- if (!w)
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 w;
12
- }, b = () => {
13
- if (!g)
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 g;
16
- }, E = (t, e = {}) => {
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 r = Date.now().toString(36) + Math.random().toString(36).substring(2);
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
- Connection: "keep-alive",
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
- async function* x(t, e = !0) {
32
- var r;
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 s = I(), i = await fetch(`${s}/chat`, E(s, {
35
- method: "POST",
36
- headers: {
37
- "Content-Type": "application/json",
38
- Accept: e ? "text/event-stream" : "application/json"
39
- },
40
- body: JSON.stringify({ message: t, stream: e })
41
- }));
42
- if (!i.ok) {
43
- const o = await i.text();
44
- throw console.error(`API request failed: ${i.status} ${o}`), new Error(`Network response was not ok: ${i.status} ${o}`);
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
- yield {
48
- text: (await i.json()).response,
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 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 = "";
57
- for (; ; ) {
58
- const { done: o, value: n } = await y.read();
59
- if (o) break;
60
- const c = P.decode(n, { stream: !0 });
61
- a += c;
62
- const p = a.split(`
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
- a = p.pop() || "";
65
- for (const d of p)
66
- if (d.trim() && d.startsWith("data: "))
67
- 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);
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(), 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
- };
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 (s) {
105
- console.error("Chat API error:", s.message), yield {
106
- text: `Error connecting to chat server: ${s.message}`,
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 A(t, e) {
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 s = Math.min(e.length, t.length);
119
- for (; r < s && e[r] === t[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
- k as configureApi,
128
- x as streamChat
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 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, 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.3.1",
5
- "description": "API client for the Chatbot server",
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",