graphai 0.6.3 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/bundle.esm.js CHANGED
@@ -247,6 +247,7 @@ class ComputedNode extends Node {
247
247
  super(nodeId, graph);
248
248
  this.retryCount = 0;
249
249
  this.dataSources = []; // no longer needed. This is for transaction log.
250
+ this.isSkip = false;
250
251
  this.isStaticNode = false;
251
252
  this.isComputedNode = true;
252
253
  this.graphId = graphId;
@@ -260,7 +261,7 @@ class ComputedNode extends Node {
260
261
  this.priority = data.priority ?? 0;
261
262
  this.anyInput = data.anyInput ?? false;
262
263
  this.inputs = data.inputs;
263
- this.dataSources = data.inputs ? inputs2dataSources(data.inputs).flat(10) : [];
264
+ this.dataSources = [...(data.inputs ? inputs2dataSources(data.inputs).flat(10) : []), ...(data.params ? inputs2dataSources(data.params).flat(10) : [])];
264
265
  if (data.inputs && Array.isArray(data.inputs)) {
265
266
  throw new Error(`array inputs have been deprecated. nodeId: ${nodeId}: see https://github.com/receptron/graphai/blob/main/docs/NamedInputs.md`);
266
267
  }
@@ -285,15 +286,10 @@ class ComputedNode extends Node {
285
286
  if (data.unless) {
286
287
  this.unlessSource = this.addPendingNode(data.unless);
287
288
  }
288
- this.dynamicParams = Object.keys(this.params).reduce((tmp, key) => {
289
- const dataSource = parseNodeName(this.params[key]);
290
- if (dataSource.nodeId) {
291
- assert(!this.anyInput, "Dynamic params are not supported with anyInput");
292
- tmp[key] = dataSource;
293
- this.pendings.add(dataSource.nodeId);
294
- }
295
- return tmp;
296
- }, {});
289
+ if (data.defaultValue) {
290
+ this.defaultValue = data.defaultValue;
291
+ }
292
+ this.isSkip = false;
297
293
  this.log.initForComputedNode(this, graph);
298
294
  }
299
295
  getAgentId() {
@@ -309,8 +305,9 @@ class ComputedNode extends Node {
309
305
  if (this.state !== NodeState.Waiting || this.pendings.size !== 0) {
310
306
  return false;
311
307
  }
312
- if ((this.ifSource && !isLogicallyTrue(this.graph.resultOf(this.ifSource))) ||
313
- (this.unlessSource && isLogicallyTrue(this.graph.resultOf(this.unlessSource)))) {
308
+ this.isSkip = !!((this.ifSource && !isLogicallyTrue(this.graph.resultOf(this.ifSource))) ||
309
+ (this.unlessSource && isLogicallyTrue(this.graph.resultOf(this.unlessSource))));
310
+ if (this.isSkip && this.defaultValue === undefined) {
314
311
  this.state = NodeState.Skipped;
315
312
  this.log.onSkipped(this, this.graph);
316
313
  return false;
@@ -404,6 +401,10 @@ class ComputedNode extends Node {
404
401
  // then it removes itself from the "running node" list of the graph.
405
402
  // Notice that setting the result of this node may make other nodes ready to run.
406
403
  async execute() {
404
+ if (this.isSkip) {
405
+ this.afterExecute(this.defaultValue, []);
406
+ return;
407
+ }
407
408
  const previousResults = this.graph.resultsOf(this.inputs, this.anyInput);
408
409
  const transactionId = Date.now();
409
410
  this.prepareExecute(transactionId, Object.values(previousResults));
@@ -420,16 +421,7 @@ class ComputedNode extends Node {
420
421
  // if this is a nested agent or not.
421
422
  if (this.nestedGraph) {
422
423
  this.graph.taskManager.prepareForNesting();
423
- // context.taskManager = this.graph.taskManager;
424
424
  context.onLogCallback = this.graph.onLogCallback;
425
- /*
426
- if ("nodes" in this.nestedGraph) {
427
- context.graphData = this.nestedGraph;
428
- } else {
429
- context.graphData = this.graph.resultOf(this.nestedGraph) as GraphData; // HACK: compiler work-around
430
- }
431
- */
432
- // context.agents = this.graph.agentFunctionInfoDictionary;
433
425
  context.forNestedGraph = {
434
426
  graphData: "nodes" in this.nestedGraph ? this.nestedGraph : this.graph.resultOf(this.nestedGraph), // HACK: compiler work-around
435
427
  agents: this.graph.agentFunctionInfoDictionary,
@@ -455,16 +447,20 @@ class ComputedNode extends Node {
455
447
  console.log(`-- transactionId mismatch with ${this.nodeId} (probably timeout)`);
456
448
  return;
457
449
  }
458
- this.state = NodeState.Completed;
459
- this.result = this.getResult(result);
460
- this.log.onComplete(this, this.graph, localLog);
461
- this.onSetResult();
462
- this.graph.onExecutionComplete(this);
450
+ // after process
451
+ this.afterExecute(result, localLog);
463
452
  }
464
453
  catch (error) {
465
454
  this.errorProcess(error, transactionId, previousResults);
466
455
  }
467
456
  }
457
+ afterExecute(result, localLog) {
458
+ this.state = NodeState.Completed;
459
+ this.result = this.getResult(result);
460
+ this.log.onComplete(this, this.graph, localLog);
461
+ this.onSetResult();
462
+ this.graph.onExecutionComplete(this);
463
+ }
468
464
  // This private method (called only by execute()) prepares the ComputedNode object
469
465
  // for execution, and create a new transaction to record it.
470
466
  prepareExecute(transactionId, inputs) {
@@ -494,24 +490,9 @@ class ComputedNode extends Node {
494
490
  this.retry(NodeState.Failed, Error("Unknown"));
495
491
  }
496
492
  }
497
- getParams() {
498
- return Object.keys(this.dynamicParams).reduce((tmp, key) => {
499
- const result = this.graph.resultOf(this.dynamicParams[key]);
500
- tmp[key] = result;
501
- return tmp;
502
- }, { ...this.params });
503
- }
504
- /*
505
- private getInputs(previousResults: Record<string, ResultData | undefined>) {
506
- if (Array.isArray(this.inputs)) {
507
- return (this.inputs ?? []).map((key) => previousResults[String(key)]).filter((a) => !this.anyInput || a);
508
- }
509
- return [];
510
- }
511
- */
512
493
  getContext(previousResults, localLog) {
513
494
  const context = {
514
- params: this.getParams(),
495
+ params: this.graph.resultsOf(this.params),
515
496
  namedInputs: previousResults,
516
497
  inputSchema: this.agentFunction ? undefined : this.graph.getAgentFunctionInfo(this.agentId)?.inputs,
517
498
  debugInfo: this.getDebugInfo(),
@@ -590,7 +571,7 @@ const propArrayFunction = (result, propId) => {
590
571
  return result.length === 0;
591
572
  }
592
573
  // array join
593
- const matchJoin = propId.match(/^join\(([,-]?)\)$/);
574
+ const matchJoin = propId.match(/^join\(([,-\s]?)\)$/);
594
575
  if (matchJoin && Array.isArray(matchJoin)) {
595
576
  return result.join(matchJoin[1] ?? "");
596
577
  }
@@ -791,6 +772,7 @@ const computedNodeAttributeKeys = [
791
772
  "priority",
792
773
  "if",
793
774
  "unless",
775
+ "defaultValue",
794
776
  "filterParams",
795
777
  "console",
796
778
  "passThrough",
@@ -846,9 +828,9 @@ const nodeValidator = (nodeData) => {
846
828
  if (nodeData.agent && nodeData.value) {
847
829
  throw new ValidationError("Cannot set both agent and value");
848
830
  }
849
- if (!("agent" in nodeData) && !("value" in nodeData)) {
850
- throw new ValidationError("Either agent or value is required");
851
- }
831
+ // if (!("agent" in nodeData) && !("value" in nodeData)) {
832
+ // throw new ValidationError("Either agent or value is required");
833
+ // }
852
834
  return true;
853
835
  };
854
836
 
@@ -967,7 +949,7 @@ const validateGraphData = (data, agentIds) => {
967
949
  const graphAgentIds = new Set();
968
950
  Object.keys(data.nodes).forEach((nodeId) => {
969
951
  const node = data.nodes[nodeId];
970
- const isStaticNode = "value" in node;
952
+ const isStaticNode = !("agent" in node);
971
953
  nodeValidator(node);
972
954
  const agentId = isStaticNode ? "" : node.agent;
973
955
  isStaticNode && staticNodeValidator(node) && staticNodeIds.push(nodeId);
@@ -1054,15 +1036,13 @@ class GraphAI {
1054
1036
  createNodes(data) {
1055
1037
  const nodes = Object.keys(data.nodes).reduce((_nodes, nodeId) => {
1056
1038
  const nodeData = data.nodes[nodeId];
1057
- if ("value" in nodeData) {
1058
- _nodes[nodeId] = new StaticNode(nodeId, nodeData, this);
1059
- }
1060
- else if ("agent" in nodeData) {
1039
+ if ("agent" in nodeData) {
1061
1040
  _nodes[nodeId] = new ComputedNode(this.graphId, nodeId, nodeData, this);
1062
1041
  }
1063
1042
  else {
1064
- throw new Error("Unknown node type (neither value nor agent): " + nodeId);
1043
+ _nodes[nodeId] = new StaticNode(nodeId, nodeData, this);
1065
1044
  }
1045
+ // throw new Error("Unknown node type (neither value nor agent): " + nodeId);
1066
1046
  return _nodes;
1067
1047
  }, {});
1068
1048
  // Generate the waitlist for each node.
@@ -1231,6 +1211,11 @@ class GraphAI {
1231
1211
  }
1232
1212
  // Public API
1233
1213
  async run(all = false) {
1214
+ if (Object.values(this.nodes)
1215
+ .filter((node) => node.isStaticNode)
1216
+ .some((node) => node.result === undefined && node.update === undefined)) {
1217
+ throw new Error("Static node must have value. Set value or injectValue or set update");
1218
+ }
1234
1219
  if (this.isRunning()) {
1235
1220
  throw new Error("This GraphUI instance is already running");
1236
1221
  }