graphai 0.0.12 → 0.1.1
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/README.md +14 -10
- package/lib/experimental_agents/array_agents/index.d.ts +3 -0
- package/lib/experimental_agents/array_agents/index.js +9 -0
- package/lib/experimental_agents/array_agents/pop_agent.d.ts +2 -0
- package/lib/experimental_agents/array_agents/pop_agent.js +15 -0
- package/lib/experimental_agents/array_agents/push_agent.d.ts +2 -0
- package/lib/experimental_agents/array_agents/push_agent.js +14 -0
- package/lib/experimental_agents/array_agents/shift_agent.d.ts +2 -0
- package/lib/experimental_agents/{array_agents.js → array_agents/shift_agent.js} +2 -17
- package/lib/experimental_agents/data_agents/data_object_merge_template_agent.d.ts +2 -0
- package/lib/experimental_agents/data_agents/data_object_merge_template_agent.js +13 -0
- package/lib/experimental_agents/data_agents/data_sum_template_agent.d.ts +17 -0
- package/lib/experimental_agents/data_agents/data_sum_template_agent.js +30 -0
- package/lib/experimental_agents/data_agents/index.d.ts +3 -0
- package/lib/experimental_agents/data_agents/index.js +9 -0
- package/lib/experimental_agents/data_agents/total_agent.d.ts +46 -0
- package/lib/experimental_agents/data_agents/total_agent.js +51 -0
- package/lib/experimental_agents/embedding_agent.d.ts +6 -0
- package/lib/experimental_agents/embedding_agent.js +43 -0
- package/lib/experimental_agents/index.d.ts +8 -3
- package/lib/experimental_agents/index.js +8 -3
- package/lib/experimental_agents/map_agent.d.ts +4 -0
- package/lib/experimental_agents/map_agent.js +46 -0
- package/lib/experimental_agents/matrix_agent.d.ts +9 -0
- package/lib/experimental_agents/matrix_agent.js +50 -0
- package/lib/experimental_agents/nested_agent.d.ts +2 -2
- package/lib/experimental_agents/nested_agent.js +14 -8
- package/lib/experimental_agents/slashgpt_agent.d.ts +1 -1
- package/lib/experimental_agents/slashgpt_agent.js +2 -7
- package/lib/experimental_agents/sleeper_agents/index.d.ts +2 -0
- package/lib/experimental_agents/sleeper_agents/index.js +7 -0
- package/lib/experimental_agents/sleeper_agents/sleeper_agent.d.ts +5 -0
- package/lib/experimental_agents/sleeper_agents/sleeper_agent.js +16 -0
- package/lib/experimental_agents/sleeper_agents/sleeper_agent_debug.d.ts +6 -0
- package/lib/experimental_agents/{sleeper_agent.js → sleeper_agents/sleeper_agent_debug.js} +4 -13
- package/lib/experimental_agents/string_agents/index.d.ts +2 -0
- package/lib/experimental_agents/string_agents/index.js +7 -0
- package/lib/experimental_agents/string_agents/string_splitter_agent.d.ts +7 -0
- package/lib/experimental_agents/string_agents/string_splitter_agent.js +24 -0
- package/lib/experimental_agents/string_agents/string_template_agent.d.ts +4 -0
- package/lib/experimental_agents/{string_agent.js → string_agents/string_template_agent.js} +2 -5
- package/lib/experimental_agents/test_agents/bypass_agent.d.ts +2 -0
- package/lib/experimental_agents/test_agents/bypass_agent.js +10 -0
- package/lib/experimental_agents/test_agents/copy_message_agent.d.ts +2 -0
- package/lib/experimental_agents/test_agents/copy_message_agent.js +11 -0
- package/lib/experimental_agents/test_agents/counting_agent.d.ts +2 -0
- package/lib/experimental_agents/test_agents/counting_agent.js +11 -0
- package/lib/experimental_agents/test_agents/echo_agent.d.ts +2 -0
- package/lib/experimental_agents/test_agents/echo_agent.js +7 -0
- package/lib/experimental_agents/test_agents/echo_fork_index_agent.d.ts +2 -0
- package/lib/experimental_agents/test_agents/echo_fork_index_agent.js +7 -0
- package/lib/experimental_agents/test_agents/index.d.ts +5 -0
- package/lib/experimental_agents/test_agents/index.js +13 -0
- package/lib/experimental_agents/test_agents/merge_node_id_agent.d.ts +2 -0
- package/lib/experimental_agents/test_agents/merge_node_id_agent.js +10 -0
- package/lib/experimental_agents/token_agent.d.ts +6 -0
- package/lib/experimental_agents/token_agent.js +33 -0
- package/lib/graphai.d.ts +28 -111
- package/lib/graphai.js +140 -322
- package/lib/index.d.ts +2 -0
- package/lib/log.d.ts +22 -0
- package/lib/log.js +49 -0
- package/lib/node.d.ts +50 -0
- package/lib/node.js +218 -0
- package/lib/task.d.ts +18 -0
- package/lib/task.js +63 -0
- package/lib/task_manager.d.ts +20 -0
- package/lib/task_manager.js +69 -0
- package/lib/transaction_log.d.ts +27 -0
- package/lib/transaction_log.js +56 -0
- package/lib/type.d.ts +77 -0
- package/lib/type.js +14 -0
- package/lib/utils/utils.d.ts +4 -0
- package/lib/utils/utils.js +22 -1
- package/lib/validator.d.ts +2 -0
- package/lib/validator.js +28 -0
- package/lib/validators/agent_validator.d.ts +1 -0
- package/lib/validators/agent_validator.js +12 -0
- package/lib/validators/common.d.ts +3 -0
- package/lib/validators/common.js +6 -0
- package/lib/validators/computed_node_validator.d.ts +2 -0
- package/lib/validators/computed_node_validator.js +13 -0
- package/lib/validators/graph_data_validator.d.ts +3 -0
- package/lib/validators/graph_data_validator.js +43 -0
- package/lib/validators/nodeValidator.d.ts +2 -0
- package/lib/validators/nodeValidator.js +13 -0
- package/lib/validators/relation_validator.d.ts +2 -0
- package/lib/validators/relation_validator.js +62 -0
- package/lib/validators/static_node_validator.d.ts +2 -0
- package/lib/validators/static_node_validator.js +13 -0
- package/package.json +3 -5
- package/lib/experimental_agents/array_agents.d.ts +0 -4
- package/lib/experimental_agents/data_agent.d.ts +0 -3
- package/lib/experimental_agents/data_agent.js +0 -25
- package/lib/experimental_agents/sleeper_agent.d.ts +0 -10
- package/lib/experimental_agents/string_agent.d.ts +0 -7
- package/lib/graphai_cli.d.ts +0 -2
- package/lib/graphai_cli.js +0 -37
package/lib/graphai.js
CHANGED
|
@@ -1,301 +1,88 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var NodeState;
|
|
5
|
-
(function (NodeState) {
|
|
6
|
-
NodeState["Waiting"] = "waiting";
|
|
7
|
-
NodeState["Executing"] = "executing";
|
|
8
|
-
NodeState["Failed"] = "failed";
|
|
9
|
-
NodeState["TimedOut"] = "timed-out";
|
|
10
|
-
NodeState["Completed"] = "completed";
|
|
11
|
-
NodeState["Injected"] = "injected";
|
|
12
|
-
NodeState["Dispatched"] = "dispatched";
|
|
13
|
-
})(NodeState || (exports.NodeState = NodeState = {}));
|
|
14
|
-
const parseNodeName = (name) => {
|
|
15
|
-
const parts = name.split(".");
|
|
16
|
-
if (parts.length == 1) {
|
|
17
|
-
return { sourceNodeId: parts[0] };
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
return { sourceNodeId: parts[0], propId: parts[1] };
|
|
21
|
-
}
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
4
|
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
this.forkIndex = forkIndex;
|
|
32
|
-
this.inputs = (data.inputs ?? []).map((input) => {
|
|
33
|
-
const { sourceNodeId, propId } = parseNodeName(input);
|
|
34
|
-
if (propId) {
|
|
35
|
-
this.inputProps[sourceNodeId] = propId;
|
|
36
|
-
}
|
|
37
|
-
return sourceNodeId;
|
|
38
|
-
});
|
|
39
|
-
this.pendings = new Set(this.inputs);
|
|
40
|
-
this.params = data.params ?? {};
|
|
41
|
-
this.agentId = data.agentId ?? graph.agentId;
|
|
42
|
-
this.fork = data.fork;
|
|
43
|
-
this.retryLimit = data.retry ?? 0;
|
|
44
|
-
this.timeout = data.timeout;
|
|
45
|
-
this.source = this.agentId === undefined;
|
|
46
|
-
this.outputs = data.outputs;
|
|
47
|
-
this.graph = graph;
|
|
48
|
-
}
|
|
49
|
-
asString() {
|
|
50
|
-
return `${this.nodeId}: ${this.state} ${[...this.waitlist]}`;
|
|
51
|
-
}
|
|
52
|
-
retry(state, error) {
|
|
53
|
-
if (this.retryCount < this.retryLimit) {
|
|
54
|
-
this.retryCount++;
|
|
55
|
-
this.execute();
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
this.state = state;
|
|
59
|
-
this.result = undefined;
|
|
60
|
-
this.error = error;
|
|
61
|
-
this.transactionId = undefined; // This is necessary for timeout case
|
|
62
|
-
this.graph.removeRunning(this);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
removePending(nodeId) {
|
|
66
|
-
this.pendings.delete(nodeId);
|
|
67
|
-
if (this.graph.isRunning) {
|
|
68
|
-
this.pushQueueIfReady();
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
pushQueueIfReady() {
|
|
72
|
-
if (this.pendings.size === 0 && !this.source) {
|
|
73
|
-
// If input property is specified, we need to ensure that the property value exists.
|
|
74
|
-
Object.keys(this.inputProps).forEach((nodeId) => {
|
|
75
|
-
const [result] = this.graph.resultsOf([nodeId]);
|
|
76
|
-
const propId = this.inputProps[nodeId];
|
|
77
|
-
if (!result || !(propId in result)) {
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
this.graph.pushQueue(this);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
injectValue(value) {
|
|
85
|
-
if (this.source) {
|
|
86
|
-
const log = {
|
|
87
|
-
nodeId: this.nodeId,
|
|
88
|
-
retryCount: this.retryCount,
|
|
89
|
-
state: NodeState.Injected,
|
|
90
|
-
startTime: Date.now(),
|
|
91
|
-
endTime: Date.now(),
|
|
92
|
-
result: value,
|
|
93
|
-
};
|
|
94
|
-
this.graph.appendLog(log);
|
|
95
|
-
this.setResult(value, NodeState.Injected);
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
console.error("- injectValue called on non-source node.", this.nodeId);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
setResult(result, state) {
|
|
102
|
-
this.state = state;
|
|
103
|
-
this.result = result;
|
|
104
|
-
this.waitlist.forEach((nodeId) => {
|
|
105
|
-
const node = this.graph.nodes[nodeId];
|
|
106
|
-
// Todo: Avoid running before Run()
|
|
107
|
-
node.removePending(this.nodeId);
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
async execute() {
|
|
111
|
-
const results = this.graph.resultsOf(this.inputs);
|
|
112
|
-
this.inputs.forEach((nodeId, index) => {
|
|
113
|
-
const propId = this.inputProps[nodeId];
|
|
114
|
-
if (propId) {
|
|
115
|
-
results[index] = results[index][propId];
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
const transactionId = Date.now();
|
|
119
|
-
const log = {
|
|
120
|
-
nodeId: this.nodeId,
|
|
121
|
-
retryCount: this.retryCount > 0 ? this.retryCount : undefined,
|
|
122
|
-
state: NodeState.Executing,
|
|
123
|
-
startTime: transactionId,
|
|
124
|
-
agentId: this.agentId,
|
|
125
|
-
params: this.params,
|
|
126
|
-
inputs: results.length > 0 ? results : undefined,
|
|
127
|
-
};
|
|
128
|
-
this.graph.appendLog(log);
|
|
129
|
-
this.state = NodeState.Executing;
|
|
130
|
-
this.transactionId = transactionId;
|
|
131
|
-
if (this.timeout && this.timeout > 0) {
|
|
132
|
-
setTimeout(() => {
|
|
133
|
-
if (this.state === NodeState.Executing && this.transactionId === transactionId) {
|
|
134
|
-
console.log(`-- ${this.nodeId}: timeout ${this.timeout}`);
|
|
135
|
-
log.errorMessage = "Timeout";
|
|
136
|
-
log.state = NodeState.TimedOut;
|
|
137
|
-
log.endTime = Date.now();
|
|
138
|
-
this.retry(NodeState.TimedOut, Error("Timeout"));
|
|
139
|
-
}
|
|
140
|
-
}, this.timeout);
|
|
141
|
-
}
|
|
142
|
-
try {
|
|
143
|
-
const callback = this.graph.getCallback(this.agentId);
|
|
144
|
-
const localLog = [];
|
|
145
|
-
const result = await callback({
|
|
146
|
-
nodeId: this.nodeId,
|
|
147
|
-
retry: this.retryCount,
|
|
148
|
-
params: this.params,
|
|
149
|
-
inputs: results,
|
|
150
|
-
forkIndex: this.forkIndex,
|
|
151
|
-
verbose: this.graph.verbose,
|
|
152
|
-
agents: this.graph.callbackDictonary,
|
|
153
|
-
log: localLog,
|
|
154
|
-
});
|
|
155
|
-
if (this.transactionId !== transactionId) {
|
|
156
|
-
console.log(`-- ${this.nodeId}: transactionId mismatch`);
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
log.endTime = Date.now();
|
|
160
|
-
log.result = result;
|
|
161
|
-
if (localLog.length > 0) {
|
|
162
|
-
log.log = localLog;
|
|
163
|
-
}
|
|
164
|
-
const outputs = this.outputs;
|
|
165
|
-
if (outputs !== undefined) {
|
|
166
|
-
Object.keys(outputs).forEach((outputId) => {
|
|
167
|
-
const nodeId = outputs[outputId];
|
|
168
|
-
const value = result[outputId];
|
|
169
|
-
if (value) {
|
|
170
|
-
this.graph.injectValue(nodeId, value);
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
console.error("-- Invalid outputId", outputId, result);
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
log.state = NodeState.Dispatched;
|
|
177
|
-
this.state = NodeState.Dispatched;
|
|
178
|
-
this.graph.removeRunning(this);
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
log.state = NodeState.Completed;
|
|
182
|
-
this.setResult(result, NodeState.Completed);
|
|
183
|
-
this.graph.removeRunning(this);
|
|
184
|
-
}
|
|
185
|
-
catch (error) {
|
|
186
|
-
if (this.transactionId !== transactionId) {
|
|
187
|
-
console.log(`-- ${this.nodeId}: transactionId mismatch(error)`);
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
log.state = NodeState.Failed;
|
|
191
|
-
log.endTime = Date.now();
|
|
192
|
-
if (error instanceof Error) {
|
|
193
|
-
log.errorMessage = error.message;
|
|
194
|
-
this.retry(NodeState.Failed, error);
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
console.error(`-- ${this.nodeId}: Unexpecrted error was caught`);
|
|
198
|
-
log.errorMessage = "Unknown";
|
|
199
|
-
this.retry(NodeState.Failed, Error("Unknown"));
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.GraphAI = void 0;
|
|
7
|
+
const type_1 = require("./type");
|
|
8
|
+
const node_1 = require("./node");
|
|
9
|
+
const utils_1 = require("./utils/utils");
|
|
10
|
+
const validator_1 = require("./validator");
|
|
11
|
+
const task_manager_1 = require("./task_manager");
|
|
12
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
204
13
|
const defaultConcurrency = 8;
|
|
205
14
|
class GraphAI {
|
|
15
|
+
// This method is called when either the GraphAI obect was created,
|
|
16
|
+
// or we are about to start n-th iteration (n>2).
|
|
206
17
|
createNodes(data) {
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if (fork) {
|
|
212
|
-
// For fork, change the nodeId and increase the node
|
|
213
|
-
nodeId2forkedNodeIds[nodeId] = new Array(fork).fill(undefined).map((_, i) => {
|
|
214
|
-
const forkedNodeId = `${nodeId}_${i}`;
|
|
215
|
-
nodes[forkedNodeId] = new Node(forkedNodeId, i, data.nodes[nodeId], this);
|
|
216
|
-
// Data for pending and waiting
|
|
217
|
-
forkedNodeId2Index[forkedNodeId] = i;
|
|
218
|
-
return forkedNodeId;
|
|
219
|
-
});
|
|
18
|
+
const nodes = Object.keys(data.nodes).reduce((_nodes, nodeId) => {
|
|
19
|
+
const isStaticNode = "value" in data.nodes[nodeId];
|
|
20
|
+
if (isStaticNode) {
|
|
21
|
+
_nodes[nodeId] = new node_1.StaticNode(nodeId, data.nodes[nodeId], this);
|
|
220
22
|
}
|
|
221
23
|
else {
|
|
222
|
-
|
|
24
|
+
const nodeData = data.nodes[nodeId];
|
|
25
|
+
_nodes[nodeId] = new node_1.ComputedNode(this.graphId, nodeId, nodeData, this);
|
|
223
26
|
}
|
|
224
|
-
return
|
|
27
|
+
return _nodes;
|
|
225
28
|
}, {});
|
|
226
|
-
// Generate the waitlist for each node
|
|
29
|
+
// Generate the waitlist for each node.
|
|
227
30
|
Object.keys(nodes).forEach((nodeId) => {
|
|
228
31
|
const node = nodes[nodeId];
|
|
229
|
-
node.
|
|
230
|
-
|
|
231
|
-
if (nodeId2forkedNodeIds[pending]) {
|
|
232
|
-
// update node.pending and pending(previous) node.wailtlist
|
|
233
|
-
if (node.fork) {
|
|
234
|
-
// 1:1 if current nodes are also forking.
|
|
235
|
-
const newPendingId = nodeId2forkedNodeIds[pending][forkedNodeId2Index[nodeId]];
|
|
236
|
-
nodes[newPendingId].waitlist.add(nodeId); // previousNode
|
|
237
|
-
node.pendings.add(newPendingId);
|
|
238
|
-
}
|
|
239
|
-
else {
|
|
240
|
-
// 1:n if current node is not forking.
|
|
241
|
-
nodeId2forkedNodeIds[pending].forEach((newPendingId) => {
|
|
242
|
-
nodes[newPendingId].waitlist.add(nodeId); // previousNode
|
|
243
|
-
node.pendings.add(newPendingId);
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
node.pendings.delete(pending);
|
|
247
|
-
}
|
|
248
|
-
else {
|
|
32
|
+
if (node.isComputedNode) {
|
|
33
|
+
node.pendings.forEach((pending) => {
|
|
249
34
|
if (nodes[pending]) {
|
|
250
35
|
nodes[pending].waitlist.add(nodeId); // previousNode
|
|
251
36
|
}
|
|
252
37
|
else {
|
|
253
38
|
console.error(`--- invalid input ${pending} for node, ${nodeId}`);
|
|
254
39
|
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
node.inputs = Array.from(node.pendings); // for fork.
|
|
40
|
+
});
|
|
41
|
+
}
|
|
258
42
|
});
|
|
259
43
|
return nodes;
|
|
260
44
|
}
|
|
261
45
|
getValueFromResults(key, results) {
|
|
262
|
-
const
|
|
263
|
-
const result = results[
|
|
264
|
-
return result
|
|
46
|
+
const source = (0, utils_1.parseNodeName)(key);
|
|
47
|
+
const result = results[source.nodeId];
|
|
48
|
+
return result && source.propId ? result[source.propId] : result;
|
|
265
49
|
}
|
|
50
|
+
// for static
|
|
266
51
|
initializeNodes(previousResults) {
|
|
267
52
|
// If the result property is specified, inject it.
|
|
268
53
|
// If the previousResults exists (indicating we are in a loop),
|
|
269
|
-
// process the
|
|
54
|
+
// process the update property (nodeId or nodeId.propId).
|
|
270
55
|
Object.keys(this.data.nodes).forEach((nodeId) => {
|
|
271
|
-
const node = this.
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
if (
|
|
279
|
-
this.
|
|
56
|
+
const node = this.nodes[nodeId];
|
|
57
|
+
if (node?.isStaticNode) {
|
|
58
|
+
const value = node?.value;
|
|
59
|
+
const update = node?.update;
|
|
60
|
+
if (value) {
|
|
61
|
+
this.injectValue(nodeId, value, nodeId);
|
|
62
|
+
}
|
|
63
|
+
if (update && previousResults) {
|
|
64
|
+
const result = this.getValueFromResults(update, previousResults);
|
|
65
|
+
if (result) {
|
|
66
|
+
this.injectValue(nodeId, result, update);
|
|
67
|
+
}
|
|
280
68
|
}
|
|
281
69
|
}
|
|
282
70
|
});
|
|
283
71
|
}
|
|
284
|
-
constructor(data, callbackDictonary) {
|
|
285
|
-
this.isRunning = false;
|
|
286
|
-
this.runningNodes = new Set();
|
|
287
|
-
this.nodeQueue = [];
|
|
288
|
-
this.repeatCount = 0;
|
|
72
|
+
constructor(data, callbackDictonary, taskManager = undefined) {
|
|
289
73
|
this.logs = [];
|
|
74
|
+
this.onLogCallback = (__log, __isUpdate) => { };
|
|
75
|
+
this.repeatCount = 0;
|
|
76
|
+
this.graphId = crypto_1.default.randomUUID();
|
|
290
77
|
this.data = data;
|
|
291
78
|
this.callbackDictonary = callbackDictonary;
|
|
292
|
-
this.
|
|
79
|
+
this.taskManager = taskManager ?? new task_manager_1.TaskManager(data.concurrency ?? defaultConcurrency);
|
|
293
80
|
this.loop = data.loop;
|
|
294
|
-
this.agentId = data.agentId;
|
|
295
81
|
this.verbose = data.verbose === true;
|
|
296
82
|
this.onComplete = () => {
|
|
297
83
|
console.error("-- SOMETHING IS WRONG: onComplete is called without run()");
|
|
298
84
|
};
|
|
85
|
+
(0, validator_1.validateGraphData)(data, Object.keys(callbackDictonary));
|
|
299
86
|
this.nodes = this.createNodes(data);
|
|
300
87
|
this.initializeNodes();
|
|
301
88
|
}
|
|
@@ -306,14 +93,18 @@ class GraphAI {
|
|
|
306
93
|
throw new Error("No agent: " + agentId);
|
|
307
94
|
}
|
|
308
95
|
asString() {
|
|
309
|
-
return Object.
|
|
310
|
-
.map((
|
|
311
|
-
return this.nodes[nodeId].asString();
|
|
312
|
-
})
|
|
96
|
+
return Object.values(this.nodes)
|
|
97
|
+
.map((node) => node.asString())
|
|
313
98
|
.join("\n");
|
|
314
99
|
}
|
|
315
|
-
|
|
316
|
-
|
|
100
|
+
// Public API
|
|
101
|
+
results(all) {
|
|
102
|
+
return Object.keys(this.nodes)
|
|
103
|
+
.filter((nodeId) => {
|
|
104
|
+
const node = this.nodes[nodeId];
|
|
105
|
+
return all || node.isResult;
|
|
106
|
+
})
|
|
107
|
+
.reduce((results, nodeId) => {
|
|
317
108
|
const node = this.nodes[nodeId];
|
|
318
109
|
if (node.result !== undefined) {
|
|
319
110
|
results[nodeId] = node.result;
|
|
@@ -321,11 +112,14 @@ class GraphAI {
|
|
|
321
112
|
return results;
|
|
322
113
|
}, {});
|
|
323
114
|
}
|
|
115
|
+
// Public API
|
|
324
116
|
errors() {
|
|
325
117
|
return Object.keys(this.nodes).reduce((errors, nodeId) => {
|
|
326
118
|
const node = this.nodes[nodeId];
|
|
327
|
-
if (node.
|
|
328
|
-
|
|
119
|
+
if (node.isComputedNode) {
|
|
120
|
+
if (node.error !== undefined) {
|
|
121
|
+
errors[nodeId] = node.error;
|
|
122
|
+
}
|
|
329
123
|
}
|
|
330
124
|
return errors;
|
|
331
125
|
}, {});
|
|
@@ -334,92 +128,116 @@ class GraphAI {
|
|
|
334
128
|
// Nodes without pending data should run immediately.
|
|
335
129
|
Object.keys(this.nodes).forEach((nodeId) => {
|
|
336
130
|
const node = this.nodes[nodeId];
|
|
337
|
-
node.
|
|
131
|
+
if (node.isComputedNode) {
|
|
132
|
+
this.pushQueueIfReady(node);
|
|
133
|
+
}
|
|
338
134
|
});
|
|
339
135
|
}
|
|
340
|
-
|
|
341
|
-
if (
|
|
136
|
+
pushQueueIfReady(node) {
|
|
137
|
+
if (node.isReadyNode()) {
|
|
138
|
+
this.pushQueue(node);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
pushQueueIfReadyAndRunning(node) {
|
|
142
|
+
if (this.isRunning()) {
|
|
143
|
+
this.pushQueueIfReady(node);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// for computed
|
|
147
|
+
pushQueue(node) {
|
|
148
|
+
node.state = type_1.NodeState.Queued;
|
|
149
|
+
this.taskManager.addTask(node, this.graphId, (_node) => {
|
|
150
|
+
(0, utils_1.assert)(node.nodeId === _node.nodeId, "GraphAI.pushQueue node mismatch");
|
|
151
|
+
node.execute();
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
// Public API
|
|
155
|
+
async run(all = false) {
|
|
156
|
+
if (this.isRunning()) {
|
|
342
157
|
console.error("-- Already Running");
|
|
343
158
|
}
|
|
344
|
-
this.isRunning = true;
|
|
345
159
|
this.pushReadyNodesIntoQueue();
|
|
346
160
|
return new Promise((resolve, reject) => {
|
|
347
161
|
this.onComplete = () => {
|
|
348
|
-
this.isRunning = false;
|
|
349
162
|
const errors = this.errors();
|
|
350
163
|
const nodeIds = Object.keys(errors);
|
|
351
164
|
if (nodeIds.length > 0) {
|
|
352
165
|
reject(errors[nodeIds[0]]);
|
|
353
166
|
}
|
|
354
167
|
else {
|
|
355
|
-
resolve(this.results());
|
|
168
|
+
resolve(this.results(all));
|
|
356
169
|
}
|
|
357
170
|
};
|
|
358
171
|
});
|
|
359
172
|
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
}
|
|
372
|
-
removeRunning
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
this.
|
|
382
|
-
|
|
383
|
-
if (loop
|
|
384
|
-
const
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
const checkWhileCondition = () => {
|
|
389
|
-
if (loop.while) {
|
|
390
|
-
const value = this.getValueFromResults(loop.while, this.results());
|
|
391
|
-
// NOTE: We treat an empty array as false.
|
|
392
|
-
return Array.isArray(value) ? value.length > 0 : !!value;
|
|
393
|
-
}
|
|
394
|
-
return true;
|
|
395
|
-
};
|
|
396
|
-
if (checkWhileCondition()) {
|
|
397
|
-
this.isRunning = true; // restore it
|
|
398
|
-
this.pushReadyNodesIntoQueue();
|
|
399
|
-
return;
|
|
173
|
+
// Public only for testing
|
|
174
|
+
isRunning() {
|
|
175
|
+
return this.taskManager.isRunning(this.graphId);
|
|
176
|
+
}
|
|
177
|
+
// callback from execute
|
|
178
|
+
onExecutionComplete(node) {
|
|
179
|
+
this.taskManager.onComplete(node);
|
|
180
|
+
if (this.isRunning() || this.processLoopIfNecessary()) {
|
|
181
|
+
return; // continue running
|
|
182
|
+
}
|
|
183
|
+
this.onComplete(); // Nothing to run. Finish it.
|
|
184
|
+
}
|
|
185
|
+
// Must be called only from onExecutionComplete righ after removeRunning
|
|
186
|
+
// Check if there is any running computed nodes.
|
|
187
|
+
// In case of no running computed note, start the another iteration if ncessary (loop)
|
|
188
|
+
processLoopIfNecessary() {
|
|
189
|
+
this.repeatCount++;
|
|
190
|
+
const loop = this.loop;
|
|
191
|
+
if (loop && (loop.count === undefined || this.repeatCount < loop.count)) {
|
|
192
|
+
const results = this.results(true); // results from previous loop
|
|
193
|
+
this.nodes = this.createNodes(this.data);
|
|
194
|
+
this.initializeNodes(results);
|
|
195
|
+
// Notice that we need to check the while condition *after* calling initializeNodes.
|
|
196
|
+
if (loop.while) {
|
|
197
|
+
const value = this.getValueFromResults(loop.while, this.results(true));
|
|
198
|
+
// NOTE: We treat an empty array as false.
|
|
199
|
+
if (Array.isArray(value) ? value.length === 0 : !value) {
|
|
200
|
+
return false; // while condition is not met
|
|
400
201
|
}
|
|
401
202
|
}
|
|
402
|
-
this.
|
|
203
|
+
this.pushReadyNodesIntoQueue();
|
|
204
|
+
return true; // Indicating that we are going to continue.
|
|
403
205
|
}
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
setLoopLog(log) {
|
|
209
|
+
log.isLoop = !!this.loop;
|
|
210
|
+
log.repeatCount = this.repeatCount;
|
|
404
211
|
}
|
|
405
212
|
appendLog(log) {
|
|
406
213
|
this.logs.push(log);
|
|
214
|
+
this.onLogCallback(log, false);
|
|
407
215
|
}
|
|
216
|
+
updateLog(log) {
|
|
217
|
+
this.onLogCallback(log, true);
|
|
218
|
+
}
|
|
219
|
+
// Public API
|
|
408
220
|
transactionLogs() {
|
|
409
221
|
return this.logs;
|
|
410
222
|
}
|
|
411
|
-
|
|
223
|
+
// Public API
|
|
224
|
+
injectValue(nodeId, value, injectFrom) {
|
|
412
225
|
const node = this.nodes[nodeId];
|
|
413
|
-
if (node) {
|
|
414
|
-
node.injectValue(value);
|
|
226
|
+
if (node && node.isStaticNode) {
|
|
227
|
+
node.injectValue(value, injectFrom);
|
|
415
228
|
}
|
|
416
229
|
else {
|
|
417
|
-
console.error("-- Invalid nodeId", nodeId);
|
|
230
|
+
console.error("-- Inject Error: Invalid nodeId", nodeId);
|
|
231
|
+
console.error("InjectionTo can only specify static nodes");
|
|
418
232
|
}
|
|
419
233
|
}
|
|
420
|
-
resultsOf(
|
|
421
|
-
return
|
|
422
|
-
|
|
234
|
+
resultsOf(sources, anyInput = false) {
|
|
235
|
+
return sources.map((source) => {
|
|
236
|
+
const { result } = this.nodes[source.nodeId];
|
|
237
|
+
if (source.propId) {
|
|
238
|
+
(0, utils_1.assert)((0, utils_1.isObject)(result), `resultsOf: result is not object. nodeId ${source.nodeId}`, anyInput);
|
|
239
|
+
}
|
|
240
|
+
return result && source.propId ? result[source.propId] : result;
|
|
423
241
|
});
|
|
424
242
|
}
|
|
425
243
|
}
|
package/lib/index.d.ts
CHANGED
package/lib/log.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ResultData, NodeDataParams, NodeState } from "./type";
|
|
2
|
+
import type { GraphAI } from "./graphai";
|
|
3
|
+
import type { ComputedNode, StaticNode } from "./node";
|
|
4
|
+
export declare class TransactionLog {
|
|
5
|
+
nodeId: string;
|
|
6
|
+
state: NodeState;
|
|
7
|
+
startTime?: number;
|
|
8
|
+
endTime?: number;
|
|
9
|
+
retryCount?: number;
|
|
10
|
+
agentId?: string;
|
|
11
|
+
params?: NodeDataParams;
|
|
12
|
+
inputs?: Array<ResultData>;
|
|
13
|
+
errorMessage?: string;
|
|
14
|
+
result?: ResultData;
|
|
15
|
+
log?: TransactionLog[];
|
|
16
|
+
constructor(nodeId: string);
|
|
17
|
+
initForComputedNode(node: ComputedNode): void;
|
|
18
|
+
onInjected(node: StaticNode, graph: GraphAI): void;
|
|
19
|
+
onComplete(node: ComputedNode, graph: GraphAI, localLog: TransactionLog[]): void;
|
|
20
|
+
beforeExecute(node: ComputedNode, graph: GraphAI, transactionId: number, inputs: ResultData[]): void;
|
|
21
|
+
onError(node: ComputedNode, graph: GraphAI, errorMessage: string): void;
|
|
22
|
+
}
|
package/lib/log.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TransactionLog = void 0;
|
|
4
|
+
const type_1 = require("./type");
|
|
5
|
+
class TransactionLog {
|
|
6
|
+
constructor(nodeId) {
|
|
7
|
+
this.nodeId = nodeId;
|
|
8
|
+
this.state = type_1.NodeState.Waiting;
|
|
9
|
+
}
|
|
10
|
+
initForComputedNode(node) {
|
|
11
|
+
this.agentId = node.agentId;
|
|
12
|
+
this.params = node.params;
|
|
13
|
+
}
|
|
14
|
+
onInjected(node, graph) {
|
|
15
|
+
const isUpdating = "endTime" in this;
|
|
16
|
+
this.result = node.value;
|
|
17
|
+
this.state = node.state;
|
|
18
|
+
this.endTime = Date.now();
|
|
19
|
+
if (isUpdating) {
|
|
20
|
+
graph.updateLog(this);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
graph.appendLog(this);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
onComplete(node, graph, localLog) {
|
|
27
|
+
this.result = node.result;
|
|
28
|
+
this.state = node.state;
|
|
29
|
+
this.endTime = Date.now();
|
|
30
|
+
if (localLog.length > 0) {
|
|
31
|
+
this.log = localLog;
|
|
32
|
+
}
|
|
33
|
+
graph.updateLog(this);
|
|
34
|
+
}
|
|
35
|
+
beforeExecute(node, graph, transactionId, inputs) {
|
|
36
|
+
this.state = node.state;
|
|
37
|
+
this.retryCount = node.retryCount > 0 ? node.retryCount : undefined;
|
|
38
|
+
this.startTime = transactionId;
|
|
39
|
+
this.inputs = inputs.length > 0 ? inputs : undefined;
|
|
40
|
+
graph.appendLog(this);
|
|
41
|
+
}
|
|
42
|
+
onError(node, graph, errorMessage) {
|
|
43
|
+
this.state = node.state;
|
|
44
|
+
this.errorMessage = errorMessage;
|
|
45
|
+
this.endTime = Date.now();
|
|
46
|
+
graph.updateLog(this);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.TransactionLog = TransactionLog;
|