@schmitech/chatbot-api 0.4.5 → 0.5.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
@@ -36,6 +36,53 @@ async function chat() {
36
36
  }
37
37
  }
38
38
  ```
39
+ ### Local test in Node.js environment
40
+
41
+ First, verify you have `Node.js` and its package manager, `npm`, installed. Then create a new folder.
42
+
43
+ ```bash
44
+ node -v
45
+ npm -v
46
+ ```
47
+
48
+ Initialize a `Node.js` Project
49
+
50
+ ```bash
51
+ npm init -y
52
+ ```
53
+
54
+ Modify `package.json`
55
+
56
+ ```json
57
+ {
58
+ "name": "orbit-node",
59
+ "version": "1.0.0",
60
+ "main": "index.js",
61
+ "type": "module",
62
+ "scripts": {
63
+ "test": "echo \"Error: no test specified\" && exit 1"
64
+ },
65
+ "keywords": [],
66
+ "author": "",
67
+ "license": "ISC",
68
+ "description": "",
69
+ "dependencies": {
70
+ "@schmitech/chatbot-api": "^0.5.0"
71
+ }
72
+ }
73
+ ```
74
+
75
+ Install chatbot api
76
+
77
+ ```bash
78
+ npm install @schmitech/chatbot-api
79
+ ```
80
+
81
+ Run this test
82
+
83
+ ```bash
84
+ node test/test-npm-package.js "how many r are in a strawberry?" "http://localhost:3000" "my-session-123"
85
+ ```
39
86
 
40
87
  ## ⚛️ React Integration
41
88
 
package/dist/api.cjs CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let b=null,N=null,O=null;const $=(t,e=null,r=null)=>{if(!t||typeof t!="string")throw new Error("API URL must be a valid string");if(e!==null&&typeof e!="string")throw new Error("API key must be a valid string or null");if(r!==null&&typeof r!="string")throw new Error("Session ID must be a valid string or null");b=t,N=e,O=r},R=()=>{if(!b)throw new Error("API URL not configured. Please call configureApi() with your server URL before using any API functions.");return b},q=()=>N,L=()=>O,j=(t,e={})=>{t.startsWith("https:");const n={Connection:"keep-alive","X-Request-ID":Date.now().toString(36)+Math.random().toString(36).substring(2)},i=q();i&&(n["X-API-Key"]=i);const u=L();return u&&(n["X-Session-ID"]=u),{...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,i,u,k,E,S,A,P;try{const a=R(),v=new AbortController,D=setTimeout(()=>v.abort(),6e4),c=await fetch(`${a}/v1/chat`,{...j(a,{method:"POST",headers:{"Content-Type":"application/json",Accept:e?"text/event-stream":"application/json"},body:JSON.stringify(x(t,e))}),signal:v.signal});if(clearTimeout(D),!c.ok){const o=await c.text();throw new Error(`Network response was not ok: ${c.status} ${o}`)}if(!e){const o=await c.json();if(o.error)throw new Error(`MCP Error: ${o.error.message}`);(u=(i=(n=(r=o.result)==null?void 0:r.output)==null?void 0:n.messages)==null?void 0:i[0])!=null&&u.content&&(yield{text:o.result.output.messages[0].content,done:!0});return}const w=(k=c.body)==null?void 0:k.getReader();if(!w)throw new Error("No reader available");const M=new TextDecoder;let l="",y="";try{for(;;){const{done:o,value:d}=await w.read();if(o)break;const f=M.decode(d,{stream:!0});l+=f;const I=l.split(`
2
- `);l=I.pop()||"";for(const h of I)if(h.trim()&&h.startsWith("data: "))try{const p=h.slice(6).trim();if(p==="[DONE]"){yield{text:"",done:!0};break}const s=JSON.parse(p);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 m=C(g,y);m?(y+=m,yield{text:m,done:s.result.type==="complete"}):s.result.type==="complete"&&(yield{text:"",done:!0})}}}catch(p){console.warn("Error parsing JSON chunk:",h,"Error:",p)}}}finally{w.releaseLock()}if(l&&l.startsWith("data: "))try{const o=l.slice(6).trim();if(o!=="[DONE]"){const d=JSON.parse(o);if((P=(A=d.result)==null?void 0:A.chunk)!=null&&P.content){const f=C(d.result.chunk.content,y);f&&(yield{text:f,done:d.result.type==="complete"})}}}catch(o){console.warn("Error parsing final JSON buffer:",l,"Error:",o)}}catch(a){a.name==="AbortError"?yield{text:"Connection timed out. Please check if the server is running.",done:!0}:a.name==="TypeError"&&a.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: ${a.message}`,done:!0}}}function C(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=R(),r=await fetch(`${e}/v1/chat`,j(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(J(t))}));if(!r.ok){const i=await r.text();throw new Error(`Network response was not ok: ${r.status} ${i}`)}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;
1
+ "use strict";var K=Object.create;var I=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var F=Object.getPrototypeOf,J=Object.prototype.hasOwnProperty;var L=(t,e,r)=>e in t?I(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var H=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of N(e))!J.call(t,o)&&o!==r&&I(t,o,{get:()=>e[o],enumerable:!(n=$(e,o))||n.enumerable});return t};var R=(t,e,r)=>(r=t!=null?K(F(t)):{},H(e||!t||!t.__esModule?I(r,"default",{value:t,enumerable:!0}):r,t));var w=(t,e,r)=>L(t,typeof e!="symbol"?e+"":e,r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let b=null,v=null;typeof window>"u"&&Promise.all([import("http").catch(()=>null),import("https").catch(()=>null)]).then(([t,e])=>{var r,n;(r=t==null?void 0:t.default)!=null&&r.Agent?b=new t.default.Agent({keepAlive:!0}):t!=null&&t.Agent&&(b=new t.Agent({keepAlive:!0})),(n=e==null?void 0:e.default)!=null&&n.Agent?v=new e.default.Agent({keepAlive:!0}):e!=null&&e.Agent&&(v=new e.Agent({keepAlive:!0}))}).catch(t=>{console.warn("Failed to initialize HTTP agents:",t.message)});class j{constructor(e){w(this,"apiUrl");w(this,"apiKey");w(this,"sessionId");if(!e.apiUrl||typeof e.apiUrl!="string")throw new Error("API URL must be a valid string");if(e.apiKey!==void 0&&e.apiKey!==null&&typeof e.apiKey!="string")throw new Error("API key must be a valid string or null");if(e.sessionId!==void 0&&e.sessionId!==null&&typeof e.sessionId!="string")throw new Error("Session ID must be a valid string or null");this.apiUrl=e.apiUrl,this.apiKey=e.apiKey??null,this.sessionId=e.sessionId??null}setSessionId(e){if(e!==null&&typeof e!="string")throw new Error("Session ID must be a valid string or null");this.sessionId=e}getSessionId(){return this.sessionId}getFetchOptions(e={}){const r={};if(typeof window>"u"){const u=this.apiUrl.startsWith("https:")?v:b;u&&(r.agent=u)}else r.headers={Connection:"keep-alive"};const n={"X-Request-ID":Date.now().toString(36)+Math.random().toString(36).substring(2)};return r.headers&&Object.assign(n,r.headers),e.headers&&Object.assign(n,e.headers),this.apiKey&&(n["X-API-Key"]=this.apiKey),this.sessionId&&(n["X-Session-ID"]=this.sessionId),{...e,...r,headers:n}}createMCPRequest(e,r=!0){return{jsonrpc:"2.0",method:"tools/call",params:{name:"chat",arguments:{messages:[{role:"user",content:e}],stream:r}},id:Date.now().toString(36)+Math.random().toString(36).substring(2)}}createMCPToolsRequest(e){return{jsonrpc:"2.0",method:"tools/call",params:{name:"tools",arguments:{tools:e}},id:Date.now().toString(36)+Math.random().toString(36).substring(2)}}async*streamChat(e,r=!0){var n,o,u,P,E,k,C,T,x,S,O;try{const l=new AbortController,D=setTimeout(()=>l.abort(),6e4),c=await fetch(`${this.apiUrl}/v1/chat`,{...this.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json",Accept:r?"text/event-stream":"application/json"},body:JSON.stringify(this.createMCPRequest(e,r))}),signal:l.signal});if(clearTimeout(D),!c.ok){const a=await c.text();throw new Error(`Network response was not ok: ${c.status} ${a}`)}if(!r){const a=await c.json();if(a.error)throw new Error(`MCP Error: ${a.error.message}`);(P=(u=(o=(n=a.result)==null?void 0:n.output)==null?void 0:o.messages)==null?void 0:u[0])!=null&&P.content&&(yield{text:a.result.output.messages[0].content,done:!0});return}const g=(E=c.body)==null?void 0:E.getReader();if(!g)throw new Error("No reader available");const M=new TextDecoder;let i="",d=!1;try{for(;;){const{done:a,value:U}=await g.read();if(a)break;const q=M.decode(U,{stream:!0});i+=q;let h=0,p;for(;(p=i.indexOf(`
2
+ `,h))!==-1;){const y=i.slice(h,p).trim();if(h=p+1,y&&y.startsWith("data: ")){const m=y.slice(6).trim();if(!m||m==="[DONE]"){yield{text:"",done:!0};return}try{const s=JSON.parse(m);if(s.error)throw new Error(`MCP Error: ${s.error.message}`);if(((k=s.result)==null?void 0:k.type)==="chunk"&&((C=s.result.chunk)!=null&&C.content))d=!0,yield{text:s.result.chunk.content,done:!1};else if(((T=s.result)==null?void 0:T.type)==="complete"){const A=((O=(S=(x=s.result.output)==null?void 0:x.messages)==null?void 0:S[0])==null?void 0:O.content)??"";!d&&A?yield{text:A,done:!0}:yield{text:"",done:!0};return}else if("response"in s&&typeof s.response=="string")if("done"in s&&s.done===!0){!d&&s.response?yield{text:s.response,done:!0}:yield{text:"",done:!0};return}else d=!0,yield{text:s.response,done:!1}}catch(s){console.warn("Error parsing JSON chunk:",s)}}}i=i.slice(h),i.length>1e6&&(console.warn("Buffer too large, truncating..."),i=i.slice(-5e5))}d&&(yield{text:"",done:!0})}finally{g.releaseLock()}}catch(l){throw l.name==="AbortError"?new Error("Connection timed out. Please check if the server is running."):l.name==="TypeError"&&l.message.includes("Failed to fetch")?new Error("Could not connect to the server. Please check if the server is running."):l}}async sendToolsRequest(e){const r=await fetch(`${this.apiUrl}/v1/chat`,this.getFetchOptions({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(this.createMCPToolsRequest(e))}));if(!r.ok){const o=await r.text();throw new Error(`Network response was not ok: ${r.status} ${o}`)}const n=await r.json();if(n.error)throw new Error(`MCP Error: ${n.error.message}`);return n}}let f=null;const X=(t,e=null,r=null)=>{f=new j({apiUrl:t,apiKey:e,sessionId:r})};async function*W(t,e=!0){if(!f)throw new Error("API not configured. Please call configureApi() with your server URL before using any API functions.");yield*f.streamChat(t,e)}async function z(t){if(!f)throw new Error("API not configured. Please call configureApi() with your server URL before using any API functions.");return f.sendToolsRequest(t)}exports.ApiClient=j;exports.configureApi=X;exports.sendToolsRequest=z;exports.streamChat=W;
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// 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 (optional), and session ID (optional)\nexport const configureApi = (apiUrl: string, apiKey: string | null = null, sessionId: string | null = null): void => {\n if (!apiUrl || typeof apiUrl !== 'string') {\n throw new Error('API URL must be a valid string');\n }\n if (apiKey !== null && typeof apiKey !== 'string') {\n throw new Error('API key must be a valid string or null');\n }\n if (sessionId !== null && typeof sessionId !== 'string') {\n throw new Error('Session ID must be a valid string or null');\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 return null if not configured\nconst getApiKey = (): string | null => {\n return configuredApiKey;\n};\n\n// Get the configured session ID or return null if not configured\nconst getSessionId = (): string | null => {\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 };\n \n // Add API key to headers only if it exists\n const apiKey = getApiKey();\n if (apiKey) {\n headers['X-API-Key'] = apiKey;\n }\n \n // Add session ID to headers only if it exists\n const sessionId = getSessionId();\n if (sessionId) {\n headers['X-Session-ID'] = sessionId;\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(), 60000); // 60 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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"}
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// Initialize agents for connection pooling in Node.js environments\nif (typeof window === 'undefined') {\n // Lazy load to avoid including 'http' in browser bundles\n Promise.all([\n import('http').catch(() => null),\n import('https').catch(() => null)\n ]).then(([http, https]) => {\n if (http?.default?.Agent) {\n httpAgent = new http.default.Agent({ keepAlive: true });\n } else if (http?.Agent) {\n httpAgent = new http.Agent({ keepAlive: true });\n }\n \n if (https?.default?.Agent) {\n httpsAgent = new https.default.Agent({ keepAlive: true });\n } else if (https?.Agent) {\n httpsAgent = new https.Agent({ keepAlive: true });\n }\n }).catch(err => {\n // Silently fail - connection pooling is optional\n console.warn('Failed to initialize HTTP agents:', err.message);\n });\n}\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\nexport class ApiClient {\n private readonly apiUrl: string;\n private readonly apiKey: string | null;\n private sessionId: string | null; // Session ID can be mutable\n\n constructor(config: { apiUrl: string; apiKey?: string | null; sessionId?: string | null }) {\n if (!config.apiUrl || typeof config.apiUrl !== 'string') {\n throw new Error('API URL must be a valid string');\n }\n if (config.apiKey !== undefined && config.apiKey !== null && typeof config.apiKey !== 'string') {\n throw new Error('API key must be a valid string or null');\n }\n if (config.sessionId !== undefined && config.sessionId !== null && typeof config.sessionId !== 'string') {\n throw new Error('Session ID must be a valid string or null');\n }\n \n this.apiUrl = config.apiUrl;\n this.apiKey = config.apiKey ?? null;\n this.sessionId = config.sessionId ?? null;\n }\n\n public setSessionId(sessionId: string | null): void {\n if (sessionId !== null && typeof sessionId !== 'string') {\n throw new Error('Session ID must be a valid string or null');\n }\n this.sessionId = sessionId;\n }\n\n public getSessionId(): string | null {\n return this.sessionId;\n }\n\n // Helper to get fetch options with connection pooling if available\n private getFetchOptions(options: RequestInit = {}): RequestInit {\n const baseOptions: RequestInit = {};\n \n // Environment-specific options\n if (typeof window === 'undefined') {\n // Node.js: Use connection pooling agent\n const isHttps = this.apiUrl.startsWith('https:');\n const agent = isHttps ? httpsAgent : httpAgent;\n if (agent) {\n (baseOptions as any).agent = agent;\n }\n } else {\n // Browser: Use keep-alive header\n baseOptions.headers = { 'Connection': 'keep-alive' };\n }\n\n // Common headers\n const headers: Record<string, string> = {\n 'X-Request-ID': Date.now().toString(36) + Math.random().toString(36).substring(2),\n };\n\n // Merge base options headers (for browser keep-alive)\n if (baseOptions.headers) {\n Object.assign(headers, baseOptions.headers);\n }\n\n // Merge original request headers\n if (options.headers) {\n Object.assign(headers, options.headers);\n }\n\n if (this.apiKey) {\n headers['X-API-Key'] = this.apiKey;\n }\n\n if (this.sessionId) {\n headers['X-Session-ID'] = this.sessionId;\n }\n\n return {\n ...options,\n ...baseOptions,\n headers,\n };\n }\n\n // Create MCP request\n private 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\n private 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\n public async *streamChat(\n message: string,\n stream: boolean = true\n ): AsyncGenerator<StreamResponse> {\n try {\n // Add timeout to the fetch request\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 60000); // 60 second timeout\n\n const response = await fetch(`${this.apiUrl}/v1/chat`, {\n ...this.getFetchOptions({\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': stream ? 'text/event-stream' : 'application/json'\n },\n body: JSON.stringify(this.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 hasReceivedContent = false;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n const chunk = decoder.decode(value, { stream: true });\n buffer += chunk;\n \n // Process complete lines immediately as they arrive\n let lineStartIndex = 0;\n let newlineIndex;\n \n while ((newlineIndex = buffer.indexOf('\\n', lineStartIndex)) !== -1) {\n const line = buffer.slice(lineStartIndex, newlineIndex).trim();\n lineStartIndex = newlineIndex + 1;\n \n if (line && line.startsWith('data: ')) {\n const jsonText = line.slice(6).trim();\n \n // Check for [DONE] message or empty data lines\n if (!jsonText || jsonText === '[DONE]') {\n yield { text: '', done: true };\n return;\n }\n\n try {\n const data = JSON.parse(jsonText) as MCPResponse;\n \n if (data.error) {\n throw new Error(`MCP Error: ${data.error.message}`);\n }\n \n // Handle MCP protocol format - server sends chunks of new text directly\n if (data.result?.type === 'chunk' && data.result.chunk?.content) {\n hasReceivedContent = true;\n yield { text: data.result.chunk.content, done: false };\n } else if (data.result?.type === 'complete') {\n // Final piece of content or just the done signal\n const finalText = data.result.output?.messages?.[0]?.content ?? '';\n // Only yield final text if we haven't received incremental chunks\n if (!hasReceivedContent && finalText) {\n yield { text: finalText, done: true };\n } else {\n yield { text: '', done: true };\n }\n return;\n } else if ('response' in data && typeof data.response === 'string') {\n // Handle direct server response format (legacy compatibility)\n const isDone = 'done' in data && data.done === true;\n \n if (isDone) {\n // For final response, only yield if we haven't received incremental chunks\n if (!hasReceivedContent && data.response) {\n yield { text: data.response, done: true };\n } else {\n yield { text: '', done: true };\n }\n return;\n } else {\n // For incremental chunks, always yield\n hasReceivedContent = true;\n yield { text: data.response, done: false };\n }\n }\n \n } catch (parseError) {\n console.warn('Error parsing JSON chunk:', parseError);\n }\n }\n }\n \n // Keep remaining incomplete line in buffer\n buffer = buffer.slice(lineStartIndex);\n \n // Prevent buffer from growing too large\n if (buffer.length > 1000000) { // 1MB limit\n console.warn('Buffer too large, truncating...');\n buffer = buffer.slice(-500000); // Keep last 500KB\n }\n }\n \n // If we exit the while loop naturally, ensure we send a done signal\n if (hasReceivedContent) {\n yield { text: '', done: true };\n }\n \n } finally {\n reader.releaseLock();\n }\n \n } catch (error: any) {\n if (error.name === 'AbortError') {\n throw new Error('Connection timed out. Please check if the server is running.');\n } else if (error.name === 'TypeError' && error.message.includes('Failed to fetch')) {\n throw new Error('Could not connect to the server. Please check if the server is running.');\n } else {\n // Re-throw the error to be caught by the caller\n throw error;\n }\n }\n }\n\n // New function to send tools request\n public async sendToolsRequest(tools: Array<{ name: string; parameters: Record<string, any> }>): Promise<MCPResponse> {\n const response = await fetch(`${this.apiUrl}/v1/chat`, this.getFetchOptions({\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(this.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 }\n}\n\n// Legacy compatibility functions - these create a default client instance\n// These are kept for backward compatibility but should be deprecated in favor of the class-based approach\n\nlet defaultClient: ApiClient | null = null;\n\n// Configure the API with a custom URL, API key (optional), and session ID (optional)\nexport const configureApi = (apiUrl: string, apiKey: string | null = null, sessionId: string | null = null): void => {\n defaultClient = new ApiClient({ apiUrl, apiKey, sessionId });\n}\n\n// Legacy streamChat function that uses the default client\nexport async function* streamChat(\n message: string,\n stream: boolean = true\n): AsyncGenerator<StreamResponse> {\n if (!defaultClient) {\n throw new Error('API not configured. Please call configureApi() with your server URL before using any API functions.');\n }\n \n yield* defaultClient.streamChat(message, stream);\n}\n\n// Legacy sendToolsRequest function that uses the default client\nexport async function sendToolsRequest(tools: Array<{ name: string; parameters: Record<string, any> }>): Promise<MCPResponse> {\n if (!defaultClient) {\n throw new Error('API not configured. Please call configureApi() with your server URL before using any API functions.');\n }\n \n return defaultClient.sendToolsRequest(tools);\n}"],"names":["httpAgent","httpsAgent","http","https","_a","_b","err","ApiClient","config","__publicField","sessionId","options","baseOptions","agent","headers","message","stream","tools","controller","timeoutId","response","errorText","data","_d","_c","reader","_e","decoder","buffer","hasReceivedContent","done","value","chunk","lineStartIndex","newlineIndex","line","jsonText","_f","_g","_h","finalText","_k","_j","_i","parseError","error","defaultClient","configureApi","apiUrl","apiKey","streamChat","sendToolsRequest"],"mappings":"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"}
@@ -25,6 +25,26 @@ interface MCPResponse {
25
25
  message: string;
26
26
  };
27
27
  }
28
+ export declare class ApiClient {
29
+ private readonly apiUrl;
30
+ private readonly apiKey;
31
+ private sessionId;
32
+ constructor(config: {
33
+ apiUrl: string;
34
+ apiKey?: string | null;
35
+ sessionId?: string | null;
36
+ });
37
+ setSessionId(sessionId: string | null): void;
38
+ getSessionId(): string | null;
39
+ private getFetchOptions;
40
+ private createMCPRequest;
41
+ private createMCPToolsRequest;
42
+ streamChat(message: string, stream?: boolean): AsyncGenerator<StreamResponse>;
43
+ sendToolsRequest(tools: Array<{
44
+ name: string;
45
+ parameters: Record<string, any>;
46
+ }>): Promise<MCPResponse>;
47
+ }
28
48
  export declare const configureApi: (apiUrl: string, apiKey?: string | null, sessionId?: string | null) => void;
29
49
  export declare function streamChat(message: string, stream?: boolean): AsyncGenerator<StreamResponse>;
30
50
  export declare function sendToolsRequest(tools: Array<{
package/dist/api.mjs CHANGED
@@ -1,188 +1,203 @@
1
- let k = null, C = null, O = null;
2
- const J = (t, e = null, r = null) => {
3
- if (!t || typeof t != "string")
4
- throw new Error("API URL must be a valid string");
5
- if (e !== null && typeof e != "string")
6
- throw new Error("API key must be a valid string or null");
7
- if (r !== null && typeof r != "string")
8
- throw new Error("Session ID must be a valid string or null");
9
- k = t, C = e, O = r;
10
- }, R = () => {
11
- if (!k)
12
- throw new Error("API URL not configured. Please call configureApi() with your server URL before using any API functions.");
13
- return k;
14
- }, M = () => C, x = () => O, j = (t, e = {}) => {
15
- t.startsWith("https:");
16
- const o = {
17
- Connection: "keep-alive",
18
- "X-Request-ID": Date.now().toString(36) + Math.random().toString(36).substring(2)
19
- }, i = M();
20
- i && (o["X-API-Key"] = i);
21
- const c = x();
22
- return c && (o["X-Session-ID"] = c), {
23
- ...e,
24
- headers: {
25
- ...e.headers,
26
- ...o
27
- }
28
- };
29
- }, L = (t, e = !0) => ({
30
- jsonrpc: "2.0",
31
- method: "tools/call",
32
- params: {
33
- name: "chat",
34
- arguments: {
35
- messages: [
36
- { role: "user", content: t }
37
- ],
38
- stream: e
39
- }
40
- },
41
- id: Date.now().toString(36) + Math.random().toString(36).substring(2)
42
- }), q = (t) => ({
43
- jsonrpc: "2.0",
44
- method: "tools/call",
45
- params: {
46
- name: "tools",
47
- arguments: {
48
- tools: t
49
- }
50
- },
51
- id: Date.now().toString(36) + Math.random().toString(36).substring(2)
1
+ var j = Object.defineProperty;
2
+ var M = (r, e, t) => e in r ? j(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
3
+ var w = (r, e, t) => M(r, typeof e != "symbol" ? e + "" : e, t);
4
+ let I = null, v = null;
5
+ typeof window > "u" && Promise.all([
6
+ import("http").catch(() => null),
7
+ import("https").catch(() => null)
8
+ ]).then(([r, e]) => {
9
+ var t, s;
10
+ (t = r == null ? void 0 : r.default) != null && t.Agent ? I = new r.default.Agent({ keepAlive: !0 }) : r != null && r.Agent && (I = new r.Agent({ keepAlive: !0 })), (s = e == null ? void 0 : e.default) != null && s.Agent ? v = new e.default.Agent({ keepAlive: !0 }) : e != null && e.Agent && (v = new e.Agent({ keepAlive: !0 }));
11
+ }).catch((r) => {
12
+ console.warn("Failed to initialize HTTP agents:", r.message);
52
13
  });
53
- async function* U(t, e = !0) {
54
- var r, o, i, c, E, b, S, A, P;
55
- try {
56
- const a = R(), I = new AbortController(), D = setTimeout(() => I.abort(), 6e4), u = await fetch(`${a}/v1/chat`, {
57
- ...j(a, {
58
- method: "POST",
59
- headers: {
60
- "Content-Type": "application/json",
61
- Accept: e ? "text/event-stream" : "application/json"
62
- },
63
- body: JSON.stringify(L(t, e))
64
- }),
65
- signal: I.signal
66
- });
67
- if (clearTimeout(D), !u.ok) {
68
- const n = await u.text();
69
- throw new Error(`Network response was not ok: ${u.status} ${n}`);
70
- }
71
- if (!e) {
72
- const n = await u.json();
73
- if (n.error)
74
- throw new Error(`MCP Error: ${n.error.message}`);
75
- (c = (i = (o = (r = n.result) == null ? void 0 : r.output) == null ? void 0 : o.messages) == null ? void 0 : i[0]) != null && c.content && (yield {
76
- text: n.result.output.messages[0].content,
77
- done: !0
78
- });
79
- return;
80
- }
81
- const w = (E = u.body) == null ? void 0 : E.getReader();
82
- if (!w) throw new Error("No reader available");
83
- const $ = new TextDecoder();
84
- let l = "", y = "";
14
+ class K {
15
+ // Session ID can be mutable
16
+ constructor(e) {
17
+ w(this, "apiUrl");
18
+ w(this, "apiKey");
19
+ w(this, "sessionId");
20
+ if (!e.apiUrl || typeof e.apiUrl != "string")
21
+ throw new Error("API URL must be a valid string");
22
+ if (e.apiKey !== void 0 && e.apiKey !== null && typeof e.apiKey != "string")
23
+ throw new Error("API key must be a valid string or null");
24
+ if (e.sessionId !== void 0 && e.sessionId !== null && typeof e.sessionId != "string")
25
+ throw new Error("Session ID must be a valid string or null");
26
+ this.apiUrl = e.apiUrl, this.apiKey = e.apiKey ?? null, this.sessionId = e.sessionId ?? null;
27
+ }
28
+ setSessionId(e) {
29
+ if (e !== null && typeof e != "string")
30
+ throw new Error("Session ID must be a valid string or null");
31
+ this.sessionId = e;
32
+ }
33
+ getSessionId() {
34
+ return this.sessionId;
35
+ }
36
+ // Helper to get fetch options with connection pooling if available
37
+ getFetchOptions(e = {}) {
38
+ const t = {};
39
+ if (typeof window > "u") {
40
+ const u = this.apiUrl.startsWith("https:") ? v : I;
41
+ u && (t.agent = u);
42
+ } else
43
+ t.headers = { Connection: "keep-alive" };
44
+ const s = {
45
+ "X-Request-ID": Date.now().toString(36) + Math.random().toString(36).substring(2)
46
+ };
47
+ return t.headers && Object.assign(s, t.headers), e.headers && Object.assign(s, e.headers), this.apiKey && (s["X-API-Key"] = this.apiKey), this.sessionId && (s["X-Session-ID"] = this.sessionId), {
48
+ ...e,
49
+ ...t,
50
+ headers: s
51
+ };
52
+ }
53
+ // Create MCP request
54
+ createMCPRequest(e, t = !0) {
55
+ return {
56
+ jsonrpc: "2.0",
57
+ method: "tools/call",
58
+ params: {
59
+ name: "chat",
60
+ arguments: {
61
+ messages: [
62
+ { role: "user", content: e }
63
+ ],
64
+ stream: t
65
+ }
66
+ },
67
+ id: Date.now().toString(36) + Math.random().toString(36).substring(2)
68
+ };
69
+ }
70
+ // Create MCP tools request
71
+ createMCPToolsRequest(e) {
72
+ return {
73
+ jsonrpc: "2.0",
74
+ method: "tools/call",
75
+ params: {
76
+ name: "tools",
77
+ arguments: {
78
+ tools: e
79
+ }
80
+ },
81
+ id: Date.now().toString(36) + Math.random().toString(36).substring(2)
82
+ };
83
+ }
84
+ async *streamChat(e, t = !0) {
85
+ var s, l, u, E, P, b, k, x, C, T, S;
85
86
  try {
86
- for (; ; ) {
87
- const { done: n, value: d } = await w.read();
88
- if (n) break;
89
- const f = $.decode(d, { stream: !0 });
90
- l += f;
91
- const v = l.split(`
92
- `);
93
- l = v.pop() || "";
94
- for (const h of v)
95
- if (h.trim() && h.startsWith("data: "))
96
- try {
97
- const p = h.slice(6).trim();
98
- if (p === "[DONE]") {
87
+ const a = new AbortController(), O = setTimeout(() => a.abort(), 6e4), c = await fetch(`${this.apiUrl}/v1/chat`, {
88
+ ...this.getFetchOptions({
89
+ method: "POST",
90
+ headers: {
91
+ "Content-Type": "application/json",
92
+ Accept: t ? "text/event-stream" : "application/json"
93
+ },
94
+ body: JSON.stringify(this.createMCPRequest(e, t))
95
+ }),
96
+ signal: a.signal
97
+ });
98
+ if (clearTimeout(O), !c.ok) {
99
+ const i = await c.text();
100
+ throw new Error(`Network response was not ok: ${c.status} ${i}`);
101
+ }
102
+ if (!t) {
103
+ const i = await c.json();
104
+ if (i.error)
105
+ throw new Error(`MCP Error: ${i.error.message}`);
106
+ (E = (u = (l = (s = i.result) == null ? void 0 : s.output) == null ? void 0 : l.messages) == null ? void 0 : u[0]) != null && E.content && (yield {
107
+ text: i.result.output.messages[0].content,
108
+ done: !0
109
+ });
110
+ return;
111
+ }
112
+ const g = (P = c.body) == null ? void 0 : P.getReader();
113
+ if (!g) throw new Error("No reader available");
114
+ const R = new TextDecoder();
115
+ let o = "", d = !1;
116
+ try {
117
+ for (; ; ) {
118
+ const { done: i, value: D } = await g.read();
119
+ if (i)
120
+ break;
121
+ const U = R.decode(D, { stream: !0 });
122
+ o += U;
123
+ let h = 0, p;
124
+ for (; (p = o.indexOf(`
125
+ `, h)) !== -1; ) {
126
+ const y = o.slice(h, p).trim();
127
+ if (h = p + 1, y && y.startsWith("data: ")) {
128
+ const m = y.slice(6).trim();
129
+ if (!m || m === "[DONE]") {
99
130
  yield { text: "", done: !0 };
100
- break;
131
+ return;
101
132
  }
102
- const s = JSON.parse(p);
103
- if (s.result) {
104
- let g = "";
105
- if (s.result.type === "start")
106
- continue;
107
- if (s.result.type === "chunk" && s.result.chunk ? g = s.result.chunk.content : s.result.type === "complete" && ((S = (b = s.result.output) == null ? void 0 : b.messages) != null && S[0]) && (g = s.result.output.messages[0].content), g) {
108
- const m = N(g, y);
109
- m ? (y += m, yield {
110
- text: m,
111
- done: s.result.type === "complete"
112
- }) : s.result.type === "complete" && (yield { text: "", done: !0 });
113
- }
133
+ try {
134
+ const n = JSON.parse(m);
135
+ if (n.error)
136
+ throw new Error(`MCP Error: ${n.error.message}`);
137
+ if (((b = n.result) == null ? void 0 : b.type) === "chunk" && ((k = n.result.chunk) != null && k.content))
138
+ d = !0, yield { text: n.result.chunk.content, done: !1 };
139
+ else if (((x = n.result) == null ? void 0 : x.type) === "complete") {
140
+ const A = ((S = (T = (C = n.result.output) == null ? void 0 : C.messages) == null ? void 0 : T[0]) == null ? void 0 : S.content) ?? "";
141
+ !d && A ? yield { text: A, done: !0 } : yield { text: "", done: !0 };
142
+ return;
143
+ } else if ("response" in n && typeof n.response == "string")
144
+ if ("done" in n && n.done === !0) {
145
+ !d && n.response ? yield { text: n.response, done: !0 } : yield { text: "", done: !0 };
146
+ return;
147
+ } else
148
+ d = !0, yield { text: n.response, done: !1 };
149
+ } catch (n) {
150
+ console.warn("Error parsing JSON chunk:", n);
114
151
  }
115
- } catch (p) {
116
- console.warn("Error parsing JSON chunk:", h, "Error:", p);
117
152
  }
118
- }
119
- } finally {
120
- w.releaseLock();
121
- }
122
- if (l && l.startsWith("data: "))
123
- try {
124
- const n = l.slice(6).trim();
125
- if (n !== "[DONE]") {
126
- const d = JSON.parse(n);
127
- if ((P = (A = d.result) == null ? void 0 : A.chunk) != null && P.content) {
128
- const f = N(d.result.chunk.content, y);
129
- f && (yield {
130
- text: f,
131
- done: d.result.type === "complete"
132
- });
133
153
  }
154
+ o = o.slice(h), o.length > 1e6 && (console.warn("Buffer too large, truncating..."), o = o.slice(-5e5));
134
155
  }
135
- } catch (n) {
136
- console.warn("Error parsing final JSON buffer:", l, "Error:", n);
156
+ d && (yield { text: "", done: !0 });
157
+ } finally {
158
+ g.releaseLock();
137
159
  }
138
- } catch (a) {
139
- a.name === "AbortError" ? yield {
140
- text: "Connection timed out. Please check if the server is running.",
141
- done: !0
142
- } : a.name === "TypeError" && a.message.includes("Failed to fetch") ? yield {
143
- text: "Could not connect to the server. Please check if the server is running.",
144
- done: !0
145
- } : yield {
146
- text: `Error: ${a.message}`,
147
- done: !0
148
- };
160
+ } catch (a) {
161
+ throw a.name === "AbortError" ? new Error("Connection timed out. Please check if the server is running.") : a.name === "TypeError" && a.message.includes("Failed to fetch") ? new Error("Could not connect to the server. Please check if the server is running.") : a;
162
+ }
149
163
  }
150
- }
151
- function N(t, e) {
152
- if (!e) return t;
153
- if (e.endsWith(t)) return "";
154
- if (t.length > e.length) {
155
- if (t.startsWith(e))
156
- return t.slice(e.length);
157
- let r = 0;
158
- const o = Math.min(e.length, t.length);
159
- for (; r < o && e[r] === t[r]; )
160
- r++;
161
- if (r > e.length / 2)
162
- return t.slice(r);
164
+ // New function to send tools request
165
+ async sendToolsRequest(e) {
166
+ const t = await fetch(`${this.apiUrl}/v1/chat`, this.getFetchOptions({
167
+ method: "POST",
168
+ headers: {
169
+ "Content-Type": "application/json"
170
+ },
171
+ body: JSON.stringify(this.createMCPToolsRequest(e))
172
+ }));
173
+ if (!t.ok) {
174
+ const l = await t.text();
175
+ throw new Error(`Network response was not ok: ${t.status} ${l}`);
176
+ }
177
+ const s = await t.json();
178
+ if (s.error)
179
+ throw new Error(`MCP Error: ${s.error.message}`);
180
+ return s;
163
181
  }
164
- return t;
165
182
  }
166
- async function W(t) {
167
- const e = R(), r = await fetch(`${e}/v1/chat`, j(e, {
168
- method: "POST",
169
- headers: {
170
- "Content-Type": "application/json"
171
- },
172
- body: JSON.stringify(q(t))
173
- }));
174
- if (!r.ok) {
175
- const i = await r.text();
176
- throw new Error(`Network response was not ok: ${r.status} ${i}`);
177
- }
178
- const o = await r.json();
179
- if (o.error)
180
- throw new Error(`MCP Error: ${o.error.message}`);
181
- return o;
183
+ let f = null;
184
+ const q = (r, e = null, t = null) => {
185
+ f = new K({ apiUrl: r, apiKey: e, sessionId: t });
186
+ };
187
+ async function* N(r, e = !0) {
188
+ if (!f)
189
+ throw new Error("API not configured. Please call configureApi() with your server URL before using any API functions.");
190
+ yield* f.streamChat(r, e);
191
+ }
192
+ async function F(r) {
193
+ if (!f)
194
+ throw new Error("API not configured. Please call configureApi() with your server URL before using any API functions.");
195
+ return f.sendToolsRequest(r);
182
196
  }
183
197
  export {
184
- J as configureApi,
185
- W as sendToolsRequest,
186
- U as streamChat
198
+ K as ApiClient,
199
+ q as configureApi,
200
+ F as sendToolsRequest,
201
+ N as streamChat
187
202
  };
188
203
  //# sourceMappingURL=api.mjs.map
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// 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 (optional), and session ID (optional)\nexport const configureApi = (apiUrl: string, apiKey: string | null = null, sessionId: string | null = null): void => {\n if (!apiUrl || typeof apiUrl !== 'string') {\n throw new Error('API URL must be a valid string');\n }\n if (apiKey !== null && typeof apiKey !== 'string') {\n throw new Error('API key must be a valid string or null');\n }\n if (sessionId !== null && typeof sessionId !== 'string') {\n throw new Error('Session ID must be a valid string or null');\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 return null if not configured\nconst getApiKey = (): string | null => {\n return configuredApiKey;\n};\n\n// Get the configured session ID or return null if not configured\nconst getSessionId = (): string | null => {\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 };\n \n // Add API key to headers only if it exists\n const apiKey = getApiKey();\n if (apiKey) {\n headers['X-API-Key'] = apiKey;\n }\n \n // Add session ID to headers only if it exists\n const sessionId = getSessionId();\n if (sessionId) {\n headers['X-Session-ID'] = sessionId;\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(), 60000); // 60 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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"}
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// Initialize agents for connection pooling in Node.js environments\nif (typeof window === 'undefined') {\n // Lazy load to avoid including 'http' in browser bundles\n Promise.all([\n import('http').catch(() => null),\n import('https').catch(() => null)\n ]).then(([http, https]) => {\n if (http?.default?.Agent) {\n httpAgent = new http.default.Agent({ keepAlive: true });\n } else if (http?.Agent) {\n httpAgent = new http.Agent({ keepAlive: true });\n }\n \n if (https?.default?.Agent) {\n httpsAgent = new https.default.Agent({ keepAlive: true });\n } else if (https?.Agent) {\n httpsAgent = new https.Agent({ keepAlive: true });\n }\n }).catch(err => {\n // Silently fail - connection pooling is optional\n console.warn('Failed to initialize HTTP agents:', err.message);\n });\n}\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\nexport class ApiClient {\n private readonly apiUrl: string;\n private readonly apiKey: string | null;\n private sessionId: string | null; // Session ID can be mutable\n\n constructor(config: { apiUrl: string; apiKey?: string | null; sessionId?: string | null }) {\n if (!config.apiUrl || typeof config.apiUrl !== 'string') {\n throw new Error('API URL must be a valid string');\n }\n if (config.apiKey !== undefined && config.apiKey !== null && typeof config.apiKey !== 'string') {\n throw new Error('API key must be a valid string or null');\n }\n if (config.sessionId !== undefined && config.sessionId !== null && typeof config.sessionId !== 'string') {\n throw new Error('Session ID must be a valid string or null');\n }\n \n this.apiUrl = config.apiUrl;\n this.apiKey = config.apiKey ?? null;\n this.sessionId = config.sessionId ?? null;\n }\n\n public setSessionId(sessionId: string | null): void {\n if (sessionId !== null && typeof sessionId !== 'string') {\n throw new Error('Session ID must be a valid string or null');\n }\n this.sessionId = sessionId;\n }\n\n public getSessionId(): string | null {\n return this.sessionId;\n }\n\n // Helper to get fetch options with connection pooling if available\n private getFetchOptions(options: RequestInit = {}): RequestInit {\n const baseOptions: RequestInit = {};\n \n // Environment-specific options\n if (typeof window === 'undefined') {\n // Node.js: Use connection pooling agent\n const isHttps = this.apiUrl.startsWith('https:');\n const agent = isHttps ? httpsAgent : httpAgent;\n if (agent) {\n (baseOptions as any).agent = agent;\n }\n } else {\n // Browser: Use keep-alive header\n baseOptions.headers = { 'Connection': 'keep-alive' };\n }\n\n // Common headers\n const headers: Record<string, string> = {\n 'X-Request-ID': Date.now().toString(36) + Math.random().toString(36).substring(2),\n };\n\n // Merge base options headers (for browser keep-alive)\n if (baseOptions.headers) {\n Object.assign(headers, baseOptions.headers);\n }\n\n // Merge original request headers\n if (options.headers) {\n Object.assign(headers, options.headers);\n }\n\n if (this.apiKey) {\n headers['X-API-Key'] = this.apiKey;\n }\n\n if (this.sessionId) {\n headers['X-Session-ID'] = this.sessionId;\n }\n\n return {\n ...options,\n ...baseOptions,\n headers,\n };\n }\n\n // Create MCP request\n private 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\n private 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\n public async *streamChat(\n message: string,\n stream: boolean = true\n ): AsyncGenerator<StreamResponse> {\n try {\n // Add timeout to the fetch request\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 60000); // 60 second timeout\n\n const response = await fetch(`${this.apiUrl}/v1/chat`, {\n ...this.getFetchOptions({\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': stream ? 'text/event-stream' : 'application/json'\n },\n body: JSON.stringify(this.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 hasReceivedContent = false;\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n const chunk = decoder.decode(value, { stream: true });\n buffer += chunk;\n \n // Process complete lines immediately as they arrive\n let lineStartIndex = 0;\n let newlineIndex;\n \n while ((newlineIndex = buffer.indexOf('\\n', lineStartIndex)) !== -1) {\n const line = buffer.slice(lineStartIndex, newlineIndex).trim();\n lineStartIndex = newlineIndex + 1;\n \n if (line && line.startsWith('data: ')) {\n const jsonText = line.slice(6).trim();\n \n // Check for [DONE] message or empty data lines\n if (!jsonText || jsonText === '[DONE]') {\n yield { text: '', done: true };\n return;\n }\n\n try {\n const data = JSON.parse(jsonText) as MCPResponse;\n \n if (data.error) {\n throw new Error(`MCP Error: ${data.error.message}`);\n }\n \n // Handle MCP protocol format - server sends chunks of new text directly\n if (data.result?.type === 'chunk' && data.result.chunk?.content) {\n hasReceivedContent = true;\n yield { text: data.result.chunk.content, done: false };\n } else if (data.result?.type === 'complete') {\n // Final piece of content or just the done signal\n const finalText = data.result.output?.messages?.[0]?.content ?? '';\n // Only yield final text if we haven't received incremental chunks\n if (!hasReceivedContent && finalText) {\n yield { text: finalText, done: true };\n } else {\n yield { text: '', done: true };\n }\n return;\n } else if ('response' in data && typeof data.response === 'string') {\n // Handle direct server response format (legacy compatibility)\n const isDone = 'done' in data && data.done === true;\n \n if (isDone) {\n // For final response, only yield if we haven't received incremental chunks\n if (!hasReceivedContent && data.response) {\n yield { text: data.response, done: true };\n } else {\n yield { text: '', done: true };\n }\n return;\n } else {\n // For incremental chunks, always yield\n hasReceivedContent = true;\n yield { text: data.response, done: false };\n }\n }\n \n } catch (parseError) {\n console.warn('Error parsing JSON chunk:', parseError);\n }\n }\n }\n \n // Keep remaining incomplete line in buffer\n buffer = buffer.slice(lineStartIndex);\n \n // Prevent buffer from growing too large\n if (buffer.length > 1000000) { // 1MB limit\n console.warn('Buffer too large, truncating...');\n buffer = buffer.slice(-500000); // Keep last 500KB\n }\n }\n \n // If we exit the while loop naturally, ensure we send a done signal\n if (hasReceivedContent) {\n yield { text: '', done: true };\n }\n \n } finally {\n reader.releaseLock();\n }\n \n } catch (error: any) {\n if (error.name === 'AbortError') {\n throw new Error('Connection timed out. Please check if the server is running.');\n } else if (error.name === 'TypeError' && error.message.includes('Failed to fetch')) {\n throw new Error('Could not connect to the server. Please check if the server is running.');\n } else {\n // Re-throw the error to be caught by the caller\n throw error;\n }\n }\n }\n\n // New function to send tools request\n public async sendToolsRequest(tools: Array<{ name: string; parameters: Record<string, any> }>): Promise<MCPResponse> {\n const response = await fetch(`${this.apiUrl}/v1/chat`, this.getFetchOptions({\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(this.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 }\n}\n\n// Legacy compatibility functions - these create a default client instance\n// These are kept for backward compatibility but should be deprecated in favor of the class-based approach\n\nlet defaultClient: ApiClient | null = null;\n\n// Configure the API with a custom URL, API key (optional), and session ID (optional)\nexport const configureApi = (apiUrl: string, apiKey: string | null = null, sessionId: string | null = null): void => {\n defaultClient = new ApiClient({ apiUrl, apiKey, sessionId });\n}\n\n// Legacy streamChat function that uses the default client\nexport async function* streamChat(\n message: string,\n stream: boolean = true\n): AsyncGenerator<StreamResponse> {\n if (!defaultClient) {\n throw new Error('API not configured. Please call configureApi() with your server URL before using any API functions.');\n }\n \n yield* defaultClient.streamChat(message, stream);\n}\n\n// Legacy sendToolsRequest function that uses the default client\nexport async function sendToolsRequest(tools: Array<{ name: string; parameters: Record<string, any> }>): Promise<MCPResponse> {\n if (!defaultClient) {\n throw new Error('API not configured. Please call configureApi() with your server URL before using any API functions.');\n }\n \n return defaultClient.sendToolsRequest(tools);\n}"],"names":["httpAgent","httpsAgent","http","https","_a","_b","err","ApiClient","config","__publicField","sessionId","options","baseOptions","agent","headers","message","stream","tools","_c","_d","_e","_f","_g","_h","_i","_j","_k","controller","timeoutId","response","errorText","data","reader","decoder","buffer","hasReceivedContent","done","value","chunk","lineStartIndex","newlineIndex","line","jsonText","finalText","parseError","error","defaultClient","configureApi","apiUrl","apiKey","streamChat","sendToolsRequest"],"mappings":";;;AACA,IAAIA,IAAiB,MACjBC,IAAkB;AAGlB,OAAO,SAAW,OAEpB,QAAQ,IAAI;AAAA,EACV,OAAO,MAAM,EAAE,MAAM,MAAM,IAAI;AAAA,EAC/B,OAAO,OAAO,EAAE,MAAM,MAAM,IAAI;AAAA,CACjC,EAAE,KAAK,CAAC,CAACC,GAAMC,CAAK,MAAM;AAT7B,MAAAC,GAAAC;AAUI,GAAID,IAAAF,KAAA,gBAAAA,EAAM,YAAN,QAAAE,EAAe,QACjBJ,IAAY,IAAIE,EAAK,QAAQ,MAAM,EAAE,WAAW,IAAM,IAC7CA,KAAA,QAAAA,EAAM,UACfF,IAAY,IAAIE,EAAK,MAAM,EAAE,WAAW,IAAM,KAG5CG,IAAAF,KAAA,gBAAAA,EAAO,YAAP,QAAAE,EAAgB,QAClBJ,IAAa,IAAIE,EAAM,QAAQ,MAAM,EAAE,WAAW,IAAM,IAC/CA,KAAA,QAAAA,EAAO,UAChBF,IAAa,IAAIE,EAAM,MAAM,EAAE,WAAW,IAAM;AAEpD,CAAC,EAAE,MAAM,CAAAG,MAAO;AAEd,UAAQ,KAAK,qCAAqCA,EAAI,OAAO;AAC/D,CAAC;AAuDI,MAAMC,EAAU;AAAA;AAAA,EAKrB,YAAYC,GAA+E;AAJ1E,IAAAC,EAAA;AACA,IAAAA,EAAA;AACT,IAAAA,EAAA;AAGN,QAAI,CAACD,EAAO,UAAU,OAAOA,EAAO,UAAW;AAC7C,YAAM,IAAI,MAAM,gCAAgC;AAElD,QAAIA,EAAO,WAAW,UAAaA,EAAO,WAAW,QAAQ,OAAOA,EAAO,UAAW;AACpF,YAAM,IAAI,MAAM,wCAAwC;AAE1D,QAAIA,EAAO,cAAc,UAAaA,EAAO,cAAc,QAAQ,OAAOA,EAAO,aAAc;AAC7F,YAAM,IAAI,MAAM,2CAA2C;AAG7D,SAAK,SAASA,EAAO,QACrB,KAAK,SAASA,EAAO,UAAU,MAC/B,KAAK,YAAYA,EAAO,aAAa;AAAA,EACvC;AAAA,EAEO,aAAaE,GAAgC;AAClD,QAAIA,MAAc,QAAQ,OAAOA,KAAc;AAC7C,YAAM,IAAI,MAAM,2CAA2C;AAE7D,SAAK,YAAYA;AAAA,EACnB;AAAA,EAEO,eAA8B;AACnC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGQ,gBAAgBC,IAAuB,IAAiB;AAC9D,UAAMC,IAA2B,CAAA;AAGjC,QAAI,OAAO,SAAW,KAAa;AAGjC,YAAMC,IADU,KAAK,OAAO,WAAW,QAAQ,IACvBZ,IAAaD;AACrC,MAAIa,MACDD,EAAoB,QAAQC;AAAA,IAEjC;AAEE,MAAAD,EAAY,UAAU,EAAE,YAAc,aAAA;AAIxC,UAAME,IAAkC;AAAA,MACtC,gBAAgB,KAAK,MAAM,SAAS,EAAE,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,UAAU,CAAC;AAAA,IAAA;AAIlF,WAAIF,EAAY,WACd,OAAO,OAAOE,GAASF,EAAY,OAAO,GAIxCD,EAAQ,WACV,OAAO,OAAOG,GAASH,EAAQ,OAAO,GAGpC,KAAK,WACPG,EAAQ,WAAW,IAAI,KAAK,SAG1B,KAAK,cACPA,EAAQ,cAAc,IAAI,KAAK,YAG1B;AAAA,MACL,GAAGH;AAAA,MACH,GAAGC;AAAA,MACH,SAAAE;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA,EAGQ,iBAAiBC,GAAiBC,IAAkB,IAAkB;AAC5E,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,WAAW;AAAA,UACT,UAAU;AAAA,YACR,EAAE,MAAM,QAAQ,SAASD,EAAA;AAAA,UAAQ;AAAA,UAEnC,QAAAC;AAAA,QAAA;AAAA,MACF;AAAA,MAEF,IAAI,KAAK,MAAM,SAAS,EAAE,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,UAAU,CAAC;AAAA,IAAA;AAAA,EAExE;AAAA;AAAA,EAGQ,sBAAsBC,GAA6E;AACzG,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,WAAW;AAAA,UACT,OAAAA;AAAA,QAAA;AAAA,MACF;AAAA,MAEF,IAAI,KAAK,MAAM,SAAS,EAAE,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,UAAU,CAAC;AAAA,IAAA;AAAA,EAExE;AAAA,EAEA,OAAc,WACZF,GACAC,IAAkB,IACc;AAlMpC,QAAAZ,GAAAC,GAAAa,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC;AAmMI,QAAI;AAEF,YAAMC,IAAa,IAAI,gBAAA,GACjBC,IAAY,WAAW,MAAMD,EAAW,MAAA,GAAS,GAAK,GAEtDE,IAAW,MAAM,MAAM,GAAG,KAAK,MAAM,YAAY;AAAA,QACrD,GAAG,KAAK,gBAAgB;AAAA,UACtB,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,QAAUb,IAAS,sBAAsB;AAAA,UAAA;AAAA,UAE3C,MAAM,KAAK,UAAU,KAAK,iBAAiBD,GAASC,CAAM,CAAC;AAAA,QAAA,CAC5D;AAAA,QACD,QAAQW,EAAW;AAAA,MAAA,CACpB;AAID,UAFA,aAAaC,CAAS,GAElB,CAACC,EAAS,IAAI;AAChB,cAAMC,IAAY,MAAMD,EAAS,KAAA;AACjC,cAAM,IAAI,MAAM,gCAAgCA,EAAS,MAAM,IAAIC,CAAS,EAAE;AAAA,MAChF;AAEA,UAAI,CAACd,GAAQ;AAEX,cAAMe,IAAO,MAAMF,EAAS,KAAA;AAC5B,YAAIE,EAAK;AACP,gBAAM,IAAI,MAAM,cAAcA,EAAK,MAAM,OAAO,EAAE;AAEpD,SAAIZ,KAAAD,KAAAb,KAAAD,IAAA2B,EAAK,WAAL,gBAAA3B,EAAa,WAAb,gBAAAC,EAAqB,aAArB,gBAAAa,EAAgC,OAAhC,QAAAC,EAAoC,YACtC,MAAM;AAAA,UACJ,MAAMY,EAAK,OAAO,OAAO,SAAS,CAAC,EAAE;AAAA,UACrC,MAAM;AAAA,QAAA;AAGV;AAAA,MACF;AAEA,YAAMC,KAASZ,IAAAS,EAAS,SAAT,gBAAAT,EAAe;AAC9B,UAAI,CAACY,EAAQ,OAAM,IAAI,MAAM,qBAAqB;AAElD,YAAMC,IAAU,IAAI,YAAA;AACpB,UAAIC,IAAS,IACTC,IAAqB;AAEzB,UAAI;AACF,mBAAa;AACX,gBAAM,EAAE,MAAAC,GAAM,OAAAC,EAAA,IAAU,MAAML,EAAO,KAAA;AACrC,cAAII;AACF;AAGF,gBAAME,IAAQL,EAAQ,OAAOI,GAAO,EAAE,QAAQ,IAAM;AACpD,UAAAH,KAAUI;AAGV,cAAIC,IAAiB,GACjBC;AAEJ,kBAAQA,IAAeN,EAAO,QAAQ;AAAA,GAAMK,CAAc,OAAO,MAAI;AACnE,kBAAME,IAAOP,EAAO,MAAMK,GAAgBC,CAAY,EAAE,KAAA;AAGxD,gBAFAD,IAAiBC,IAAe,GAE5BC,KAAQA,EAAK,WAAW,QAAQ,GAAG;AACrC,oBAAMC,IAAWD,EAAK,MAAM,CAAC,EAAE,KAAA;AAG/B,kBAAI,CAACC,KAAYA,MAAa,UAAU;AACtC,sBAAM,EAAE,MAAM,IAAI,MAAM,GAAA;AACxB;AAAA,cACF;AAEA,kBAAI;AACF,sBAAMX,IAAO,KAAK,MAAMW,CAAQ;AAEhC,oBAAIX,EAAK;AACP,wBAAM,IAAI,MAAM,cAAcA,EAAK,MAAM,OAAO,EAAE;AAIpD,sBAAIV,IAAAU,EAAK,WAAL,gBAAAV,EAAa,UAAS,aAAWC,IAAAS,EAAK,OAAO,UAAZ,QAAAT,EAAmB;AACtD,kBAAAa,IAAqB,IACrB,MAAM,EAAE,MAAMJ,EAAK,OAAO,MAAM,SAAS,MAAM,GAAA;AAAA,2BACtCR,IAAAQ,EAAK,WAAL,gBAAAR,EAAa,UAAS,YAAY;AAE3C,wBAAMoB,MAAYjB,KAAAD,KAAAD,IAAAO,EAAK,OAAO,WAAZ,gBAAAP,EAAoB,aAApB,gBAAAC,EAA+B,OAA/B,gBAAAC,EAAmC,YAAW;AAEhE,kBAAI,CAACS,KAAsBQ,IACzB,MAAM,EAAE,MAAMA,GAAW,MAAM,GAAA,IAE/B,MAAM,EAAE,MAAM,IAAI,MAAM,GAAA;AAE1B;AAAA,gBACF,WAAW,cAAcZ,KAAQ,OAAOA,EAAK,YAAa;AAIxD,sBAFe,UAAUA,KAAQA,EAAK,SAAS,IAEnC;AAEV,oBAAI,CAACI,KAAsBJ,EAAK,WAC9B,MAAM,EAAE,MAAMA,EAAK,UAAU,MAAM,GAAA,IAEnC,MAAM,EAAE,MAAM,IAAI,MAAM,GAAA;AAE1B;AAAA,kBACF;AAEE,oBAAAI,IAAqB,IACrB,MAAM,EAAE,MAAMJ,EAAK,UAAU,MAAM,GAAA;AAAA,cAIzC,SAASa,GAAY;AACnB,wBAAQ,KAAK,6BAA6BA,CAAU;AAAA,cACtD;AAAA,YACF;AAAA,UACF;AAGA,UAAAV,IAASA,EAAO,MAAMK,CAAc,GAGhCL,EAAO,SAAS,QAClB,QAAQ,KAAK,iCAAiC,GAC9CA,IAASA,EAAO,MAAM,IAAO;AAAA,QAEjC;AAGA,QAAIC,MACF,MAAM,EAAE,MAAM,IAAI,MAAM,GAAA;AAAA,MAG5B,UAAA;AACE,QAAAH,EAAO,YAAA;AAAA,MACT;AAAA,IAEF,SAASa,GAAY;AACnB,YAAIA,EAAM,SAAS,eACX,IAAI,MAAM,8DAA8D,IACrEA,EAAM,SAAS,eAAeA,EAAM,QAAQ,SAAS,iBAAiB,IACzE,IAAI,MAAM,yEAAyE,IAGnFA;AAAA,IAEV;AAAA,EACF;AAAA;AAAA,EAGA,MAAa,iBAAiB5B,GAAuF;AACnH,UAAMY,IAAW,MAAM,MAAM,GAAG,KAAK,MAAM,YAAY,KAAK,gBAAgB;AAAA,MAC1E,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,MAAA;AAAA,MAElB,MAAM,KAAK,UAAU,KAAK,sBAAsBZ,CAAK,CAAC;AAAA,IAAA,CACvD,CAAC;AAEF,QAAI,CAACY,EAAS,IAAI;AAChB,YAAMC,IAAY,MAAMD,EAAS,KAAA;AACjC,YAAM,IAAI,MAAM,gCAAgCA,EAAS,MAAM,IAAIC,CAAS,EAAE;AAAA,IAChF;AAEA,UAAMC,IAAO,MAAMF,EAAS,KAAA;AAC5B,QAAIE,EAAK;AACP,YAAM,IAAI,MAAM,cAAcA,EAAK,MAAM,OAAO,EAAE;AAGpD,WAAOA;AAAA,EACT;AACF;AAKA,IAAIe,IAAkC;AAG/B,MAAMC,IAAe,CAACC,GAAgBC,IAAwB,MAAMvC,IAA2B,SAAe;AACnH,EAAAoC,IAAgB,IAAIvC,EAAU,EAAE,QAAAyC,GAAQ,QAAAC,GAAQ,WAAAvC,GAAW;AAC7D;AAGA,gBAAuBwC,EACrBnC,GACAC,IAAkB,IACc;AAChC,MAAI,CAAC8B;AACH,UAAM,IAAI,MAAM,qGAAqG;AAGvH,SAAOA,EAAc,WAAW/B,GAASC,CAAM;AACjD;AAGA,eAAsBmC,EAAiBlC,GAAuF;AAC5H,MAAI,CAAC6B;AACH,UAAM,IAAI,MAAM,qGAAqG;AAGvH,SAAOA,EAAc,iBAAiB7B,CAAK;AAC7C;"}
package/package.json CHANGED
@@ -1,26 +1,30 @@
1
1
  {
2
2
  "name": "@schmitech/chatbot-api",
3
3
  "private": false,
4
- "version": "0.4.5",
4
+ "version": "0.5.1",
5
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",
9
- "types": "./api.d.ts",
9
+ "types": "./dist/api.d.ts",
10
10
  "exports": {
11
11
  ".": {
12
- "import": "./dist/api.mjs",
13
- "require": "./dist/api.cjs",
14
- "types": "./api.d.ts"
12
+ "import": {
13
+ "types": "./dist/api.d.ts",
14
+ "default": "./dist/api.mjs"
15
+ },
16
+ "require": {
17
+ "types": "./dist/api.d.ts",
18
+ "default": "./dist/api.cjs"
19
+ }
15
20
  }
16
21
  },
17
22
  "files": [
18
- "dist",
19
- "api.d.ts"
23
+ "dist"
20
24
  ],
21
25
  "scripts": {
22
26
  "dev": "vite",
23
- "build": "tsc --emitDeclarationOnly && vite build",
27
+ "build": "vite build",
24
28
  "lint": "eslint .",
25
29
  "preview": "vite preview",
26
30
  "test": "vitest",
@@ -28,15 +32,9 @@
28
32
  "test-query": "node --import 'data:text/javascript,import { register } from \"node:module\"; import { pathToFileURL } from \"node:url\"; register(\"ts-node/esm\", pathToFileURL(\"./\"));' ./test/run-query.js",
29
33
  "test-query-from-pairs": "node --import 'data:text/javascript,import { register } from \"node:module\"; import { pathToFileURL } from \"node:url\"; register(\"ts-node/esm\", pathToFileURL(\"./\"));' ./test/run-query-from-pairs.js"
30
34
  },
31
- "dependencies": {
32
- "cors": "^2.8.5",
33
- "express": "^4.18.3",
34
- "node-fetch": "^3.3.2"
35
- },
35
+ "dependencies": {},
36
36
  "devDependencies": {
37
37
  "@eslint/js": "^9.9.1",
38
- "@types/cors": "^2.8.17",
39
- "@types/express": "^4.17.21",
40
38
  "@types/node": "^20.11.24",
41
39
  "eslint": "^9.9.1",
42
40
  "globals": "^15.9.0",
@@ -45,6 +43,7 @@
45
43
  "typescript": "^5.5.3",
46
44
  "typescript-eslint": "^8.3.0",
47
45
  "vite": "^5.4.2",
46
+ "vite-plugin-dts": "^4.3.0",
48
47
  "vitest": "^0.34.6"
49
48
  },
50
49
  "peerDependencies": {
package/dist/api.mjs.d.ts DELETED
@@ -1 +0,0 @@
1
- export * from "../api.d.ts";