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/graphai.js CHANGED
@@ -86,6 +86,7 @@ class GraphAI {
86
86
  bypassAgentIds: [],
87
87
  config: {},
88
88
  graphLoader: undefined,
89
+ forceLoop: false,
89
90
  }) {
90
91
  this.logs = [];
91
92
  this.config = {};
@@ -108,6 +109,7 @@ class GraphAI {
108
109
  this.bypassAgentIds = options.bypassAgentIds ?? [];
109
110
  this.config = options.config;
110
111
  this.graphLoader = options.graphLoader;
112
+ this.forceLoop = options.forceLoop ?? false;
111
113
  this.loop = graphData.loop;
112
114
  this.verbose = graphData.verbose === true;
113
115
  this.onComplete = (__isAbort) => {
@@ -148,9 +150,9 @@ class GraphAI {
148
150
  .join("\n");
149
151
  }
150
152
  // Public API
151
- results(all) {
153
+ results(all, internalUse = false) {
152
154
  return Object.keys(this.nodes)
153
- .filter((nodeId) => (all && nodeId !== utils_1.loopCounterKey) || this.nodes[nodeId].isResult)
155
+ .filter((nodeId) => (all && (internalUse || nodeId !== utils_1.loopCounterKey)) || this.nodes[nodeId].isResult)
154
156
  .reduce((results, nodeId) => {
155
157
  const node = this.nodes[nodeId];
156
158
  if (node.result !== undefined) {
@@ -216,9 +218,9 @@ class GraphAI {
216
218
  return new Promise((resolve, reject) => {
217
219
  this.onComplete = (isAbort = false) => {
218
220
  const errors = this.errors();
219
- const nodeIds = Object.keys(errors);
220
- if (nodeIds.length > 0 || isAbort) {
221
- reject(errors[nodeIds[0]]);
221
+ const errorNodeIds = Object.keys(errors);
222
+ if (errorNodeIds.length > 0 || isAbort) {
223
+ reject(errors[errorNodeIds[0]]);
222
224
  }
223
225
  else {
224
226
  resolve(this.results(all));
@@ -259,18 +261,22 @@ class GraphAI {
259
261
  // Check if there is any running computed nodes.
260
262
  // In case of no running computed note, start the another iteration if ncessary (loop)
261
263
  processLoopIfNecessary() {
264
+ //
265
+ if (!this.forceLoop && Object.keys(this.errors()).length > 0) {
266
+ return false;
267
+ }
262
268
  this.repeatCount++;
263
269
  const loop = this.loop;
264
270
  if (!loop) {
265
271
  return false;
266
272
  }
267
273
  // We need to update static nodes, before checking the condition
268
- const previousResults = this.results(true); // results from previous loop
274
+ const previousResults = this.results(true, true); // results from previous loop
269
275
  this.updateStaticNodes(previousResults);
270
276
  if (loop.count === undefined || this.repeatCount < loop.count) {
271
277
  if (loop.while) {
272
278
  const source = (0, utils_1.parseNodeName)(loop.while);
273
- const value = this.getValueFromResults(source, this.results(true));
279
+ const value = this.getValueFromResults(source, this.results(true, true));
274
280
  // NOTE: We treat an empty array as false.
275
281
  if (!(0, utils_1.isLogicallyTrue)(value)) {
276
282
  return false; // while condition is not met
package/lib/type.d.ts CHANGED
@@ -85,6 +85,7 @@ export type GraphOptions = {
85
85
  bypassAgentIds?: string[] | undefined;
86
86
  config?: ConfigDataDictionary;
87
87
  graphLoader?: GraphDataLoader;
88
+ forceLoop?: boolean;
88
89
  };
89
90
  export type CacheTypes = "pureAgent" | "impureAgent";
90
91
  export type AgentFunctionContextDebugInfo = {
@@ -21,6 +21,7 @@ const inputs2dataSources = (inputs) => {
21
21
  return (0, utils_1.parseNodeName)(inputs);
22
22
  };
23
23
  exports.inputs2dataSources = inputs2dataSources;
24
+ // TODO: Maybe it's a remnant of old array inputs. Check and delete.
24
25
  const dataSourceNodeIds = (sources) => {
25
26
  if (!Array.isArray(sources)) {
26
27
  throw new Error("sources must be array!! maybe inputs is invalid");
@@ -34,7 +34,8 @@ const resultsOfInner = (input, nodes, propFunctions, isSelfNode = false) => {
34
34
  return replaceTemplatePlaceholders(input, templateMatch, nodes, propFunctions, isSelfNode);
35
35
  }
36
36
  }
37
- return (0, exports.resultOf)((0, utils_1.parseNodeName)(input, isSelfNode), nodes, propFunctions);
37
+ // :node.prod
38
+ return (0, exports.resultOf)((0, utils_1.parseNodeName)(input, isSelfNode, nodes), nodes, propFunctions);
38
39
  };
39
40
  const resultsOf = (inputs, nodes, propFunctions, isSelfNode = false) => {
40
41
  return Object.keys(inputs).reduce((tmp, key) => {
@@ -1,6 +1,7 @@
1
1
  import { DataSource, AgentFunction, AgentFunctionInfo, NodeData, StaticNodeData, ComputedNodeData, NodeState } from "../type";
2
+ import type { GraphNodes } from "../node";
2
3
  export declare const sleep: (milliseconds: number) => Promise<unknown>;
3
- export declare const parseNodeName: (inputNodeId: any, isSelfNode?: boolean) => DataSource;
4
+ export declare const parseNodeName: (inputNodeId: any, isSelfNode?: boolean, nodes?: GraphNodes) => DataSource;
4
5
  export declare function assert(condition: boolean, message: string, isWarn?: boolean): asserts condition;
5
6
  export declare const isObject: <Values = unknown>(x: unknown) => x is Record<string, Values>;
6
7
  export declare const isNull: (data: unknown) => data is null | undefined;
@@ -4,11 +4,12 @@ exports.loopCounterKey = exports.isStaticNodeData = exports.isComputedNodeData =
4
4
  exports.assert = assert;
5
5
  const type_1 = require("../type");
6
6
  const GraphAILogger_1 = require("./GraphAILogger");
7
+ const prop_function_1 = require("./prop_function");
7
8
  const sleep = async (milliseconds) => {
8
9
  return await new Promise((resolve) => setTimeout(resolve, milliseconds));
9
10
  };
10
11
  exports.sleep = sleep;
11
- const parseNodeName = (inputNodeId, isSelfNode = false) => {
12
+ const parseNodeName = (inputNodeId, isSelfNode = false, nodes) => {
12
13
  if (isSelfNode) {
13
14
  if (typeof inputNodeId === "string" && inputNodeId[0] === ".") {
14
15
  const parts = inputNodeId.split(".");
@@ -19,14 +20,19 @@ const parseNodeName = (inputNodeId, isSelfNode = false) => {
19
20
  if (typeof inputNodeId === "string") {
20
21
  const regex = /^:(.*)$/;
21
22
  const match = inputNodeId.match(regex);
22
- if (!match) {
23
- return { value: inputNodeId }; // string literal
23
+ if (match) {
24
+ const parts = match[1].split(/(?<!\()\.(?!\))/);
25
+ if (parts.length == 1) {
26
+ return { nodeId: parts[0] };
27
+ }
28
+ return { nodeId: parts[0], propIds: parts.slice(1) };
24
29
  }
25
- const parts = match[1].split(/(?<!\()\.(?!\))/);
26
- if (parts.length == 1) {
27
- return { nodeId: parts[0] };
30
+ const regexUtil = /^@(.*)$/;
31
+ const matchUtil = inputNodeId.match(regexUtil);
32
+ // Only when just called from resultsOfInner
33
+ if (nodes && matchUtil) {
34
+ return { value: (0, prop_function_1.utilsFunctions)(inputNodeId, nodes) };
28
35
  }
29
- return { nodeId: parts[0], propIds: parts.slice(1) };
30
36
  }
31
37
  return { value: inputNodeId }; // non-string literal
32
38
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphai",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
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",
@@ -29,7 +29,7 @@
29
29
  },
30
30
  "homepage": "https://github.com/receptron/graphai#readme",
31
31
  "devDependencies": {
32
- "typedoc": "^0.28.3",
32
+ "typedoc": "^0.28.4",
33
33
  "typedoc-plugin-markdown": "^4.6.3"
34
34
  },
35
35
  "types": "./lib/index.d.ts",