graphai 0.5.3 → 0.5.5
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.d.ts +2 -1
- package/lib/graphai.js +16 -3
- package/lib/node.d.ts +6 -1
- package/lib/node.js +79 -79
- package/lib/transaction_log.js +4 -1
- package/lib/utils/nodeUtils.d.ts +3 -0
- package/lib/utils/nodeUtils.js +24 -0
- package/package.json +1 -1
package/lib/graphai.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ export declare class GraphAI {
|
|
|
46
46
|
updateLog(log: TransactionLog): void;
|
|
47
47
|
transactionLogs(): TransactionLog[];
|
|
48
48
|
injectValue(nodeId: string, value: ResultData, injectFrom?: string): void;
|
|
49
|
-
resultsOf(sources:
|
|
49
|
+
resultsOf(sources: Record<string, DataSource | DataSource[]>): Record<string, ResultData>;
|
|
50
|
+
resultOf(source: DataSource): ResultData;
|
|
50
51
|
}
|
|
51
52
|
export {};
|
package/lib/graphai.js
CHANGED
|
@@ -253,10 +253,23 @@ class GraphAI {
|
|
|
253
253
|
}
|
|
254
254
|
}
|
|
255
255
|
resultsOf(sources) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
256
|
+
const ret = {};
|
|
257
|
+
Object.keys(sources).forEach((key) => {
|
|
258
|
+
const source = sources[key];
|
|
259
|
+
if (Array.isArray(source)) {
|
|
260
|
+
ret[key] = source.map((s) => {
|
|
261
|
+
return this.resultOf(s);
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
ret[key] = this.resultOf(source);
|
|
266
|
+
}
|
|
259
267
|
});
|
|
268
|
+
return ret;
|
|
269
|
+
}
|
|
270
|
+
resultOf(source) {
|
|
271
|
+
const { result } = source.nodeId ? this.nodes[source.nodeId] : { result: undefined };
|
|
272
|
+
return (0, utils_1.getDataFromSource)(result, source);
|
|
260
273
|
}
|
|
261
274
|
}
|
|
262
275
|
exports.GraphAI = GraphAI;
|
package/lib/node.d.ts
CHANGED
|
@@ -28,7 +28,8 @@ export declare class ComputedNode extends Node {
|
|
|
28
28
|
error?: Error;
|
|
29
29
|
transactionId: undefined | number;
|
|
30
30
|
readonly anyInput: boolean;
|
|
31
|
-
dataSources:
|
|
31
|
+
dataSources: Record<string, DataSource | DataSource[]>;
|
|
32
|
+
private inputs?;
|
|
32
33
|
inputNames?: Array<string>;
|
|
33
34
|
pendings: Set<string>;
|
|
34
35
|
private ifSource?;
|
|
@@ -38,6 +39,7 @@ export declare class ComputedNode extends Node {
|
|
|
38
39
|
readonly isComputedNode = true;
|
|
39
40
|
constructor(graphId: string, nodeId: string, data: ComputedNodeData, graph: GraphAI);
|
|
40
41
|
getAgentId(): string;
|
|
42
|
+
private addPengindNode;
|
|
41
43
|
isReadyNode(): boolean;
|
|
42
44
|
private retry;
|
|
43
45
|
private checkDataAvailability;
|
|
@@ -50,6 +52,9 @@ export declare class ComputedNode extends Node {
|
|
|
50
52
|
execute(): Promise<void>;
|
|
51
53
|
private prepareExecute;
|
|
52
54
|
private errorProcess;
|
|
55
|
+
private getNamedInput;
|
|
56
|
+
private getInputs;
|
|
57
|
+
private getDebugInfo;
|
|
53
58
|
}
|
|
54
59
|
export declare class StaticNode extends Node {
|
|
55
60
|
value?: ResultData;
|
package/lib/node.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StaticNode = exports.ComputedNode = exports.Node = void 0;
|
|
4
4
|
const utils_1 = require("./utils/utils");
|
|
5
|
+
const nodeUtils_1 = require("./utils/nodeUtils");
|
|
5
6
|
const type_1 = require("./type");
|
|
6
7
|
const utils_2 = require("./utils/utils");
|
|
7
8
|
const transaction_log_1 = require("./transaction_log");
|
|
@@ -34,6 +35,7 @@ class ComputedNode extends Node {
|
|
|
34
35
|
constructor(graphId, nodeId, data, graph) {
|
|
35
36
|
super(nodeId, graph);
|
|
36
37
|
this.retryCount = 0;
|
|
38
|
+
this.dataSources = {}; // data sources.
|
|
37
39
|
this.isStaticNode = false;
|
|
38
40
|
this.isComputedNode = true;
|
|
39
41
|
this.graphId = graphId;
|
|
@@ -45,19 +47,20 @@ class ComputedNode extends Node {
|
|
|
45
47
|
this.isResult = data.isResult ?? false;
|
|
46
48
|
this.priority = data.priority ?? 0;
|
|
47
49
|
this.anyInput = data.anyInput ?? false;
|
|
48
|
-
if (
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
this.inputNames = keys;
|
|
58
|
-
this.dataSources = keys.map((key) => (0, utils_2.parseNodeName)(inputs[key], graph.version));
|
|
50
|
+
if (data.inputs) {
|
|
51
|
+
if (Array.isArray(data.inputs)) {
|
|
52
|
+
this.inputs = data.inputs;
|
|
53
|
+
this.dataSources = (0, nodeUtils_1.inputs2dataSources)(data.inputs, graph.version);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
this.inputNames = Object.keys(data.inputs);
|
|
57
|
+
this.dataSources = (0, nodeUtils_1.namedInputs2dataSources)(data.inputs, graph.version);
|
|
58
|
+
}
|
|
59
59
|
}
|
|
60
|
-
this.pendings = new Set(this.dataSources
|
|
60
|
+
this.pendings = new Set(Object.values(this.dataSources)
|
|
61
|
+
.flat()
|
|
62
|
+
.filter((source) => source.nodeId)
|
|
63
|
+
.map((source) => source.nodeId));
|
|
61
64
|
if (typeof data.agent === "string") {
|
|
62
65
|
this.agentId = data.agent;
|
|
63
66
|
}
|
|
@@ -76,23 +79,16 @@ class ComputedNode extends Node {
|
|
|
76
79
|
}
|
|
77
80
|
}
|
|
78
81
|
if (typeof data.graph === "string") {
|
|
79
|
-
|
|
80
|
-
(0, utils_2.assert)(!!source.nodeId, `Invalid data source ${data.graph}`);
|
|
81
|
-
this.pendings.add(source.nodeId);
|
|
82
|
-
this.nestedGraph = source;
|
|
82
|
+
this.nestedGraph = this.addPengindNode(data.graph);
|
|
83
83
|
}
|
|
84
84
|
else if (data.graph) {
|
|
85
85
|
this.nestedGraph = data.graph;
|
|
86
86
|
}
|
|
87
87
|
if (data.if) {
|
|
88
|
-
this.ifSource =
|
|
89
|
-
(0, utils_2.assert)(!!this.ifSource.nodeId, `Invalid data source ${data.if}`);
|
|
90
|
-
this.pendings.add(this.ifSource.nodeId);
|
|
88
|
+
this.ifSource = this.addPengindNode(data.if);
|
|
91
89
|
}
|
|
92
90
|
if (data.unless) {
|
|
93
|
-
this.unlessSource =
|
|
94
|
-
(0, utils_2.assert)(!!this.unlessSource.nodeId, `Invalid data source ${data.unless}`);
|
|
95
|
-
this.pendings.add(this.unlessSource.nodeId);
|
|
91
|
+
this.unlessSource = this.addPengindNode(data.unless);
|
|
96
92
|
}
|
|
97
93
|
this.dynamicParams = Object.keys(this.params).reduce((tmp, key) => {
|
|
98
94
|
const dataSource = (0, utils_2.parseNodeName)(this.params[key], graph.version < 0.3 ? 0.3 : graph.version);
|
|
@@ -108,36 +104,29 @@ class ComputedNode extends Node {
|
|
|
108
104
|
getAgentId() {
|
|
109
105
|
return this.agentId ?? "__custom__function"; // only for display purpose in the log.
|
|
110
106
|
}
|
|
107
|
+
addPengindNode(nodeId) {
|
|
108
|
+
const source = (0, utils_2.parseNodeName)(nodeId, this.graph.version);
|
|
109
|
+
(0, utils_2.assert)(!!source.nodeId, `Invalid data source ${nodeId}`);
|
|
110
|
+
this.pendings.add(source.nodeId);
|
|
111
|
+
return source;
|
|
112
|
+
}
|
|
111
113
|
isReadyNode() {
|
|
112
|
-
if (this.state
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (!this.anyInput || counter > 0) {
|
|
121
|
-
if (this.ifSource) {
|
|
122
|
-
const [condition] = this.graph.resultsOf([this.ifSource]);
|
|
123
|
-
if (!(0, utils_2.isLogicallyTrue)(condition)) {
|
|
124
|
-
this.state = type_1.NodeState.Skipped;
|
|
125
|
-
this.log.onSkipped(this, this.graph);
|
|
126
|
-
return false;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
if (this.unlessSource) {
|
|
130
|
-
const [condition] = this.graph.resultsOf([this.unlessSource]);
|
|
131
|
-
if ((0, utils_2.isLogicallyTrue)(condition)) {
|
|
132
|
-
this.state = type_1.NodeState.Skipped;
|
|
133
|
-
this.log.onSkipped(this, this.graph);
|
|
134
|
-
return false;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
return true;
|
|
138
|
-
}
|
|
114
|
+
if (this.state !== type_1.NodeState.Waiting || this.pendings.size !== 0) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
// Count the number of data actually available.
|
|
118
|
+
// We care it only when this.anyInput is true.
|
|
119
|
+
// Notice that this logic enables dynamic data-flows.
|
|
120
|
+
if (this.anyInput && !this.checkDataAvailability(false)) {
|
|
121
|
+
return false;
|
|
139
122
|
}
|
|
140
|
-
|
|
123
|
+
if ((this.ifSource && !(0, utils_2.isLogicallyTrue)(this.graph.resultOf(this.ifSource))) ||
|
|
124
|
+
(this.unlessSource && (0, utils_2.isLogicallyTrue)(this.graph.resultOf(this.unlessSource)))) {
|
|
125
|
+
this.state = type_1.NodeState.Skipped;
|
|
126
|
+
this.log.onSkipped(this, this.graph);
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
return true;
|
|
141
130
|
}
|
|
142
131
|
// This private method (only called while executing execute()) performs
|
|
143
132
|
// the "retry" if specified. The transaction log must be updated before
|
|
@@ -156,12 +145,13 @@ class ComputedNode extends Node {
|
|
|
156
145
|
this.graph.onExecutionComplete(this);
|
|
157
146
|
}
|
|
158
147
|
}
|
|
159
|
-
checkDataAvailability() {
|
|
160
|
-
(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
148
|
+
checkDataAvailability(checkAnyInput = true) {
|
|
149
|
+
if (checkAnyInput) {
|
|
150
|
+
(0, utils_2.assert)(this.anyInput, "checkDataAvailability should be called only for anyInput case");
|
|
151
|
+
}
|
|
152
|
+
return Object.values(this.graph.resultsOf(this.dataSources))
|
|
153
|
+
.flat()
|
|
154
|
+
.some((result) => result !== undefined);
|
|
165
155
|
}
|
|
166
156
|
// This method is called right before the Graph add this node to the task manager.
|
|
167
157
|
beforeAddTask() {
|
|
@@ -228,12 +218,9 @@ class ComputedNode extends Node {
|
|
|
228
218
|
// then it removes itself from the "running node" list of the graph.
|
|
229
219
|
// Notice that setting the result of this node may make other nodes ready to run.
|
|
230
220
|
async execute() {
|
|
231
|
-
const previousResults = this.graph.resultsOf(this.dataSources)
|
|
232
|
-
// Remove undefined if anyInput flag is set.
|
|
233
|
-
return !this.anyInput || result !== undefined;
|
|
234
|
-
});
|
|
221
|
+
const previousResults = this.graph.resultsOf(this.dataSources);
|
|
235
222
|
const transactionId = Date.now();
|
|
236
|
-
this.prepareExecute(transactionId, previousResults);
|
|
223
|
+
this.prepareExecute(transactionId, Object.values(previousResults));
|
|
237
224
|
if (this.timeout && this.timeout > 0) {
|
|
238
225
|
setTimeout(() => {
|
|
239
226
|
this.executeTimeout(transactionId);
|
|
@@ -243,34 +230,21 @@ class ComputedNode extends Node {
|
|
|
243
230
|
const agentFunction = this.agentFunction ?? this.graph.getAgentFunctionInfo(this.agentId).agent;
|
|
244
231
|
const localLog = [];
|
|
245
232
|
const params = Object.keys(this.dynamicParams).reduce((tmp, key) => {
|
|
246
|
-
const
|
|
233
|
+
const result = this.graph.resultOf(this.dynamicParams[key]);
|
|
247
234
|
tmp[key] = result;
|
|
248
235
|
return tmp;
|
|
249
236
|
}, { ...this.params });
|
|
250
237
|
const context = {
|
|
251
238
|
params: params,
|
|
252
|
-
inputs: previousResults,
|
|
239
|
+
inputs: this.getInputs(previousResults),
|
|
240
|
+
namedInputs: this.getNamedInput(previousResults),
|
|
253
241
|
inputSchema: this.agentFunction ? undefined : this.graph.getAgentFunctionInfo(this.agentId)?.inputs,
|
|
254
|
-
|
|
255
|
-
debugInfo: {
|
|
256
|
-
nodeId: this.nodeId,
|
|
257
|
-
agentId: this.agentId,
|
|
258
|
-
retry: this.retryCount,
|
|
259
|
-
verbose: this.graph.verbose,
|
|
260
|
-
version: this.graph.version,
|
|
261
|
-
},
|
|
242
|
+
debugInfo: this.getDebugInfo(),
|
|
262
243
|
filterParams: this.filterParams,
|
|
263
244
|
agentFilters: this.graph.agentFilters,
|
|
264
245
|
config: this.graph.config,
|
|
265
246
|
log: localLog,
|
|
266
247
|
};
|
|
267
|
-
if (this.inputNames) {
|
|
268
|
-
context.namedInputs = this.inputNames.reduce((tmp, name, index) => {
|
|
269
|
-
tmp[name] = previousResults[index];
|
|
270
|
-
return tmp;
|
|
271
|
-
}, {});
|
|
272
|
-
context.inputs = [];
|
|
273
|
-
}
|
|
274
248
|
// NOTE: We use the existence of graph object in the agent-specific params to determine
|
|
275
249
|
// if this is a nested agent or not.
|
|
276
250
|
if (this.nestedGraph) {
|
|
@@ -280,7 +254,7 @@ class ComputedNode extends Node {
|
|
|
280
254
|
context.graphData = this.nestedGraph;
|
|
281
255
|
}
|
|
282
256
|
else {
|
|
283
|
-
const
|
|
257
|
+
const graphData = this.graph.resultOf(this.nestedGraph);
|
|
284
258
|
context.graphData = graphData; // HACK: compiler work-around
|
|
285
259
|
}
|
|
286
260
|
context.agents = this.graph.agentFunctionInfoDictionary;
|
|
@@ -339,6 +313,32 @@ class ComputedNode extends Node {
|
|
|
339
313
|
this.retry(type_1.NodeState.Failed, Error("Unknown"));
|
|
340
314
|
}
|
|
341
315
|
}
|
|
316
|
+
getNamedInput(previousResults) {
|
|
317
|
+
if (this.inputNames) {
|
|
318
|
+
return this.inputNames.reduce((tmp, name) => {
|
|
319
|
+
if (!this.anyInput || previousResults[name]) {
|
|
320
|
+
tmp[name] = previousResults[name];
|
|
321
|
+
}
|
|
322
|
+
return tmp;
|
|
323
|
+
}, {});
|
|
324
|
+
}
|
|
325
|
+
return {};
|
|
326
|
+
}
|
|
327
|
+
getInputs(previousResults) {
|
|
328
|
+
if (this.inputNames) {
|
|
329
|
+
return [];
|
|
330
|
+
}
|
|
331
|
+
return (this.inputs ?? []).map((key) => previousResults[String(key)]).filter((a) => !this.anyInput || a);
|
|
332
|
+
}
|
|
333
|
+
getDebugInfo() {
|
|
334
|
+
return {
|
|
335
|
+
nodeId: this.nodeId,
|
|
336
|
+
agentId: this.agentId,
|
|
337
|
+
retry: this.retryCount,
|
|
338
|
+
verbose: this.graph.verbose,
|
|
339
|
+
version: this.graph.version,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
342
|
}
|
|
343
343
|
exports.ComputedNode = ComputedNode;
|
|
344
344
|
class StaticNode extends Node {
|
package/lib/transaction_log.js
CHANGED
|
@@ -43,7 +43,10 @@ class TransactionLog {
|
|
|
43
43
|
this.state = node.state;
|
|
44
44
|
this.retryCount = node.retryCount > 0 ? node.retryCount : undefined;
|
|
45
45
|
this.startTime = transactionId;
|
|
46
|
-
this.inputs = node.dataSources
|
|
46
|
+
this.inputs = Object.values(node.dataSources)
|
|
47
|
+
.flat()
|
|
48
|
+
.filter((source) => source.nodeId)
|
|
49
|
+
.map((source) => source.nodeId);
|
|
47
50
|
this.inputsData = inputs.length > 0 ? inputs : undefined;
|
|
48
51
|
graph.setLoopLog(this);
|
|
49
52
|
graph.appendLog(this);
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { DataSource } from "../type";
|
|
2
|
+
export declare const inputs2dataSources: (inputs: string[], graphVersion: number) => Record<string, DataSource>;
|
|
3
|
+
export declare const namedInputs2dataSources: (inputs: Record<string, any>, graphVersion: number) => Record<string, DataSource | DataSource[]>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.namedInputs2dataSources = exports.inputs2dataSources = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
const inputs2dataSources = (inputs, graphVersion) => {
|
|
6
|
+
return inputs.reduce((tmp, input) => {
|
|
7
|
+
tmp[input] = (0, utils_1.parseNodeName)(input, graphVersion);
|
|
8
|
+
return tmp;
|
|
9
|
+
}, {});
|
|
10
|
+
};
|
|
11
|
+
exports.inputs2dataSources = inputs2dataSources;
|
|
12
|
+
const namedInputs2dataSources = (inputs, graphVersion) => {
|
|
13
|
+
return Object.keys(inputs).reduce((tmp, key) => {
|
|
14
|
+
const input = inputs[key];
|
|
15
|
+
if (Array.isArray(input)) {
|
|
16
|
+
tmp[key] = input.map((inp) => (0, utils_1.parseNodeName)(inp, graphVersion));
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
tmp[key] = (0, utils_1.parseNodeName)(input, graphVersion);
|
|
20
|
+
}
|
|
21
|
+
return tmp;
|
|
22
|
+
}, {});
|
|
23
|
+
};
|
|
24
|
+
exports.namedInputs2dataSources = namedInputs2dataSources;
|