graphai 0.3.1 → 0.3.2
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 +27 -8
- package/lib/experimental_agents/data_agents/data_object_merge_template_agent.d.ts +43 -0
- package/lib/experimental_agents/data_agents/data_object_merge_template_agent.js +22 -0
- package/lib/experimental_agents/data_agents/data_sum_template_agent.js +15 -0
- package/lib/experimental_agents/data_agents/property_filter_agent.d.ts +109 -8
- package/lib/experimental_agents/data_agents/property_filter_agent.js +60 -9
- package/lib/experimental_agents/data_agents/total_agent.d.ts +13 -0
- package/lib/experimental_agents/data_agents/total_agent.js +29 -0
- package/lib/experimental_agents/graph_agents/map_agent.js +2 -2
- package/lib/experimental_agents/graph_agents/nested_agent.js +9 -12
- package/lib/experimental_agents/llm_agents/groq_stream_agent.d.ts +42 -0
- package/lib/experimental_agents/llm_agents/groq_stream_agent.js +84 -0
- package/lib/experimental_agents/llm_agents/index.d.ts +2 -0
- package/lib/experimental_agents/llm_agents/index.js +2 -0
- package/lib/experimental_agents/llm_agents/openai_agent.d.ts +1 -0
- package/lib/experimental_agents/llm_agents/openai_agent.js +1 -0
- package/lib/experimental_agents/llm_agents/packages.d.ts +3 -1
- package/lib/experimental_agents/llm_agents/packages.js +5 -1
- package/lib/experimental_agents/matrix_agents/dot_product_agent.js +11 -0
- package/lib/experimental_agents/matrix_agents/sort_by_values_agent.d.ts +13 -1
- package/lib/experimental_agents/matrix_agents/sort_by_values_agent.js +20 -1
- package/lib/experimental_agents/service_agents/fetch_agent.js +1 -1
- package/lib/experimental_agents/service_agents/packages.d.ts +2 -1
- package/lib/experimental_agents/service_agents/packages.js +3 -1
- package/lib/experimental_agents/service_agents/wikipedia.d.ts +1 -0
- package/lib/experimental_agents/service_agents/wikipedia.js +1 -0
- package/lib/experimental_agents/token_agent.d.ts +11 -1
- package/lib/experimental_agents/token_agent.js +30 -1
- package/lib/graphai.d.ts +3 -3
- package/lib/graphai.js +6 -6
- package/lib/node.js +11 -10
- package/lib/task_manager.js +3 -6
- package/lib/transaction_log.d.ts +1 -1
- package/lib/transaction_log.js +2 -1
- package/lib/type.d.ts +2 -0
- package/lib/utils/test_utils.js +2 -2
- package/package.json +10 -11
package/README.md
CHANGED
|
@@ -317,9 +317,12 @@ flowchart LR
|
|
|
317
317
|
```
|
|
318
318
|
### Conditional Flow
|
|
319
319
|
|
|
320
|
-
|
|
320
|
+
GraphAI provides mechanisms to control the flow of data based on certain conditions. This is achieved through the *if* and *anyInput* properties.
|
|
321
321
|
|
|
322
|
-
|
|
322
|
+
#### If Property
|
|
323
|
+
|
|
324
|
+
The *if* property allows you to specify a condition that must be met for the data to flow into a particular node. The condition is defined by a data source. If the value obtained from the specified *data source* is truthy (i.e., not null, undefined, 0, false, NaN, or an empty array/string), the node will be executed; otherwise, it will be skipped.
|
|
325
|
+
For example, the following node will only be executed if the *tool_calls* property of the message from the LLM contains a value:
|
|
323
326
|
|
|
324
327
|
```typescript
|
|
325
328
|
tool_calls: {
|
|
@@ -331,11 +334,13 @@ A sample code, [weather chat](https://github.com/receptron/graphai/blob/main/sam
|
|
|
331
334
|
// This graph is nested only for the readability.
|
|
332
335
|
```
|
|
333
336
|
|
|
334
|
-
|
|
337
|
+
It is recommended to use the *if* property in conjunction with nested graphs for better code readability and organization.
|
|
338
|
+
|
|
339
|
+
#### AnyInput Property
|
|
335
340
|
|
|
336
|
-
The *anyInput* property (boolean) allows
|
|
341
|
+
The *anyInput* property (boolean) allows you to merge multiple data flow paths into a single node. When set to *true*, the agent function associated with the node will be executed as soon as data becomes available from any of the specified input data sources.
|
|
337
342
|
|
|
338
|
-
|
|
343
|
+
This property is particularly useful when you want to continue the flow regardless of which path the data comes from. In the weather chat sample application, it is used to continue the chat iteration whether a tool was requested by the LLM or not:
|
|
339
344
|
|
|
340
345
|
```typescript
|
|
341
346
|
reducer: {
|
|
@@ -346,17 +351,31 @@ The [weather chat](https://github.com/receptron/graphai/blob/main/samples/sample
|
|
|
346
351
|
},
|
|
347
352
|
```
|
|
348
353
|
|
|
354
|
+
In this example, the "reducer" node will execute as soon as data is available from either the "no_tool_calls" or "tool_calls.messagesWithSecondRes" data source.
|
|
355
|
+
|
|
356
|
+
By combining the *if* and *anyInput* properties, you can create complex conditional flows that control the execution of nodes based on the availability and values of data from various sources. This flexibility allows you to build sophisticated data-driven applications with GraphAI.
|
|
357
|
+
|
|
349
358
|
## Concurrency
|
|
350
359
|
|
|
351
|
-
|
|
360
|
+
GraphAI supports concurrent execution of tasks, allowing you to leverage parallelism and improve performance. The level of concurrency can be controlled through the *concurrency* property at the top level of the graph definition.
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
concurrency: 16 # Maximum number of concurrent tasks
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
If the *concurrency* property is not specified, the default value of 8 is used.
|
|
367
|
+
|
|
368
|
+
### Concurrency and Nested Graphs
|
|
352
369
|
|
|
353
370
|
Since the task queue is shared between the parent graph and the children graph (uness the graph is running remotely), tasks created by the child graph will be bound by the same concurrency specified by the parent graph.
|
|
354
371
|
|
|
355
372
|
Since the task executing the nested graph will be in "running" state while tasks within the child graph are runnig, the concurrency limit will be incremented by one when we start running the child graph and restored when it is completed.
|
|
356
373
|
|
|
357
|
-
|
|
374
|
+
### Task Prioritization
|
|
375
|
+
|
|
376
|
+
By default, tasks are executed in a first-in, first-out (FIFO) order with a neutral priority (0). However, you can assign custom priorities to nodes using the *priority* property. Tasks associated with nodes that have a higher priority value will be executed before those with lower priorities.
|
|
358
377
|
|
|
359
|
-
|
|
378
|
+
Negative priority values are allowed, enabling you to fine-tune the execution order based on your application's requirements.
|
|
360
379
|
|
|
361
380
|
## GraphAI class
|
|
362
381
|
|
|
@@ -5,6 +5,46 @@ declare const dataObjectMergeTemplateAgentInfo: {
|
|
|
5
5
|
agent: AgentFunction;
|
|
6
6
|
mock: AgentFunction;
|
|
7
7
|
samples: ({
|
|
8
|
+
inputs: ({
|
|
9
|
+
content1: string;
|
|
10
|
+
content2?: undefined;
|
|
11
|
+
} | {
|
|
12
|
+
content2: string;
|
|
13
|
+
content1?: undefined;
|
|
14
|
+
})[];
|
|
15
|
+
params: {};
|
|
16
|
+
result: {
|
|
17
|
+
content1: string;
|
|
18
|
+
content2: string;
|
|
19
|
+
content?: undefined;
|
|
20
|
+
a?: undefined;
|
|
21
|
+
b?: undefined;
|
|
22
|
+
};
|
|
23
|
+
} | {
|
|
24
|
+
inputs: {
|
|
25
|
+
content1: string;
|
|
26
|
+
}[];
|
|
27
|
+
params: {};
|
|
28
|
+
result: {
|
|
29
|
+
content1: string;
|
|
30
|
+
content2?: undefined;
|
|
31
|
+
content?: undefined;
|
|
32
|
+
a?: undefined;
|
|
33
|
+
b?: undefined;
|
|
34
|
+
};
|
|
35
|
+
} | {
|
|
36
|
+
inputs: {
|
|
37
|
+
content: string;
|
|
38
|
+
}[];
|
|
39
|
+
params: {};
|
|
40
|
+
result: {
|
|
41
|
+
content: string;
|
|
42
|
+
content1?: undefined;
|
|
43
|
+
content2?: undefined;
|
|
44
|
+
a?: undefined;
|
|
45
|
+
b?: undefined;
|
|
46
|
+
};
|
|
47
|
+
} | {
|
|
8
48
|
inputs: ({
|
|
9
49
|
a: number;
|
|
10
50
|
b: number;
|
|
@@ -72,6 +112,9 @@ declare const dataObjectMergeTemplateAgentInfo: {
|
|
|
72
112
|
};
|
|
73
113
|
};
|
|
74
114
|
};
|
|
115
|
+
content1?: undefined;
|
|
116
|
+
content2?: undefined;
|
|
117
|
+
content?: undefined;
|
|
75
118
|
};
|
|
76
119
|
})[];
|
|
77
120
|
description: string;
|
|
@@ -24,6 +24,28 @@ const dataObjectMergeTemplateAgentInfo = {
|
|
|
24
24
|
agent: exports.dataObjectMergeTemplateAgent,
|
|
25
25
|
mock: exports.dataObjectMergeTemplateAgent,
|
|
26
26
|
samples: [
|
|
27
|
+
{
|
|
28
|
+
inputs: [{ content1: "hello" }, { content2: "test" }],
|
|
29
|
+
params: {},
|
|
30
|
+
result: {
|
|
31
|
+
content1: "hello",
|
|
32
|
+
content2: "test",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
inputs: [{ content1: "hello" }],
|
|
37
|
+
params: {},
|
|
38
|
+
result: {
|
|
39
|
+
content1: "hello",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
inputs: [{ content: "hello1" }, { content: "hello2" }],
|
|
44
|
+
params: {},
|
|
45
|
+
result: {
|
|
46
|
+
content: "hello2",
|
|
47
|
+
},
|
|
48
|
+
},
|
|
27
49
|
{
|
|
28
50
|
inputs: sampleInputs,
|
|
29
51
|
params: sampleParams,
|
|
@@ -21,6 +21,21 @@ const dataSumTemplateAgentInfo = {
|
|
|
21
21
|
params: sampleParams,
|
|
22
22
|
result: sampleResult,
|
|
23
23
|
},
|
|
24
|
+
{
|
|
25
|
+
inputs: [1],
|
|
26
|
+
params: {},
|
|
27
|
+
result: 1,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
inputs: [1, 2],
|
|
31
|
+
params: {},
|
|
32
|
+
result: 3,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
inputs: [1, 2, 3],
|
|
36
|
+
params: {},
|
|
37
|
+
result: 6,
|
|
38
|
+
},
|
|
24
39
|
],
|
|
25
40
|
description: "Returns the sum of input values",
|
|
26
41
|
category: ["data"],
|
|
@@ -2,55 +2,156 @@ import { AgentFunction } from "../../graphai";
|
|
|
2
2
|
export declare const propertyFilterAgent: AgentFunction<{
|
|
3
3
|
include?: Array<string>;
|
|
4
4
|
exclude?: Array<string>;
|
|
5
|
+
alter?: Record<string, Record<string, string>>;
|
|
6
|
+
inject?: Record<string, Record<string, any>>;
|
|
5
7
|
}>;
|
|
6
8
|
declare const propertyFilterAgentInfo: {
|
|
7
9
|
name: string;
|
|
8
10
|
agent: AgentFunction<{
|
|
9
11
|
include?: string[] | undefined;
|
|
10
12
|
exclude?: string[] | undefined;
|
|
13
|
+
alter?: Record<string, Record<string, string>> | undefined;
|
|
14
|
+
inject?: Record<string, Record<string, any>> | undefined;
|
|
11
15
|
}>;
|
|
12
16
|
mock: AgentFunction<{
|
|
13
17
|
include?: string[] | undefined;
|
|
14
18
|
exclude?: string[] | undefined;
|
|
19
|
+
alter?: Record<string, Record<string, string>> | undefined;
|
|
20
|
+
inject?: Record<string, Record<string, any>> | undefined;
|
|
15
21
|
}>;
|
|
16
22
|
samples: ({
|
|
17
|
-
inputs: {
|
|
23
|
+
inputs: (string | {
|
|
18
24
|
color: string;
|
|
19
25
|
model: string;
|
|
20
26
|
type: string;
|
|
21
27
|
maker: string;
|
|
22
28
|
range: number;
|
|
23
|
-
}[];
|
|
29
|
+
})[];
|
|
24
30
|
params: {
|
|
25
31
|
include: string[];
|
|
26
32
|
exclude?: undefined;
|
|
33
|
+
alter?: undefined;
|
|
34
|
+
inject?: undefined;
|
|
27
35
|
};
|
|
28
36
|
result: {
|
|
29
37
|
color: string;
|
|
30
38
|
model: string;
|
|
31
|
-
type?: undefined;
|
|
32
|
-
maker?: undefined;
|
|
33
|
-
range?: undefined;
|
|
34
39
|
};
|
|
35
40
|
} | {
|
|
36
|
-
inputs: {
|
|
41
|
+
inputs: (string | {
|
|
37
42
|
color: string;
|
|
38
43
|
model: string;
|
|
39
44
|
type: string;
|
|
40
45
|
maker: string;
|
|
41
46
|
range: number;
|
|
47
|
+
}[])[];
|
|
48
|
+
params: {
|
|
49
|
+
include: string[];
|
|
50
|
+
exclude?: undefined;
|
|
51
|
+
alter?: undefined;
|
|
52
|
+
inject?: undefined;
|
|
53
|
+
};
|
|
54
|
+
result: {
|
|
55
|
+
color: string;
|
|
56
|
+
model: string;
|
|
42
57
|
}[];
|
|
58
|
+
} | {
|
|
59
|
+
inputs: (string | {
|
|
60
|
+
color: string;
|
|
61
|
+
model: string;
|
|
62
|
+
type: string;
|
|
63
|
+
maker: string;
|
|
64
|
+
range: number;
|
|
65
|
+
}[])[];
|
|
43
66
|
params: {
|
|
44
67
|
exclude: string[];
|
|
45
68
|
include?: undefined;
|
|
69
|
+
alter?: undefined;
|
|
70
|
+
inject?: undefined;
|
|
46
71
|
};
|
|
47
72
|
result: {
|
|
48
73
|
type: string;
|
|
49
74
|
maker: string;
|
|
50
75
|
range: number;
|
|
51
|
-
|
|
52
|
-
|
|
76
|
+
}[];
|
|
77
|
+
} | {
|
|
78
|
+
inputs: (string | {
|
|
79
|
+
color: string;
|
|
80
|
+
model: string;
|
|
81
|
+
type: string;
|
|
82
|
+
maker: string;
|
|
83
|
+
range: number;
|
|
84
|
+
}[])[];
|
|
85
|
+
params: {
|
|
86
|
+
alter: {
|
|
87
|
+
color: {
|
|
88
|
+
red: string;
|
|
89
|
+
blue: string;
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
include?: undefined;
|
|
93
|
+
exclude?: undefined;
|
|
94
|
+
inject?: undefined;
|
|
53
95
|
};
|
|
96
|
+
result: {
|
|
97
|
+
color: string;
|
|
98
|
+
model: string;
|
|
99
|
+
type: string;
|
|
100
|
+
maker: string;
|
|
101
|
+
range: number;
|
|
102
|
+
}[];
|
|
103
|
+
} | {
|
|
104
|
+
inputs: (string | {
|
|
105
|
+
color: string;
|
|
106
|
+
model: string;
|
|
107
|
+
type: string;
|
|
108
|
+
maker: string;
|
|
109
|
+
range: number;
|
|
110
|
+
}[])[];
|
|
111
|
+
params: {
|
|
112
|
+
inject: {
|
|
113
|
+
maker: {
|
|
114
|
+
from: number;
|
|
115
|
+
index?: undefined;
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
include?: undefined;
|
|
119
|
+
exclude?: undefined;
|
|
120
|
+
alter?: undefined;
|
|
121
|
+
};
|
|
122
|
+
result: {
|
|
123
|
+
color: string;
|
|
124
|
+
model: string;
|
|
125
|
+
type: string;
|
|
126
|
+
maker: string;
|
|
127
|
+
range: number;
|
|
128
|
+
}[];
|
|
129
|
+
} | {
|
|
130
|
+
inputs: (string | {
|
|
131
|
+
color: string;
|
|
132
|
+
model: string;
|
|
133
|
+
type: string;
|
|
134
|
+
maker: string;
|
|
135
|
+
range: number;
|
|
136
|
+
}[])[];
|
|
137
|
+
params: {
|
|
138
|
+
inject: {
|
|
139
|
+
maker: {
|
|
140
|
+
index: number;
|
|
141
|
+
from: number;
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
include?: undefined;
|
|
145
|
+
exclude?: undefined;
|
|
146
|
+
alter?: undefined;
|
|
147
|
+
};
|
|
148
|
+
result: {
|
|
149
|
+
color: string;
|
|
150
|
+
model: string;
|
|
151
|
+
type: string;
|
|
152
|
+
maker: string;
|
|
153
|
+
range: number;
|
|
154
|
+
}[];
|
|
54
155
|
})[];
|
|
55
156
|
description: string;
|
|
56
157
|
category: string[];
|
|
@@ -1,40 +1,91 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.propertyFilterAgent = void 0;
|
|
4
|
-
const applyFilter = (input, include, exclude) => {
|
|
4
|
+
const applyFilter = (input, index, inputs, include, exclude, alter, inject) => {
|
|
5
5
|
const propIds = include ? include : Object.keys(input);
|
|
6
6
|
const excludeSet = new Set(exclude ?? []);
|
|
7
7
|
return propIds.reduce((tmp, propId) => {
|
|
8
8
|
if (!excludeSet.has(propId)) {
|
|
9
|
-
|
|
9
|
+
const injection = inject && inject[propId];
|
|
10
|
+
const mapping = alter && alter[propId];
|
|
11
|
+
if (injection && (injection.index === undefined || injection.index === index)) {
|
|
12
|
+
tmp[propId] = inputs[injection.from];
|
|
13
|
+
}
|
|
14
|
+
else if (mapping && mapping[input[propId]]) {
|
|
15
|
+
tmp[propId] = mapping[input[propId]];
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
tmp[propId] = input[propId];
|
|
19
|
+
}
|
|
10
20
|
}
|
|
11
21
|
return tmp;
|
|
12
22
|
}, {});
|
|
13
23
|
};
|
|
14
24
|
const propertyFilterAgent = async ({ inputs, params }) => {
|
|
15
25
|
const [input] = inputs;
|
|
16
|
-
const { include, exclude } = params;
|
|
26
|
+
const { include, exclude, alter, inject } = params;
|
|
17
27
|
if (Array.isArray(input)) {
|
|
18
|
-
return input.map((item) => applyFilter(item, include, exclude));
|
|
28
|
+
return input.map((item, index) => applyFilter(item, index, inputs, include, exclude, alter, inject));
|
|
19
29
|
}
|
|
20
|
-
return applyFilter(input, include, exclude);
|
|
30
|
+
return applyFilter(input, 0, inputs, include, exclude, alter);
|
|
21
31
|
};
|
|
22
32
|
exports.propertyFilterAgent = propertyFilterAgent;
|
|
23
|
-
const
|
|
33
|
+
const testInputs = [
|
|
34
|
+
[
|
|
35
|
+
{ color: "red", model: "Model 3", type: "EV", maker: "Tesla", range: 300 },
|
|
36
|
+
{ color: "blue", model: "Model Y", type: "EV", maker: "Tesla", range: 400 },
|
|
37
|
+
],
|
|
38
|
+
"Tesla Motors",
|
|
39
|
+
];
|
|
24
40
|
const propertyFilterAgentInfo = {
|
|
25
41
|
name: "propertyFilterAgent",
|
|
26
42
|
agent: exports.propertyFilterAgent,
|
|
27
43
|
mock: exports.propertyFilterAgent,
|
|
28
44
|
samples: [
|
|
29
45
|
{
|
|
30
|
-
inputs,
|
|
46
|
+
inputs: [testInputs[0][0]],
|
|
31
47
|
params: { include: ["color", "model"] },
|
|
32
48
|
result: { color: "red", model: "Model 3" },
|
|
33
49
|
},
|
|
34
50
|
{
|
|
35
|
-
inputs,
|
|
51
|
+
inputs: testInputs,
|
|
52
|
+
params: { include: ["color", "model"] },
|
|
53
|
+
result: [
|
|
54
|
+
{ color: "red", model: "Model 3" },
|
|
55
|
+
{ color: "blue", model: "Model Y" },
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
inputs: testInputs,
|
|
36
60
|
params: { exclude: ["color", "model"] },
|
|
37
|
-
result:
|
|
61
|
+
result: [
|
|
62
|
+
{ type: "EV", maker: "Tesla", range: 300 },
|
|
63
|
+
{ type: "EV", maker: "Tesla", range: 400 },
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
inputs: testInputs,
|
|
68
|
+
params: { alter: { color: { red: "blue", blue: "red" } } },
|
|
69
|
+
result: [
|
|
70
|
+
{ color: "blue", model: "Model 3", type: "EV", maker: "Tesla", range: 300 },
|
|
71
|
+
{ color: "red", model: "Model Y", type: "EV", maker: "Tesla", range: 400 },
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
inputs: testInputs,
|
|
76
|
+
params: { inject: { maker: { from: 1 } } },
|
|
77
|
+
result: [
|
|
78
|
+
{ color: "red", model: "Model 3", type: "EV", maker: "Tesla Motors", range: 300 },
|
|
79
|
+
{ color: "blue", model: "Model Y", type: "EV", maker: "Tesla Motors", range: 400 },
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
inputs: testInputs,
|
|
84
|
+
params: { inject: { maker: { index: 0, from: 1 } } },
|
|
85
|
+
result: [
|
|
86
|
+
{ color: "red", model: "Model 3", type: "EV", maker: "Tesla Motors", range: 300 },
|
|
87
|
+
{ color: "blue", model: "Model Y", type: "EV", maker: "Tesla", range: 400 },
|
|
88
|
+
],
|
|
38
89
|
},
|
|
39
90
|
],
|
|
40
91
|
description: "Filter properties based on property name either with 'include' or 'exclude'",
|
|
@@ -37,6 +37,19 @@ declare const totalAgentInfo: {
|
|
|
37
37
|
c: number;
|
|
38
38
|
d: number;
|
|
39
39
|
};
|
|
40
|
+
} | {
|
|
41
|
+
inputs: ({
|
|
42
|
+
a: number;
|
|
43
|
+
b?: undefined;
|
|
44
|
+
} | {
|
|
45
|
+
a: number;
|
|
46
|
+
b: number;
|
|
47
|
+
})[];
|
|
48
|
+
params: {};
|
|
49
|
+
result: {
|
|
50
|
+
a: number;
|
|
51
|
+
b: number;
|
|
52
|
+
};
|
|
40
53
|
})[];
|
|
41
54
|
description: string;
|
|
42
55
|
category: string[];
|
|
@@ -42,6 +42,35 @@ const totalAgentInfo = {
|
|
|
42
42
|
params: sample2Params,
|
|
43
43
|
result: sample2Result,
|
|
44
44
|
},
|
|
45
|
+
{
|
|
46
|
+
inputs: [{ a: 1 }],
|
|
47
|
+
params: {},
|
|
48
|
+
result: { a: 1 },
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
inputs: [{ a: 1 }, { a: 2 }],
|
|
52
|
+
params: {},
|
|
53
|
+
result: { a: 3 },
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
inputs: [{ a: 1 }, { a: 2 }, { a: 3 }],
|
|
57
|
+
params: {},
|
|
58
|
+
result: { a: 6 },
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
inputs: [
|
|
62
|
+
{ a: 1, b: 1 },
|
|
63
|
+
{ a: 2, b: 2 },
|
|
64
|
+
{ a: 3, b: 0 },
|
|
65
|
+
],
|
|
66
|
+
params: {},
|
|
67
|
+
result: { a: 6, b: 3 },
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
inputs: [{ a: 1 }, { a: 2, b: 2 }, { a: 3, b: 0 }],
|
|
71
|
+
params: {},
|
|
72
|
+
result: { a: 6, b: 2 },
|
|
73
|
+
},
|
|
45
74
|
],
|
|
46
75
|
description: "Returns the sum of input values",
|
|
47
76
|
category: ["data"],
|
|
@@ -4,7 +4,7 @@ exports.mapAgent = void 0;
|
|
|
4
4
|
const graphai_1 = require("../../graphai");
|
|
5
5
|
const utils_1 = require("../../utils/utils");
|
|
6
6
|
const nested_agent_1 = require("./nested_agent");
|
|
7
|
-
const mapAgent = async ({ params, inputs, agents, log, taskManager, graphData }) => {
|
|
7
|
+
const mapAgent = async ({ params, inputs, agents, log, taskManager, graphData, agentFilters }) => {
|
|
8
8
|
if (taskManager) {
|
|
9
9
|
const status = taskManager.getStatus();
|
|
10
10
|
(0, utils_1.assert)(status.concurrency > status.running, `mapAgent: Concurrency is too low: ${status.concurrency}`);
|
|
@@ -25,7 +25,7 @@ const mapAgent = async ({ params, inputs, agents, log, taskManager, graphData })
|
|
|
25
25
|
}
|
|
26
26
|
});
|
|
27
27
|
const graphs = input.map((data) => {
|
|
28
|
-
const graphAI = new graphai_1.GraphAI(nestedGraphData, agents || {}, { taskManager });
|
|
28
|
+
const graphAI = new graphai_1.GraphAI(nestedGraphData, agents || {}, { taskManager, agentFilters: agentFilters || [] });
|
|
29
29
|
// Only the first input will be mapped
|
|
30
30
|
injectionTo.forEach((injectToNodeId, index) => {
|
|
31
31
|
graphAI.injectValue(injectToNodeId, index === 0 ? data : inputs[index], "__mapAgent_inputs__");
|
|
@@ -21,27 +21,24 @@ const getNestedGraphData = (graphData, inputs) => {
|
|
|
21
21
|
return graphData;
|
|
22
22
|
};
|
|
23
23
|
exports.getNestedGraphData = getNestedGraphData;
|
|
24
|
-
const nestedAgent = async ({ params, inputs, agents, log, taskManager, graphData }) => {
|
|
24
|
+
const nestedAgent = async ({ params, inputs, agents, log, taskManager, graphData, agentFilters }) => {
|
|
25
25
|
if (taskManager) {
|
|
26
26
|
const status = taskManager.getStatus(false);
|
|
27
27
|
(0, utils_1.assert)(status.concurrency > status.running, `nestedAgent: Concurrency is too low: ${status.concurrency}`);
|
|
28
28
|
}
|
|
29
29
|
const nestedGraphData = (0, exports.getNestedGraphData)(graphData, inputs);
|
|
30
|
-
const injectionTo = params.injectionTo ??
|
|
31
|
-
|
|
32
|
-
return `$${index}`;
|
|
33
|
-
});
|
|
34
|
-
injectionTo.forEach((nodeId) => {
|
|
30
|
+
const injectionTo = params.injectionTo ?? inputs.map((__input, index) => `$${index}`);
|
|
31
|
+
injectionTo.forEach((nodeId, index) => {
|
|
35
32
|
if (nestedGraphData.nodes[nodeId] === undefined) {
|
|
36
33
|
// If the input node does not exist, automatically create a static node
|
|
37
|
-
nestedGraphData.nodes[nodeId] = { value:
|
|
34
|
+
nestedGraphData.nodes[nodeId] = { value: inputs[index] };
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// Otherwise, inject the proper data here (instead of calling injectTo method later)
|
|
38
|
+
nestedGraphData.nodes[nodeId]["value"] = inputs[index];
|
|
38
39
|
}
|
|
39
40
|
});
|
|
40
|
-
const graphAI = new graphai_1.GraphAI(nestedGraphData, agents || {}, { taskManager });
|
|
41
|
-
// Inject inputs to specified source nodes
|
|
42
|
-
injectionTo.forEach((injectToNodeId, index) => {
|
|
43
|
-
graphAI.injectValue(injectToNodeId, inputs[index]);
|
|
44
|
-
});
|
|
41
|
+
const graphAI = new graphai_1.GraphAI(nestedGraphData, agents || {}, { taskManager, agentFilters });
|
|
45
42
|
const results = await graphAI.run(false);
|
|
46
43
|
log?.push(...graphAI.transactionLogs());
|
|
47
44
|
return results;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { AgentFunction } from "../../graphai";
|
|
2
|
+
import { Groq } from "groq-sdk";
|
|
3
|
+
export declare const groqStreamAgent: AgentFunction<{
|
|
4
|
+
model: string;
|
|
5
|
+
query?: string;
|
|
6
|
+
system?: string;
|
|
7
|
+
verbose?: boolean;
|
|
8
|
+
tools?: Groq.Chat.CompletionCreateParams.Tool[];
|
|
9
|
+
temperature?: number;
|
|
10
|
+
max_tokens?: number;
|
|
11
|
+
tool_choice?: Groq.Chat.CompletionCreateParams.ToolChoice;
|
|
12
|
+
}, any, string | Array<Groq.Chat.CompletionCreateParams.Message>>;
|
|
13
|
+
declare const groqStreamAgentInfo: {
|
|
14
|
+
name: string;
|
|
15
|
+
agent: AgentFunction<{
|
|
16
|
+
model: string;
|
|
17
|
+
query?: string | undefined;
|
|
18
|
+
system?: string | undefined;
|
|
19
|
+
verbose?: boolean | undefined;
|
|
20
|
+
tools?: Groq.Chat.Completions.CompletionCreateParams.Tool[] | undefined;
|
|
21
|
+
temperature?: number | undefined;
|
|
22
|
+
max_tokens?: number | undefined;
|
|
23
|
+
tool_choice?: Groq.Chat.Completions.CompletionCreateParams.ToolChoice | undefined;
|
|
24
|
+
}, any, string | Groq.Chat.Completions.CompletionCreateParams.Message[]>;
|
|
25
|
+
mock: AgentFunction<{
|
|
26
|
+
model: string;
|
|
27
|
+
query?: string | undefined;
|
|
28
|
+
system?: string | undefined;
|
|
29
|
+
verbose?: boolean | undefined;
|
|
30
|
+
tools?: Groq.Chat.Completions.CompletionCreateParams.Tool[] | undefined;
|
|
31
|
+
temperature?: number | undefined;
|
|
32
|
+
max_tokens?: number | undefined;
|
|
33
|
+
tool_choice?: Groq.Chat.Completions.CompletionCreateParams.ToolChoice | undefined;
|
|
34
|
+
}, any, string | Groq.Chat.Completions.CompletionCreateParams.Message[]>;
|
|
35
|
+
samples: never[];
|
|
36
|
+
description: string;
|
|
37
|
+
category: string[];
|
|
38
|
+
author: string;
|
|
39
|
+
repository: string;
|
|
40
|
+
license: string;
|
|
41
|
+
};
|
|
42
|
+
export default groqStreamAgentInfo;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.groqStreamAgent = void 0;
|
|
4
|
+
const groq_sdk_1 = require("groq-sdk");
|
|
5
|
+
const utils_1 = require("../../utils/utils");
|
|
6
|
+
const groq = process.env.GROQ_API_KEY ? new groq_sdk_1.Groq({ apiKey: process.env.GROQ_API_KEY }) : undefined;
|
|
7
|
+
//
|
|
8
|
+
// This agent takes two optional inputs, and following parameters.
|
|
9
|
+
// inputs:
|
|
10
|
+
// - [0]: query string (typically from the user), optional
|
|
11
|
+
// - [1]: array of messages from previous conversation, optional
|
|
12
|
+
//
|
|
13
|
+
// params:
|
|
14
|
+
// - model: LLM model (Llama3-8b-8192, Llama3-70b-8192, Mixtral-8x7b-32768), required.
|
|
15
|
+
// - query: Additional query string from the app to prepend the query from the user, optional.
|
|
16
|
+
// - system: System prompt (ignored if inputs[1] is specified), optional
|
|
17
|
+
// - tools: Function definitions, optional
|
|
18
|
+
// - tool_choice: Tool choice parameter, optional (default = "auto")
|
|
19
|
+
// - temperature: Controls randomness of responses, optional (default = 0.7)
|
|
20
|
+
// - max_tokens: The maximum number of tokens that the model can process in a single response, optional.
|
|
21
|
+
// - verbose: dumps the message array to the debug console, before sending it the LLM.
|
|
22
|
+
//
|
|
23
|
+
// https://console.groq.com/docs/quickstart
|
|
24
|
+
//
|
|
25
|
+
const groqStreamAgent = async ({ params, inputs, filterParams }) => {
|
|
26
|
+
(0, utils_1.assert)(groq !== undefined, "The GROQ_API_KEY environment variable is missing.");
|
|
27
|
+
const { verbose, query, system, tools, tool_choice, max_tokens, temperature } = params;
|
|
28
|
+
const [input_query, previous_messages] = inputs;
|
|
29
|
+
// Notice that we ignore params.system if previous_message exists.
|
|
30
|
+
const messages = previous_messages && Array.isArray(previous_messages) ? previous_messages : system ? [{ role: "system", content: system }] : [];
|
|
31
|
+
const content = (query ? [query] : []).concat(input_query && typeof input_query === "string" ? [input_query] : []).join("\n");
|
|
32
|
+
if (content) {
|
|
33
|
+
messages.push({
|
|
34
|
+
role: "user",
|
|
35
|
+
content,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
if (verbose) {
|
|
39
|
+
console.log(messages);
|
|
40
|
+
}
|
|
41
|
+
const options = {
|
|
42
|
+
messages,
|
|
43
|
+
model: params.model,
|
|
44
|
+
temperature: temperature ?? 0.7,
|
|
45
|
+
stream: true,
|
|
46
|
+
};
|
|
47
|
+
if (max_tokens) {
|
|
48
|
+
options.max_tokens = max_tokens;
|
|
49
|
+
}
|
|
50
|
+
if (tools) {
|
|
51
|
+
options.tools = tools;
|
|
52
|
+
options.tool_choice = tool_choice ?? "auto";
|
|
53
|
+
}
|
|
54
|
+
const stream = await groq.chat.completions.create(options);
|
|
55
|
+
let lastMessage = null;
|
|
56
|
+
const contents = [];
|
|
57
|
+
for await (const message of stream) {
|
|
58
|
+
const token = message.choices[0].delta.content;
|
|
59
|
+
if (token) {
|
|
60
|
+
if (filterParams && filterParams.streamTokenCallback) {
|
|
61
|
+
filterParams.streamTokenCallback(token);
|
|
62
|
+
}
|
|
63
|
+
contents.push(token);
|
|
64
|
+
}
|
|
65
|
+
lastMessage = message;
|
|
66
|
+
}
|
|
67
|
+
if (lastMessage) {
|
|
68
|
+
lastMessage.choices[0]["message"] = [{ role: "assistant", content: contents.join("") }];
|
|
69
|
+
}
|
|
70
|
+
return lastMessage;
|
|
71
|
+
};
|
|
72
|
+
exports.groqStreamAgent = groqStreamAgent;
|
|
73
|
+
const groqStreamAgentInfo = {
|
|
74
|
+
name: "groqStreamAgent",
|
|
75
|
+
agent: exports.groqStreamAgent,
|
|
76
|
+
mock: exports.groqStreamAgent,
|
|
77
|
+
samples: [],
|
|
78
|
+
description: "Groq Stream Agent",
|
|
79
|
+
category: ["llm"],
|
|
80
|
+
author: "Receptron team",
|
|
81
|
+
repository: "https://github.com/receptron/graphai",
|
|
82
|
+
license: "MIT",
|
|
83
|
+
};
|
|
84
|
+
exports.default = groqStreamAgentInfo;
|
|
@@ -14,5 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./openai_agent"), exports);
|
|
17
18
|
__exportStar(require("./slashgpt_agent"), exports);
|
|
18
19
|
__exportStar(require("./groq_agent"), exports);
|
|
20
|
+
__exportStar(require("./groq_stream_agent"), exports);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import groqAgent from "../../experimental_agents/llm_agents/groq_agent";
|
|
2
|
+
import groqStreamAgent from "../../experimental_agents/llm_agents/groq_stream_agent";
|
|
2
3
|
import slashGPTAgent from "../../experimental_agents/llm_agents/slashgpt_agent";
|
|
3
|
-
|
|
4
|
+
import openAIAgent from "../../experimental_agents/llm_agents/openai_agent";
|
|
5
|
+
export { groqAgent, groqStreamAgent, slashGPTAgent, openAIAgent };
|
|
@@ -3,8 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.slashGPTAgent = exports.groqAgent = void 0;
|
|
6
|
+
exports.openAIAgent = exports.slashGPTAgent = exports.groqStreamAgent = exports.groqAgent = void 0;
|
|
7
7
|
const groq_agent_1 = __importDefault(require("../../experimental_agents/llm_agents/groq_agent"));
|
|
8
8
|
exports.groqAgent = groq_agent_1.default;
|
|
9
|
+
const groq_stream_agent_1 = __importDefault(require("../../experimental_agents/llm_agents/groq_stream_agent"));
|
|
10
|
+
exports.groqStreamAgent = groq_stream_agent_1.default;
|
|
9
11
|
const slashgpt_agent_1 = __importDefault(require("../../experimental_agents/llm_agents/slashgpt_agent"));
|
|
10
12
|
exports.slashGPTAgent = slashgpt_agent_1.default;
|
|
13
|
+
const openai_agent_1 = __importDefault(require("../../experimental_agents/llm_agents/openai_agent"));
|
|
14
|
+
exports.openAIAgent = openai_agent_1.default;
|
|
@@ -39,6 +39,17 @@ const dotProductAgentInfo = {
|
|
|
39
39
|
params: {},
|
|
40
40
|
result: [7, 17, 27],
|
|
41
41
|
},
|
|
42
|
+
{
|
|
43
|
+
inputs: [
|
|
44
|
+
[
|
|
45
|
+
[1, 2],
|
|
46
|
+
[2, 3],
|
|
47
|
+
],
|
|
48
|
+
[1, 2],
|
|
49
|
+
],
|
|
50
|
+
params: {},
|
|
51
|
+
result: [5, 8],
|
|
52
|
+
},
|
|
42
53
|
],
|
|
43
54
|
description: "dotProduct Agent",
|
|
44
55
|
category: [],
|
|
@@ -10,7 +10,19 @@ declare const sortByValuesAgentInfo: {
|
|
|
10
10
|
mock: AgentFunction<{
|
|
11
11
|
assendant?: boolean | undefined;
|
|
12
12
|
}, any[], any[]>;
|
|
13
|
-
samples:
|
|
13
|
+
samples: ({
|
|
14
|
+
inputs: (string[] | number[])[];
|
|
15
|
+
params: {
|
|
16
|
+
assendant?: undefined;
|
|
17
|
+
};
|
|
18
|
+
result: string[];
|
|
19
|
+
} | {
|
|
20
|
+
inputs: (string[] | number[])[];
|
|
21
|
+
params: {
|
|
22
|
+
assendant: boolean;
|
|
23
|
+
};
|
|
24
|
+
result: string[];
|
|
25
|
+
})[];
|
|
14
26
|
description: string;
|
|
15
27
|
category: never[];
|
|
16
28
|
author: string;
|
|
@@ -31,7 +31,26 @@ const sortByValuesAgentInfo = {
|
|
|
31
31
|
name: "sortByValuesAgent",
|
|
32
32
|
agent: exports.sortByValuesAgent,
|
|
33
33
|
mock: exports.sortByValuesAgent,
|
|
34
|
-
samples: [
|
|
34
|
+
samples: [
|
|
35
|
+
{
|
|
36
|
+
inputs: [
|
|
37
|
+
["banana", "orange", "lemon", "apple"],
|
|
38
|
+
[2, 5, 6, 4],
|
|
39
|
+
],
|
|
40
|
+
params: {},
|
|
41
|
+
result: ["lemon", "orange", "apple", "banana"],
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
inputs: [
|
|
45
|
+
["banana", "orange", "lemon", "apple"],
|
|
46
|
+
[2, 5, 6, 4],
|
|
47
|
+
],
|
|
48
|
+
params: {
|
|
49
|
+
assendant: true,
|
|
50
|
+
},
|
|
51
|
+
result: ["banana", "apple", "orange", "lemon"],
|
|
52
|
+
},
|
|
53
|
+
],
|
|
35
54
|
description: "sortByValues Agent",
|
|
36
55
|
category: [],
|
|
37
56
|
author: "Receptron team",
|
|
@@ -3,6 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.fetchAgent = void 0;
|
|
6
|
+
exports.wikipediaAgent = exports.fetchAgent = void 0;
|
|
7
|
+
const wikipedia_1 = __importDefault(require("../../experimental_agents/service_agents/wikipedia"));
|
|
8
|
+
exports.wikipediaAgent = wikipedia_1.default;
|
|
7
9
|
const fetch_agent_1 = __importDefault(require("../../experimental_agents/service_agents/fetch_agent"));
|
|
8
10
|
exports.fetchAgent = fetch_agent_1.default;
|
|
@@ -16,7 +16,17 @@ declare const tokenBoundStringsAgentInfo: {
|
|
|
16
16
|
}, {
|
|
17
17
|
content: string;
|
|
18
18
|
}, string[]>;
|
|
19
|
-
samples:
|
|
19
|
+
samples: {
|
|
20
|
+
inputs: string[][];
|
|
21
|
+
params: {
|
|
22
|
+
limit: number;
|
|
23
|
+
};
|
|
24
|
+
result: {
|
|
25
|
+
content: string;
|
|
26
|
+
tokenCount: number;
|
|
27
|
+
endIndex: number;
|
|
28
|
+
};
|
|
29
|
+
}[];
|
|
20
30
|
description: string;
|
|
21
31
|
category: never[];
|
|
22
32
|
author: string;
|
|
@@ -35,7 +35,36 @@ const tokenBoundStringsAgentInfo = {
|
|
|
35
35
|
name: "tokenBoundStringsAgent",
|
|
36
36
|
agent: exports.tokenBoundStringsAgent,
|
|
37
37
|
mock: exports.tokenBoundStringsAgent,
|
|
38
|
-
samples: [
|
|
38
|
+
samples: [
|
|
39
|
+
{
|
|
40
|
+
inputs: [
|
|
41
|
+
[
|
|
42
|
+
"Here's to the crazy ones. The misfits. The rebels. The troublemakers.",
|
|
43
|
+
"The round pegs in the square holes. The ones who see things differently.",
|
|
44
|
+
"They're not fond of rules. And they have no respect for the status quo.",
|
|
45
|
+
"You can quote them, disagree with them, glorify or vilify them.",
|
|
46
|
+
"About the only thing you can't do is ignore them.",
|
|
47
|
+
"Because they change things.",
|
|
48
|
+
"They push the human race forward.",
|
|
49
|
+
"And while some may see them as the crazy ones, we see genius.",
|
|
50
|
+
"Because the people who are crazy enough to think they can change the world, are the ones who do.",
|
|
51
|
+
],
|
|
52
|
+
],
|
|
53
|
+
params: {
|
|
54
|
+
limit: 80,
|
|
55
|
+
},
|
|
56
|
+
result: {
|
|
57
|
+
content: "Here's to the crazy ones. The misfits. The rebels. The troublemakers.\n" +
|
|
58
|
+
"The round pegs in the square holes. The ones who see things differently.\n" +
|
|
59
|
+
"They're not fond of rules. And they have no respect for the status quo.\n" +
|
|
60
|
+
"You can quote them, disagree with them, glorify or vilify them.\n" +
|
|
61
|
+
"About the only thing you can't do is ignore them.\n" +
|
|
62
|
+
"Because they change things.",
|
|
63
|
+
tokenCount: 79,
|
|
64
|
+
endIndex: 6,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
],
|
|
39
68
|
description: "token bound Agent",
|
|
40
69
|
category: [],
|
|
41
70
|
author: "Receptron team",
|
package/lib/graphai.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export declare class GraphAI {
|
|
|
10
10
|
private readonly data;
|
|
11
11
|
private readonly loop?;
|
|
12
12
|
private readonly logs;
|
|
13
|
-
readonly
|
|
13
|
+
readonly agentFunctionDictionary: AgentFunctionDictonary;
|
|
14
14
|
readonly taskManager: TaskManager;
|
|
15
15
|
readonly agentFilters: AgentFilterInfo[];
|
|
16
16
|
readonly retryLimit?: number;
|
|
@@ -22,11 +22,11 @@ export declare class GraphAI {
|
|
|
22
22
|
private createNodes;
|
|
23
23
|
private getValueFromResults;
|
|
24
24
|
private initializeNodes;
|
|
25
|
-
constructor(data: GraphData,
|
|
25
|
+
constructor(data: GraphData, agentFunctionDictionary: AgentFunctionDictonary, options?: {
|
|
26
26
|
agentFilters?: AgentFilterInfo[] | undefined;
|
|
27
27
|
taskManager?: TaskManager | undefined;
|
|
28
28
|
});
|
|
29
|
-
|
|
29
|
+
getAgentFunction(agentId?: string): import("./type").AgentFunction<any, any, any>;
|
|
30
30
|
asString(): string;
|
|
31
31
|
results<T = DefaultResultData>(all: boolean): ResultDataDictonary<T>;
|
|
32
32
|
errors(): Record<string, Error>;
|
package/lib/graphai.js
CHANGED
|
@@ -63,7 +63,7 @@ class GraphAI {
|
|
|
63
63
|
}
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
|
-
constructor(data,
|
|
66
|
+
constructor(data, agentFunctionDictionary, options = { taskManager: undefined, agentFilters: [] }) {
|
|
67
67
|
this.logs = [];
|
|
68
68
|
this.onLogCallback = (__log, __isUpdate) => { };
|
|
69
69
|
this.repeatCount = 0;
|
|
@@ -77,7 +77,7 @@ class GraphAI {
|
|
|
77
77
|
this.retryLimit = data.retry; // optional
|
|
78
78
|
this.graphId = URL.createObjectURL(new Blob()).slice(-36);
|
|
79
79
|
this.data = data;
|
|
80
|
-
this.
|
|
80
|
+
this.agentFunctionDictionary = agentFunctionDictionary;
|
|
81
81
|
this.taskManager = options.taskManager ?? new task_manager_1.TaskManager(data.concurrency ?? defaultConcurrency);
|
|
82
82
|
this.agentFilters = options.agentFilters ?? [];
|
|
83
83
|
this.loop = data.loop;
|
|
@@ -85,13 +85,13 @@ class GraphAI {
|
|
|
85
85
|
this.onComplete = () => {
|
|
86
86
|
console.error("-- SOMETHING IS WRONG: onComplete is called without run()");
|
|
87
87
|
};
|
|
88
|
-
(0, validator_1.validateGraphData)(data, Object.keys(
|
|
88
|
+
(0, validator_1.validateGraphData)(data, Object.keys(agentFunctionDictionary));
|
|
89
89
|
this.nodes = this.createNodes(data);
|
|
90
90
|
this.initializeNodes();
|
|
91
91
|
}
|
|
92
|
-
|
|
93
|
-
if (agentId && this.
|
|
94
|
-
return this.
|
|
92
|
+
getAgentFunction(agentId) {
|
|
93
|
+
if (agentId && this.agentFunctionDictionary[agentId]) {
|
|
94
|
+
return this.agentFunctionDictionary[agentId];
|
|
95
95
|
}
|
|
96
96
|
throw new Error("No agent: " + agentId);
|
|
97
97
|
}
|
package/lib/node.js
CHANGED
|
@@ -71,7 +71,7 @@ class ComputedNode extends Node {
|
|
|
71
71
|
}
|
|
72
72
|
return tmp;
|
|
73
73
|
}, {});
|
|
74
|
-
this.log.initForComputedNode(this);
|
|
74
|
+
this.log.initForComputedNode(this, graph);
|
|
75
75
|
}
|
|
76
76
|
getAgentId() {
|
|
77
77
|
return this.agentId ?? "__custom__function"; // only for display purpose in the log.
|
|
@@ -167,20 +167,20 @@ class ComputedNode extends Node {
|
|
|
167
167
|
}
|
|
168
168
|
return !agentFilter.agentIds && !agentFilter.nodeIds;
|
|
169
169
|
}
|
|
170
|
-
agentFilterHandler(context,
|
|
170
|
+
agentFilterHandler(context, agentFunction) {
|
|
171
171
|
let index = 0;
|
|
172
|
-
const next = (
|
|
172
|
+
const next = (innerContext) => {
|
|
173
173
|
const agentFilter = this.graph.agentFilters[index++];
|
|
174
174
|
if (agentFilter) {
|
|
175
175
|
if (this.shouldApplyAgentFilter(agentFilter)) {
|
|
176
176
|
if (agentFilter.filterParams) {
|
|
177
|
-
|
|
177
|
+
innerContext.filterParams = { ...agentFilter.filterParams, ...innerContext.filterParams };
|
|
178
178
|
}
|
|
179
|
-
return agentFilter.agent(
|
|
179
|
+
return agentFilter.agent(innerContext, next);
|
|
180
180
|
}
|
|
181
|
-
return next(
|
|
181
|
+
return next(innerContext);
|
|
182
182
|
}
|
|
183
|
-
return
|
|
183
|
+
return agentFunction(innerContext);
|
|
184
184
|
};
|
|
185
185
|
return next(context);
|
|
186
186
|
}
|
|
@@ -201,7 +201,7 @@ class ComputedNode extends Node {
|
|
|
201
201
|
}, this.timeout);
|
|
202
202
|
}
|
|
203
203
|
try {
|
|
204
|
-
const
|
|
204
|
+
const agentFunction = this.agentFunction ?? this.graph.getAgentFunction(this.agentId);
|
|
205
205
|
const localLog = [];
|
|
206
206
|
const params = Object.keys(this.dynamicParams).reduce((tmp, key) => {
|
|
207
207
|
const [result] = this.graph.resultsOf([this.dynamicParams[key]]);
|
|
@@ -218,6 +218,7 @@ class ComputedNode extends Node {
|
|
|
218
218
|
verbose: this.graph.verbose,
|
|
219
219
|
},
|
|
220
220
|
filterParams: this.filterParams,
|
|
221
|
+
agentFilters: this.graph.agentFilters,
|
|
221
222
|
log: localLog,
|
|
222
223
|
};
|
|
223
224
|
// NOTE: We use the existence of graph object in the agent-specific params to determine
|
|
@@ -226,9 +227,9 @@ class ComputedNode extends Node {
|
|
|
226
227
|
this.graph.taskManager.prepareForNesting();
|
|
227
228
|
context.taskManager = this.graph.taskManager;
|
|
228
229
|
context.graphData = this.nestedGraph;
|
|
229
|
-
context.agents = this.graph.
|
|
230
|
+
context.agents = this.graph.agentFunctionDictionary;
|
|
230
231
|
}
|
|
231
|
-
const result = await this.agentFilterHandler(context,
|
|
232
|
+
const result = await this.agentFilterHandler(context, agentFunction);
|
|
232
233
|
if (this.nestedGraph) {
|
|
233
234
|
this.graph.taskManager.restoreAfterNesting();
|
|
234
235
|
}
|
package/lib/task_manager.js
CHANGED
|
@@ -58,12 +58,9 @@ class TaskManager {
|
|
|
58
58
|
this.concurrency--;
|
|
59
59
|
}
|
|
60
60
|
getStatus(verbose = false) {
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
queuedNodes: this.taskQueue.map((task) => task.node.nodeId),
|
|
65
|
-
}
|
|
66
|
-
: {};
|
|
61
|
+
const runningNodes = Array.from(this.runningNodes).map((node) => node.nodeId);
|
|
62
|
+
const queuedNodes = this.taskQueue.map((task) => task.node.nodeId);
|
|
63
|
+
const nodes = verbose ? { runningNodes, queuedNodes } : {};
|
|
67
64
|
return {
|
|
68
65
|
concurrency: this.concurrency,
|
|
69
66
|
queue: this.taskQueue.length,
|
package/lib/transaction_log.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export declare class TransactionLog {
|
|
|
19
19
|
repeatCount?: number;
|
|
20
20
|
log?: TransactionLog[];
|
|
21
21
|
constructor(nodeId: string);
|
|
22
|
-
initForComputedNode(node: ComputedNode): void;
|
|
22
|
+
initForComputedNode(node: ComputedNode, graph: GraphAI): void;
|
|
23
23
|
onInjected(node: StaticNode, graph: GraphAI, injectFrom?: string): void;
|
|
24
24
|
onComplete(node: ComputedNode, graph: GraphAI, localLog: TransactionLog[]): void;
|
|
25
25
|
beforeExecute(node: ComputedNode, graph: GraphAI, transactionId: number, inputs: ResultData[]): void;
|
package/lib/transaction_log.js
CHANGED
|
@@ -7,9 +7,10 @@ class TransactionLog {
|
|
|
7
7
|
this.nodeId = nodeId;
|
|
8
8
|
this.state = type_1.NodeState.Waiting;
|
|
9
9
|
}
|
|
10
|
-
initForComputedNode(node) {
|
|
10
|
+
initForComputedNode(node, graph) {
|
|
11
11
|
this.agentId = node.getAgentId();
|
|
12
12
|
this.params = node.params;
|
|
13
|
+
graph.appendLog(this);
|
|
13
14
|
}
|
|
14
15
|
onInjected(node, graph, injectFrom) {
|
|
15
16
|
const isUpdating = "endTime" in this;
|
package/lib/type.d.ts
CHANGED
|
@@ -67,6 +67,7 @@ export type AgentFunctionContext<ParamsType = DefaultParamsType, InputDataType =
|
|
|
67
67
|
agents?: AgentFunctionDictonary;
|
|
68
68
|
taskManager?: TaskManager;
|
|
69
69
|
filterParams: AgentFilterParams;
|
|
70
|
+
agentFilters?: AgentFilterInfo[];
|
|
70
71
|
log?: TransactionLog[];
|
|
71
72
|
};
|
|
72
73
|
export type AgentFunction<ParamsType = DefaultParamsType, ResultType = DefaultResultData, InputDataType = DefaultInputData> = (context: AgentFunctionContext<ParamsType, InputDataType>) => Promise<ResultData<ResultType>>;
|
|
@@ -88,6 +89,7 @@ export type AgentFunctionInfo = {
|
|
|
88
89
|
params: DefaultParamsType;
|
|
89
90
|
result: any;
|
|
90
91
|
}[];
|
|
92
|
+
skipTest?: boolean;
|
|
91
93
|
description: string;
|
|
92
94
|
category: string[];
|
|
93
95
|
author: string;
|
package/lib/utils/test_utils.js
CHANGED
|
@@ -19,8 +19,8 @@ exports.defaultTestContext = {
|
|
|
19
19
|
};
|
|
20
20
|
// for agent
|
|
21
21
|
const agentTestRunner = async (agentInfo) => {
|
|
22
|
-
const { agent, samples } = agentInfo;
|
|
23
|
-
if (samples.length === 0) {
|
|
22
|
+
const { agent, samples, skipTest } = agentInfo;
|
|
23
|
+
if (samples.length === 0 || skipTest) {
|
|
24
24
|
console.log(`test ${agentInfo.name}: No test`);
|
|
25
25
|
}
|
|
26
26
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "graphai",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Asynchronous data flow execution engine for agentic AI apps.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"files": [
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
],
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "rm -r lib/* && tsc && tsc-alias",
|
|
11
|
-
"eslint": "eslint
|
|
12
|
-
"format": "prettier --write '{src,tests,samples}/**/*.ts'
|
|
11
|
+
"eslint": "eslint",
|
|
12
|
+
"format": "prettier --write '{src,tests,samples}/**/*.ts'",
|
|
13
13
|
"test": "node --test -r tsconfig-paths/register --require ts-node/register ./tests/**/test_*.ts",
|
|
14
14
|
"http_test": "node --test -r tsconfig-paths/register --require ts-node/register ./tests/**/http_*.ts",
|
|
15
15
|
"b": "yarn run format && yarn run eslint && yarn run build",
|
|
@@ -30,26 +30,25 @@
|
|
|
30
30
|
"@inquirer/prompts": "^5.0.0",
|
|
31
31
|
"@types/cors": "^2.8.17",
|
|
32
32
|
"@types/express": "^4.17.21",
|
|
33
|
-
"@types/node": "^20.
|
|
33
|
+
"@types/node": "^20.12.11",
|
|
34
34
|
"@types/xml2js": "^0.4.14",
|
|
35
|
-
"@typescript-eslint/eslint-plugin": "^6.8.0",
|
|
36
|
-
"@typescript-eslint/parser": "^6.8.0",
|
|
37
35
|
"arxiv-api-ts": "^1.0.3",
|
|
38
36
|
"cors": "^2.8.5",
|
|
39
37
|
"deepmerge": "^4.3.1",
|
|
40
38
|
"dotenv": "^16.4.5",
|
|
41
|
-
"eslint": "^
|
|
42
|
-
"eslint-plugin-import": "^2.25.2",
|
|
39
|
+
"eslint": "^9.2.0",
|
|
43
40
|
"express": "^4.19.2",
|
|
41
|
+
"globals": "^15.2.0",
|
|
44
42
|
"groq-sdk": "^0.3.3",
|
|
45
43
|
"openai": "^4.12.4",
|
|
46
|
-
"prettier": "^3.
|
|
44
|
+
"prettier": "^3.2.5",
|
|
47
45
|
"slashgpt": "^0.0.9",
|
|
48
46
|
"tiktoken": "^1.0.14",
|
|
49
|
-
"ts-node": "^10.9.
|
|
47
|
+
"ts-node": "^10.9.2",
|
|
50
48
|
"tsc-alias": "^1.8.8",
|
|
51
49
|
"tsconfig-paths": "^4.2.0",
|
|
52
|
-
"typescript": "^5.
|
|
50
|
+
"typescript": "^5.4.5",
|
|
51
|
+
"typescript-eslint": "^7.8.0",
|
|
53
52
|
"wikipedia": "^2.1.2",
|
|
54
53
|
"xml2js": "^0.6.2",
|
|
55
54
|
"yaml": "^2.4.1"
|