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/node.d.ts CHANGED
@@ -19,7 +19,6 @@ export declare class ComputedNode extends Node {
19
19
  readonly isResult: boolean;
20
20
  readonly params: NodeDataParams;
21
21
  private readonly filterParams;
22
- private readonly dynamicParams;
23
22
  readonly nestedGraph?: GraphData | DataSource;
24
23
  readonly retryLimit: number;
25
24
  retryCount: number;
@@ -36,6 +35,8 @@ export declare class ComputedNode extends Node {
36
35
  pendings: Set<string>;
37
36
  private ifSource?;
38
37
  private unlessSource?;
38
+ private defaultValue?;
39
+ private isSkip;
39
40
  readonly isStaticNode = false;
40
41
  readonly isComputedNode = true;
41
42
  constructor(graphId: string, nodeId: string, data: ComputedNodeData, graph: GraphAI);
@@ -51,9 +52,9 @@ export declare class ComputedNode extends Node {
51
52
  private shouldApplyAgentFilter;
52
53
  private agentFilterHandler;
53
54
  execute(): Promise<void>;
55
+ private afterExecute;
54
56
  private prepareExecute;
55
57
  private errorProcess;
56
- private getParams;
57
58
  private getContext;
58
59
  private getResult;
59
60
  private getDebugInfo;
package/lib/node.js CHANGED
@@ -45,6 +45,7 @@ class ComputedNode extends Node {
45
45
  super(nodeId, graph);
46
46
  this.retryCount = 0;
47
47
  this.dataSources = []; // no longer needed. This is for transaction log.
48
+ this.isSkip = false;
48
49
  this.isStaticNode = false;
49
50
  this.isComputedNode = true;
50
51
  this.graphId = graphId;
@@ -58,7 +59,7 @@ class ComputedNode extends Node {
58
59
  this.priority = data.priority ?? 0;
59
60
  this.anyInput = data.anyInput ?? false;
60
61
  this.inputs = data.inputs;
61
- this.dataSources = data.inputs ? (0, nodeUtils_1.inputs2dataSources)(data.inputs).flat(10) : [];
62
+ this.dataSources = [...(data.inputs ? (0, nodeUtils_1.inputs2dataSources)(data.inputs).flat(10) : []), ...(data.params ? (0, nodeUtils_1.inputs2dataSources)(data.params).flat(10) : [])];
62
63
  if (data.inputs && Array.isArray(data.inputs)) {
63
64
  throw new Error(`array inputs have been deprecated. nodeId: ${nodeId}: see https://github.com/receptron/graphai/blob/main/docs/NamedInputs.md`);
64
65
  }
@@ -83,15 +84,10 @@ class ComputedNode extends Node {
83
84
  if (data.unless) {
84
85
  this.unlessSource = this.addPendingNode(data.unless);
85
86
  }
86
- this.dynamicParams = Object.keys(this.params).reduce((tmp, key) => {
87
- const dataSource = (0, utils_2.parseNodeName)(this.params[key]);
88
- if (dataSource.nodeId) {
89
- (0, utils_2.assert)(!this.anyInput, "Dynamic params are not supported with anyInput");
90
- tmp[key] = dataSource;
91
- this.pendings.add(dataSource.nodeId);
92
- }
93
- return tmp;
94
- }, {});
87
+ if (data.defaultValue) {
88
+ this.defaultValue = data.defaultValue;
89
+ }
90
+ this.isSkip = false;
95
91
  this.log.initForComputedNode(this, graph);
96
92
  }
97
93
  getAgentId() {
@@ -107,8 +103,9 @@ class ComputedNode extends Node {
107
103
  if (this.state !== type_1.NodeState.Waiting || this.pendings.size !== 0) {
108
104
  return false;
109
105
  }
110
- if ((this.ifSource && !(0, utils_2.isLogicallyTrue)(this.graph.resultOf(this.ifSource))) ||
111
- (this.unlessSource && (0, utils_2.isLogicallyTrue)(this.graph.resultOf(this.unlessSource)))) {
106
+ this.isSkip = !!((this.ifSource && !(0, utils_2.isLogicallyTrue)(this.graph.resultOf(this.ifSource))) ||
107
+ (this.unlessSource && (0, utils_2.isLogicallyTrue)(this.graph.resultOf(this.unlessSource))));
108
+ if (this.isSkip && this.defaultValue === undefined) {
112
109
  this.state = type_1.NodeState.Skipped;
113
110
  this.log.onSkipped(this, this.graph);
114
111
  return false;
@@ -202,6 +199,10 @@ class ComputedNode extends Node {
202
199
  // then it removes itself from the "running node" list of the graph.
203
200
  // Notice that setting the result of this node may make other nodes ready to run.
204
201
  async execute() {
202
+ if (this.isSkip) {
203
+ this.afterExecute(this.defaultValue, []);
204
+ return;
205
+ }
205
206
  const previousResults = this.graph.resultsOf(this.inputs, this.anyInput);
206
207
  const transactionId = Date.now();
207
208
  this.prepareExecute(transactionId, Object.values(previousResults));
@@ -218,16 +219,7 @@ class ComputedNode extends Node {
218
219
  // if this is a nested agent or not.
219
220
  if (this.nestedGraph) {
220
221
  this.graph.taskManager.prepareForNesting();
221
- // context.taskManager = this.graph.taskManager;
222
222
  context.onLogCallback = this.graph.onLogCallback;
223
- /*
224
- if ("nodes" in this.nestedGraph) {
225
- context.graphData = this.nestedGraph;
226
- } else {
227
- context.graphData = this.graph.resultOf(this.nestedGraph) as GraphData; // HACK: compiler work-around
228
- }
229
- */
230
- // context.agents = this.graph.agentFunctionInfoDictionary;
231
223
  context.forNestedGraph = {
232
224
  graphData: "nodes" in this.nestedGraph ? this.nestedGraph : this.graph.resultOf(this.nestedGraph), // HACK: compiler work-around
233
225
  agents: this.graph.agentFunctionInfoDictionary,
@@ -253,16 +245,20 @@ class ComputedNode extends Node {
253
245
  console.log(`-- transactionId mismatch with ${this.nodeId} (probably timeout)`);
254
246
  return;
255
247
  }
256
- this.state = type_1.NodeState.Completed;
257
- this.result = this.getResult(result);
258
- this.log.onComplete(this, this.graph, localLog);
259
- this.onSetResult();
260
- this.graph.onExecutionComplete(this);
248
+ // after process
249
+ this.afterExecute(result, localLog);
261
250
  }
262
251
  catch (error) {
263
252
  this.errorProcess(error, transactionId, previousResults);
264
253
  }
265
254
  }
255
+ afterExecute(result, localLog) {
256
+ this.state = type_1.NodeState.Completed;
257
+ this.result = this.getResult(result);
258
+ this.log.onComplete(this, this.graph, localLog);
259
+ this.onSetResult();
260
+ this.graph.onExecutionComplete(this);
261
+ }
266
262
  // This private method (called only by execute()) prepares the ComputedNode object
267
263
  // for execution, and create a new transaction to record it.
268
264
  prepareExecute(transactionId, inputs) {
@@ -292,24 +288,9 @@ class ComputedNode extends Node {
292
288
  this.retry(type_1.NodeState.Failed, Error("Unknown"));
293
289
  }
294
290
  }
295
- getParams() {
296
- return Object.keys(this.dynamicParams).reduce((tmp, key) => {
297
- const result = this.graph.resultOf(this.dynamicParams[key]);
298
- tmp[key] = result;
299
- return tmp;
300
- }, { ...this.params });
301
- }
302
- /*
303
- private getInputs(previousResults: Record<string, ResultData | undefined>) {
304
- if (Array.isArray(this.inputs)) {
305
- return (this.inputs ?? []).map((key) => previousResults[String(key)]).filter((a) => !this.anyInput || a);
306
- }
307
- return [];
308
- }
309
- */
310
291
  getContext(previousResults, localLog) {
311
292
  const context = {
312
- params: this.getParams(),
293
+ params: this.graph.resultsOf(this.params),
313
294
  namedInputs: previousResults,
314
295
  inputSchema: this.agentFunction ? undefined : this.graph.getAgentFunctionInfo(this.agentId)?.inputs,
315
296
  debugInfo: this.getDebugInfo(),
package/lib/type.d.ts CHANGED
@@ -24,7 +24,7 @@ export type DataSource = {
24
24
  propIds?: string[];
25
25
  };
26
26
  export type StaticNodeData = {
27
- value: ResultData;
27
+ value?: ResultData;
28
28
  update?: string;
29
29
  isResult?: boolean;
30
30
  console?: Record<string, string | boolean>;
@@ -45,6 +45,7 @@ export type ComputedNodeData = {
45
45
  timeout?: number;
46
46
  if?: string;
47
47
  unless?: string;
48
+ defaultValue?: ResultData;
48
49
  graph?: GraphData | string;
49
50
  graphLoader?: GraphDataLoaderOption;
50
51
  isResult?: boolean;
@@ -18,7 +18,7 @@ const propArrayFunction = (result, propId) => {
18
18
  return result.length === 0;
19
19
  }
20
20
  // array join
21
- const matchJoin = propId.match(/^join\(([,-]?)\)$/);
21
+ const matchJoin = propId.match(/^join\(([,-\s]?)\)$/);
22
22
  if (matchJoin && Array.isArray(matchJoin)) {
23
23
  return result.join(matchJoin[1] ?? "");
24
24
  }
package/lib/validator.js CHANGED
@@ -15,7 +15,7 @@ const validateGraphData = (data, agentIds) => {
15
15
  const graphAgentIds = new Set();
16
16
  Object.keys(data.nodes).forEach((nodeId) => {
17
17
  const node = data.nodes[nodeId];
18
- const isStaticNode = "value" in node;
18
+ const isStaticNode = !("agent" in node);
19
19
  (0, nodeValidator_1.nodeValidator)(node);
20
20
  const agentId = isStaticNode ? "" : node.agent;
21
21
  isStaticNode && (0, static_node_validator_1.staticNodeValidator)(node) && staticNodeIds.push(nodeId);
@@ -15,6 +15,7 @@ exports.computedNodeAttributeKeys = [
15
15
  "priority",
16
16
  "if",
17
17
  "unless",
18
+ "defaultValue",
18
19
  "filterParams",
19
20
  "console",
20
21
  "passThrough",
@@ -6,9 +6,9 @@ const nodeValidator = (nodeData) => {
6
6
  if (nodeData.agent && nodeData.value) {
7
7
  throw new common_1.ValidationError("Cannot set both agent and value");
8
8
  }
9
- if (!("agent" in nodeData) && !("value" in nodeData)) {
10
- throw new common_1.ValidationError("Either agent or value is required");
11
- }
9
+ // if (!("agent" in nodeData) && !("value" in nodeData)) {
10
+ // throw new ValidationError("Either agent or value is required");
11
+ // }
12
12
  return true;
13
13
  };
14
14
  exports.nodeValidator = nodeValidator;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphai",
3
- "version": "0.6.3",
3
+ "version": "0.6.4",
4
4
  "description": "Asynchronous data flow execution engine for agentic AI apps.",
5
5
  "main": "lib/bundle.cjs.js",
6
6
  "module": "lib/bundle.esm.js",