graphai 1.0.12 → 1.0.14
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.cjs.js +1 -1
- package/lib/bundle.cjs.js.map +1 -1
- package/lib/bundle.esm.js +145 -132
- package/lib/bundle.esm.js.map +1 -1
- package/lib/bundle.umd.js +1 -1
- package/lib/bundle.umd.js.map +1 -1
- package/lib/graphai.d.ts +2 -1
- package/lib/graphai.js +13 -7
- package/lib/type.d.ts +1 -0
- package/lib/utils/nodeUtils.js +1 -0
- package/lib/utils/result.js +2 -1
- package/lib/utils/utils.d.ts +2 -1
- package/lib/utils/utils.js +13 -7
- package/package.json +2 -2
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=(t,e=!1)=>{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=/^:(.*)$/,s=t.match(e);if(!s)return{value:t};const i=s[1].split(/(?<!\()\.(?!\))/);return 1==i.length?{nodeId:i[0]}:{nodeId:i[0],propIds:i.slice(1)}}return{value:t}};function a(t,e,s=!1){if(!t){if(!s)throw new Error(e);r.warn("warn: "+e)}}const h=t=>null!==t&&"object"==typeof t,u=t=>null==t,d="Intentional Error for Debugging",c={name:"defaultAgentInfo",samples:[{inputs:[],params:{},result:{}}],description:"",category:[],author:"",repository:"",license:""},l=t=>{const e=[];return Object.keys(t).forEach((s=>{e.push([s]),Object.keys(t[s]).length>0&&l(t[s]).forEach((t=>{e.push([s,...t])}))})),e},p=(t,e)=>l({[t]:g(e)}).map((t=>":"+t.join("."))),g=t=>null==t||"string"==typeof t?{}:Array.isArray(t)?Array.from(t.keys()).reduce(((e,s)=>(e["$"+String(s)]=g(t[s]),e)),{}):Object.keys(t).reduce(((e,s)=>(e[s]=g(t[s]),e)),{}),f=t=>!!(Array.isArray(t)?0!==t.length:t),y={debugInfo:{nodeId:"test",retry:0,verbose:!0,state:t.NodeState.Executing,subGraphs:new Map},params:{},filterParams:{},agents:{},log:[]},m=t=>h(t)&&!Array.isArray(t)&&Object.keys(t||{}).length>0,I=t=>"agent"in t,b=t=>!("agent"in t),w="__loopIndex",N=t=>{if(Array.isArray(t))return t.map((t=>N(t))).flat();if(h(t))return Object.values(t).map((t=>N(t))).flat();if("string"==typeof t){const e=[...t.matchAll(/\${(:[^}]+)}/g)].map((t=>t[1]));if(e.length>0)return N(e)}return o(t)},S=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 v{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=p(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=S(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 k=/^[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(h(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}],C=(t,e,s)=>{if(!u(t)&&e&&e.length>0){const i=((t,e,s)=>{if(e.match(k))for(const i of s){const s=i(t,e);if(!u(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(h(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?C(i,e.slice(1),s):i}return t},E=(t,e,s=[])=>e.nodeId?C(t,e.propIds,s):e.value,L=(t,e,s,i,n)=>{const o=O(e.filter((t=>t.startsWith(":"))),s,i,n),a=e.filter((t=>t.startsWith("@"))).reduce(((t,e)=>(t[e]=((t,e)=>"@now"===t||"@now_ms"===t?Date.now():"@now_s"===t?Math.floor(Date.now()/1e3):"@loop"===t?e[w].result:(r.warn("not match template utility function: ${"+t+"}"),""))(e,s),t)),{});return Array.from(e.keys()).reduce(((t,s)=>e[s].startsWith(":")?t.replaceAll("${"+e[s]+"}",o[s]):t.replaceAll("${"+e[s]+"}",a[e[s]])),t)},O=(t,e,s,i=!1)=>{if(Array.isArray(t))return t.map((t=>O(t,e,s,i)));if(m(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 L(t,n,e,s,i)}return T(o(t,i),e,s)},j=(t,e,s,i=!1)=>Object.keys(t).reduce(((n,r)=>{const o=t[r];return n[r]=m(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=>!u(t))):h(t)?Object.keys(t).reduce(((e,s)=>{const i=F(t[s]);return u(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 v(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&&(h(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,a(["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?N(s.inputs).flat(10):[],...s.params?N(s.params).flat(10):[],...this.agentId?[o(this.agentId)]:[],...s.passThrough?N(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(S(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=o(t);return a(!!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&&!f(this.graph.resultOf(this.ifSource))||this.unlessSource&&f(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(o(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!==d&&(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.graph.resultsOf(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(h(t)&&!Array.isArray(t))return{...t,...this.graph.resultsOf(this.passThrough)};if(Array.isArray(t))return t.map((t=>h(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?o(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(`[41m${t}[0m`),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=b(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&&I(s)&&(s.inputs&&o("Inputs",S(N(s.inputs))),s.params&&o("Params",S(N(s.params))),s.if&&o("If",S(N({if:s.if}))),s.unless&&o("Unless",S(N({unless:s.unless}))),s.graph&&"string"==typeof s?.graph&&o("Graph",S(N({graph:s.graph}))),"string"==typeof s.agent&&":"===s.agent[0]&&o("Agent",S(N({agent:s.agent}))))})),e.forEach((e=>{const s=t.nodes[e];if(b(s)&&s.update){const t=s.update,n=o(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 a=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 h=a(e);if(0===h.length)throw new Q("No Initial Runnning Node");do{h=a(h)}while(h.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;a(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){a(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 I(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}){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.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,[w]:{value:0,update:`:${w}.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){return Object.keys(this.nodes).filter((e=>t&&e!==w||this.nodes[e].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=>{a(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(){this.repeatCount++;const t=this.loop;if(!t)return!1;const e=this.results(!0);if(this.updateStaticNodes(e),void 0===t.count||this.repeatCount<t.count){if(t.while){const e=o(t.while),s=this.getValueFromResults(e,this.results(!0));if(!f(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 u(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,...c}),t.assert=a,t.debugResultKey=p,t.defaultAgentInfo=c,t.defaultConcurrency=8,t.defaultTestContext=y,t.graphDataLatestVersion=z,t.inputs2dataSources=N,t.isComputedNodeData=I,t.isObject=h,t.isStaticNodeData=b,t.parseNodeName=o,t.sleep=async t=>await new Promise((e=>setTimeout(e,t))),t.strIntentionalError=d}));
|
|
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):[],...s.params?k(s.params).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.graph.resultsOf(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(`[41m${t}[0m`),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}));
|
|
2
2
|
//# sourceMappingURL=bundle.umd.js.map
|