@mencraft/lore-headless
Version:
A headless library for chat streaming functionality
3 lines (2 loc) • 8.55 kB
JavaScript
"use strict";var t,e,a,r,o;exports.EventType=void 0,(t=exports.EventType||(exports.EventType={})).BatchDataIntermediate="batch_data_intermediate",t.TextBatchIntermediate="text_batch_intermediate",t.TextStreamIntermediate="text_stream_intermediate",t.ToolCallIntermediate="tool_call_intermediate",t.BatchDataOutput="batch_data_output",t.TextBatchOutput="text_batch_output",t.TextStreamOutput="text_stream_output",t.ToolCallOutput="tool_call_output",t.End="end",t.Error="error",exports.LoreNodeOutputTypes=void 0,(e=exports.LoreNodeOutputTypes||(exports.LoreNodeOutputTypes={})).HYDE_PROMPT="HydePromptNode",e.PROMPT="PromptNode",e.BOOL_PROMPT="BoolPromptNode",e.DEFAULT_RESPONSE="DefaultResponseNode",e.QUERY="QueryNode",e.ROUTER="RouterNode",e.REACT="ReactNode",e.CONDITIONAL="ConditionalNode",e.SEARCH="SearchNode",exports.LoreNodeTypes=void 0,(a=exports.LoreNodeTypes||(exports.LoreNodeTypes={})).HYDE_PROMPT="HydePromptNode",a.PROMPT="PromptNode",a.BOOL_PROMPT="BoolPromptNode",a.DEFAULT_RESPONSE="DefaultResponseNode",a.QUERY="QueryNode",a.ROUTER="RouterNode",a.REACT="ReactNode",a.CONDITIONAL="ConditionalNode",a.SEARCH="SearchNode",exports.LLMRole=void 0,(r=exports.LLMRole||(exports.LLMRole={})).ASSISTANT="assistant",r.USER="user",r.SYSTEM="system",r.DEVELOPER="developer",exports.ToolParameterType=void 0,(o=exports.ToolParameterType||(exports.ToolParameterType={})).STRING="string",o.NUMBER="number",o.INTEGER="integer",o.BOOLEAN="boolean",o.OBJECT="object",o.ARRAY="array";exports.ChatStreamManager=class{constructor(t,e,a={}){this.readerRef=null,this.loreClient=t,this.auth=e,this.callbacks=a}setCallbacks(t){this.callbacks={...this.callbacks,...t}}async processChatStream(t){var e,a,r,o,s,i;const l=t.getReader();this.readerRef=l;const n=new TextDecoder;let c="";try{for(;;){const{done:t,value:r}=await l.read();if(t){if(c.trim())try{const t=JSON.parse(c.trim());await this.processEvent(t)}catch(t){}null===(a=(e=this.callbacks).onEnd)||void 0===a||a.call(e);break}for(c+=n.decode(r,{stream:!0});;){const t=c.indexOf("\n");if(-1===t)break;const e=c.slice(0,t).trim();if(c=c.slice(t+1),e)try{const t=JSON.parse(e);await this.processEvent(t)}catch(t){continue}}}}catch(t){null===(o=(r=this.callbacks).onError)||void 0===o||o.call(r,t instanceof Error?t:new Error("Stream processing error"))}finally{l.cancel(),null===(i=(s=this.callbacks).onEnd)||void 0===i||i.call(s)}}handleGraphValidationErrors(t){var e,a,r,o,s,i,l,n,c;return t.test_failure&&(null===(a=(e=this.callbacks).onSystemMessage)||void 0===a||a.call(e,"Graph validation failed due to test failures.")),t.too_many_graphs&&(null===(o=(r=this.callbacks).onSystemMessage)||void 0===o||o.call(r,"Error: Too many graphs detected.")),(null===(s=t.validation_errors)||void 0===s?void 0:s.length)&&(t.validation_errors.forEach((t=>{var e,a;const r=`Validation error in node ${t.node_id}: ${t.message} (${t.error_type})`;null===(a=(e=this.callbacks).onSystemMessage)||void 0===a||a.call(e,r)})),null===(l=(i=this.callbacks).onSystemMessage)||void 0===l||l.call(i,"This graph is not able to run. [Click to go to graph](/graph?graphId="+this.callbacks.graphId+") , load the graph to fix the graph error.")),(null===(n=t.tests)||void 0===n?void 0:n.length)&&t.tests.forEach((t=>{var e,a,r,o,s;if(t.error){const i=t.error_text||(null===(r=null===(a=null===(e=t.events)||void 0===e?void 0:e[0])||void 0===a?void 0:a.event_data)||void 0===r?void 0:r.error)||"Unknown test error";null===(s=(o=this.callbacks).onSystemMessage)||void 0===s||s.call(o,`Test error: ${i}`)}})),!((null===(c=t.validation_errors)||void 0===c?void 0:c.length)||t.test_failure||t.too_many_graphs)}async processEvent(t){var e,a,r,o,s,i,l,n,c,d,h,p,u;switch(null===(a=(e=this.callbacks).onEvent)||void 0===a||a.call(e,t),t.event_type){case exports.EventType.TextStreamOutput:void 0!==(null===(r=t.event_data)||void 0===r?void 0:r.text)&&(null===(s=(o=this.callbacks).onTextStream)||void 0===s||s.call(o,t.event_data.text));break;case exports.EventType.ToolCallOutput:t.event_data&&(null===(l=(i=this.callbacks).onToolCall)||void 0===l||l.call(i,t.event_data));break;case exports.EventType.BatchDataOutput:null===(c=(n=this.callbacks).onBatchData)||void 0===c||c.call(n,t.event_data);break;case exports.EventType.TextBatchOutput:null===(h=(d=this.callbacks).onTextBatch)||void 0===h||h.call(d,t.event_data);break;case exports.EventType.End:null===(u=(p=this.callbacks).onEnd)||void 0===u||u.call(p)}}async startGraphChatStream(t,e,a=!1){var r,o;try{if(!a){if(!await this.validateGraph(t,e))return}const r=await this.loreClient.chatPost("/chat_stream",this.auth,t,{headers:{Accept:"text/event-stream","Graph-Id":this.callbacks.graphId||e||"personal"}});if(!r.data)throw new Error("No stream data received");await this.processChatStream(r.data)}catch(t){null===(o=(r=this.callbacks).onError)||void 0===o||o.call(r,t instanceof Error?t:new Error("Failed to start chat stream"))}}async startChatStream(t,e,a=!1){let r=null;if(a?r=await this.loreClient.adminPost("/chat/chat_stream",this.auth,t,{headers:{Accept:"text/event-stream","Graph-Id":this.callbacks.graphId||e||"personal"}}):a||(r=await this.loreClient.chatPost("/chat_stream",this.auth,t,{headers:{Accept:"text/event-stream","Graph-Id":this.callbacks.graphId||e||"personal"}})),!r)throw new Error("No response received");if(!r.data)throw new Error("No stream data received");await this.processChatStream(r.data)}cancelStream(){this.readerRef&&(this.readerRef.cancel(),this.readerRef=null)}async sendFeedback(t,e){return this.loreClient.post("/feedback",this.auth,t,{headers:{...e&&{"Graph-Id":e}},useValidationUrl:!1})}async validateGraph(t,e){var a,r,o,s,i,l,n,c;try{null===(r=(a=this.callbacks).onSystemMessage)||void 0===r||r.call(a,"Verifying graph structure...");const n={graphID:e,tests:[t.query]},c=await this.loreClient.post("/graph/verify",this.auth,n,{headers:{Accept:"text/event-stream","Graph-Id":e},useValidationUrl:!0});if(!c.data)return null===(s=(o=this.callbacks).onSystemMessage)||void 0===s||s.call(o,"Validation failed: No response received"),!1;const d=this.handleGraphValidationErrors(c.data);return d&&(null===(l=(i=this.callbacks).onSystemMessage)||void 0===l||l.call(i,"Graph structure verified successfully.")),d}catch(t){return null===(c=(n=this.callbacks).onError)||void 0===c||c.call(n,t instanceof Error?t:new Error("Graph validation error")),!1}}},exports.LoreClient=class{constructor(t="production",e,a){if(e||a){if(!e||!a)throw new Error("Both customChatUrl and customValidationUrl must be provided together");this.chatUrl=e,this.validationUrl=a}else"staging"===t?(this.chatUrl="https://staging-chat.lore.center",this.validationUrl="https://staging-api.lore.center"):"development"===t?(this.chatUrl="http://127.0.0.1:8002",this.validationUrl="http://127.0.0.1:8000"):(this.chatUrl="https://chat-cloudrun-service-778776159944.us-central1.run.app",this.validationUrl="https://api.lore.center")}async post(t,e,a,r={}){if(!e.clientId||!e.token)throw new Error(`Authentication error: ${e.clientId?"Token":"Client ID"} missing`);const o={"Content-Type":"application/json",Accept:"application/json","client-id":e.clientId,"firebase-id-token":e.token},s={...r,method:"POST",headers:{...o,...r.headers},body:a?JSON.stringify(a):void 0},i=!0===r.useValidationUrl?this.validationUrl:this.chatUrl,l=await fetch(`${i}${t}`,s);if(!l.ok)throw new Error(`HTTP error! status: ${l.status}`);const n={status:l.status,statusText:l.statusText,headers:l.headers},c=l.headers.get("content-type");if(null==c?void 0:c.includes("text/event-stream"))return{...n,data:l.body};if(null==c?void 0:c.includes("application/json")){const t=await l.text();if(t)return{...n,data:JSON.parse(t)}}return n}async chatPost(t,e,a,r={}){return this.post(t,e,a,{...r,useValidationUrl:!1})}async adminPost(t,e,a,r={}){if(!e.clientId||!e.token)throw new Error(`Authentication error: ${e.clientId?"Firebase token":"Client ID"} missing`);const o={"Content-Type":"application/json",Accept:"application/json","client-id":e.clientId,"firebase-id-token":e.token},s={...r,method:"POST",headers:{...o,...r.headers},body:a?JSON.stringify(a):void 0},i=this.validationUrl,l=await fetch(`${i}${t}`,s);if(!l.ok)throw new Error(`HTTP error! status: ${l.status}`);const n={status:l.status,statusText:l.statusText,headers:l.headers},c=l.headers.get("content-type");if(null==c?void 0:c.includes("text/event-stream"))return{...n,data:l.body};if(null==c?void 0:c.includes("application/json")){const t=await l.text();if(t)return{...n,data:JSON.parse(t)}}return n}};
//# sourceMappingURL=index.js.map