graphai 0.0.12 → 0.1.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/README.md +9 -7
- package/lib/graphai.d.ts +9 -97
- package/lib/graphai.js +49 -226
- package/lib/log.d.ts +6 -0
- package/lib/log.js +48 -0
- package/lib/node.d.ts +44 -0
- package/lib/node.js +179 -0
- package/lib/type.d.ts +64 -0
- package/lib/type.js +13 -0
- package/lib/utils/utils.d.ts +2 -0
- package/lib/utils/utils.js +11 -1
- package/lib/utils.d.ts +7 -0
- package/lib/utils.js +13 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ You just need to describe dependencies among those API calls in a single data fl
|
|
|
9
9
|
Here is an example:
|
|
10
10
|
|
|
11
11
|
```YAML
|
|
12
|
+
agentId: sample
|
|
12
13
|
nodes:
|
|
13
14
|
taskA:
|
|
14
15
|
params:
|
|
@@ -37,7 +38,7 @@ const sampleAgentFunction = async (context: AgentFunctionContext) => {
|
|
|
37
38
|
...
|
|
38
39
|
const file = fs.readFileSync(pathToYamlFile, "utf8");
|
|
39
40
|
const graphData = YAML.parse(file);
|
|
40
|
-
const graph = new GraphAI(graphData, sampleAgentFunction);
|
|
41
|
+
const graph = new GraphAI(graphData, { sample: sampleAgentFunction });
|
|
41
42
|
const results = await graph.run();
|
|
42
43
|
return results["taskC"];
|
|
43
44
|
```
|
|
@@ -48,7 +49,7 @@ As Andrew Ng has described in his article, "[The batch: Issue 242](https://www.d
|
|
|
48
49
|
|
|
49
50
|
Building applications that employ these workflows, however, is challenging due to the complexities of managing multiple asynchronous API calls, including error handling, timeouts, retries, and logging.
|
|
50
51
|
|
|
51
|
-
GraphAI is designed to simplify this process by decoupling the complexity of multiple asynchronous calls from the application's core logic. It enables developers to model these calls and their dependencies within a single Data Flow Graph, enhancing development and debugging processes.
|
|
52
|
+
GraphAI is designed to simplify this process by decoupling the complexity of multiple asynchronous calls from the application's core logic. It enables developers to model these calls and their dependencies within a single acyclic Data Flow Graph, enhancing development and debugging processes.
|
|
52
53
|
|
|
53
54
|
Furthermore, GraphAI's robust mechanisms for error handling, retry strategies, timeouts, and logging empower developers to concentrate on refining the application logic.
|
|
54
55
|
|
|
@@ -114,7 +115,9 @@ Key principles:
|
|
|
114
115
|
|
|
115
116
|
A Data Flow Graph (DFG) is a JavaScript object, which defines the flow of data. It is typically described in YAML file and loaded at runtime.
|
|
116
117
|
|
|
117
|
-
A DFG consists of a collection of 'nodes', which contains a series of nested
|
|
118
|
+
A DFG consists of a collection of 'nodes', which contains a series of nested properties representing individual nodes in the data flow. Each node is identified by a unique key, *nodeId* (e.g., node1, node2) and can contain several predefined properties (params, inputs, retry, timeout, agentId, fork, value, update) that dictate the node's behavior and its relationship with other nodes.
|
|
119
|
+
|
|
120
|
+
Connections between nodes will be established by references from one not to another, using either its "inputs" or "update" property. The values of those properties are *data sources*. A *data souce* is specified by either the nodeId (e.g., "node1"), or nodeId + propertyId ("node1.item").
|
|
118
121
|
|
|
119
122
|
### DFG Structure
|
|
120
123
|
|
|
@@ -132,10 +135,10 @@ nodes:
|
|
|
132
135
|
- Steve Jobs
|
|
133
136
|
- Elon Musk
|
|
134
137
|
- Nikola Tesla
|
|
135
|
-
|
|
138
|
+
update: retriever.array
|
|
136
139
|
result:
|
|
137
140
|
value: []
|
|
138
|
-
|
|
141
|
+
update: reducer
|
|
139
142
|
retriever:
|
|
140
143
|
agentId: shift
|
|
141
144
|
inputs: [people]
|
|
@@ -172,12 +175,11 @@ A *computed node* have following properties.
|
|
|
172
175
|
- 'timeout': An optional number, which specifies the maximum waittime in msec. If the associated agent function does not return the value in time, the "Timeout" error will be recorded and the returned value will be discarded.
|
|
173
176
|
- 'params': An optional property to the associated agent function, which are agent specific.
|
|
174
177
|
- 'fork': An optional paramter, which specifies the number of concurrent transactions to be created for the current node.
|
|
175
|
-
- 'outputs' (MAY BECOME OBSOLETE): An optinal property, which specifies the mapping from outputId to nodeId. If this property is set, the node become a special node called *dispatcher*. A *dispatcher* node injects result(s) into specified static nodes, enabling the dynamic flow of data.
|
|
176
178
|
|
|
177
179
|
A *static* node have following properties.
|
|
178
180
|
|
|
179
181
|
- 'value': An optional property, which specifies the value of this static node (equivalent to calling the injectValue method from outside).
|
|
180
|
-
- '
|
|
182
|
+
- 'update': An optional property, which specifies the *data source* after each iteration.
|
|
181
183
|
|
|
182
184
|
## GraphAI class
|
|
183
185
|
|
package/lib/graphai.d.ts
CHANGED
|
@@ -1,94 +1,7 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
TimedOut = "timed-out",
|
|
6
|
-
Completed = "completed",
|
|
7
|
-
Injected = "injected",
|
|
8
|
-
Dispatched = "dispatched"
|
|
9
|
-
}
|
|
10
|
-
type ResultData<ResultType = Record<string, any>> = ResultType | undefined;
|
|
11
|
-
type ResultDataDictonary<ResultType = Record<string, any>> = Record<string, ResultData<ResultType>>;
|
|
12
|
-
export type NodeDataParams<ParamsType = Record<string, any>> = ParamsType;
|
|
13
|
-
type NodeData = {
|
|
14
|
-
inputs?: Array<string>;
|
|
15
|
-
params?: NodeDataParams;
|
|
16
|
-
retry?: number;
|
|
17
|
-
timeout?: number;
|
|
18
|
-
agentId?: string;
|
|
19
|
-
fork?: number;
|
|
20
|
-
source?: boolean;
|
|
21
|
-
value?: ResultData;
|
|
22
|
-
next?: string;
|
|
23
|
-
outputs?: Record<string, string>;
|
|
24
|
-
};
|
|
25
|
-
type LoopData = {
|
|
26
|
-
count?: number;
|
|
27
|
-
while?: string;
|
|
28
|
-
};
|
|
29
|
-
export type GraphData = {
|
|
30
|
-
agentId?: string;
|
|
31
|
-
nodes: Record<string, NodeData>;
|
|
32
|
-
concurrency?: number;
|
|
33
|
-
loop?: LoopData;
|
|
34
|
-
verbose?: boolean;
|
|
35
|
-
};
|
|
36
|
-
export type TransactionLog = {
|
|
37
|
-
nodeId: string;
|
|
38
|
-
state: NodeState;
|
|
39
|
-
startTime: number;
|
|
40
|
-
endTime?: number;
|
|
41
|
-
retryCount?: number;
|
|
42
|
-
agentId?: string;
|
|
43
|
-
params?: NodeDataParams;
|
|
44
|
-
inputs?: Array<ResultData>;
|
|
45
|
-
errorMessage?: string;
|
|
46
|
-
result?: ResultData;
|
|
47
|
-
log?: TransactionLog[];
|
|
48
|
-
};
|
|
49
|
-
export type AgentFunctionContext<ParamsType, PreviousResultType> = {
|
|
50
|
-
nodeId: string;
|
|
51
|
-
forkIndex?: number;
|
|
52
|
-
retry: number;
|
|
53
|
-
params: NodeDataParams<ParamsType>;
|
|
54
|
-
inputs: Array<PreviousResultType>;
|
|
55
|
-
verbose: boolean;
|
|
56
|
-
agents: CallbackDictonaryArgs;
|
|
57
|
-
log: TransactionLog[];
|
|
58
|
-
};
|
|
59
|
-
export type AgentFunction<ParamsType = Record<string, any>, ResultType = Record<string, any>, PreviousResultType = Record<string, any>> = (context: AgentFunctionContext<ParamsType, PreviousResultType>) => Promise<ResultData<ResultType>>;
|
|
60
|
-
export type AgentFunctionDictonary = Record<string, AgentFunction<any, any, any>>;
|
|
61
|
-
declare class Node {
|
|
62
|
-
nodeId: string;
|
|
63
|
-
params: NodeDataParams;
|
|
64
|
-
inputs: Array<string>;
|
|
65
|
-
inputProps: Record<string, string>;
|
|
66
|
-
pendings: Set<string>;
|
|
67
|
-
waitlist: Set<string>;
|
|
68
|
-
state: NodeState;
|
|
69
|
-
agentId?: string;
|
|
70
|
-
fork?: number;
|
|
71
|
-
forkIndex?: number;
|
|
72
|
-
result: ResultData;
|
|
73
|
-
retryLimit: number;
|
|
74
|
-
retryCount: number;
|
|
75
|
-
transactionId: undefined | number;
|
|
76
|
-
timeout?: number;
|
|
77
|
-
error?: Error;
|
|
78
|
-
source: boolean;
|
|
79
|
-
outputs?: Record<string, string>;
|
|
80
|
-
private graph;
|
|
81
|
-
constructor(nodeId: string, forkIndex: number | undefined, data: NodeData, graph: GraphAI);
|
|
82
|
-
asString(): string;
|
|
83
|
-
private retry;
|
|
84
|
-
removePending(nodeId: string): void;
|
|
85
|
-
pushQueueIfReady(): void;
|
|
86
|
-
injectValue(value: ResultData): void;
|
|
87
|
-
private setResult;
|
|
88
|
-
execute(): Promise<void>;
|
|
89
|
-
}
|
|
90
|
-
type GraphNodes = Record<string, Node>;
|
|
91
|
-
export type CallbackDictonaryArgs = AgentFunctionDictonary;
|
|
1
|
+
export { AgentFunction, AgentFunctionDictonary, GraphData } from "./type";
|
|
2
|
+
import { AgentFunctionDictonary, GraphData, DataSource, TransactionLog, ResultDataDictonary, ResultData, CallbackDictonaryArgs } from "./type";
|
|
3
|
+
import { ComputedNode, StaticNode } from "./node";
|
|
4
|
+
type GraphNodes = Record<string, ComputedNode | StaticNode>;
|
|
92
5
|
export declare class GraphAI {
|
|
93
6
|
private data;
|
|
94
7
|
nodes: GraphNodes;
|
|
@@ -107,18 +20,17 @@ export declare class GraphAI {
|
|
|
107
20
|
private getValueFromResults;
|
|
108
21
|
private initializeNodes;
|
|
109
22
|
constructor(data: GraphData, callbackDictonary: CallbackDictonaryArgs);
|
|
110
|
-
getCallback(agentId?: string): AgentFunction<any, any, any>;
|
|
23
|
+
getCallback(agentId?: string): import("./type").AgentFunction<any, any, any>;
|
|
111
24
|
asString(): string;
|
|
112
|
-
results(): ResultDataDictonary
|
|
25
|
+
results(): ResultDataDictonary;
|
|
113
26
|
errors(): Record<string, Error>;
|
|
114
27
|
private pushReadyNodesIntoQueue;
|
|
115
28
|
run(): Promise<ResultDataDictonary>;
|
|
116
29
|
private runNode;
|
|
117
|
-
pushQueue(node:
|
|
118
|
-
removeRunning(node:
|
|
30
|
+
pushQueue(node: ComputedNode): void;
|
|
31
|
+
removeRunning(node: ComputedNode): void;
|
|
119
32
|
appendLog(log: TransactionLog): void;
|
|
120
33
|
transactionLogs(): TransactionLog[];
|
|
121
34
|
injectValue(nodeId: string, value: ResultData): void;
|
|
122
|
-
resultsOf(
|
|
35
|
+
resultsOf(sources: Array<DataSource>): any[];
|
|
123
36
|
}
|
|
124
|
-
export {};
|
package/lib/graphai.js
CHANGED
|
@@ -1,227 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GraphAI =
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
}
|
|
22
|
-
};
|
|
23
|
-
class Node {
|
|
24
|
-
constructor(nodeId, forkIndex, data, graph) {
|
|
25
|
-
this.inputProps = {}; // optional properties for input
|
|
26
|
-
this.waitlist = new Set(); // List of nodes which need data from this node.
|
|
27
|
-
this.state = NodeState.Waiting;
|
|
28
|
-
this.result = undefined;
|
|
29
|
-
this.retryCount = 0;
|
|
30
|
-
this.nodeId = nodeId;
|
|
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
|
-
}
|
|
3
|
+
exports.GraphAI = void 0;
|
|
4
|
+
const node_1 = require("./node");
|
|
5
|
+
const utils_1 = require("./utils/utils");
|
|
204
6
|
const defaultConcurrency = 8;
|
|
205
7
|
class GraphAI {
|
|
206
8
|
createNodes(data) {
|
|
207
9
|
const nodeId2forkedNodeIds = {};
|
|
208
10
|
const forkedNodeId2Index = {};
|
|
209
|
-
const
|
|
11
|
+
const forkedNodeId2NodeId = {}; // for sources
|
|
12
|
+
const nodes = Object.keys(data.nodes).reduce((_nodes, nodeId) => {
|
|
210
13
|
const fork = data.nodes[nodeId].fork;
|
|
14
|
+
const isStaticNode = (data.nodes[nodeId].agentId ?? data.agentId) === undefined;
|
|
15
|
+
const node = isStaticNode ? node_1.StaticNode : node_1.ComputedNode;
|
|
211
16
|
if (fork) {
|
|
212
17
|
// For fork, change the nodeId and increase the node
|
|
213
18
|
nodeId2forkedNodeIds[nodeId] = new Array(fork).fill(undefined).map((_, i) => {
|
|
214
19
|
const forkedNodeId = `${nodeId}_${i}`;
|
|
215
|
-
|
|
20
|
+
_nodes[forkedNodeId] = new node(forkedNodeId, i, data.nodes[nodeId], this);
|
|
216
21
|
// Data for pending and waiting
|
|
217
22
|
forkedNodeId2Index[forkedNodeId] = i;
|
|
23
|
+
forkedNodeId2NodeId[forkedNodeId] = nodeId;
|
|
218
24
|
return forkedNodeId;
|
|
219
25
|
});
|
|
220
26
|
}
|
|
221
27
|
else {
|
|
222
|
-
|
|
28
|
+
_nodes[nodeId] = new node(nodeId, undefined, data.nodes[nodeId], this);
|
|
223
29
|
}
|
|
224
|
-
return
|
|
30
|
+
return _nodes;
|
|
225
31
|
}, {});
|
|
226
32
|
// Generate the waitlist for each node, and update the pendings in case of forked node.
|
|
227
33
|
Object.keys(nodes).forEach((nodeId) => {
|
|
@@ -255,28 +61,37 @@ class GraphAI {
|
|
|
255
61
|
}
|
|
256
62
|
});
|
|
257
63
|
node.inputs = Array.from(node.pendings); // for fork.
|
|
64
|
+
node.sources = node.inputs.reduce((sources, input) => {
|
|
65
|
+
const refNodeId = forkedNodeId2NodeId[input] ?? input;
|
|
66
|
+
sources[input] = { nodeId: input, propId: node.sources[refNodeId].propId };
|
|
67
|
+
return sources;
|
|
68
|
+
}, {});
|
|
258
69
|
});
|
|
259
70
|
return nodes;
|
|
260
71
|
}
|
|
261
72
|
getValueFromResults(key, results) {
|
|
262
|
-
const
|
|
263
|
-
const result = results[
|
|
264
|
-
return result ? (propId ? result[propId] : result) : undefined;
|
|
73
|
+
const source = (0, utils_1.parseNodeName)(key);
|
|
74
|
+
const result = results[source.nodeId];
|
|
75
|
+
return result ? (source.propId ? result[source.propId] : result) : undefined;
|
|
265
76
|
}
|
|
77
|
+
// for static
|
|
266
78
|
initializeNodes(previousResults) {
|
|
267
79
|
// If the result property is specified, inject it.
|
|
268
80
|
// If the previousResults exists (indicating we are in a loop),
|
|
269
|
-
// process the
|
|
81
|
+
// process the update property (nodeId or nodeId.propId).
|
|
270
82
|
Object.keys(this.data.nodes).forEach((nodeId) => {
|
|
271
|
-
const node = this.
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
if (
|
|
279
|
-
this.
|
|
83
|
+
const node = this.nodes[nodeId];
|
|
84
|
+
if (node?.isStaticNode) {
|
|
85
|
+
const value = node?.value;
|
|
86
|
+
const update = node?.update;
|
|
87
|
+
if (value) {
|
|
88
|
+
this.injectValue(nodeId, value);
|
|
89
|
+
}
|
|
90
|
+
if (update && previousResults) {
|
|
91
|
+
const result = this.getValueFromResults(update, previousResults);
|
|
92
|
+
if (result) {
|
|
93
|
+
this.injectValue(nodeId, result);
|
|
94
|
+
}
|
|
280
95
|
}
|
|
281
96
|
}
|
|
282
97
|
});
|
|
@@ -284,7 +99,7 @@ class GraphAI {
|
|
|
284
99
|
constructor(data, callbackDictonary) {
|
|
285
100
|
this.isRunning = false;
|
|
286
101
|
this.runningNodes = new Set();
|
|
287
|
-
this.nodeQueue = [];
|
|
102
|
+
this.nodeQueue = []; // for Computed Node
|
|
288
103
|
this.repeatCount = 0;
|
|
289
104
|
this.logs = [];
|
|
290
105
|
this.data = data;
|
|
@@ -324,8 +139,10 @@ class GraphAI {
|
|
|
324
139
|
errors() {
|
|
325
140
|
return Object.keys(this.nodes).reduce((errors, nodeId) => {
|
|
326
141
|
const node = this.nodes[nodeId];
|
|
327
|
-
if (node.
|
|
328
|
-
|
|
142
|
+
if (node.isComputedNode) {
|
|
143
|
+
if (node.error !== undefined) {
|
|
144
|
+
errors[nodeId] = node.error;
|
|
145
|
+
}
|
|
329
146
|
}
|
|
330
147
|
return errors;
|
|
331
148
|
}, {});
|
|
@@ -334,7 +151,9 @@ class GraphAI {
|
|
|
334
151
|
// Nodes without pending data should run immediately.
|
|
335
152
|
Object.keys(this.nodes).forEach((nodeId) => {
|
|
336
153
|
const node = this.nodes[nodeId];
|
|
337
|
-
node.
|
|
154
|
+
if (node.isComputedNode) {
|
|
155
|
+
node.pushQueueIfReady();
|
|
156
|
+
}
|
|
338
157
|
});
|
|
339
158
|
}
|
|
340
159
|
async run() {
|
|
@@ -357,10 +176,12 @@ class GraphAI {
|
|
|
357
176
|
};
|
|
358
177
|
});
|
|
359
178
|
}
|
|
179
|
+
// for computed
|
|
360
180
|
runNode(node) {
|
|
361
181
|
this.runningNodes.add(node.nodeId);
|
|
362
182
|
node.execute();
|
|
363
183
|
}
|
|
184
|
+
// for computed
|
|
364
185
|
pushQueue(node) {
|
|
365
186
|
if (this.runningNodes.size < this.concurrency) {
|
|
366
187
|
this.runNode(node);
|
|
@@ -369,6 +190,7 @@ class GraphAI {
|
|
|
369
190
|
this.nodeQueue.push(node);
|
|
370
191
|
}
|
|
371
192
|
}
|
|
193
|
+
// for completed
|
|
372
194
|
removeRunning(node) {
|
|
373
195
|
this.runningNodes.delete(node.nodeId);
|
|
374
196
|
if (this.nodeQueue.length > 0) {
|
|
@@ -410,16 +232,17 @@ class GraphAI {
|
|
|
410
232
|
}
|
|
411
233
|
injectValue(nodeId, value) {
|
|
412
234
|
const node = this.nodes[nodeId];
|
|
413
|
-
if (node) {
|
|
235
|
+
if (node && node.isStaticNode) {
|
|
414
236
|
node.injectValue(value);
|
|
415
237
|
}
|
|
416
238
|
else {
|
|
417
239
|
console.error("-- Invalid nodeId", nodeId);
|
|
418
240
|
}
|
|
419
241
|
}
|
|
420
|
-
resultsOf(
|
|
421
|
-
return
|
|
422
|
-
|
|
242
|
+
resultsOf(sources) {
|
|
243
|
+
return sources.map((source) => {
|
|
244
|
+
const result = this.nodes[source.nodeId].result;
|
|
245
|
+
return result && source.propId ? result[source.propId] : result;
|
|
423
246
|
});
|
|
424
247
|
}
|
|
425
248
|
}
|
package/lib/log.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ResultData, TransactionLog, NodeDataParams } from "./type";
|
|
2
|
+
export declare const injectValueLog: (nodeId: string, value: ResultData) => TransactionLog;
|
|
3
|
+
export declare const executeLog: (nodeId: string, retryCount: number, transactionId: number, agentId: string | undefined, params: NodeDataParams, results: ResultData[]) => TransactionLog;
|
|
4
|
+
export declare const timeoutLog: (log: TransactionLog) => void;
|
|
5
|
+
export declare const callbackLog: (log: TransactionLog, result: ResultData, localLog: TransactionLog[]) => void;
|
|
6
|
+
export declare const errorLog: (log: TransactionLog, errorMessage: string) => void;
|
package/lib/log.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.errorLog = exports.callbackLog = exports.timeoutLog = exports.executeLog = exports.injectValueLog = void 0;
|
|
4
|
+
const type_1 = require("./type");
|
|
5
|
+
const injectValueLog = (nodeId, value) => {
|
|
6
|
+
const log = {
|
|
7
|
+
nodeId,
|
|
8
|
+
state: type_1.NodeState.Injected,
|
|
9
|
+
startTime: Date.now(),
|
|
10
|
+
endTime: Date.now(),
|
|
11
|
+
result: value,
|
|
12
|
+
};
|
|
13
|
+
return log;
|
|
14
|
+
};
|
|
15
|
+
exports.injectValueLog = injectValueLog;
|
|
16
|
+
const executeLog = (nodeId, retryCount, transactionId, agentId, params, results) => {
|
|
17
|
+
const log = {
|
|
18
|
+
nodeId,
|
|
19
|
+
retryCount: retryCount > 0 ? retryCount : undefined,
|
|
20
|
+
state: type_1.NodeState.Executing,
|
|
21
|
+
startTime: transactionId,
|
|
22
|
+
agentId,
|
|
23
|
+
params,
|
|
24
|
+
inputs: results.length > 0 ? results : undefined,
|
|
25
|
+
};
|
|
26
|
+
return log;
|
|
27
|
+
};
|
|
28
|
+
exports.executeLog = executeLog;
|
|
29
|
+
const timeoutLog = (log) => {
|
|
30
|
+
log.errorMessage = "Timeout";
|
|
31
|
+
log.state = type_1.NodeState.TimedOut;
|
|
32
|
+
log.endTime = Date.now();
|
|
33
|
+
};
|
|
34
|
+
exports.timeoutLog = timeoutLog;
|
|
35
|
+
const callbackLog = (log, result, localLog) => {
|
|
36
|
+
log.endTime = Date.now();
|
|
37
|
+
log.result = result;
|
|
38
|
+
if (localLog.length > 0) {
|
|
39
|
+
log.log = localLog;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
exports.callbackLog = callbackLog;
|
|
43
|
+
const errorLog = (log, errorMessage) => {
|
|
44
|
+
log.state = type_1.NodeState.Failed;
|
|
45
|
+
log.endTime = Date.now();
|
|
46
|
+
log.errorMessage = errorMessage;
|
|
47
|
+
};
|
|
48
|
+
exports.errorLog = errorLog;
|
package/lib/node.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { NodeDataParams, ResultData, DataSource, NodeData } from "./type";
|
|
2
|
+
import type { GraphAI } from "./graphai";
|
|
3
|
+
import { NodeState } from "./type";
|
|
4
|
+
export declare class Node {
|
|
5
|
+
nodeId: string;
|
|
6
|
+
sources: Record<string, DataSource>;
|
|
7
|
+
anyInput: boolean;
|
|
8
|
+
inputs: Array<string>;
|
|
9
|
+
pendings: Set<string>;
|
|
10
|
+
waitlist: Set<string>;
|
|
11
|
+
state: NodeState;
|
|
12
|
+
fork?: number;
|
|
13
|
+
forkIndex?: number;
|
|
14
|
+
result: ResultData;
|
|
15
|
+
transactionId: undefined | number;
|
|
16
|
+
protected graph: GraphAI;
|
|
17
|
+
constructor(nodeId: string, forkIndex: number | undefined, data: NodeData, graph: GraphAI);
|
|
18
|
+
asString(): string;
|
|
19
|
+
removePending(nodeId: string): void;
|
|
20
|
+
protected setResult(result: ResultData, state: NodeState): void;
|
|
21
|
+
}
|
|
22
|
+
export declare class ComputedNode extends Node {
|
|
23
|
+
params: NodeDataParams;
|
|
24
|
+
retryLimit: number;
|
|
25
|
+
retryCount: number;
|
|
26
|
+
agentId?: string;
|
|
27
|
+
timeout?: number;
|
|
28
|
+
error?: Error;
|
|
29
|
+
readonly isStaticNode = false;
|
|
30
|
+
readonly isComputedNode = true;
|
|
31
|
+
constructor(nodeId: string, forkIndex: number | undefined, data: NodeData, graph: GraphAI);
|
|
32
|
+
pushQueueIfReady(): void;
|
|
33
|
+
private retry;
|
|
34
|
+
removePending(nodeId: string): void;
|
|
35
|
+
execute(): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
export declare class StaticNode extends Node {
|
|
38
|
+
value?: ResultData;
|
|
39
|
+
update?: string;
|
|
40
|
+
readonly isStaticNode = true;
|
|
41
|
+
readonly isComputedNode = false;
|
|
42
|
+
constructor(nodeId: string, forkIndex: number | undefined, data: NodeData, graph: GraphAI);
|
|
43
|
+
injectValue(value: ResultData): void;
|
|
44
|
+
}
|
package/lib/node.js
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StaticNode = exports.ComputedNode = exports.Node = void 0;
|
|
4
|
+
const type_1 = require("./type");
|
|
5
|
+
const utils_1 = require("./utils/utils");
|
|
6
|
+
const log_1 = require("./log");
|
|
7
|
+
class Node {
|
|
8
|
+
constructor(nodeId, forkIndex, data, graph) {
|
|
9
|
+
this.sources = {}; // data sources.
|
|
10
|
+
this.waitlist = new Set(); // List of nodes which need data from this node.
|
|
11
|
+
this.state = type_1.NodeState.Waiting;
|
|
12
|
+
this.result = undefined;
|
|
13
|
+
this.nodeId = nodeId;
|
|
14
|
+
this.forkIndex = forkIndex;
|
|
15
|
+
this.anyInput = data.anyInput ?? false;
|
|
16
|
+
this.inputs = (data.inputs ?? []).map((input) => {
|
|
17
|
+
const source = (0, utils_1.parseNodeName)(input);
|
|
18
|
+
this.sources[source.nodeId] = source;
|
|
19
|
+
return source.nodeId;
|
|
20
|
+
});
|
|
21
|
+
this.pendings = new Set(this.inputs);
|
|
22
|
+
this.fork = data.fork;
|
|
23
|
+
this.graph = graph;
|
|
24
|
+
}
|
|
25
|
+
asString() {
|
|
26
|
+
return `${this.nodeId}: ${this.state} ${[...this.waitlist]}`;
|
|
27
|
+
}
|
|
28
|
+
removePending(nodeId) {
|
|
29
|
+
if (this.anyInput) {
|
|
30
|
+
const [result] = this.graph.resultsOf([this.sources[nodeId]]);
|
|
31
|
+
if (result) {
|
|
32
|
+
this.pendings.clear();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
this.pendings.delete(nodeId);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
setResult(result, state) {
|
|
40
|
+
this.state = state;
|
|
41
|
+
this.result = result;
|
|
42
|
+
this.waitlist.forEach((nodeId) => {
|
|
43
|
+
const node = this.graph.nodes[nodeId];
|
|
44
|
+
// Todo: Avoid running before Run()
|
|
45
|
+
node.removePending(this.nodeId);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.Node = Node;
|
|
50
|
+
class ComputedNode extends Node {
|
|
51
|
+
constructor(nodeId, forkIndex, data, graph) {
|
|
52
|
+
super(nodeId, forkIndex, data, graph);
|
|
53
|
+
this.retryCount = 0;
|
|
54
|
+
this.isStaticNode = false;
|
|
55
|
+
this.isComputedNode = true;
|
|
56
|
+
this.params = data.params ?? {};
|
|
57
|
+
this.agentId = data.agentId ?? graph.agentId;
|
|
58
|
+
this.retryLimit = data.retry ?? 0;
|
|
59
|
+
this.timeout = data.timeout;
|
|
60
|
+
}
|
|
61
|
+
// for completed
|
|
62
|
+
pushQueueIfReady() {
|
|
63
|
+
if (this.pendings.size === 0) {
|
|
64
|
+
// If input property is specified, we need to ensure that the property value exists.
|
|
65
|
+
const count = this.inputs.reduce((count, nodeId) => {
|
|
66
|
+
const source = this.sources[nodeId];
|
|
67
|
+
if (source.propId) {
|
|
68
|
+
const [result] = this.graph.resultsOf([source]);
|
|
69
|
+
if (!result) {
|
|
70
|
+
return count;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return count + 1;
|
|
74
|
+
}, 0);
|
|
75
|
+
if ((this.anyInput && count > 0) || count == this.inputs.length) {
|
|
76
|
+
this.graph.pushQueue(this);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// for computed
|
|
81
|
+
retry(state, error) {
|
|
82
|
+
if (this.retryCount < this.retryLimit) {
|
|
83
|
+
this.retryCount++;
|
|
84
|
+
this.execute();
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
this.state = state;
|
|
88
|
+
this.result = undefined;
|
|
89
|
+
this.error = error;
|
|
90
|
+
this.transactionId = undefined; // This is necessary for timeout case
|
|
91
|
+
this.graph.removeRunning(this);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
removePending(nodeId) {
|
|
95
|
+
super.removePending(nodeId);
|
|
96
|
+
if (this.graph.isRunning) {
|
|
97
|
+
this.pushQueueIfReady();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async execute() {
|
|
101
|
+
const results = this.graph
|
|
102
|
+
.resultsOf(this.inputs.map((input) => {
|
|
103
|
+
return this.sources[input];
|
|
104
|
+
}))
|
|
105
|
+
.filter((result) => {
|
|
106
|
+
// Remove undefined if anyInput flag is set.
|
|
107
|
+
return !this.anyInput || result !== undefined;
|
|
108
|
+
});
|
|
109
|
+
const transactionId = Date.now();
|
|
110
|
+
const log = (0, log_1.executeLog)(this.nodeId, this.retryCount, transactionId, this.agentId, this.params, results);
|
|
111
|
+
this.graph.appendLog(log);
|
|
112
|
+
this.state = type_1.NodeState.Executing;
|
|
113
|
+
this.transactionId = transactionId;
|
|
114
|
+
if (this.timeout && this.timeout > 0) {
|
|
115
|
+
setTimeout(() => {
|
|
116
|
+
if (this.state === type_1.NodeState.Executing && this.transactionId === transactionId) {
|
|
117
|
+
console.log(`-- ${this.nodeId}: timeout ${this.timeout}`);
|
|
118
|
+
(0, log_1.timeoutLog)(log);
|
|
119
|
+
this.retry(type_1.NodeState.TimedOut, Error("Timeout"));
|
|
120
|
+
}
|
|
121
|
+
}, this.timeout);
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
const callback = this.graph.getCallback(this.agentId);
|
|
125
|
+
const localLog = [];
|
|
126
|
+
const result = await callback({
|
|
127
|
+
nodeId: this.nodeId,
|
|
128
|
+
retry: this.retryCount,
|
|
129
|
+
params: this.params,
|
|
130
|
+
inputs: results,
|
|
131
|
+
forkIndex: this.forkIndex,
|
|
132
|
+
verbose: this.graph.verbose,
|
|
133
|
+
agents: this.graph.callbackDictonary,
|
|
134
|
+
log: localLog,
|
|
135
|
+
});
|
|
136
|
+
if (this.transactionId !== transactionId) {
|
|
137
|
+
console.log(`-- ${this.nodeId}: transactionId mismatch`);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
(0, log_1.callbackLog)(log, result, localLog);
|
|
141
|
+
log.state = type_1.NodeState.Completed;
|
|
142
|
+
this.setResult(result, type_1.NodeState.Completed);
|
|
143
|
+
this.graph.removeRunning(this);
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
if (this.transactionId !== transactionId) {
|
|
147
|
+
console.log(`-- ${this.nodeId}: transactionId mismatch(error)`);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const isError = error instanceof Error;
|
|
151
|
+
(0, log_1.errorLog)(log, isError ? error.message : "Unknown");
|
|
152
|
+
if (isError) {
|
|
153
|
+
this.retry(type_1.NodeState.Failed, error);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
console.error(`-- ${this.nodeId}: Unexpecrted error was caught`);
|
|
157
|
+
this.retry(type_1.NodeState.Failed, Error("Unknown"));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
exports.ComputedNode = ComputedNode;
|
|
163
|
+
class StaticNode extends Node {
|
|
164
|
+
constructor(nodeId, forkIndex, data, graph) {
|
|
165
|
+
super(nodeId, forkIndex, data, graph);
|
|
166
|
+
this.isStaticNode = true;
|
|
167
|
+
this.isComputedNode = false;
|
|
168
|
+
this.value = data.value;
|
|
169
|
+
this.update = data.update;
|
|
170
|
+
}
|
|
171
|
+
// for static
|
|
172
|
+
injectValue(value) {
|
|
173
|
+
const log = (0, log_1.injectValueLog)(this.nodeId, value);
|
|
174
|
+
this.graph.appendLog(log);
|
|
175
|
+
this.setResult(value, type_1.NodeState.Injected);
|
|
176
|
+
//console.error("- injectValue called on non-source node.", this.nodeId);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
exports.StaticNode = StaticNode;
|
package/lib/type.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export declare enum NodeState {
|
|
2
|
+
Waiting = "waiting",
|
|
3
|
+
Executing = "executing",
|
|
4
|
+
Failed = "failed",
|
|
5
|
+
TimedOut = "timed-out",
|
|
6
|
+
Completed = "completed",
|
|
7
|
+
Injected = "injected",
|
|
8
|
+
Dispatched = "dispatched"
|
|
9
|
+
}
|
|
10
|
+
export type ResultData<ResultType = Record<string, any>> = ResultType | undefined;
|
|
11
|
+
export type ResultDataDictonary<ResultType = Record<string, any>> = Record<string, ResultData<ResultType>>;
|
|
12
|
+
export type NodeDataParams<ParamsType = Record<string, any>> = ParamsType;
|
|
13
|
+
export type DataSource = {
|
|
14
|
+
nodeId: string;
|
|
15
|
+
propId?: string;
|
|
16
|
+
};
|
|
17
|
+
export type NodeData = {
|
|
18
|
+
inputs?: Array<string>;
|
|
19
|
+
anyInput?: boolean;
|
|
20
|
+
params?: NodeDataParams;
|
|
21
|
+
retry?: number;
|
|
22
|
+
timeout?: number;
|
|
23
|
+
agentId?: string;
|
|
24
|
+
fork?: number;
|
|
25
|
+
value?: ResultData;
|
|
26
|
+
update?: string;
|
|
27
|
+
};
|
|
28
|
+
export type LoopData = {
|
|
29
|
+
count?: number;
|
|
30
|
+
while?: string;
|
|
31
|
+
};
|
|
32
|
+
export type GraphData = {
|
|
33
|
+
agentId?: string;
|
|
34
|
+
nodes: Record<string, NodeData>;
|
|
35
|
+
concurrency?: number;
|
|
36
|
+
loop?: LoopData;
|
|
37
|
+
verbose?: boolean;
|
|
38
|
+
};
|
|
39
|
+
export type TransactionLog = {
|
|
40
|
+
nodeId: string;
|
|
41
|
+
state: NodeState;
|
|
42
|
+
startTime: number;
|
|
43
|
+
endTime?: number;
|
|
44
|
+
retryCount?: number;
|
|
45
|
+
agentId?: string;
|
|
46
|
+
params?: NodeDataParams;
|
|
47
|
+
inputs?: Array<ResultData>;
|
|
48
|
+
errorMessage?: string;
|
|
49
|
+
result?: ResultData;
|
|
50
|
+
log?: TransactionLog[];
|
|
51
|
+
};
|
|
52
|
+
export type AgentFunctionContext<ParamsType, PreviousResultType> = {
|
|
53
|
+
nodeId: string;
|
|
54
|
+
forkIndex?: number;
|
|
55
|
+
retry: number;
|
|
56
|
+
params: NodeDataParams<ParamsType>;
|
|
57
|
+
inputs: Array<PreviousResultType>;
|
|
58
|
+
verbose: boolean;
|
|
59
|
+
agents: CallbackDictonaryArgs;
|
|
60
|
+
log: TransactionLog[];
|
|
61
|
+
};
|
|
62
|
+
export type AgentFunction<ParamsType = Record<string, any>, ResultType = Record<string, any>, PreviousResultType = Record<string, any>> = (context: AgentFunctionContext<ParamsType, PreviousResultType>) => Promise<ResultData<ResultType>>;
|
|
63
|
+
export type AgentFunctionDictonary = Record<string, AgentFunction<any, any, any>>;
|
|
64
|
+
export type CallbackDictonaryArgs = AgentFunctionDictonary;
|
package/lib/type.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NodeState = void 0;
|
|
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 = {}));
|
package/lib/utils/utils.d.ts
CHANGED
package/lib/utils/utils.js
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sleep = void 0;
|
|
3
|
+
exports.parseNodeName = exports.sleep = void 0;
|
|
4
4
|
const sleep = async (milliseconds) => {
|
|
5
5
|
return await new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
6
6
|
};
|
|
7
7
|
exports.sleep = sleep;
|
|
8
|
+
const parseNodeName = (name) => {
|
|
9
|
+
const parts = name.split(".");
|
|
10
|
+
if (parts.length == 1) {
|
|
11
|
+
return { nodeId: parts[0] };
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
return { nodeId: parts[0], propId: parts[1] };
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
exports.parseNodeName = parseNodeName;
|
package/lib/utils.d.ts
ADDED
package/lib/utils.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseNodeName = void 0;
|
|
4
|
+
const parseNodeName = (name) => {
|
|
5
|
+
const parts = name.split(".");
|
|
6
|
+
if (parts.length == 1) {
|
|
7
|
+
return { sourceNodeId: parts[0] };
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
return { sourceNodeId: parts[0], propId: parts[1] };
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
exports.parseNodeName = parseNodeName;
|