graphai 0.5.9 → 0.5.11

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
@@ -228,7 +228,7 @@ class GraphAI {
228
228
  this.updateStaticNodes(previousResults);
229
229
  if (loop.count === undefined || this.repeatCount < loop.count) {
230
230
  if (loop.while) {
231
- const source = (0, utils_1.parseNodeName)(loop.while, this.version);
231
+ const source = (0, utils_1.parseNodeName)(loop.while);
232
232
  const value = this.getValueFromResults(source, this.results(true));
233
233
  // NOTE: We treat an empty array as false.
234
234
  if (!(0, utils_1.isLogicallyTrue)(value)) {
@@ -269,7 +269,7 @@ class GraphAI {
269
269
  }
270
270
  }
271
271
  resultsOf(inputs, anyInput = false) {
272
- const results = (0, result_1.resultsOf)(inputs ?? [], this.nodes, this.version);
272
+ const results = (0, result_1.resultsOf)(inputs ?? [], this.nodes);
273
273
  if (anyInput) {
274
274
  return (0, result_1.cleanResult)(results);
275
275
  }
package/lib/node.js CHANGED
@@ -51,7 +51,7 @@ class ComputedNode extends Node {
51
51
  this.anyInput = data.anyInput ?? false;
52
52
  this.inputs = data.inputs;
53
53
  this.isNamedInputs = (0, utils_2.isObject)(data.inputs) && !Array.isArray(data.inputs);
54
- this.dataSources = data.inputs ? (0, nodeUtils_1.inputs2dataSources)(data.inputs, graph.version).flat(10) : [];
54
+ this.dataSources = data.inputs ? (0, nodeUtils_1.inputs2dataSources)(data.inputs).flat(10) : [];
55
55
  if (data.inputs && !this.isNamedInputs) {
56
56
  console.warn(`array inputs have been deprecated. nodeId: ${nodeId}: see https://github.com/receptron/graphai/blob/main/docs/NamedInputs.md`);
57
57
  }
@@ -74,7 +74,7 @@ class ComputedNode extends Node {
74
74
  this.unlessSource = this.addPendingNode(data.unless);
75
75
  }
76
76
  this.dynamicParams = Object.keys(this.params).reduce((tmp, key) => {
77
- const dataSource = (0, utils_2.parseNodeName)(this.params[key], graph.version < 0.3 ? 0.3 : graph.version);
77
+ const dataSource = (0, utils_2.parseNodeName)(this.params[key]);
78
78
  if (dataSource.nodeId) {
79
79
  (0, utils_2.assert)(!this.anyInput, "Dynamic params are not supported with anyInput");
80
80
  tmp[key] = dataSource;
@@ -88,7 +88,7 @@ class ComputedNode extends Node {
88
88
  return this.agentId ?? "__custom__function"; // only for display purpose in the log.
89
89
  }
90
90
  addPendingNode(nodeId) {
91
- const source = (0, utils_2.parseNodeName)(nodeId, this.graph.version);
91
+ const source = (0, utils_2.parseNodeName)(nodeId);
92
92
  (0, utils_2.assert)(!!source.nodeId, `Invalid data source ${nodeId}`);
93
93
  this.pendings.add(source.nodeId);
94
94
  return source;
@@ -340,7 +340,7 @@ class StaticNode extends Node {
340
340
  this.isStaticNode = true;
341
341
  this.isComputedNode = false;
342
342
  this.value = data.value;
343
- this.update = data.update ? (0, utils_2.parseNodeName)(data.update, graph.version) : undefined;
343
+ this.update = data.update ? (0, utils_2.parseNodeName)(data.update) : undefined;
344
344
  this.isResult = data.isResult ?? false;
345
345
  }
346
346
  injectValue(value, injectFrom) {
package/lib/result.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { DataSource, ResultData } from "./type";
2
2
  import { GraphNodes } from "./node";
3
- export declare const resultsOf: (inputs: Record<string, any> | Array<string>, nodes: GraphNodes, graphVersion: number) => Record<string, ResultData>;
3
+ export declare const resultsOf: (inputs: Record<string, any> | Array<string>, nodes: GraphNodes) => Record<string, ResultData>;
4
4
  export declare const resultOf: (source: DataSource, nodes: GraphNodes) => ResultData;
5
5
  export declare const cleanResultInner: (results: ResultData) => ResultData | null;
6
6
  export declare const cleanResult: (results: Record<string, ResultData | undefined>) => Record<string, ResultData>;
package/lib/result.js CHANGED
@@ -2,35 +2,35 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.cleanResult = exports.cleanResultInner = exports.resultOf = exports.resultsOf = void 0;
4
4
  const utils_1 = require("./utils/utils");
5
- const resultsOfInner = (input, nodes, graphVersion) => {
5
+ const resultsOfInner = (input, nodes) => {
6
6
  if (Array.isArray(input)) {
7
- return input.map((inp) => resultsOfInner(inp, nodes, graphVersion));
7
+ return input.map((inp) => resultsOfInner(inp, nodes));
8
8
  }
9
9
  if ((0, utils_1.isNamedInputs)(input)) {
10
- return (0, exports.resultsOf)(input, nodes, graphVersion);
10
+ return (0, exports.resultsOf)(input, nodes);
11
11
  }
12
12
  if (typeof input === "string") {
13
13
  const templateMatch = [...input.matchAll(/\${(:[^}]+)}/g)].map((m) => m[1]);
14
14
  if (templateMatch.length > 0) {
15
- const results = resultsOfInner(templateMatch, nodes, graphVersion);
15
+ const results = resultsOfInner(templateMatch, nodes);
16
16
  return Array.from(templateMatch.keys()).reduce((tmp, key) => {
17
17
  return tmp.replaceAll("${" + templateMatch[key] + "}", results[key]);
18
18
  }, input);
19
19
  }
20
20
  }
21
- return (0, exports.resultOf)((0, utils_1.parseNodeName)(input, graphVersion), nodes);
21
+ return (0, exports.resultOf)((0, utils_1.parseNodeName)(input), nodes);
22
22
  };
23
- const resultsOf = (inputs, nodes, graphVersion) => {
23
+ const resultsOf = (inputs, nodes) => {
24
24
  // for inputs. TODO remove if array input is not supported
25
25
  if (Array.isArray(inputs)) {
26
26
  return inputs.reduce((tmp, key) => {
27
- tmp[key] = resultsOfInner(key, nodes, graphVersion);
27
+ tmp[key] = resultsOfInner(key, nodes);
28
28
  return tmp;
29
29
  }, {});
30
30
  }
31
31
  return Object.keys(inputs).reduce((tmp, key) => {
32
32
  const input = inputs[key];
33
- tmp[key] = (0, utils_1.isNamedInputs)(input) ? (0, exports.resultsOf)(input, nodes, graphVersion) : resultsOfInner(input, nodes, graphVersion);
33
+ tmp[key] = (0, utils_1.isNamedInputs)(input) ? (0, exports.resultsOf)(input, nodes) : resultsOfInner(input, nodes);
34
34
  return tmp;
35
35
  }, {});
36
36
  };
@@ -1,3 +1,3 @@
1
1
  import { DataSource } from "../type";
2
- export declare const inputs2dataSources: (inputs: any, graphVersion: number) => DataSource[];
2
+ export declare const inputs2dataSources: (inputs: any) => DataSource[];
3
3
  export declare const dataSourceNodeIds: (sources: DataSource[]) => string[];
@@ -3,22 +3,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.dataSourceNodeIds = exports.inputs2dataSources = void 0;
4
4
  const utils_1 = require("./utils");
5
5
  // for dataSource
6
- const inputs2dataSources = (inputs, graphVersion) => {
6
+ const inputs2dataSources = (inputs) => {
7
7
  if (Array.isArray(inputs)) {
8
- return inputs.map((inp) => (0, exports.inputs2dataSources)(inp, graphVersion)).flat();
8
+ return inputs.map((inp) => (0, exports.inputs2dataSources)(inp)).flat();
9
9
  }
10
10
  if ((0, utils_1.isObject)(inputs)) {
11
11
  return Object.values(inputs)
12
- .map((input) => (0, exports.inputs2dataSources)(input, graphVersion))
12
+ .map((input) => (0, exports.inputs2dataSources)(input))
13
13
  .flat();
14
14
  }
15
15
  if (typeof inputs === "string") {
16
16
  const templateMatch = [...inputs.matchAll(/\${(:[^}]+)}/g)].map((m) => m[1]);
17
17
  if (templateMatch.length > 0) {
18
- return (0, exports.inputs2dataSources)(templateMatch, graphVersion);
18
+ return (0, exports.inputs2dataSources)(templateMatch);
19
19
  }
20
20
  }
21
- return (0, utils_1.parseNodeName)(inputs, graphVersion);
21
+ return (0, utils_1.parseNodeName)(inputs);
22
22
  };
23
23
  exports.inputs2dataSources = inputs2dataSources;
24
24
  const dataSourceNodeIds = (sources) => {
@@ -1,6 +1,6 @@
1
1
  import { DataSource, ResultData, AgentFunction, DefaultInputData } from "../type";
2
2
  export declare const sleep: (milliseconds: number) => Promise<unknown>;
3
- export declare const parseNodeName: (inputNodeId: any, version: number) => DataSource;
3
+ export declare const parseNodeName: (inputNodeId: any) => DataSource;
4
4
  export declare function assert(condition: boolean, message: string, isWarn?: boolean): asserts condition;
5
5
  export declare const isObject: (x: unknown) => x is object;
6
6
  export declare const isNull: (data: unknown) => data is null | undefined;
@@ -6,25 +6,7 @@ const sleep = async (milliseconds) => {
6
6
  return await new Promise((resolve) => setTimeout(resolve, milliseconds));
7
7
  };
8
8
  exports.sleep = sleep;
9
- const parseNodeName_02 = (inputNodeId) => {
10
- if (typeof inputNodeId === "string") {
11
- const regex = /^"(.*)"$/;
12
- const match = inputNodeId.match(regex);
13
- if (match) {
14
- return { value: match[1] }; // string literal
15
- }
16
- const parts = inputNodeId.split(".");
17
- if (parts.length == 1) {
18
- return { nodeId: parts[0] };
19
- }
20
- return { nodeId: parts[0], propIds: parts.slice(1) };
21
- }
22
- return { value: inputNodeId }; // non-string literal
23
- };
24
- const parseNodeName = (inputNodeId, version) => {
25
- if (version === 0.2) {
26
- return parseNodeName_02(inputNodeId);
27
- }
9
+ const parseNodeName = (inputNodeId) => {
28
10
  if (typeof inputNodeId === "string") {
29
11
  const regex = /^:(.*)$/;
30
12
  const match = inputNodeId.match(regex);
@@ -57,7 +39,9 @@ const isNull = (data) => {
57
39
  };
58
40
  exports.isNull = isNull;
59
41
  const getNestedData = (result, propId) => {
42
+ // for array.
60
43
  if (Array.isArray(result)) {
44
+ // $0, $1. array value.
61
45
  const regex = /^\$(\d+)$/;
62
46
  const match = propId.match(regex);
63
47
  if (match) {
@@ -73,9 +57,13 @@ const getNestedData = (result, propId) => {
73
57
  if (propId === "flat()") {
74
58
  return result.flat();
75
59
  }
76
- const matchJoin = propId.match(/^join\(([,-])\)$/);
60
+ if (propId === "toJSON()") {
61
+ return JSON.stringify(result);
62
+ }
63
+ // array join
64
+ const matchJoin = propId.match(/^join\(([,-]?)\)$/);
77
65
  if (matchJoin && Array.isArray(matchJoin)) {
78
- return result.join(matchJoin[1]);
66
+ return result.join(matchJoin[1] ?? "");
79
67
  }
80
68
  // flat, join
81
69
  }
@@ -86,12 +74,28 @@ const getNestedData = (result, propId) => {
86
74
  if (propId === "values()") {
87
75
  return Object.values(result);
88
76
  }
89
- return result[propId];
77
+ if (propId === "toJSON()") {
78
+ return JSON.stringify(result);
79
+ }
80
+ if (propId in result) {
81
+ return result[propId];
82
+ }
90
83
  }
91
84
  else if (typeof result === "string") {
92
85
  if (propId === "jsonParse()") {
93
86
  return JSON.parse(result);
94
87
  }
88
+ if (propId === "toNumber()") {
89
+ const ret = Number(result);
90
+ if (!isNaN(ret)) {
91
+ return ret;
92
+ }
93
+ }
94
+ }
95
+ else if (Number.isFinite(result)) {
96
+ if (propId === "toString()") {
97
+ return String(result);
98
+ }
95
99
  }
96
100
  return undefined;
97
101
  };
@@ -99,6 +103,9 @@ const innerGetDataFromSource = (result, propIds) => {
99
103
  if (result && propIds && propIds.length > 0) {
100
104
  const propId = propIds[0];
101
105
  const ret = getNestedData(result, propId);
106
+ if (ret === undefined) {
107
+ console.error(`prop: ${propIds.join(".")} is not hit`);
108
+ }
102
109
  if (propIds.length > 1) {
103
110
  return innerGetDataFromSource(ret, propIds.slice(1));
104
111
  }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.relationValidator = void 0;
4
4
  const utils_1 = require("../utils/utils");
5
5
  const common_1 = require("../validators/common");
6
+ const nodeUtils_1 = require("../utils/nodeUtils");
6
7
  const relationValidator = (data, staticNodeIds, computedNodeIds) => {
7
8
  const nodeIds = new Set(Object.keys(data.nodes));
8
9
  const pendings = {};
@@ -11,34 +12,34 @@ const relationValidator = (data, staticNodeIds, computedNodeIds) => {
11
12
  computedNodeIds.forEach((computedNodeId) => {
12
13
  const nodeData = data.nodes[computedNodeId];
13
14
  pendings[computedNodeId] = new Set();
14
- if ("inputs" in nodeData && nodeData && nodeData.inputs) {
15
- if (Array.isArray(nodeData.inputs)) {
16
- nodeData.inputs.forEach((inputNodeId) => {
17
- const sourceNodeId = (0, utils_1.parseNodeName)(inputNodeId, data.version ?? 0.2).nodeId;
18
- if (sourceNodeId) {
19
- if (!nodeIds.has(sourceNodeId)) {
20
- throw new common_1.ValidationError(`Inputs not match: NodeId ${computedNodeId}, Inputs: ${sourceNodeId}`);
21
- }
22
- waitlist[sourceNodeId] === undefined && (waitlist[sourceNodeId] = new Set());
23
- pendings[computedNodeId].add(sourceNodeId);
24
- waitlist[sourceNodeId].add(computedNodeId);
15
+ const dataSourceValidator = (sourceType, sourceNodeIds) => {
16
+ sourceNodeIds.forEach((sourceNodeId) => {
17
+ if (sourceNodeId) {
18
+ if (!nodeIds.has(sourceNodeId)) {
19
+ throw new common_1.ValidationError(`${sourceType} not match: NodeId ${computedNodeId}, Inputs: ${sourceNodeId}`);
25
20
  }
26
- });
21
+ waitlist[sourceNodeId] === undefined && (waitlist[sourceNodeId] = new Set());
22
+ pendings[computedNodeId].add(sourceNodeId);
23
+ waitlist[sourceNodeId].add(computedNodeId);
24
+ }
25
+ });
26
+ };
27
+ if ("agent" in nodeData && nodeData) {
28
+ if (nodeData.inputs) {
29
+ const sourceNodeIds = (0, nodeUtils_1.dataSourceNodeIds)((0, nodeUtils_1.inputs2dataSources)(nodeData.inputs));
30
+ dataSourceValidator("Inputs", sourceNodeIds);
27
31
  }
28
- else {
29
- const keys = Object.keys(nodeData.inputs);
30
- keys.forEach((key) => {
31
- const inputNodeId = nodeData.inputs[key];
32
- const sourceNodeId = (0, utils_1.parseNodeName)(inputNodeId, data.version ?? 0.3).nodeId;
33
- if (sourceNodeId) {
34
- if (!nodeIds.has(sourceNodeId)) {
35
- throw new common_1.ValidationError(`Inputs not match: NodeId ${computedNodeId}, Inputs: ${sourceNodeId}`);
36
- }
37
- waitlist[sourceNodeId] === undefined && (waitlist[sourceNodeId] = new Set());
38
- pendings[computedNodeId].add(sourceNodeId);
39
- waitlist[sourceNodeId].add(computedNodeId);
40
- }
41
- });
32
+ if (nodeData.if) {
33
+ const sourceNodeIds = (0, nodeUtils_1.dataSourceNodeIds)((0, nodeUtils_1.inputs2dataSources)({ if: nodeData.if }));
34
+ dataSourceValidator("If", sourceNodeIds);
35
+ }
36
+ if (nodeData.unless) {
37
+ const sourceNodeIds = (0, nodeUtils_1.dataSourceNodeIds)((0, nodeUtils_1.inputs2dataSources)({ unless: nodeData.unless }));
38
+ dataSourceValidator("Unless", sourceNodeIds);
39
+ }
40
+ if (nodeData.graph && typeof nodeData?.graph === "string") {
41
+ const sourceNodeIds = (0, nodeUtils_1.dataSourceNodeIds)((0, nodeUtils_1.inputs2dataSources)({ graph: nodeData.graph }));
42
+ dataSourceValidator("Graph", sourceNodeIds);
42
43
  }
43
44
  }
44
45
  });
@@ -47,7 +48,7 @@ const relationValidator = (data, staticNodeIds, computedNodeIds) => {
47
48
  const nodeData = data.nodes[staticNodeId];
48
49
  if ("value" in nodeData && nodeData.update) {
49
50
  const update = nodeData.update;
50
- const updateNodeId = (0, utils_1.parseNodeName)(update, data.version ?? 0.2).nodeId;
51
+ const updateNodeId = (0, utils_1.parseNodeName)(update).nodeId;
51
52
  if (!updateNodeId) {
52
53
  throw new common_1.ValidationError("Update it a literal");
53
54
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphai",
3
- "version": "0.5.9",
3
+ "version": "0.5.11",
4
4
  "description": "Asynchronous data flow execution engine for agentic AI apps.",
5
5
  "main": "lib/index.js",
6
6
  "files": [
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "homepage": "https://github.com/receptron/graphai#readme",
28
28
  "devDependencies": {
29
- "typedoc": "^0.26.7"
29
+ "typedoc": "^0.26.10"
30
30
  },
31
31
  "types": "./lib/index.d.ts",
32
32
  "directories": {