graphai 1.0.13 → 2.0.0
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 +138 -131
- 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 +1 -1
- package/lib/graphai.js +4 -4
- package/lib/node.js +3 -2
- 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 +1 -1
package/lib/bundle.esm.js
CHANGED
|
@@ -61,10 +61,127 @@ const GraphAILogger = {
|
|
|
61
61
|
error,
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
+
const propFunctionRegex = /^[a-zA-Z]+\([^)]*\)$/;
|
|
65
|
+
const propArrayFunction = (result, propId) => {
|
|
66
|
+
if (Array.isArray(result)) {
|
|
67
|
+
if (propId === "length()") {
|
|
68
|
+
return result.length;
|
|
69
|
+
}
|
|
70
|
+
if (propId === "flat()") {
|
|
71
|
+
return result.flat();
|
|
72
|
+
}
|
|
73
|
+
if (propId === "toJSON()") {
|
|
74
|
+
return JSON.stringify(result, null, 2);
|
|
75
|
+
}
|
|
76
|
+
if (propId === "isEmpty()") {
|
|
77
|
+
return result.length === 0;
|
|
78
|
+
}
|
|
79
|
+
// array join
|
|
80
|
+
const matchJoin = propId.match(/^join\(([,-\s]?)\)$/);
|
|
81
|
+
if (matchJoin && Array.isArray(matchJoin)) {
|
|
82
|
+
return result.join(matchJoin[1] ?? "");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return undefined;
|
|
86
|
+
};
|
|
87
|
+
const propObjectFunction = (result, propId) => {
|
|
88
|
+
if (isObject(result)) {
|
|
89
|
+
if (propId === "keys()") {
|
|
90
|
+
return Object.keys(result);
|
|
91
|
+
}
|
|
92
|
+
if (propId === "values()") {
|
|
93
|
+
return Object.values(result);
|
|
94
|
+
}
|
|
95
|
+
if (propId === "toJSON()") {
|
|
96
|
+
return JSON.stringify(result, null, 2);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return undefined;
|
|
100
|
+
};
|
|
101
|
+
const propStringFunction = (result, propId) => {
|
|
102
|
+
if (typeof result === "string") {
|
|
103
|
+
if (propId === "codeBlock()") {
|
|
104
|
+
const match = ("\n" + result).match(/\n```[a-zA-z]*([\s\S]*?)\n```/);
|
|
105
|
+
if (match) {
|
|
106
|
+
return match[1];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (propId === "jsonParse()") {
|
|
110
|
+
return JSON.parse(result);
|
|
111
|
+
}
|
|
112
|
+
if (propId === "toNumber()") {
|
|
113
|
+
const ret = Number(result);
|
|
114
|
+
if (!isNaN(ret)) {
|
|
115
|
+
return ret;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (propId === "trim()") {
|
|
119
|
+
return result.trim();
|
|
120
|
+
}
|
|
121
|
+
if (propId === "toLowerCase()") {
|
|
122
|
+
return result.toLowerCase();
|
|
123
|
+
}
|
|
124
|
+
if (propId === "toUpperCase()") {
|
|
125
|
+
return result.toUpperCase();
|
|
126
|
+
}
|
|
127
|
+
const sliceMatch = propId.match(/^slice\((-?\d+)(?:,\s*(-?\d+))?\)/);
|
|
128
|
+
if (sliceMatch) {
|
|
129
|
+
if (sliceMatch[2] !== undefined) {
|
|
130
|
+
return result.slice(Number(sliceMatch[1]), Number(sliceMatch[2]));
|
|
131
|
+
}
|
|
132
|
+
if (sliceMatch[1] !== undefined) {
|
|
133
|
+
return result.slice(Number(sliceMatch[1]));
|
|
134
|
+
}
|
|
135
|
+
GraphAILogger.warn("slice is not valid format: " + sliceMatch);
|
|
136
|
+
}
|
|
137
|
+
const splitMatch = propId.match(/^split\(([-_:;.,\s\n]+)\)$/);
|
|
138
|
+
if (splitMatch) {
|
|
139
|
+
return result.split(splitMatch[1]);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return undefined;
|
|
143
|
+
};
|
|
144
|
+
const propNumberFunction = (result, propId) => {
|
|
145
|
+
if (result !== undefined && Number.isFinite(result)) {
|
|
146
|
+
if (propId === "toString()") {
|
|
147
|
+
return String(result);
|
|
148
|
+
}
|
|
149
|
+
const regex = /^add\((-?\d+)\)$/;
|
|
150
|
+
const match = propId.match(regex);
|
|
151
|
+
if (match) {
|
|
152
|
+
return Number(result) + Number(match[1]);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return undefined;
|
|
156
|
+
};
|
|
157
|
+
const propBooleanFunction = (result, propId) => {
|
|
158
|
+
if (typeof result === "boolean") {
|
|
159
|
+
if (propId === "not()") {
|
|
160
|
+
return !result;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return undefined;
|
|
164
|
+
};
|
|
165
|
+
const propFunctions = [propArrayFunction, propObjectFunction, propStringFunction, propNumberFunction, propBooleanFunction];
|
|
166
|
+
const utilsFunctions = (input, nodes) => {
|
|
167
|
+
if (input === "@now" || input === "@now_ms") {
|
|
168
|
+
return Date.now();
|
|
169
|
+
}
|
|
170
|
+
if (input === "@now_s") {
|
|
171
|
+
return Math.floor(Date.now() / 1000);
|
|
172
|
+
}
|
|
173
|
+
if (input === "@loop") {
|
|
174
|
+
return nodes[loopCounterKey].result;
|
|
175
|
+
}
|
|
176
|
+
// If a placeholder does not match any key, replace it with an empty string.
|
|
177
|
+
GraphAILogger.warn("not match template utility function: ${" + input + "}");
|
|
178
|
+
return "";
|
|
179
|
+
};
|
|
180
|
+
|
|
64
181
|
const sleep = async (milliseconds) => {
|
|
65
182
|
return await new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
66
183
|
};
|
|
67
|
-
const parseNodeName = (inputNodeId, isSelfNode = false) => {
|
|
184
|
+
const parseNodeName = (inputNodeId, isSelfNode = false, nodes) => {
|
|
68
185
|
if (isSelfNode) {
|
|
69
186
|
if (typeof inputNodeId === "string" && inputNodeId[0] === ".") {
|
|
70
187
|
const parts = inputNodeId.split(".");
|
|
@@ -75,14 +192,19 @@ const parseNodeName = (inputNodeId, isSelfNode = false) => {
|
|
|
75
192
|
if (typeof inputNodeId === "string") {
|
|
76
193
|
const regex = /^:(.*)$/;
|
|
77
194
|
const match = inputNodeId.match(regex);
|
|
78
|
-
if (
|
|
79
|
-
|
|
195
|
+
if (match) {
|
|
196
|
+
const parts = match[1].split(/(?<!\()\.(?!\))/);
|
|
197
|
+
if (parts.length == 1) {
|
|
198
|
+
return { nodeId: parts[0] };
|
|
199
|
+
}
|
|
200
|
+
return { nodeId: parts[0], propIds: parts.slice(1) };
|
|
80
201
|
}
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
202
|
+
const regexUtil = /^@(.*)$/;
|
|
203
|
+
const matchUtil = inputNodeId.match(regexUtil);
|
|
204
|
+
// Only when just called from resultsOfInner
|
|
205
|
+
if (nodes && matchUtil) {
|
|
206
|
+
return { value: utilsFunctions(inputNodeId, nodes) };
|
|
84
207
|
}
|
|
85
|
-
return { nodeId: parts[0], propIds: parts.slice(1) };
|
|
86
208
|
}
|
|
87
209
|
return { value: inputNodeId }; // non-string literal
|
|
88
210
|
};
|
|
@@ -279,123 +401,6 @@ class TransactionLog {
|
|
|
279
401
|
}
|
|
280
402
|
}
|
|
281
403
|
|
|
282
|
-
const propFunctionRegex = /^[a-zA-Z]+\([^)]*\)$/;
|
|
283
|
-
const propArrayFunction = (result, propId) => {
|
|
284
|
-
if (Array.isArray(result)) {
|
|
285
|
-
if (propId === "length()") {
|
|
286
|
-
return result.length;
|
|
287
|
-
}
|
|
288
|
-
if (propId === "flat()") {
|
|
289
|
-
return result.flat();
|
|
290
|
-
}
|
|
291
|
-
if (propId === "toJSON()") {
|
|
292
|
-
return JSON.stringify(result, null, 2);
|
|
293
|
-
}
|
|
294
|
-
if (propId === "isEmpty()") {
|
|
295
|
-
return result.length === 0;
|
|
296
|
-
}
|
|
297
|
-
// array join
|
|
298
|
-
const matchJoin = propId.match(/^join\(([,-\s]?)\)$/);
|
|
299
|
-
if (matchJoin && Array.isArray(matchJoin)) {
|
|
300
|
-
return result.join(matchJoin[1] ?? "");
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
return undefined;
|
|
304
|
-
};
|
|
305
|
-
const propObjectFunction = (result, propId) => {
|
|
306
|
-
if (isObject(result)) {
|
|
307
|
-
if (propId === "keys()") {
|
|
308
|
-
return Object.keys(result);
|
|
309
|
-
}
|
|
310
|
-
if (propId === "values()") {
|
|
311
|
-
return Object.values(result);
|
|
312
|
-
}
|
|
313
|
-
if (propId === "toJSON()") {
|
|
314
|
-
return JSON.stringify(result, null, 2);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
return undefined;
|
|
318
|
-
};
|
|
319
|
-
const propStringFunction = (result, propId) => {
|
|
320
|
-
if (typeof result === "string") {
|
|
321
|
-
if (propId === "codeBlock()") {
|
|
322
|
-
const match = ("\n" + result).match(/\n```[a-zA-z]*([\s\S]*?)\n```/);
|
|
323
|
-
if (match) {
|
|
324
|
-
return match[1];
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
if (propId === "jsonParse()") {
|
|
328
|
-
return JSON.parse(result);
|
|
329
|
-
}
|
|
330
|
-
if (propId === "toNumber()") {
|
|
331
|
-
const ret = Number(result);
|
|
332
|
-
if (!isNaN(ret)) {
|
|
333
|
-
return ret;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
if (propId === "trim()") {
|
|
337
|
-
return result.trim();
|
|
338
|
-
}
|
|
339
|
-
if (propId === "toLowerCase()") {
|
|
340
|
-
return result.toLowerCase();
|
|
341
|
-
}
|
|
342
|
-
if (propId === "toUpperCase()") {
|
|
343
|
-
return result.toUpperCase();
|
|
344
|
-
}
|
|
345
|
-
const sliceMatch = propId.match(/^slice\((-?\d+)(?:,\s*(-?\d+))?\)/);
|
|
346
|
-
if (sliceMatch) {
|
|
347
|
-
if (sliceMatch[2] !== undefined) {
|
|
348
|
-
return result.slice(Number(sliceMatch[1]), Number(sliceMatch[2]));
|
|
349
|
-
}
|
|
350
|
-
if (sliceMatch[1] !== undefined) {
|
|
351
|
-
return result.slice(Number(sliceMatch[1]));
|
|
352
|
-
}
|
|
353
|
-
GraphAILogger.warn("slice is not valid format: " + sliceMatch);
|
|
354
|
-
}
|
|
355
|
-
const splitMatch = propId.match(/^split\(([-_:;.,\s\n]+)\)$/);
|
|
356
|
-
if (splitMatch) {
|
|
357
|
-
return result.split(splitMatch[1]);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
return undefined;
|
|
361
|
-
};
|
|
362
|
-
const propNumberFunction = (result, propId) => {
|
|
363
|
-
if (result !== undefined && Number.isFinite(result)) {
|
|
364
|
-
if (propId === "toString()") {
|
|
365
|
-
return String(result);
|
|
366
|
-
}
|
|
367
|
-
const regex = /^add\((-?\d+)\)$/;
|
|
368
|
-
const match = propId.match(regex);
|
|
369
|
-
if (match) {
|
|
370
|
-
return Number(result) + Number(match[1]);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
return undefined;
|
|
374
|
-
};
|
|
375
|
-
const propBooleanFunction = (result, propId) => {
|
|
376
|
-
if (typeof result === "boolean") {
|
|
377
|
-
if (propId === "not()") {
|
|
378
|
-
return !result;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
return undefined;
|
|
382
|
-
};
|
|
383
|
-
const propFunctions = [propArrayFunction, propObjectFunction, propStringFunction, propNumberFunction, propBooleanFunction];
|
|
384
|
-
const utilsFunctions = (input, nodes) => {
|
|
385
|
-
if (input === "@now" || input === "@now_ms") {
|
|
386
|
-
return Date.now();
|
|
387
|
-
}
|
|
388
|
-
if (input === "@now_s") {
|
|
389
|
-
return Math.floor(Date.now() / 1000);
|
|
390
|
-
}
|
|
391
|
-
if (input === "@loop") {
|
|
392
|
-
return nodes[loopCounterKey].result;
|
|
393
|
-
}
|
|
394
|
-
// If a placeholder does not match any key, replace it with an empty string.
|
|
395
|
-
GraphAILogger.warn("not match template utility function: ${" + input + "}");
|
|
396
|
-
return "";
|
|
397
|
-
};
|
|
398
|
-
|
|
399
404
|
const getNestedData = (result, propId, propFunctions) => {
|
|
400
405
|
const match = propId.match(propFunctionRegex);
|
|
401
406
|
if (match) {
|
|
@@ -477,7 +482,8 @@ const resultsOfInner = (input, nodes, propFunctions, isSelfNode = false) => {
|
|
|
477
482
|
return replaceTemplatePlaceholders(input, templateMatch, nodes, propFunctions, isSelfNode);
|
|
478
483
|
}
|
|
479
484
|
}
|
|
480
|
-
|
|
485
|
+
// :node.prod
|
|
486
|
+
return resultOf(parseNodeName(input, isSelfNode, nodes), nodes, propFunctions);
|
|
481
487
|
};
|
|
482
488
|
const resultsOf = (inputs, nodes, propFunctions, isSelfNode = false) => {
|
|
483
489
|
return Object.keys(inputs).reduce((tmp, key) => {
|
|
@@ -587,7 +593,7 @@ class ComputedNode extends Node {
|
|
|
587
593
|
this.output = data.output;
|
|
588
594
|
this.dataSources = [
|
|
589
595
|
...(data.inputs ? inputs2dataSources(data.inputs).flat(10) : []),
|
|
590
|
-
...(data.params ? inputs2dataSources(data.params).flat(10) : []),
|
|
596
|
+
// ...(data.params ? inputs2dataSources(data.params).flat(10) : []),
|
|
591
597
|
...(this.agentId ? [parseNodeName(this.agentId)] : []),
|
|
592
598
|
...(data.passThrough ? inputs2dataSources(data.passThrough).flat(10) : []),
|
|
593
599
|
];
|
|
@@ -863,7 +869,8 @@ class ComputedNode extends Node {
|
|
|
863
869
|
// From graphAgent(nested, map), set the instance of graphai, and use abort on the child graphai.
|
|
864
870
|
this.debugInfo = this.getDebugInfo(agentId);
|
|
865
871
|
const context = {
|
|
866
|
-
params: this.graph.resultsOf(this.params),
|
|
872
|
+
//params: this.graph.resultsOf(this.params),
|
|
873
|
+
params: this.params,
|
|
867
874
|
namedInputs: previousResults,
|
|
868
875
|
inputSchema: this.agentFunction ? undefined : this.graph.getAgentFunctionInfo(agentId)?.inputs,
|
|
869
876
|
debugInfo: this.debugInfo,
|
|
@@ -1361,9 +1368,9 @@ class GraphAI {
|
|
|
1361
1368
|
.join("\n");
|
|
1362
1369
|
}
|
|
1363
1370
|
// Public API
|
|
1364
|
-
results(all) {
|
|
1371
|
+
results(all, internalUse = false) {
|
|
1365
1372
|
return Object.keys(this.nodes)
|
|
1366
|
-
.filter((nodeId) => (all && nodeId !== loopCounterKey) || this.nodes[nodeId].isResult)
|
|
1373
|
+
.filter((nodeId) => (all && (internalUse || nodeId !== loopCounterKey)) || this.nodes[nodeId].isResult)
|
|
1367
1374
|
.reduce((results, nodeId) => {
|
|
1368
1375
|
const node = this.nodes[nodeId];
|
|
1369
1376
|
if (node.result !== undefined) {
|
|
@@ -1482,12 +1489,12 @@ class GraphAI {
|
|
|
1482
1489
|
return false;
|
|
1483
1490
|
}
|
|
1484
1491
|
// We need to update static nodes, before checking the condition
|
|
1485
|
-
const previousResults = this.results(true); // results from previous loop
|
|
1492
|
+
const previousResults = this.results(true, true); // results from previous loop
|
|
1486
1493
|
this.updateStaticNodes(previousResults);
|
|
1487
1494
|
if (loop.count === undefined || this.repeatCount < loop.count) {
|
|
1488
1495
|
if (loop.while) {
|
|
1489
1496
|
const source = parseNodeName(loop.while);
|
|
1490
|
-
const value = this.getValueFromResults(source, this.results(true));
|
|
1497
|
+
const value = this.getValueFromResults(source, this.results(true, true));
|
|
1491
1498
|
// NOTE: We treat an empty array as false.
|
|
1492
1499
|
if (!isLogicallyTrue(value)) {
|
|
1493
1500
|
return false; // while condition is not met
|