@schmitech/chatbot-api 0.4.3 → 0.4.4
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/dist/api.cjs +1 -1
- package/dist/api.cjs.map +1 -1
- package/dist/api.mjs +1 -1
- package/dist/api.mjs.map +1 -1
- package/package.json +1 -1
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(),
|
|
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
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;
|
|
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(), 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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"}
|
|
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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"}
|
package/dist/api.mjs
CHANGED
|
@@ -53,7 +53,7 @@ const J = (t, e = null, r = null) => {
|
|
|
53
53
|
async function* U(t, e = !0) {
|
|
54
54
|
var r, o, i, c, E, b, S, A, P;
|
|
55
55
|
try {
|
|
56
|
-
const a = R(), I = new AbortController(), D = setTimeout(() => I.abort(),
|
|
56
|
+
const a = R(), I = new AbortController(), D = setTimeout(() => I.abort(), 6e4), u = await fetch(`${a}/v1/chat`, {
|
|
57
57
|
...j(a, {
|
|
58
58
|
method: "POST",
|
|
59
59
|
headers: {
|
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(), 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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"}
|
|
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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"}
|