graphai 2.0.1 → 2.0.3

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/lib/bundle.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).graphai={})}(this,(function(t){"use strict";var e;t.NodeState=void 0,(e=t.NodeState||(t.NodeState={})).Waiting="waiting",e.Queued="queued",e.Executing="executing",e.ExecutingServer="executing-server",e.Failed="failed",e.TimedOut="timed-out",e.Abort="abort",e.Completed="completed",e.Injected="injected",e.Skipped="skipped";const s={debug:!0,info:!0,log:!0,warn:!0,error:!0};let i=null;function n(t,...e){s[t]&&(i?i(t,...e):(console[t]||console.log)(...e))}const r={setLevelEnabled:function(t,e){s[t]=e},setLogger:function(t){i=t},debug:function(...t){n("debug",...t)},info:function(...t){n("info",...t)},log:function(...t){n("log",...t)},warn:function(...t){n("warn",...t)},error:function(...t){n("error",...t)}},o=/^[a-zA-Z]+\([^)]*\)$/,a=[(t,e)=>{if(Array.isArray(t)){if("length()"===e)return t.length;if("flat()"===e)return t.flat();if("toJSON()"===e)return JSON.stringify(t,null,2);if("isEmpty()"===e)return 0===t.length;const s=e.match(/^join\(([,-\s]?)\)$/);if(s&&Array.isArray(s))return t.join(s[1]??"")}},(t,e)=>{if(c(t)){if("keys()"===e)return Object.keys(t);if("values()"===e)return Object.values(t);if("toJSON()"===e)return JSON.stringify(t,null,2)}},(t,e)=>{if("string"==typeof t){if("codeBlock()"===e){const e=("\n"+t).match(/\n```[a-zA-z]*([\s\S]*?)\n```/);if(e)return e[1]}if("jsonParse()"===e)return JSON.parse(t);if("toNumber()"===e){const e=Number(t);if(!isNaN(e))return e}if("trim()"===e)return t.trim();if("toLowerCase()"===e)return t.toLowerCase();if("toUpperCase()"===e)return t.toUpperCase();const s=e.match(/^slice\((-?\d+)(?:,\s*(-?\d+))?\)/);if(s){if(void 0!==s[2])return t.slice(Number(s[1]),Number(s[2]));if(void 0!==s[1])return t.slice(Number(s[1]));r.warn("slice is not valid format: "+s)}const i=e.match(/^split\(([-_:;.,\s\n]+)\)$/);if(i)return t.split(i[1])}},(t,e)=>{if(void 0!==t&&Number.isFinite(t)){if("toString()"===e)return String(t);const s=/^add\((-?\d+)\)$/,i=e.match(s);if(i)return Number(t)+Number(i[1])}},(t,e)=>{if("boolean"==typeof t&&"not()"===e)return!t}],h=(t,e)=>"@now"===t||"@now_ms"===t?Date.now():"@now_s"===t?Math.floor(Date.now()/1e3):"@loop"===t?e[v].result:(r.warn("not match template utility function: ${"+t+"}"),""),u=(t,e=!1,s)=>{if(e){if("string"==typeof t&&"."===t[0]){return{nodeId:"self",propIds:t.split(".").slice(1)}}return{value:t}}if("string"==typeof t){const e=/^:(.*)$/,i=t.match(e);if(i){const t=i[1].split(/(?<!\()\.(?!\))/);return 1==t.length?{nodeId:t[0]}:{nodeId:t[0],propIds:t.slice(1)}}const n=/^@(.*)$/,r=t.match(n);if(s&&r)return{value:h(t,s)}}return{value:t}};function d(t,e,s=!1){if(!t){if(!s)throw new Error(e);r.warn("warn: "+e)}}const c=t=>null!==t&&"object"==typeof t,l=t=>null==t,p="Intentional Error for Debugging",g={name:"defaultAgentInfo",samples:[{inputs:[],params:{},result:{}}],description:"",category:[],author:"",repository:"",license:""},f=t=>{const e=[];return Object.keys(t).forEach((s=>{e.push([s]),Object.keys(t[s]).length>0&&f(t[s]).forEach((t=>{e.push([s,...t])}))})),e},y=(t,e)=>f({[t]:m(e)}).map((t=>":"+t.join("."))),m=t=>null==t||"string"==typeof t?{}:Array.isArray(t)?Array.from(t.keys()).reduce(((e,s)=>(e["$"+String(s)]=m(t[s]),e)),{}):Object.keys(t).reduce(((e,s)=>(e[s]=m(t[s]),e)),{}),I=t=>!!(Array.isArray(t)?0!==t.length:t),b={debugInfo:{nodeId:"test",retry:0,verbose:!0,state:t.NodeState.Executing,subGraphs:new Map},params:{},filterParams:{},agents:{},log:[]},w=t=>c(t)&&!Array.isArray(t)&&Object.keys(t||{}).length>0,N=t=>"agent"in t,S=t=>!("agent"in t),v="__loopIndex",k=t=>{if(Array.isArray(t))return t.map((t=>k(t))).flat();if(c(t))return Object.values(t).map((t=>k(t))).flat();if("string"==typeof t){const e=[...t.matchAll(/\${(:[^}]+)}/g)].map((t=>t[1]));if(e.length>0)return k(e)}return u(t)},A=t=>{if(!Array.isArray(t))throw new Error("sources must be array!! maybe inputs is invalid");return t.filter((t=>t.nodeId)).map((t=>t.nodeId))};class C{constructor(e){this.nodeId=e,this.state=t.NodeState.Waiting}initForComputedNode(t,e){this.agentId=t.getAgentId(),this.params=t.params,e.appendLog(this)}onInjected(t,e,s){const i="endTime"in this;this.result=t.result,this.state=t.state,this.endTime=Date.now(),this.injectFrom=s,e.setLoopLog(this),i?e.updateLog(this):e.appendLog(this)}onComplete(t,e,s){this.result=t.result,this.resultKeys=y(this.agentId||"",t.result),this.state=t.state,this.endTime=Date.now(),e.setLoopLog(this),s.length>0&&(this.log=s),e.updateLog(this)}beforeExecute(t,e,s,i){this.state=t.state,this.retryCount=t.retryCount>0?t.retryCount:void 0,this.startTime=s,this.inputs=A(t.dataSources),this.inputsData=i.length>0?i:void 0,e.setLoopLog(this),e.appendLog(this)}beforeAddTask(t,e){this.state=t.state,e.setLoopLog(this),e.appendLog(this)}onError(t,e,s){this.state=t.state,this.errorMessage=s,this.endTime=Date.now(),e.setLoopLog(this),e.updateLog(this)}onSkipped(t,e){this.state=t.state,e.setLoopLog(this),e.updateLog(this)}}const L=(t,e,s)=>{if(!l(t)&&e&&e.length>0){const i=((t,e,s)=>{if(e.match(o))for(const i of s){const s=i(t,e);if(!l(s))return s}if(Array.isArray(t)){const s=/^\$(\d+)$/,i=e.match(s);if(i)return t[parseInt(i[1],10)];if("$last"===e)return t[t.length-1]}else if(c(t)&&e in t)return t[e]})(t,e[0],s);return void 0===i&&r.error(`prop: ${e.join(".")} is not hit`),e.length>1?L(i,e.slice(1),s):i}return t},E=(t,e,s=[])=>e.nodeId?L(t,e.propIds,s):e.value,O=(t,e,s,i=!1)=>{if(Array.isArray(t))return t.map((t=>O(t,e,s,i)));if(w(t))return j(t,e,s,i);if("string"==typeof t){const n=[...t.matchAll(/\${([:@][^}]+)}/g)].map((t=>t[1]));if(n.length>0)return((t,e,s,i,n)=>{const r=O(e.filter((t=>t.startsWith(":"))),s,i,n),o=e.filter((t=>t.startsWith("@"))).reduce(((t,e)=>(t[e]=h(e,s),t)),{});return Array.from(e.keys()).reduce(((t,s)=>e[s].startsWith(":")?t.replaceAll("${"+e[s]+"}",r[s]):t.replaceAll("${"+e[s]+"}",o[e[s]])),t)})(t,n,e,s,i)}return T(u(t,i,e),e,s)},j=(t,e,s,i=!1)=>Object.keys(t).reduce(((n,r)=>{const o=t[r];return n[r]=w(o)?j(o,e,s,i):O(o,e,s,i),n}),{}),T=(t,e,s)=>{const{result:i}=t.nodeId?e[t.nodeId]:{result:void 0};return E(i,t,s)},F=t=>Array.isArray(t)?t.map((t=>F(t))).filter((t=>!l(t))):c(t)?Object.keys(t).reduce(((e,s)=>{const i=F(t[s]);return l(i)||(e[s]=i),e}),{}):t;class R{constructor(e,s){this.waitlist=new Set,this.state=t.NodeState.Waiting,this.result=void 0,this.nodeId=e,this.graph=s,this.log=new C(e),this.console={}}asString(){return`${this.nodeId}: ${this.state} ${[...this.waitlist]}`}onSetResult(){this.waitlist.forEach((t=>{const e=this.graph.nodes[t];e.isComputedNode&&(e.removePending(this.nodeId),this.graph.pushQueueIfReadyAndRunning(e))}))}afterConsoleLog(t){!1!==this.console&&(!0===this.console||!0===this.console.after?r.log("string"==typeof t?t:JSON.stringify(t,null,2)):this.console.after&&(c(this.console.after)?r.log(JSON.stringify(j(this.console.after,{self:{result:t}},this.graph.propFunctions,!0),null,2)):r.log(this.console.after)))}}class $ extends R{constructor(t,e,s,i){if(super(e,i),this.retryCount=0,this.dataSources=[],this.isSkip=!1,this.isStaticNode=!1,this.isComputedNode=!0,this.graphId=t,this.params=s.params??{},this.console=s.console??{},this.filterParams=s.filterParams??{},this.passThrough=s.passThrough,this.retryLimit=s.retry??i.retryLimit??0,this.timeout=s.timeout,this.isResult=s.isResult??!1,this.priority=s.priority??0,d(["function","string"].includes(typeof s.agent),"agent must be either string or function"),"string"==typeof s.agent)this.agentId=s.agent;else{const t=s.agent;this.agentFunction=async({namedInputs:e,params:s})=>t(e,s)}if(this.anyInput=s.anyInput??!1,this.inputs=s.inputs,this.output=s.output,this.dataSources=[...s.inputs?k(s.inputs).flat(10):[],...this.agentId?[u(this.agentId)]:[],...s.passThrough?k(s.passThrough).flat(10):[]],s.inputs&&Array.isArray(s.inputs))throw new Error(`array inputs have been deprecated. nodeId: ${e}: see https://github.com/receptron/graphai/blob/main/docs/NamedInputs.md`);this.pendings=new Set(A(this.dataSources)),s.graph&&(this.nestedGraph="string"==typeof s.graph?this.addPendingNode(s.graph):s.graph),s.graphLoader&&i.graphLoader&&(this.nestedGraph=i.graphLoader(s.graphLoader)),s.if&&(this.ifSource=this.addPendingNode(s.if)),s.unless&&(this.unlessSource=this.addPendingNode(s.unless)),s.defaultValue&&(this.defaultValue=s.defaultValue),this.isSkip=!1,this.log.initForComputedNode(this,i)}getAgentId(){return this.agentId??"__custom__function"}getConfig(t,e){if(e){if(t)return this.graph.config;const s=this.graph.config??{};return{...s.global??{},...s[e]??{}}}return{}}addPendingNode(t){const e=u(t);return d(!!e.nodeId,`Invalid data source ${t}`),this.pendings.add(e.nodeId),e}updateState(t){this.state=t,this.debugInfo&&(this.debugInfo.state=t)}resetPending(){this.pendings.clear(),this.state===t.NodeState.Executing&&this.updateState(t.NodeState.Abort),this.debugInfo&&this.debugInfo.subGraphs&&this.debugInfo.subGraphs.forEach((t=>t.abort()))}isReadyNode(){return this.state===t.NodeState.Waiting&&0===this.pendings.size&&(this.isSkip=!!(this.ifSource&&!I(this.graph.resultOf(this.ifSource))||this.unlessSource&&I(this.graph.resultOf(this.unlessSource))),!this.isSkip||void 0!==this.defaultValue||(this.updateState(t.NodeState.Skipped),this.log.onSkipped(this,this.graph),!1))}retry(t,e){this.updateState(t),this.log.onError(this,this.graph,e.message),this.retryCount<this.retryLimit?(this.retryCount++,this.execute()):(this.result=void 0,this.error=e,this.transactionId=void 0,this.graph.onExecutionComplete(this))}checkDataAvailability(){return Object.values(this.graph.resultsOf(this.inputs)).flat().some((t=>void 0!==t))}beforeAddTask(){this.updateState(t.NodeState.Queued),this.log.beforeAddTask(this,this.graph)}removePending(t){this.anyInput?this.checkDataAvailability()&&this.pendings.clear():this.pendings.delete(t)}isCurrentTransaction(t){return this.transactionId===t}executeTimeout(e){this.state===t.NodeState.Executing&&this.isCurrentTransaction(e)&&(r.warn(`-- timeout ${this.timeout} with ${this.nodeId}`),this.retry(t.NodeState.TimedOut,Error("Timeout")))}shouldApplyAgentFilter(t,e){return!!(t.agentIds&&Array.isArray(t.agentIds)&&t.agentIds.length>0&&e&&t.agentIds.includes(e))||(!!(t.nodeIds&&Array.isArray(t.nodeIds)&&t.nodeIds.length>0&&t.nodeIds.includes(this.nodeId))||!t.agentIds&&!t.nodeIds)}agentFilterHandler(t,e,s){let i=0;const n=t=>{const r=this.graph.agentFilters[i++];return r?this.shouldApplyAgentFilter(r,s)?(r.filterParams&&(t.filterParams={...r.filterParams,...t.filterParams}),r.agent(t,n)):n(t):e(t)};return n(t)}async execute(){if(this.isSkip)return void this.afterExecute(this.defaultValue,[]);const t=this.graph.resultsOf(this.inputs,this.anyInput),e=this.agentId?this.graph.resultOf(u(this.agentId)):this.agentId;"function"==typeof e&&(this.agentFunction=e);const s=Boolean(this.nestedGraph)||Boolean(e&&this.graph.getAgentFunctionInfo(e).hasGraphData),i=this.getConfig(s,e),n=Date.now();this.prepareExecute(n,Object.values(t)),this.timeout&&this.timeout>0&&setTimeout((()=>{this.executeTimeout(n)}),this.timeout);try{const o=this.agentFunction??this.graph.getAgentFunctionInfo(e).agent,a=[],h=this.getContext(t,a,e,i);s&&(this.graph.taskManager.prepareForNesting(),h.forNestedGraph={graphData:this.nestedGraph?"nodes"in this.nestedGraph?this.nestedGraph:this.graph.resultOf(this.nestedGraph):{version:0,nodes:{}},agents:this.graph.agentFunctionInfoDictionary,graphOptions:{agentFilters:this.graph.agentFilters,taskManager:this.graph.taskManager,bypassAgentIds:this.graph.bypassAgentIds,config:i,graphLoader:this.graph.graphLoader},onLogCallback:this.graph.onLogCallback,callbacks:this.graph.callbacks}),this.beforeConsoleLog(h);const u=await this.agentFilterHandler(h,o,e);if(this.afterConsoleLog(u),s&&this.graph.taskManager.restoreAfterNesting(),!this.isCurrentTransaction(n))return void r.log(`-- transactionId mismatch with ${this.nodeId} (probably timeout)`);this.afterExecute(u,a)}catch(e){this.errorProcess(e,n,t)}}afterExecute(e,s){this.state!=t.NodeState.Abort&&(this.updateState(t.NodeState.Completed),this.result=this.getResult(e),this.output&&(this.result=j(this.output,{self:this},this.graph.propFunctions,!0),this.passThrough&&(this.result={...this.result,...this.graph.resultsOf(this.passThrough)})),this.log.onComplete(this,this.graph,s),this.onSetResult(),this.graph.onExecutionComplete(this))}prepareExecute(e,s){this.updateState(t.NodeState.Executing),this.log.beforeExecute(this,this.graph,e,s),this.transactionId=e}errorProcess(e,s,i){e instanceof Error&&e.message!==p&&(r.error(`<-- NodeId: ${this.nodeId}, Agent: ${this.agentId}`),r.error({namedInputs:i}),r.error(e),r.error("--\x3e")),this.isCurrentTransaction(s)?e instanceof Error?this.retry(t.NodeState.Failed,e):(r.error(`-- NodeId: ${this.nodeId}: Unknown error was caught`),this.retry(t.NodeState.Failed,Error("Unknown"))):r.warn(`-- transactionId mismatch with ${this.nodeId} (not timeout)`)}getContext(t,e,s,i){this.debugInfo=this.getDebugInfo(s);return{params:this.params,namedInputs:t,inputSchema:this.agentFunction?void 0:this.graph.getAgentFunctionInfo(s)?.inputs,debugInfo:this.debugInfo,cacheType:this.agentFunction?void 0:this.graph.getAgentFunctionInfo(s)?.cacheType,filterParams:this.filterParams,config:i,log:e}}getResult(t){if(t&&this.passThrough){if(c(t)&&!Array.isArray(t))return{...t,...this.graph.resultsOf(this.passThrough)};if(Array.isArray(t))return t.map((t=>c(t)&&!Array.isArray(t)?{...t,...this.graph.resultsOf(this.passThrough)}:t))}return t}getDebugInfo(t){return{nodeId:this.nodeId,agentId:t,retry:this.retryCount,state:this.state,subGraphs:new Map,verbose:this.graph.verbose,version:this.graph.version,isResult:this.isResult}}beforeConsoleLog(t){!1!==this.console&&(!0===this.console||!0===this.console.before?r.log(JSON.stringify(t.namedInputs,null,2)):this.console.before&&r.log(this.console.before))}}class x extends R{constructor(t,e,s){super(t,s),this.isStaticNode=!0,this.isComputedNode=!1,this.value=e.value,this.update=e.update?u(e.update):void 0,this.isResult=e.isResult??!1,this.console=e.console??{}}injectValue(e,s){this.state=t.NodeState.Injected,this.result=e,this.log.onInjected(this,this.graph,s),this.onSetResult()}consoleLog(){this.afterConsoleLog(this.result)}}const D=["nodes","concurrency","agentId","loop","verbose","version","metadata"],P=["inputs","output","anyInput","params","retry","timeout","agent","graph","graphLoader","isResult","priority","if","unless","defaultValue","filterParams","console","passThrough"],G=["value","update","isResult","console"];class Q extends Error{constructor(t){super(`${t}`),Object.setPrototypeOf(this,Q.prototype)}}const M=(t,e)=>{(t=>{if(void 0===t.nodes)throw new Q("Invalid Graph Data: no nodes");if("object"!=typeof t.nodes)throw new Q("Invalid Graph Data: invalid nodes");if(Array.isArray(t.nodes))throw new Q("Invalid Graph Data: nodes must be object");if(0===Object.keys(t.nodes).length)throw new Q("Invalid Graph Data: nodes is empty");Object.keys(t).forEach((t=>{if(!D.includes(t))throw new Q("Graph Data does not allow "+t)}))})(t),(t=>{if(t.loop){if(void 0===t.loop.count&&void 0===t.loop.while)throw new Q("Loop: Either count or while is required in loop");if(void 0!==t.loop.count&&void 0!==t.loop.while)throw new Q("Loop: Both count and while cannot be set")}if(void 0!==t.concurrency){if(!Number.isInteger(t.concurrency))throw new Q("Concurrency must be an integer");if(t.concurrency<1)throw new Q("Concurrency must be a positive integer")}})(t);const s=[],i=[],n=new Set;return Object.keys(t.nodes).forEach((e=>{const r=t.nodes[e],o=S(r);(t=>{if(t.agent&&t.value)throw new Q("Cannot set both agent and value")})(r);const a=o?"":r.agent;var h;o&&(h=r,Object.keys(h).forEach((t=>{if(!G.includes(t))throw new Q("Static node does not allow "+t)})),1)&&i.push(e),!o&&(t=>(Object.keys(t).forEach((t=>{if(!P.includes(t))throw new Q("Computed node does not allow "+t)})),!0))(r)&&s.push(e)&&"string"==typeof a&&n.add(a)})),((t,e)=>{t.forEach((t=>{if(!e.has(t)&&":"!==t[0])throw new Q("Invalid Agent : "+t+" is not in AgentFunctionInfoDictionary.")}))})(n,new Set(e)),((t,e,s)=>{const i=new Set(Object.keys(t.nodes)),n={},r={};s.forEach((e=>{const s=t.nodes[e];n[e]=new Set;const o=(t,s)=>{s.forEach((s=>{if(s){if(!i.has(s))throw new Q(`${t} not match: NodeId ${e}, Inputs: ${s}`);void 0===r[s]&&(r[s]=new Set),n[e].add(s),r[s].add(e)}}))};s&&N(s)&&(s.inputs&&o("Inputs",A(k(s.inputs))),s.params&&o("Params",A(k(s.params))),s.if&&o("If",A(k({if:s.if}))),s.unless&&o("Unless",A(k({unless:s.unless}))),s.graph&&"string"==typeof s?.graph&&o("Graph",A(k({graph:s.graph}))),"string"==typeof s.agent&&":"===s.agent[0]&&o("Agent",A(k({agent:s.agent}))))})),e.forEach((e=>{const s=t.nodes[e];if(S(s)&&s.update){const t=s.update,n=u(t).nodeId;if(!n)throw new Q("Update it a literal");if(!i.has(n))throw new Q(`Update not match: NodeId ${e}, update: ${t}`)}}));const o=t=>{t.forEach((t=>{(r[t]||[]).forEach((e=>{n[e].delete(t)}))}));const e=[];return Object.keys(n).forEach((t=>{0===n[t].size&&(e.push(t),delete n[t])})),e};let a=o(e);if(0===a.length)throw new Q("No Initial Runnning Node");do{a=o(a)}while(a.length>0);if(Object.keys(n).length>0)throw new Q("Some nodes are not executed: "+Object.keys(n).join(", "))})(t,i,s),!0};class V{constructor(t){this.taskQueue=[],this.runningNodes=new Set,this.concurrency=t}dequeueTaskIfPossible(){if(this.runningNodes.size<this.concurrency){const t=this.taskQueue.shift();t&&(this.runningNodes.add(t.node),t.callback(t.node))}}addTask(t,e,s){const i=this.taskQueue.filter((e=>e.node.priority>=t.priority)).length;d(i<=this.taskQueue.length,"TaskManager.addTask: Something is really wrong."),this.taskQueue.splice(i,0,{node:t,graphId:e,callback:s}),this.dequeueTaskIfPossible()}isRunning(t){return[...this.runningNodes].filter((e=>e.graphId==t)).length>0||Array.from(this.taskQueue).filter((e=>e.graphId===t)).length>0}onComplete(t){d(this.runningNodes.has(t),`TaskManager.onComplete node(${t.nodeId}) is not in list`),this.runningNodes.delete(t),this.dequeueTaskIfPossible()}prepareForNesting(){this.concurrency++}restoreAfterNesting(){this.concurrency--}getStatus(t=!1){const e=Array.from(this.runningNodes).map((t=>t.nodeId)),s=this.taskQueue.map((t=>t.node.nodeId)),i=t?{runningNodes:e,queuedNodes:s}:{};return{concurrency:this.concurrency,queue:this.taskQueue.length,running:this.runningNodes.size,...i}}}const z=.5;t.GraphAI=class{createNodes(t){const e=Object.keys(t.nodes).reduce(((e,s)=>{const i=t.nodes[s];return N(i)?e[s]=new $(this.graphId,s,i,this):e[s]=new x(s,i,this),e}),{});return Object.keys(e).forEach((t=>{const s=e[t];s.isComputedNode&&s.pendings.forEach((s=>{if(!e[s])throw new Error(`createNode: invalid input ${s} for node, ${t}`);e[s].waitlist.add(t)}))})),e}getValueFromResults(t,e){return E(t.nodeId?e[t.nodeId]:void 0,t,this.propFunctions)}initializeStaticNodes(t=!1){Object.keys(this.graphData.nodes).forEach((e=>{const s=this.nodes[e];if(s?.isStaticNode){const i=s?.value;void 0!==i&&this.injectValue(e,i,e),t&&s.consoleLog()}}))}updateStaticNodes(t,e=!1){Object.keys(this.graphData.nodes).forEach((s=>{const i=this.nodes[s];if(i?.isStaticNode){const n=i?.update;if(n&&t){const e=this.getValueFromResults(n,t);this.injectValue(s,e,n.nodeId)}e&&i.consoleLog()}}))}constructor(t,e,s={taskManager:void 0,agentFilters:[],bypassAgentIds:[],config:{},graphLoader:void 0,forceLoop:!1}){this.logs=[],this.config={},this.onLogCallback=(t,e)=>{},this.callbacks=[],this.repeatCount=0,t.version||s.taskManager||r.warn("------------ missing version number"),this.version=t.version??z,this.version<z&&r.warn("------------ upgrade to 0.5!"),this.retryLimit=t.retry,this.graphId=`${Date.now().toString(36)}-${Math.random().toString(36).substr(2,9)}`,this.agentFunctionInfoDictionary=e,this.propFunctions=a,this.taskManager=s.taskManager??new V(t.concurrency??8),this.agentFilters=s.agentFilters??[],this.bypassAgentIds=s.bypassAgentIds??[],this.config=s.config,this.graphLoader=s.graphLoader,this.forceLoop=s.forceLoop??!1,this.loop=t.loop,this.verbose=!0===t.verbose,this.onComplete=t=>{throw new Error("SOMETHING IS WRONG: onComplete is called without run()")},M(t,[...Object.keys(e),...this.bypassAgentIds]),(t=>{Object.keys(t).forEach((e=>{if("default"!==e){const s=t[e];if(!s||!s.agent)throw new Q("No Agent: "+e+" is not in AgentFunctionInfoDictionary.")}}))})(e),this.graphData={...t,nodes:{...t.nodes,[v]:{value:0,update:`:${v}.add(1)`}}},this.nodes=this.createNodes(this.graphData),this.initializeStaticNodes(!0)}getAgentFunctionInfo(t){if(t&&this.agentFunctionInfoDictionary[t])return this.agentFunctionInfoDictionary[t];if(t&&this.bypassAgentIds.includes(t))return{agent:async()=>null,hasGraphData:!1,inputs:null,cacheType:void 0};throw new Error("No agent: "+t)}asString(){return Object.values(this.nodes).map((t=>t.asString())).join("\n")}results(t,e=!1){return Object.keys(this.nodes).filter((s=>t&&(e||s!==v)||this.nodes[s].isResult)).reduce(((t,e)=>{const s=this.nodes[e];return void 0!==s.result&&(t[e]=s.result),t}),{})}errors(){return Object.keys(this.nodes).reduce(((t,e)=>{const s=this.nodes[e];return s.isComputedNode&&void 0!==s.error&&(t[e]=s.error),t}),{})}pushReadyNodesIntoQueue(){Object.keys(this.nodes).forEach((t=>{const e=this.nodes[t];e.isComputedNode&&this.pushQueueIfReady(e)}))}pushQueueIfReady(t){t.isReadyNode()&&this.pushQueue(t)}pushQueueIfReadyAndRunning(t){this.isRunning()&&this.pushQueueIfReady(t)}pushQueue(t){t.beforeAddTask(),this.taskManager.addTask(t,this.graphId,(e=>{d(t.nodeId===e.nodeId,"GraphAI.pushQueue node mismatch"),t.execute()}))}async run(t=!1){if(Object.values(this.nodes).filter((t=>t.isStaticNode)).some((t=>void 0===t.result&&void 0===t.update)))throw new Error("Static node must have value. Set value or injectValue or set update");if(this.isRunning())throw new Error("This GraphAI instance is already running");return this.pushReadyNodesIntoQueue(),this.isRunning()?new Promise(((e,s)=>{this.onComplete=(i=!1)=>{const n=this.errors(),r=Object.keys(n);r.length>0||i?s(n[r[0]]):e(this.results(t))}})):(r.warn("-- nothing to execute"),{})}abort(){this.isRunning()&&this.resetPending(),Object.values(this.nodes).forEach((t=>t.isComputedNode&&(t.transactionId=void 0))),this.onComplete(this.isRunning())}resetPending(){Object.values(this.nodes).map((t=>{t.isComputedNode&&t.resetPending()}))}isRunning(){return this.taskManager.isRunning(this.graphId)}onExecutionComplete(t){this.taskManager.onComplete(t),this.isRunning()||this.processLoopIfNecessary()||this.onComplete(!1)}processLoopIfNecessary(){if(!this.forceLoop&&Object.keys(this.errors()).length>0)return!1;this.repeatCount++;const t=this.loop;if(!t)return!1;const e=this.results(!0,!0);if(this.updateStaticNodes(e),void 0===t.count||this.repeatCount<t.count){if(t.while){const e=u(t.while),s=this.getValueFromResults(e,this.results(!0,!0));if(!I(s))return!1}return this.initializeGraphAI(),this.updateStaticNodes(e,!0),this.pushReadyNodesIntoQueue(),!0}return!1}initializeGraphAI(){if(this.isRunning())throw new Error("This GraphAI instance is running");this.nodes=this.createNodes(this.graphData),this.initializeStaticNodes()}setPreviousResults(t){this.updateStaticNodes(t)}setLoopLog(t){t.isLoop=!!this.loop,t.repeatCount=this.repeatCount}appendLog(t){this.logs.push(t),this.onLogCallback(t,!1),this.callbacks.forEach((e=>e(t,!1)))}updateLog(t){this.onLogCallback(t,!0),this.callbacks.forEach((e=>e(t,!1)))}registerCallback(t){this.callbacks.push(t)}clearCallbacks(){this.callbacks=[]}transactionLogs(){return this.logs}injectValue(t,e,s){const i=this.nodes[t];if(!i||!i.isStaticNode)throw new Error(`injectValue with Invalid nodeId, ${t}`);i.injectValue(e,s)}resultsOf(t,e=!1){const s=j(t??{},this.nodes,this.propFunctions);return e?(t=>Object.keys(t).reduce(((e,s)=>{const i=F(t[s]);return l(i)||(e[s]=i),e}),{}))(s):s}resultOf(t){return T(t,this.nodes,this.propFunctions)}},t.GraphAILogger=r,t.ValidationError=Q,t.agentInfoWrapper=t=>({agent:t,mock:t,...g}),t.assert=d,t.debugResultKey=y,t.defaultAgentInfo=g,t.defaultConcurrency=8,t.defaultTestContext=b,t.graphDataLatestVersion=z,t.inputs2dataSources=k,t.isComputedNodeData=N,t.isObject=c,t.isStaticNodeData=S,t.parseNodeName=u,t.sleep=async t=>await new Promise((e=>setTimeout(e,t))),t.strIntentionalError=p}));
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).graphai={})}(this,(function(t){"use strict";var e;t.NodeState=void 0,(e=t.NodeState||(t.NodeState={})).Waiting="waiting",e.Queued="queued",e.Executing="executing",e.ExecutingServer="executing-server",e.Failed="failed",e.TimedOut="timed-out",e.Abort="abort",e.Completed="completed",e.Injected="injected",e.Skipped="skipped";const s={debug:!0,info:!0,log:!0,warn:!0,error:!0};let i=null;function n(t,...e){s[t]&&(i?i(t,...e):(console[t]||console.log)(...e))}const r={setLevelEnabled:function(t,e){s[t]=e},setLogger:function(t){i=t},debug:function(...t){n("debug",...t)},info:function(...t){n("info",...t)},log:function(...t){n("log",...t)},warn:function(...t){n("warn",...t)},error:function(...t){n("error",...t)}},o=/^[a-zA-Z]+\([^)]*\)$/,a=[(t,e)=>{if(Array.isArray(t)){if("length()"===e)return t.length;if("flat()"===e)return t.flat();if("toJSON()"===e)return JSON.stringify(t,null,2);if("isEmpty()"===e)return 0===t.length;const s=e.match(/^join\(([,-\s]?)\)$/);if(s&&Array.isArray(s))return t.join(s[1]??"")}},(t,e)=>{if(c(t)){if("keys()"===e)return Object.keys(t);if("values()"===e)return Object.values(t);if("toJSON()"===e)return JSON.stringify(t,null,2)}},(t,e)=>{if("string"==typeof t){if("codeBlock()"===e){const e=("\n"+t).match(/\n```[a-zA-z]*([\s\S]*?)\n```/);if(e)return e[1]}if("jsonParse()"===e)return JSON.parse(t);if("toNumber()"===e){const e=Number(t);if(!isNaN(e))return e}if("trim()"===e)return t.trim();if("toLowerCase()"===e)return t.toLowerCase();if("toUpperCase()"===e)return t.toUpperCase();const s=e.match(/^slice\((-?\d+)(?:,\s*(-?\d+))?\)/);if(s){if(void 0!==s[2])return t.slice(Number(s[1]),Number(s[2]));if(void 0!==s[1])return t.slice(Number(s[1]));r.warn("slice is not valid format: "+s)}const i=e.match(/^split\(([-_:;.,\s\n]+)\)$/);if(i)return t.split(i[1])}},(t,e)=>{if(void 0!==t&&Number.isFinite(t)){if("toString()"===e)return String(t);const s=/^add\((-?\d+)\)$/,i=e.match(s);if(i)return Number(t)+Number(i[1])}},(t,e)=>{if("boolean"==typeof t&&"not()"===e)return!t}],h=(t,e)=>"@now"===t||"@now_ms"===t?Date.now():"@now_s"===t?Math.floor(Date.now()/1e3):"@loop"===t?e[v].result:(r.warn("not match template utility function: ${"+t+"}"),""),u=(t,e=!1,s)=>{if(e){if("string"==typeof t&&"."===t[0]){return{nodeId:"self",propIds:t.split(".").slice(1)}}return{value:t}}if("string"==typeof t){const e=/^:(.*)$/,i=t.match(e);if(i){const t=i[1].split(/(?<!\()\.(?!\))/);return 1==t.length?{nodeId:t[0]}:{nodeId:t[0],propIds:t.slice(1)}}const n=/^@(.*)$/,r=t.match(n);if(s&&r)return{value:h(t,s)}}return{value:t}};function d(t,e,s=!1){if(!t){if(!s)throw new Error(e);r.warn("warn: "+e)}}const c=t=>null!==t&&"object"==typeof t,l=t=>null==t,p="Intentional Error for Debugging",g={name:"defaultAgentInfo",samples:[{inputs:[],params:{},result:{}}],description:"",category:[],author:"",repository:"",license:""},f=t=>{const e=[];return Object.keys(t).forEach((s=>{e.push([s]),Object.keys(t[s]).length>0&&f(t[s]).forEach((t=>{e.push([s,...t])}))})),e},y=(t,e)=>f({[t]:m(e)}).map((t=>":"+t.join("."))),m=t=>null==t||"string"==typeof t?{}:Array.isArray(t)?Array.from(t.keys()).reduce(((e,s)=>(e["$"+String(s)]=m(t[s]),e)),{}):Object.keys(t).reduce(((e,s)=>(e[s]=m(t[s]),e)),{}),I=t=>!!(Array.isArray(t)?0!==t.length:t),b={debugInfo:{nodeId:"test",retry:0,verbose:!0,state:t.NodeState.Executing,subGraphs:new Map},params:{},filterParams:{},agents:{},log:[]},w=t=>c(t)&&!Array.isArray(t)&&Object.keys(t||{}).length>0,N=t=>"agent"in t,S=t=>!("agent"in t),v="__loopIndex",k=t=>{if(Array.isArray(t))return t.map((t=>k(t))).flat();if(c(t))return Object.values(t).map((t=>k(t))).flat();if("string"==typeof t){const e=[...t.matchAll(/\${(:[^}]+)}/g)].map((t=>t[1]));if(e.length>0)return k(e)}return u(t)},A=t=>{if(!Array.isArray(t))throw new Error("sources must be array!! maybe inputs is invalid");return t.filter((t=>t.nodeId)).map((t=>t.nodeId))};class C{constructor(e){this.nodeId=e,this.state=t.NodeState.Waiting}initForComputedNode(t,e){this.agentId=t.getAgentId(),this.params=t.params,e.appendLog(this)}onInjected(t,e,s){const i="endTime"in this;this.result=t.result,this.state=t.state,this.endTime=Date.now(),this.injectFrom=s,e.setLoopLog(this),i?e.updateLog(this):e.appendLog(this)}onComplete(t,e,s){this.result=t.result,this.resultKeys=y(this.agentId||"",t.result),this.state=t.state,this.endTime=Date.now(),e.setLoopLog(this),s.length>0&&(this.log=s),e.updateLog(this)}beforeExecute(t,e,s,i){this.state=t.state,this.retryCount=t.retryCount>0?t.retryCount:void 0,this.startTime=s,this.inputs=A(t.dataSources),this.inputsData=i.length>0?i:void 0,e.setLoopLog(this),e.appendLog(this)}beforeAddTask(t,e){this.state=t.state,e.setLoopLog(this),e.appendLog(this)}onError(t,e,s){this.state=t.state,this.errorMessage=s,this.endTime=Date.now(),e.setLoopLog(this),e.updateLog(this)}onSkipped(t,e){this.state=t.state,e.setLoopLog(this),e.updateLog(this)}}const L=(t,e,s)=>{if(!l(t)&&e&&e.length>0){const i=((t,e,s)=>{if(e.match(o))for(const i of s){const s=i(t,e);if(!l(s))return s}if(Array.isArray(t)){const s=/^\$(\d+)$/,i=e.match(s);if(i)return t[parseInt(i[1],10)];if("$last"===e)return t[t.length-1]}else if(c(t)&&e in t)return t[e]})(t,e[0],s);return void 0===i&&r.error(`prop: ${e.join(".")} is not hit`),e.length>1?L(i,e.slice(1),s):i}return t},E=(t,e,s=[])=>e.nodeId?L(t,e.propIds,s):e.value,O=(t,e,s,i=!1)=>{if(Array.isArray(t))return t.map((t=>O(t,e,s,i)));if(w(t))return j(t,e,s,i);if("string"==typeof t){const n=[...t.matchAll(/\${([:@][^}]+)}/g)].map((t=>t[1]));if(n.length>0)return((t,e,s,i,n)=>{const r=O(e.filter((t=>t.startsWith(":"))),s,i,n),o=e.filter((t=>t.startsWith("@"))).reduce(((t,e)=>(t[e]=h(e,s),t)),{});return Array.from(e.keys()).reduce(((t,s)=>e[s].startsWith(":")?t.replaceAll("${"+e[s]+"}",r[s]):t.replaceAll("${"+e[s]+"}",o[e[s]])),t)})(t,n,e,s,i)}return T(u(t,i,e),e,s)},j=(t,e,s,i=!1)=>Object.keys(t).reduce(((n,r)=>{const o=t[r];return n[r]=w(o)?j(o,e,s,i):O(o,e,s,i),n}),{}),T=(t,e,s)=>{const{result:i}=t.nodeId?e[t.nodeId]:{result:void 0};return E(i,t,s)},F=t=>Array.isArray(t)?t.map((t=>F(t))).filter((t=>!l(t))):c(t)?Object.keys(t).reduce(((e,s)=>{const i=F(t[s]);return l(i)||(e[s]=i),e}),{}):t;class R{constructor(e,s){this.waitlist=new Set,this.state=t.NodeState.Waiting,this.result=void 0,this.nodeId=e,this.graph=s,this.log=new C(e),this.console={}}asString(){return`${this.nodeId}: ${this.state} ${[...this.waitlist]}`}onSetResult(){this.waitlist.forEach((t=>{const e=this.graph.nodes[t];e.isComputedNode&&(e.removePending(this.nodeId),this.graph.pushQueueIfReadyAndRunning(e))}))}afterConsoleLog(t){!1!==this.console&&(!0===this.console||!0===this.console.after?r.log("string"==typeof t?t:JSON.stringify(t,null,2)):this.console.after&&(c(this.console.after)?r.log(JSON.stringify(j(this.console.after,{self:{result:t}},this.graph.propFunctions,!0),null,2)):r.log(this.console.after)))}}class $ extends R{constructor(t,e,s,i){if(super(e,i),this.retryCount=0,this.dataSources=[],this.isSkip=!1,this.isStaticNode=!1,this.isComputedNode=!0,this.graphId=t,this.params=s.params??{},this.console=s.console??{},this.filterParams=s.filterParams??{},this.passThrough=s.passThrough,this.retryLimit=s.retry??i.retryLimit??0,this.timeout=s.timeout,this.isResult=s.isResult??!1,this.priority=s.priority??0,d(["function","string"].includes(typeof s.agent),"agent must be either string or function"),"string"==typeof s.agent)this.agentId=s.agent;else{const t=s.agent;this.agentFunction=async({namedInputs:e,params:s})=>t(e,s)}if(this.anyInput=s.anyInput??!1,this.inputs=s.inputs,this.output=s.output,this.dataSources=[...s.inputs?k(s.inputs).flat(10):[],...this.agentId?[u(this.agentId)]:[],...s.passThrough?k(s.passThrough).flat(10):[]],s.inputs&&Array.isArray(s.inputs))throw new Error(`array inputs have been deprecated. nodeId: ${e}: see https://github.com/receptron/graphai/blob/main/docs/NamedInputs.md`);this.pendings=new Set(A(this.dataSources)),s.graph&&(this.nestedGraph="string"==typeof s.graph?this.addPendingNode(s.graph):s.graph),s.graphLoader&&i.graphLoader&&(this.nestedGraph=i.graphLoader(s.graphLoader)),s.if&&(this.ifSource=this.addPendingNode(s.if)),s.unless&&(this.unlessSource=this.addPendingNode(s.unless)),s.defaultValue&&(this.defaultValue=s.defaultValue),this.isSkip=!1,this.log.initForComputedNode(this,i)}getAgentId(){return this.agentId??"__custom__function"}getConfig(t,e){if(e){if(t)return this.graph.config;const s=this.graph.config??{};return{...s.global??{},...s[e]??{}}}return{}}addPendingNode(t){const e=u(t);return d(!!e.nodeId,`Invalid data source ${t}`),this.pendings.add(e.nodeId),e}updateState(t){this.state=t,this.debugInfo&&(this.debugInfo.state=t)}resetPending(){this.pendings.clear(),this.state===t.NodeState.Executing&&this.updateState(t.NodeState.Abort),this.debugInfo&&this.debugInfo.subGraphs&&this.debugInfo.subGraphs.forEach((t=>t.abort()))}isReadyNode(){return this.state===t.NodeState.Waiting&&0===this.pendings.size&&(this.isSkip=!!(this.ifSource&&!I(this.graph.resultOf(this.ifSource))||this.unlessSource&&I(this.graph.resultOf(this.unlessSource))),!this.isSkip||void 0!==this.defaultValue||(this.updateState(t.NodeState.Skipped),this.log.onSkipped(this,this.graph),!1))}retry(t,e){this.updateState(t),this.log.onError(this,this.graph,e.message),this.retryCount<this.retryLimit?(this.retryCount++,this.execute()):(this.result=void 0,this.error=e,this.transactionId=void 0,this.graph.onExecutionComplete(this))}checkDataAvailability(){return Object.values(this.graph.resultsOf(this.inputs)).flat().some((t=>void 0!==t))}beforeAddTask(){this.updateState(t.NodeState.Queued),this.log.beforeAddTask(this,this.graph)}removePending(t){this.anyInput?this.checkDataAvailability()&&this.pendings.clear():this.pendings.delete(t)}isCurrentTransaction(t){return this.transactionId===t}executeTimeout(e){this.state===t.NodeState.Executing&&this.isCurrentTransaction(e)&&(r.warn(`-- timeout ${this.timeout} with ${this.nodeId}`),this.retry(t.NodeState.TimedOut,Error("Timeout")))}shouldApplyAgentFilter(t,e){return!!(t.agentIds&&Array.isArray(t.agentIds)&&t.agentIds.length>0&&e&&t.agentIds.includes(e))||(!!(t.nodeIds&&Array.isArray(t.nodeIds)&&t.nodeIds.length>0&&t.nodeIds.includes(this.nodeId))||!t.agentIds&&!t.nodeIds)}agentFilterHandler(t,e,s){let i=0;const n=t=>{const r=this.graph.agentFilters[i++];return r?this.shouldApplyAgentFilter(r,s)?(r.filterParams&&(t.filterParams={...r.filterParams,...t.filterParams}),r.agent(t,n)):n(t):e(t)};return n(t)}async execute(){if(this.isSkip)return void this.afterExecute(this.defaultValue,[]);const t=this.graph.resultsOf(this.inputs,this.anyInput),e=this.agentId?this.graph.resultOf(u(this.agentId)):this.agentId;"function"==typeof e&&(this.agentFunction=e);const s=Boolean(this.nestedGraph)||Boolean(e&&this.graph.getAgentFunctionInfo(e).hasGraphData),i=this.getConfig(s,e),n=Date.now();this.prepareExecute(n,Object.values(t)),this.timeout&&this.timeout>0&&setTimeout((()=>{this.executeTimeout(n)}),this.timeout);try{const o=this.agentFunction??this.graph.getAgentFunctionInfo(e).agent,a=[],h=this.getContext(t,a,e,i);s&&(this.graph.taskManager.prepareForNesting(),h.forNestedGraph={graphData:this.nestedGraph?"nodes"in this.nestedGraph?this.nestedGraph:this.graph.resultOf(this.nestedGraph):{version:0,nodes:{}},agents:this.graph.agentFunctionInfoDictionary,graphOptions:{agentFilters:this.graph.agentFilters,taskManager:this.graph.taskManager,bypassAgentIds:this.graph.bypassAgentIds,config:i,graphLoader:this.graph.graphLoader},onLogCallback:this.graph.onLogCallback,callbacks:this.graph.callbacks}),this.beforeConsoleLog(h);const u=await this.agentFilterHandler(h,o,e);if(this.afterConsoleLog(u),s&&this.graph.taskManager.restoreAfterNesting(),!this.isCurrentTransaction(n))return void r.log(`-- transactionId mismatch with ${this.nodeId} (probably timeout)`);this.afterExecute(u,a)}catch(e){this.errorProcess(e,n,t)}}afterExecute(e,s){this.state!=t.NodeState.Abort&&(this.updateState(t.NodeState.Completed),this.result=this.getResult(e),this.output&&(this.result=j(this.output,{self:this},this.graph.propFunctions,!0),this.passThrough&&(this.result={...this.result,...this.graph.resultsOf(this.passThrough)})),this.log.onComplete(this,this.graph,s),this.onSetResult(),this.graph.onExecutionComplete(this))}prepareExecute(e,s){this.updateState(t.NodeState.Executing),this.log.beforeExecute(this,this.graph,e,s),this.transactionId=e}errorProcess(e,s,i){e instanceof Error&&e.message!==p&&(r.error(`<-- NodeId: ${this.nodeId}, Agent: ${this.agentId}`),r.error({namedInputs:i}),r.error(e),r.error("--\x3e")),this.isCurrentTransaction(s)?e instanceof Error?this.retry(t.NodeState.Failed,e):(r.error(`-- NodeId: ${this.nodeId}: Unknown error was caught`),this.retry(t.NodeState.Failed,Error("Unknown"))):r.warn(`-- transactionId mismatch with ${this.nodeId} (not timeout)`)}getContext(t,e,s,i){this.debugInfo=this.getDebugInfo(s);return{params:{...this.params??{},...w(t?.params)?t?.params:{}},namedInputs:t,inputSchema:this.agentFunction?void 0:this.graph.getAgentFunctionInfo(s)?.inputs,debugInfo:this.debugInfo,cacheType:this.agentFunction?void 0:this.graph.getAgentFunctionInfo(s)?.cacheType,filterParams:this.filterParams,config:i,log:e}}getResult(t){if(t&&this.passThrough){if(c(t)&&!Array.isArray(t))return{...t,...this.graph.resultsOf(this.passThrough)};if(Array.isArray(t))return t.map((t=>c(t)&&!Array.isArray(t)?{...t,...this.graph.resultsOf(this.passThrough)}:t))}return t}getDebugInfo(t){return{nodeId:this.nodeId,agentId:t,retry:this.retryCount,state:this.state,subGraphs:new Map,verbose:this.graph.verbose,version:this.graph.version,isResult:this.isResult}}beforeConsoleLog(t){!1!==this.console&&(!0===this.console||!0===this.console.before?r.log(JSON.stringify(t.namedInputs,null,2)):this.console.before&&r.log(this.console.before))}}class x extends R{constructor(t,e,s){super(t,s),this.isStaticNode=!0,this.isComputedNode=!1,this.value=e.value,this.update=e.update?u(e.update):void 0,this.isResult=e.isResult??!1,this.console=e.console??{}}injectValue(e,s){this.state=t.NodeState.Injected,this.result=e,this.log.onInjected(this,this.graph,s),this.onSetResult()}consoleLog(){this.afterConsoleLog(this.result)}}const D=["nodes","concurrency","agentId","loop","verbose","version","metadata"],P=["inputs","output","anyInput","params","retry","timeout","agent","graph","graphLoader","isResult","priority","if","unless","defaultValue","filterParams","console","passThrough"],G=["value","update","isResult","console"];class Q extends Error{constructor(t){super(`${t}`),Object.setPrototypeOf(this,Q.prototype)}}const M=(t,e)=>{(t=>{if(void 0===t.nodes)throw new Q("Invalid Graph Data: no nodes");if("object"!=typeof t.nodes)throw new Q("Invalid Graph Data: invalid nodes");if(Array.isArray(t.nodes))throw new Q("Invalid Graph Data: nodes must be object");if(0===Object.keys(t.nodes).length)throw new Q("Invalid Graph Data: nodes is empty");Object.keys(t).forEach((t=>{if(!D.includes(t))throw new Q("Graph Data does not allow "+t)}))})(t),(t=>{if(t.loop){if(void 0===t.loop.count&&void 0===t.loop.while)throw new Q("Loop: Either count or while is required in loop");if(void 0!==t.loop.count&&void 0!==t.loop.while)throw new Q("Loop: Both count and while cannot be set")}if(void 0!==t.concurrency){if(!Number.isInteger(t.concurrency))throw new Q("Concurrency must be an integer");if(t.concurrency<1)throw new Q("Concurrency must be a positive integer")}})(t);const s=[],i=[],n=new Set;return Object.keys(t.nodes).forEach((e=>{const r=t.nodes[e],o=S(r);(t=>{if(t.agent&&t.value)throw new Q("Cannot set both agent and value")})(r);const a=o?"":r.agent;var h;o&&(h=r,Object.keys(h).forEach((t=>{if(!G.includes(t))throw new Q("Static node does not allow "+t)})),1)&&i.push(e),!o&&(t=>(Object.keys(t).forEach((t=>{if(!P.includes(t))throw new Q("Computed node does not allow "+t)})),!0))(r)&&s.push(e)&&"string"==typeof a&&n.add(a)})),((t,e)=>{t.forEach((t=>{if(!e.has(t)&&":"!==t[0])throw new Q("Invalid Agent : "+t+" is not in AgentFunctionInfoDictionary.")}))})(n,new Set(e)),((t,e,s)=>{const i=new Set(Object.keys(t.nodes)),n={},r={};s.forEach((e=>{const s=t.nodes[e];n[e]=new Set;const o=(t,s)=>{s.forEach((s=>{if(s){if(!i.has(s))throw new Q(`${t} not match: NodeId ${e}, Inputs: ${s}`);void 0===r[s]&&(r[s]=new Set),n[e].add(s),r[s].add(e)}}))};s&&N(s)&&(s.inputs&&o("Inputs",A(k(s.inputs))),s.if&&o("If",A(k({if:s.if}))),s.unless&&o("Unless",A(k({unless:s.unless}))),s.graph&&"string"==typeof s?.graph&&o("Graph",A(k({graph:s.graph}))),"string"==typeof s.agent&&":"===s.agent[0]&&o("Agent",A(k({agent:s.agent}))))})),e.forEach((e=>{const s=t.nodes[e];if(S(s)&&s.update){const t=s.update,n=u(t).nodeId;if(!n)throw new Q("Update it a literal");if(!i.has(n))throw new Q(`Update not match: NodeId ${e}, update: ${t}`)}}));const o=t=>{t.forEach((t=>{(r[t]||[]).forEach((e=>{n[e].delete(t)}))}));const e=[];return Object.keys(n).forEach((t=>{0===n[t].size&&(e.push(t),delete n[t])})),e};let a=o(e);if(0===a.length)throw new Q("No Initial Runnning Node");do{a=o(a)}while(a.length>0);if(Object.keys(n).length>0)throw new Q("Some nodes are not executed: "+Object.keys(n).join(", "))})(t,i,s),!0};class V{constructor(t){this.taskQueue=[],this.runningNodes=new Set,this.concurrency=t}dequeueTaskIfPossible(){if(this.runningNodes.size<this.concurrency){const t=this.taskQueue.shift();t&&(this.runningNodes.add(t.node),t.callback(t.node))}}addTask(t,e,s){const i=this.taskQueue.filter((e=>e.node.priority>=t.priority)).length;d(i<=this.taskQueue.length,"TaskManager.addTask: Something is really wrong."),this.taskQueue.splice(i,0,{node:t,graphId:e,callback:s}),this.dequeueTaskIfPossible()}isRunning(t){return[...this.runningNodes].filter((e=>e.graphId==t)).length>0||Array.from(this.taskQueue).filter((e=>e.graphId===t)).length>0}onComplete(t){d(this.runningNodes.has(t),`TaskManager.onComplete node(${t.nodeId}) is not in list`),this.runningNodes.delete(t),this.dequeueTaskIfPossible()}prepareForNesting(){this.concurrency++}restoreAfterNesting(){this.concurrency--}getStatus(t=!1){const e=Array.from(this.runningNodes).map((t=>t.nodeId)),s=this.taskQueue.map((t=>t.node.nodeId)),i=t?{runningNodes:e,queuedNodes:s}:{};return{concurrency:this.concurrency,queue:this.taskQueue.length,running:this.runningNodes.size,...i}}}const z=.5;t.GraphAI=class{createNodes(t){const e=Object.keys(t.nodes).reduce(((e,s)=>{const i=t.nodes[s];return N(i)?e[s]=new $(this.graphId,s,i,this):e[s]=new x(s,i,this),e}),{});return Object.keys(e).forEach((t=>{const s=e[t];s.isComputedNode&&s.pendings.forEach((s=>{if(!e[s])throw new Error(`createNode: invalid input ${s} for node, ${t}`);e[s].waitlist.add(t)}))})),e}getValueFromResults(t,e){return E(t.nodeId?e[t.nodeId]:void 0,t,this.propFunctions)}initializeStaticNodes(t=!1){Object.keys(this.graphData.nodes).forEach((e=>{const s=this.nodes[e];if(s?.isStaticNode){const i=s?.value;void 0!==i&&this.injectValue(e,i,e),t&&s.consoleLog()}}))}updateStaticNodes(t,e=!1){Object.keys(this.graphData.nodes).forEach((s=>{const i=this.nodes[s];if(i?.isStaticNode){const n=i?.update;if(n&&t){const e=this.getValueFromResults(n,t);this.injectValue(s,e,n.nodeId)}e&&i.consoleLog()}}))}constructor(t,e,s={taskManager:void 0,agentFilters:[],bypassAgentIds:[],config:{},graphLoader:void 0,forceLoop:!1}){this.logs=[],this.config={},this.onLogCallback=(t,e)=>{},this.callbacks=[],this.repeatCount=0,t.version||s.taskManager||r.warn("------------ missing version number"),this.version=t.version??z,this.version<z&&r.warn("------------ upgrade to 0.5!"),this.retryLimit=t.retry,this.graphId=`${Date.now().toString(36)}-${Math.random().toString(36).substr(2,9)}`,this.agentFunctionInfoDictionary=e,this.propFunctions=a,this.taskManager=s.taskManager??new V(t.concurrency??8),this.agentFilters=s.agentFilters??[],this.bypassAgentIds=s.bypassAgentIds??[],this.config=s.config,this.graphLoader=s.graphLoader,this.forceLoop=s.forceLoop??!1,this.loop=t.loop,this.verbose=!0===t.verbose,this.onComplete=t=>{throw new Error("SOMETHING IS WRONG: onComplete is called without run()")},M(t,[...Object.keys(e),...this.bypassAgentIds]),(t=>{Object.keys(t).forEach((e=>{if("default"!==e){const s=t[e];if(!s||!s.agent)throw new Q("No Agent: "+e+" is not in AgentFunctionInfoDictionary.")}}))})(e),this.graphData={...t,nodes:{...t.nodes,[v]:{value:0,update:`:${v}.add(1)`}}},this.nodes=this.createNodes(this.graphData),this.initializeStaticNodes(!0)}getAgentFunctionInfo(t){if(t&&this.agentFunctionInfoDictionary[t])return this.agentFunctionInfoDictionary[t];if(t&&this.bypassAgentIds.includes(t))return{agent:async()=>null,hasGraphData:!1,inputs:null,cacheType:void 0};throw new Error("No agent: "+t)}asString(){return Object.values(this.nodes).map((t=>t.asString())).join("\n")}results(t,e=!1){return Object.keys(this.nodes).filter((s=>t&&(e||s!==v)||this.nodes[s].isResult)).reduce(((t,e)=>{const s=this.nodes[e];return void 0!==s.result&&(t[e]=s.result),t}),{})}errors(){return Object.keys(this.nodes).reduce(((t,e)=>{const s=this.nodes[e];return s.isComputedNode&&void 0!==s.error&&(t[e]=s.error),t}),{})}pushReadyNodesIntoQueue(){Object.keys(this.nodes).forEach((t=>{const e=this.nodes[t];e.isComputedNode&&this.pushQueueIfReady(e)}))}pushQueueIfReady(t){t.isReadyNode()&&this.pushQueue(t)}pushQueueIfReadyAndRunning(t){this.isRunning()&&this.pushQueueIfReady(t)}pushQueue(t){t.beforeAddTask(),this.taskManager.addTask(t,this.graphId,(e=>{d(t.nodeId===e.nodeId,"GraphAI.pushQueue node mismatch"),t.execute()}))}async run(t=!1){if(Object.values(this.nodes).filter((t=>t.isStaticNode)).some((t=>void 0===t.result&&void 0===t.update)))throw new Error("Static node must have value. Set value or injectValue or set update");if(this.isRunning())throw new Error("This GraphAI instance is already running");return this.pushReadyNodesIntoQueue(),this.isRunning()?new Promise(((e,s)=>{this.onComplete=(i=!1)=>{const n=this.errors(),r=Object.keys(n);r.length>0||i?s(n[r[0]]):e(this.results(t))}})):(r.warn("-- nothing to execute"),{})}abort(){this.isRunning()&&this.resetPending(),Object.values(this.nodes).forEach((t=>t.isComputedNode&&(t.transactionId=void 0))),this.onComplete(this.isRunning())}resetPending(){Object.values(this.nodes).map((t=>{t.isComputedNode&&t.resetPending()}))}isRunning(){return this.taskManager.isRunning(this.graphId)}onExecutionComplete(t){this.taskManager.onComplete(t),this.isRunning()||this.processLoopIfNecessary()||this.onComplete(!1)}processLoopIfNecessary(){if(!this.forceLoop&&Object.keys(this.errors()).length>0)return!1;this.repeatCount++;const t=this.loop;if(!t)return!1;const e=this.results(!0,!0);if(this.updateStaticNodes(e),void 0===t.count||this.repeatCount<t.count){if(t.while){const e=u(t.while),s=this.getValueFromResults(e,this.results(!0,!0));if(!I(s))return!1}return this.initializeGraphAI(),this.updateStaticNodes(e,!0),this.pushReadyNodesIntoQueue(),!0}return!1}initializeGraphAI(){if(this.isRunning())throw new Error("This GraphAI instance is running");this.nodes=this.createNodes(this.graphData),this.initializeStaticNodes()}setPreviousResults(t){this.updateStaticNodes(t)}setLoopLog(t){t.isLoop=!!this.loop,t.repeatCount=this.repeatCount}appendLog(t){this.logs.push(t),this.onLogCallback(t,!1),this.callbacks.forEach((e=>e(t,!1)))}updateLog(t){this.onLogCallback(t,!0),this.callbacks.forEach((e=>e(t,!1)))}registerCallback(t){this.callbacks.push(t)}clearCallbacks(){this.callbacks=[]}transactionLogs(){return this.logs}injectValue(t,e,s){const i=this.nodes[t];if(!i||!i.isStaticNode)throw new Error(`injectValue with Invalid nodeId, ${t}`);i.injectValue(e,s)}resultsOf(t,e=!1){const s=j(t??{},this.nodes,this.propFunctions);return e?(t=>Object.keys(t).reduce(((e,s)=>{const i=F(t[s]);return l(i)||(e[s]=i),e}),{}))(s):s}resultOf(t){return T(t,this.nodes,this.propFunctions)}},t.GraphAILogger=r,t.ValidationError=Q,t.agentInfoWrapper=t=>({agent:t,mock:t,...g}),t.assert=d,t.debugResultKey=y,t.defaultAgentInfo=g,t.defaultConcurrency=8,t.defaultTestContext=b,t.graphDataLatestVersion=z,t.inputs2dataSources=k,t.isComputedNodeData=N,t.isObject=c,t.isStaticNodeData=S,t.parseNodeName=u,t.sleep=async t=>await new Promise((e=>setTimeout(e,t))),t.strIntentionalError=p}));
2
2
  //# sourceMappingURL=bundle.umd.js.map