graphai 0.1.1 → 0.2.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 +145 -106
- package/lib/experimental_agents/array_agents/packages.d.ts +4 -0
- package/lib/experimental_agents/array_agents/packages.js +12 -0
- package/lib/experimental_agents/array_agents/pop_agent.d.ts +26 -0
- package/lib/experimental_agents/array_agents/pop_agent.js +40 -0
- package/lib/experimental_agents/array_agents/push_agent.d.ts +16 -0
- package/lib/experimental_agents/array_agents/push_agent.js +18 -0
- package/lib/experimental_agents/array_agents/shift_agent.d.ts +26 -0
- package/lib/experimental_agents/array_agents/shift_agent.js +29 -0
- package/lib/experimental_agents/data_agents/data_object_merge_template_agent.d.ts +81 -0
- package/lib/experimental_agents/data_agents/data_object_merge_template_agent.js +37 -0
- package/lib/experimental_agents/data_agents/data_sum_template_agent.d.ts +1 -0
- package/lib/experimental_agents/data_agents/data_sum_template_agent.js +2 -1
- package/lib/experimental_agents/data_agents/packages.d.ts +4 -0
- package/lib/experimental_agents/data_agents/packages.js +12 -0
- package/lib/experimental_agents/data_agents/total_agent.d.ts +1 -0
- package/lib/experimental_agents/data_agents/total_agent.js +1 -0
- package/lib/experimental_agents/embedding_agent.d.ts +17 -3
- package/lib/experimental_agents/embedding_agent.js +13 -1
- package/lib/experimental_agents/graph_agents/index.d.ts +2 -0
- package/lib/experimental_agents/graph_agents/index.js +7 -0
- package/lib/experimental_agents/graph_agents/map_agent.d.ts +20 -0
- package/lib/experimental_agents/{map_agent.js → graph_agents/map_agent.js} +31 -10
- package/lib/experimental_agents/graph_agents/nested_agent.d.ts +22 -0
- package/lib/experimental_agents/graph_agents/nested_agent.js +70 -0
- package/lib/experimental_agents/graph_agents/packages.d.ts +3 -0
- package/lib/experimental_agents/graph_agents/packages.js +10 -0
- package/lib/experimental_agents/index.d.ts +4 -5
- package/lib/experimental_agents/index.js +4 -5
- package/lib/experimental_agents/matrix_agents/dot_product_agent.d.ts +18 -0
- package/lib/experimental_agents/{matrix_agent.js → matrix_agents/dot_product_agent.js} +26 -27
- package/lib/experimental_agents/matrix_agents/index.d.ts +2 -0
- package/lib/experimental_agents/matrix_agents/index.js +7 -0
- package/lib/experimental_agents/matrix_agents/packages.d.ts +3 -0
- package/lib/experimental_agents/matrix_agents/packages.js +10 -0
- package/lib/experimental_agents/matrix_agents/sort_by_values_agent.d.ts +20 -0
- package/lib/experimental_agents/matrix_agents/sort_by_values_agent.js +41 -0
- package/lib/experimental_agents/packages.d.ts +11 -0
- package/lib/experimental_agents/packages.js +33 -0
- package/lib/experimental_agents/slashgpt_agent.d.ts +24 -0
- package/lib/experimental_agents/slashgpt_agent.js +12 -0
- package/lib/experimental_agents/sleeper_agents/packages.d.ts +3 -0
- package/lib/experimental_agents/sleeper_agents/packages.js +10 -0
- package/lib/experimental_agents/sleeper_agents/sleeper_agent.d.ts +18 -0
- package/lib/experimental_agents/sleeper_agents/sleeper_agent.js +12 -0
- package/lib/experimental_agents/sleeper_agents/sleeper_agent_debug.d.ts +20 -0
- package/lib/experimental_agents/sleeper_agents/sleeper_agent_debug.js +13 -1
- package/lib/experimental_agents/string_agents/packages.d.ts +3 -0
- package/lib/experimental_agents/string_agents/packages.js +10 -0
- package/lib/experimental_agents/string_agents/string_splitter_agent.d.ts +33 -0
- package/lib/experimental_agents/string_agents/string_splitter_agent.js +41 -0
- package/lib/experimental_agents/string_agents/string_template_agent.d.ts +24 -0
- package/lib/experimental_agents/string_agents/string_template_agent.js +22 -0
- package/lib/experimental_agents/test_agents/bypass_agent.d.ts +3 -0
- package/lib/experimental_agents/test_agents/bypass_agent.js +24 -0
- package/lib/experimental_agents/test_agents/copy2array_agent.d.ts +7 -0
- package/lib/experimental_agents/test_agents/copy2array_agent.js +39 -0
- package/lib/experimental_agents/test_agents/copy_message_agent.d.ts +9 -1
- package/lib/experimental_agents/test_agents/copy_message_agent.js +19 -0
- package/lib/experimental_agents/test_agents/counting_agent.d.ts +8 -1
- package/lib/experimental_agents/test_agents/counting_agent.js +19 -0
- package/lib/experimental_agents/test_agents/echo_agent.d.ts +3 -0
- package/lib/experimental_agents/test_agents/echo_agent.js +13 -0
- package/lib/experimental_agents/test_agents/index.d.ts +1 -0
- package/lib/experimental_agents/test_agents/index.js +3 -1
- package/lib/experimental_agents/test_agents/merge_node_id_agent.d.ts +3 -0
- package/lib/experimental_agents/test_agents/merge_node_id_agent.js +22 -0
- package/lib/experimental_agents/test_agents/packages.d.ts +7 -0
- package/lib/experimental_agents/test_agents/packages.js +18 -0
- package/lib/experimental_agents/token_agent.d.ts +20 -0
- package/lib/experimental_agents/token_agent.js +12 -0
- package/lib/graphai.d.ts +1 -1
- package/lib/graphai.js +9 -16
- package/lib/node.d.ts +2 -2
- package/lib/node.js +19 -21
- package/lib/transaction_log.js +1 -1
- package/lib/type.d.ts +4 -3
- package/lib/utils/test_agents.d.ts +2 -0
- package/lib/utils/test_agents.js +20 -0
- package/lib/utils/test_utils.d.ts +12 -0
- package/lib/utils/test_utils.js +34 -0
- package/lib/utils/utils.d.ts +3 -1
- package/lib/utils/utils.js +30 -2
- package/package.json +10 -11
- package/lib/experimental_agents/map_agent.d.ts +0 -4
- package/lib/experimental_agents/matrix_agent.d.ts +0 -9
- package/lib/experimental_agents/nested_agent.d.ts +0 -6
- package/lib/experimental_agents/nested_agent.js +0 -30
- package/lib/experimental_agents/test_agents/echo_fork_index_agent.d.ts +0 -2
- package/lib/experimental_agents/test_agents/echo_fork_index_agent.js +0 -7
- package/lib/log.d.ts +0 -22
- package/lib/log.js +0 -49
- package/lib/task.d.ts +0 -18
- package/lib/task.js +0 -63
package/README.md
CHANGED
|
@@ -2,58 +2,79 @@
|
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
GraphAI is an asynchronous data flow execution engine, which
|
|
5
|
+
GraphAI is an asynchronous data flow execution engine, which allows developers to build *agentic applications* by describing *agent workflows* as declarative data flow graphs in YAML or JSON.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
As Andrew Ng has described in his article, "[The batch: Issue 242](https://www.deeplearning.ai/the-batch/issue-242/)", better results can often be achieved by making multiple calls to a Large Language Model (LLM) and allowing it to incrementally build towards a higher-quality output. Dr. Ng refers to this approach as 'agentic workflows.'
|
|
8
|
+
|
|
9
|
+
Such *agentic applications* need to make multiple asynchronous API calls (such as OpenAI's chat-completion API, database query, web search, and etc.) and manage data dependencies among them, such as giving the answer from one LLM call to another -- which will become quite difficult to manage in a traditional programing style as the complexity of the application increases, because of the asynchronous nature of those APIs.
|
|
10
|
+
|
|
11
|
+
GraphAI allows developers to describe dependencies among those agents (asynchronous API calls) in a data flow graph in YAML or JSON, which is called *declarative data flow programming* . The GraphAI engine will take care of all the complexity of concurrent asynchronous calls, data dependency management, error handling, retries and logging.
|
|
12
|
+
|
|
13
|
+
## Declarative Data Flow Programming
|
|
8
14
|
|
|
9
|
-
Here is an
|
|
15
|
+
Here is a simple example, which uses the Wikipedia as the data source and perform an in-memory RAG (Retrieval-Augmented Generation).
|
|
10
16
|
|
|
11
17
|
```YAML
|
|
12
18
|
nodes:
|
|
13
|
-
|
|
14
|
-
|
|
19
|
+
source: // Input data to this RAG application
|
|
20
|
+
value:
|
|
21
|
+
name: Sam Bankman-Fried
|
|
22
|
+
query: describe the final sentence by the court for Sam Bank-Fried
|
|
23
|
+
wikipedia: // Retrieve data from Wikipedia。
|
|
24
|
+
agentId: wikipediaAgent
|
|
25
|
+
inputs: [source.name]
|
|
26
|
+
chunks: // Break the text from Wikipedia into chunks(2048 character each with 512 overlap)
|
|
27
|
+
agentId: stringSplitterAgent
|
|
28
|
+
inputs: [wikipedia]
|
|
29
|
+
chunkEmbeddings: // Get embedding vector of each chunk
|
|
30
|
+
agentId: stringEmbeddingsAgent
|
|
31
|
+
inputs: [chunks]
|
|
32
|
+
topicEmbedding: // Get embedding vector of the question
|
|
33
|
+
agentId: stringEmbeddingsAgent
|
|
34
|
+
inputs: [source.query]
|
|
35
|
+
similarities: // Calculate the cosine similarity of each chunk
|
|
36
|
+
agentId: dotProductAgent
|
|
37
|
+
inputs: [chunkEmbeddings, topicEmbedding]
|
|
38
|
+
sortedChunks: // Sort chunks based on the similarity
|
|
39
|
+
agentId: sortByValuesAgent
|
|
40
|
+
inputs: [chunks, similarities]
|
|
41
|
+
referenceText: // Concatenate chunks up to the token limit (5000)
|
|
42
|
+
agentId: tokenBoundStringsAgent
|
|
43
|
+
inputs: [sortedChunks]
|
|
15
44
|
params:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
agentId:
|
|
45
|
+
limit: 5000
|
|
46
|
+
prompt: // Generate a prompt with that reference text
|
|
47
|
+
agentId: stringTemplateAgent
|
|
48
|
+
inputs: [source, referenceText]
|
|
19
49
|
params:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
50
|
+
template: |-
|
|
51
|
+
Using the following document, ${0}
|
|
52
|
+
${1}
|
|
53
|
+
query: // retrieves the answer from GPT3.5
|
|
54
|
+
agentId: slashGPTAgent
|
|
23
55
|
params:
|
|
24
|
-
|
|
25
|
-
|
|
56
|
+
manifest:
|
|
57
|
+
model: gpt-3.5-turbo
|
|
58
|
+
isResult: true // indicating this is the final result
|
|
59
|
+
inputs: [prompt]
|
|
26
60
|
```
|
|
27
61
|
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const file = fs.readFileSync(pathToYamlFile, "utf8");
|
|
42
|
-
const graphData = YAML.parse(file);
|
|
43
|
-
const graph = new GraphAI(graphData, { sample: sampleAgentFunction });
|
|
44
|
-
const results = await graph.run();
|
|
45
|
-
return results["taskC"];
|
|
62
|
+
```mermaid
|
|
63
|
+
flowchart TD
|
|
64
|
+
source(source) -- name --> wikipedia
|
|
65
|
+
source -- query --> topicEmbedding
|
|
66
|
+
wikipedia --> chunks
|
|
67
|
+
chunks --> chunksEmbeddings
|
|
68
|
+
chunksEmbeddings --> similarities
|
|
69
|
+
topicEmbedding --> similarities
|
|
70
|
+
similarities --> sortedChunks
|
|
71
|
+
sortedChunks --> resourceText
|
|
72
|
+
source -- query --> prompt
|
|
73
|
+
resourceText --> prompt
|
|
74
|
+
prompt --> query
|
|
46
75
|
```
|
|
47
76
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
As Andrew Ng has described in his article, "[The batch: Issue 242](https://www.deeplearning.ai/the-batch/issue-242/)", better results can often be achieved by making multiple calls to a Large Language Model (LLM) and allowing it to incrementally build towards a higher-quality output. Dr. Ng refers to this approach as 'agentic workflows.'
|
|
51
|
-
|
|
52
|
-
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.
|
|
53
|
-
|
|
54
|
-
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.
|
|
55
|
-
|
|
56
|
-
Furthermore, GraphAI's robust mechanisms for error handling, retry strategies, timeouts, and logging empower developers to concentrate on refining the application logic.
|
|
77
|
+
Notice that the conversion of the querty text into an embedding vector and text chunks into an array of embedding vectors can be done concurrently because there is no dependency between them. GraphAI will automatically recognize it and execute them concurrently. This kind of *concurrent programing* is very difficult in traditional programming style, and GraphAI's *data flow programming* style is much better alternative.
|
|
57
78
|
|
|
58
79
|
## Quick Install
|
|
59
80
|
|
|
@@ -67,75 +88,71 @@ or
|
|
|
67
88
|
yarn add graphai
|
|
68
89
|
```
|
|
69
90
|
|
|
70
|
-
##
|
|
91
|
+
## Data Flow Graph
|
|
71
92
|
|
|
72
|
-
|
|
93
|
+
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.
|
|
73
94
|
|
|
74
|
-
|
|
95
|
+
A DFG consists of a collection of [nodes](#node), 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 (such as params, inputs, and value) that dictate the node's behavior and its relationship with other nodes. There are two types of nodes, [computed nodes](#computed-node) and [static nodes](#static-node), which are described below.
|
|
75
96
|
|
|
76
|
-
|
|
77
|
-
git clone git@github.com:snakajima/graphai.git
|
|
78
|
-
cd graphai
|
|
79
|
-
yarn install
|
|
80
|
-
```
|
|
97
|
+
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").
|
|
81
98
|
|
|
82
|
-
|
|
99
|
+
### DFG Structure
|
|
83
100
|
|
|
84
|
-
|
|
101
|
+
- 'nodes': A list of node. Required.
|
|
102
|
+
- 'concurrency': An optional property, which specifies the maximum number of concurrent operations (agent functions to be executed at the same time). The default is 8.
|
|
103
|
+
- 'loop': An optional property, which specifies if the graph needs to be executed multiple times. See the [Loop section below](#loop) for details.
|
|
85
104
|
|
|
86
|
-
|
|
105
|
+
## Agent
|
|
87
106
|
|
|
88
|
-
|
|
107
|
+
An *agent* is an abstract object which takes some inputs and generates an output asynchronously. It could be an LLM (such as GPT-4), a media generator, a database, or a REST API over HTTP. A node associated with an agent (specified by 'agentId' property) is called [computed node](#computed-node), which takes a set of inputs from other nodes, lets the agent to process it, and pushes the returned value to other nodes.
|
|
89
108
|
|
|
90
|
-
|
|
91
|
-
cd tests/http-server/docs/
|
|
92
|
-
npx http-server
|
|
93
|
-
```
|
|
109
|
+
### Agent function
|
|
94
110
|
|
|
95
|
-
|
|
111
|
+
An agent function is a TypeScript function, which implements a particular *agent*. An *agent function* receives two set of parameters via AgentFunctionContext:
|
|
96
112
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
```
|
|
113
|
+
- params: agent specific parameters specified in the DFG (specified by the "params" property of the node)
|
|
114
|
+
- inputs: a set of inputs came from other nodes (specified by "inputs" property of the node).
|
|
100
115
|
|
|
101
|
-
|
|
116
|
+
## Node
|
|
102
117
|
|
|
103
|
-
|
|
104
|
-
npm run sample ./samples/home.ts
|
|
105
|
-
```
|
|
118
|
+
There are two types of Node, *computed nodes* and *static nodes*. A *computed node* is associated with an *agent function*, which receives some inputs, performs some computations asynchronously then returns the result (output). A *static node* is a placeholder of a value (just like a variable in programming language), which is specified by the *value* property, injected by an external program, or is updated at the end of iteration (see the [loop](#loop)).
|
|
106
119
|
|
|
107
|
-
|
|
120
|
+
### Computed Node
|
|
108
121
|
|
|
109
|
-
|
|
122
|
+
A *computed node* have following properties.
|
|
110
123
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
124
|
+
- 'agentId': An **required** property, which specifies the id of the *agent function*.
|
|
125
|
+
- 'params': An optional agent-specific property to control the behavior of the associated agent function.
|
|
126
|
+
- 'inputs': An optional list of *data sources* that the current node receives the data from. This establishes a data flow where the current node can only be executed after the completion of the nodes listed under 'inputs'. If this list is empty, the associated *agent function* will be immediatley executed.
|
|
127
|
+
- 'anyInput': An optiona boolean flag, which indicates that the associated *agent function* will be called when at least one of input data became available. Otherwise, it will wait until all the data became available.
|
|
128
|
+
- 'retry': An optional number, which specifies the maximum number of retries to be made. If the last attempt fails, the error will be recorded.
|
|
129
|
+
- '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. The returned value received after the time out will be discarded.
|
|
115
130
|
|
|
116
|
-
|
|
131
|
+
### Static Node
|
|
117
132
|
|
|
118
|
-
A
|
|
133
|
+
A *static* node have following properties.
|
|
119
134
|
|
|
120
|
-
|
|
135
|
+
- 'value': An **required** property, which specifies the initial value of this static node (equivalent to calling the injectValue method from outside).
|
|
136
|
+
- 'update': An optional property, which specifies the *data source* after each iteration. See the [loop](#loop) for details.
|
|
121
137
|
|
|
122
|
-
|
|
138
|
+
## Flow Control
|
|
123
139
|
|
|
124
|
-
|
|
140
|
+
Since the data-flow graph must be asyclic by design, we added a few mechanism to control data flows, [loop](#loop), [nesting](#nesting), [mapping](#mapping) and [condtional flow](#conditional-flow).
|
|
125
141
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
142
|
+
### Loop
|
|
143
|
+
|
|
144
|
+
The loop is an optioal property of a graph, which has two optional properties. The *count* property specifies the number of times the graph needs to be executed and the *while* property specifies the condition required to contineu the loop in the form of node name (nodeId) or its property (nodeId.propId). Unlike JavaScript, an empty array will be treated as false.
|
|
145
|
+
|
|
146
|
+
Here is an example, which performs an LLM query for each person in the list and create the list of answers. The "people" node (static), is initialized with an array of names, and the "retriever" node (computed) retrieves one name at a time, and send it to the "query" node (computed) to perform an LLM query. The "reducer" append it the array retrieved form the "result" node (static node, which is initialized as an empty array).
|
|
147
|
+
|
|
148
|
+
The "update" property of two static nodes ("people" and "result"), updates those properties based on the results from the previous itelation. This loop continues until the value of "people" node become an empty array.
|
|
129
149
|
|
|
130
150
|
```
|
|
131
151
|
loop:
|
|
132
152
|
while: people
|
|
133
153
|
nodes:
|
|
134
154
|
people:
|
|
135
|
-
value:
|
|
136
|
-
- Steve Jobs
|
|
137
|
-
- Elon Musk
|
|
138
|
-
- Nikola Tesla
|
|
155
|
+
value: [Steve Jobs, Elon Musk, Nikola Tesla]
|
|
139
156
|
update: retriever.array
|
|
140
157
|
result:
|
|
141
158
|
value: []
|
|
@@ -147,41 +164,24 @@ nodes:
|
|
|
147
164
|
agentId: slashgpt
|
|
148
165
|
params:
|
|
149
166
|
manifest:
|
|
150
|
-
prompt:
|
|
167
|
+
prompt: Describe about the person in less than 100 words
|
|
151
168
|
inputs: [retriever.item]
|
|
152
169
|
reducer:
|
|
153
170
|
agentId: push
|
|
154
171
|
inputs: [result, query.content]
|
|
155
172
|
```
|
|
156
173
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
An agent is an abstract object, which takes some inputs and generates an output asynchronously. It could be an LLM (such as GPT-4), an image/video/music generator, a database, or a REST API over HTTP. Each node (except 'source node') is associated with an agent function, which takes data flow into the node as inputs, and generates an output.
|
|
174
|
+
### Nesting
|
|
160
175
|
|
|
161
|
-
|
|
176
|
+
To be filled.
|
|
162
177
|
|
|
163
|
-
|
|
178
|
+
### Mapping
|
|
164
179
|
|
|
165
|
-
|
|
180
|
+
To be filled.
|
|
166
181
|
|
|
167
|
-
|
|
182
|
+
### Conditional Flow
|
|
168
183
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
A *computed node* have following properties.
|
|
172
|
-
|
|
173
|
-
- 'agentId': An **required** property, which specifies the id of the *agent function*.
|
|
174
|
-
- 'inputs': An optional list of *data sources* that the current node depends on. This establishes a flow where the current node can only be executed after the completion of the nodes listed under 'inputs'. If this list is empty, the associated *agent function* will be immediatley executed.
|
|
175
|
-
- 'anyInput': An optiona boolean flag, which indicates that the associated *agent function* will be called when at least one of input data became available. Otherwise, it will wait until all the data became available.
|
|
176
|
-
- 'retry': An optional number, which specifies the maximum number of retries to be made. If the last attempt fails, that return value will be recorded.
|
|
177
|
-
- '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.
|
|
178
|
-
- 'params': An optional property to the associated agent function, which are agent specific.
|
|
179
|
-
- 'fork': An optional paramter, which specifies the number of concurrent transactions to be created for the current node.
|
|
180
|
-
|
|
181
|
-
A *static* node have following properties.
|
|
182
|
-
|
|
183
|
-
- 'value': An **required** property, which specifies the initial value of this static node (equivalent to calling the injectValue method from outside).
|
|
184
|
-
- 'update': An optional property, which specifies the *data source* after each iteration.
|
|
184
|
+
To be filled.
|
|
185
185
|
|
|
186
186
|
## GraphAI class
|
|
187
187
|
|
|
@@ -216,3 +216,42 @@ Injects a result into a specified node. This is used to manually set the result
|
|
|
216
216
|
|
|
217
217
|
- ```nodeId: string```: The ID of the static node into which the result is to be injected.
|
|
218
218
|
- ```result: ResultData```: The result to be injected into the specified node.
|
|
219
|
+
|
|
220
|
+
## Collaboration
|
|
221
|
+
|
|
222
|
+
Step 1. Install git, node and yarn
|
|
223
|
+
|
|
224
|
+
Step 2. Clone the project and install necessary node modules
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
git clone git@github.com:snakajima/graphai.git
|
|
228
|
+
cd graphai
|
|
229
|
+
yarn install
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Step 3. Set the environment variable OPENAI_API_KEY to your own key (=sk-...)
|
|
233
|
+
|
|
234
|
+
You need to set ANTHROPIC_API_KEY as well, if you want to use Claude.
|
|
235
|
+
|
|
236
|
+
Step 4. Run the test script
|
|
237
|
+
|
|
238
|
+
Run the test
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
npm run test
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Step 5. Run one of sample scripts
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
npm run sample ./samples/home.ts
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Step 6. Write some code and send pull requests
|
|
251
|
+
|
|
252
|
+
Key principles:
|
|
253
|
+
|
|
254
|
+
1. Keep the core (Node and GraphAI classes) small and simple.
|
|
255
|
+
2. Enhance the platform by adding 'agents' (plug ins).
|
|
256
|
+
3. Simple but effective test scripts make it easy to maintain.
|
|
257
|
+
4. Run "npm run format" before submitting pull requests.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import pushAgent from "../../experimental_agents/array_agents/push_agent";
|
|
2
|
+
import popAgent from "../../experimental_agents/array_agents/pop_agent";
|
|
3
|
+
import shiftAgent from "../../experimental_agents/array_agents/shift_agent";
|
|
4
|
+
export { pushAgent, popAgent, shiftAgent };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.shiftAgent = exports.popAgent = exports.pushAgent = void 0;
|
|
7
|
+
const push_agent_1 = __importDefault(require("../../experimental_agents/array_agents/push_agent"));
|
|
8
|
+
exports.pushAgent = push_agent_1.default;
|
|
9
|
+
const pop_agent_1 = __importDefault(require("../../experimental_agents/array_agents/pop_agent"));
|
|
10
|
+
exports.popAgent = pop_agent_1.default;
|
|
11
|
+
const shift_agent_1 = __importDefault(require("../../experimental_agents/array_agents/shift_agent"));
|
|
12
|
+
exports.shiftAgent = shift_agent_1.default;
|
|
@@ -1,2 +1,28 @@
|
|
|
1
1
|
import { AgentFunction } from "../../graphai";
|
|
2
2
|
export declare const popAgent: AgentFunction<Record<string, any>, Record<string, any>, Record<string, any>>;
|
|
3
|
+
declare const popAgentInfo: {
|
|
4
|
+
name: string;
|
|
5
|
+
agent: AgentFunction<Record<string, any>, Record<string, any>, Record<string, any>>;
|
|
6
|
+
mock: AgentFunction<Record<string, any>, Record<string, any>, Record<string, any>>;
|
|
7
|
+
samples: ({
|
|
8
|
+
inputs: string[][];
|
|
9
|
+
params: {};
|
|
10
|
+
result: {
|
|
11
|
+
array: string[];
|
|
12
|
+
item: string;
|
|
13
|
+
};
|
|
14
|
+
} | {
|
|
15
|
+
inputs: (string[] | number[])[];
|
|
16
|
+
params: {};
|
|
17
|
+
result: {
|
|
18
|
+
array: number[];
|
|
19
|
+
item: number;
|
|
20
|
+
};
|
|
21
|
+
})[];
|
|
22
|
+
description: string;
|
|
23
|
+
category: string[];
|
|
24
|
+
author: string;
|
|
25
|
+
repository: string;
|
|
26
|
+
license: string;
|
|
27
|
+
};
|
|
28
|
+
export default popAgentInfo;
|
|
@@ -13,3 +13,43 @@ const popAgent = async (context) => {
|
|
|
13
13
|
return { array, item };
|
|
14
14
|
};
|
|
15
15
|
exports.popAgent = popAgent;
|
|
16
|
+
const popAgentInfo = {
|
|
17
|
+
name: "popAgent",
|
|
18
|
+
agent: exports.popAgent,
|
|
19
|
+
mock: exports.popAgent,
|
|
20
|
+
samples: [
|
|
21
|
+
{
|
|
22
|
+
inputs: [[1, 2, 3]],
|
|
23
|
+
params: {},
|
|
24
|
+
result: {
|
|
25
|
+
array: [1, 2],
|
|
26
|
+
item: 3,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
inputs: [["a", "b", "c"]],
|
|
31
|
+
params: {},
|
|
32
|
+
result: {
|
|
33
|
+
array: ["a", "b"],
|
|
34
|
+
item: "c",
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
inputs: [
|
|
39
|
+
[1, 2, 3],
|
|
40
|
+
["a", "b", "c"],
|
|
41
|
+
],
|
|
42
|
+
params: {},
|
|
43
|
+
result: {
|
|
44
|
+
array: [1, 2],
|
|
45
|
+
item: 3,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
description: "Pop Agent",
|
|
50
|
+
category: ["array"],
|
|
51
|
+
author: "Receptron team",
|
|
52
|
+
repository: "https://github.com/receptron/graphai",
|
|
53
|
+
license: "MIT",
|
|
54
|
+
};
|
|
55
|
+
exports.default = popAgentInfo;
|
|
@@ -1,2 +1,18 @@
|
|
|
1
1
|
import { AgentFunction } from "../../graphai";
|
|
2
2
|
export declare const pushAgent: AgentFunction<Record<string, any>, Record<string, any>, Record<string, any>>;
|
|
3
|
+
declare const pushAgentInfo: {
|
|
4
|
+
name: string;
|
|
5
|
+
agent: AgentFunction<Record<string, any>, Record<string, any>, Record<string, any>>;
|
|
6
|
+
mock: AgentFunction<Record<string, any>, Record<string, any>, Record<string, any>>;
|
|
7
|
+
samples: {
|
|
8
|
+
inputs: (number | number[])[];
|
|
9
|
+
params: {};
|
|
10
|
+
result: number[];
|
|
11
|
+
}[];
|
|
12
|
+
description: string;
|
|
13
|
+
category: never[];
|
|
14
|
+
author: string;
|
|
15
|
+
repository: string;
|
|
16
|
+
license: string;
|
|
17
|
+
};
|
|
18
|
+
export default pushAgentInfo;
|
|
@@ -12,3 +12,21 @@ const pushAgent = async ({ inputs }) => {
|
|
|
12
12
|
return array;
|
|
13
13
|
};
|
|
14
14
|
exports.pushAgent = pushAgent;
|
|
15
|
+
const pushAgentInfo = {
|
|
16
|
+
name: "pushAgent",
|
|
17
|
+
agent: exports.pushAgent,
|
|
18
|
+
mock: exports.pushAgent,
|
|
19
|
+
samples: [
|
|
20
|
+
{
|
|
21
|
+
inputs: [[1, 2], 3],
|
|
22
|
+
params: {},
|
|
23
|
+
result: [1, 2, 3],
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
description: "push Agent",
|
|
27
|
+
category: [],
|
|
28
|
+
author: "Receptron team",
|
|
29
|
+
repository: "https://github.com/receptron/graphai",
|
|
30
|
+
license: "MIT",
|
|
31
|
+
};
|
|
32
|
+
exports.default = pushAgentInfo;
|
|
@@ -1,2 +1,28 @@
|
|
|
1
1
|
import { AgentFunction } from "../../graphai";
|
|
2
2
|
export declare const shiftAgent: AgentFunction<Record<string, any>, Record<string, any>, Record<string, any>>;
|
|
3
|
+
declare const shiftAgentInfo: {
|
|
4
|
+
name: string;
|
|
5
|
+
agent: AgentFunction<Record<string, any>, Record<string, any>, Record<string, any>>;
|
|
6
|
+
mock: AgentFunction<Record<string, any>, Record<string, any>, Record<string, any>>;
|
|
7
|
+
samples: ({
|
|
8
|
+
inputs: number[][];
|
|
9
|
+
params: {};
|
|
10
|
+
result: {
|
|
11
|
+
array: number[];
|
|
12
|
+
item: number;
|
|
13
|
+
};
|
|
14
|
+
} | {
|
|
15
|
+
inputs: string[][];
|
|
16
|
+
params: {};
|
|
17
|
+
result: {
|
|
18
|
+
array: string[];
|
|
19
|
+
item: string;
|
|
20
|
+
};
|
|
21
|
+
})[];
|
|
22
|
+
description: string;
|
|
23
|
+
category: never[];
|
|
24
|
+
author: string;
|
|
25
|
+
repository: string;
|
|
26
|
+
license: string;
|
|
27
|
+
};
|
|
28
|
+
export default shiftAgentInfo;
|
|
@@ -13,3 +13,32 @@ const shiftAgent = async (context) => {
|
|
|
13
13
|
return { array, item };
|
|
14
14
|
};
|
|
15
15
|
exports.shiftAgent = shiftAgent;
|
|
16
|
+
const shiftAgentInfo = {
|
|
17
|
+
name: "shiftAgent",
|
|
18
|
+
agent: exports.shiftAgent,
|
|
19
|
+
mock: exports.shiftAgent,
|
|
20
|
+
samples: [
|
|
21
|
+
{
|
|
22
|
+
inputs: [[1, 2, 3]],
|
|
23
|
+
params: {},
|
|
24
|
+
result: {
|
|
25
|
+
array: [2, 3],
|
|
26
|
+
item: 1,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
inputs: [["a", "b", "c"]],
|
|
31
|
+
params: {},
|
|
32
|
+
result: {
|
|
33
|
+
array: ["b", "c"],
|
|
34
|
+
item: "a",
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
description: "shift Agent",
|
|
39
|
+
category: [],
|
|
40
|
+
author: "Receptron team",
|
|
41
|
+
repository: "https://github.com/receptron/graphai",
|
|
42
|
+
license: "MIT",
|
|
43
|
+
};
|
|
44
|
+
exports.default = shiftAgentInfo;
|
|
@@ -1,2 +1,83 @@
|
|
|
1
1
|
import { AgentFunction } from "../../graphai";
|
|
2
2
|
export declare const dataObjectMergeTemplateAgent: AgentFunction;
|
|
3
|
+
declare const dataObjectMergeTemplateAgentInfo: {
|
|
4
|
+
name: string;
|
|
5
|
+
agent: AgentFunction;
|
|
6
|
+
mock: AgentFunction;
|
|
7
|
+
samples: ({
|
|
8
|
+
inputs: ({
|
|
9
|
+
a: number;
|
|
10
|
+
b: number;
|
|
11
|
+
c?: undefined;
|
|
12
|
+
} | {
|
|
13
|
+
a: number;
|
|
14
|
+
b: number;
|
|
15
|
+
c: number;
|
|
16
|
+
})[];
|
|
17
|
+
params: {};
|
|
18
|
+
result: {
|
|
19
|
+
a: number;
|
|
20
|
+
b: number;
|
|
21
|
+
c: number;
|
|
22
|
+
};
|
|
23
|
+
} | {
|
|
24
|
+
inputs: ({
|
|
25
|
+
a: {
|
|
26
|
+
b: {
|
|
27
|
+
c: {
|
|
28
|
+
d: string;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
b?: undefined;
|
|
33
|
+
} | {
|
|
34
|
+
b: {
|
|
35
|
+
c: {
|
|
36
|
+
d: {
|
|
37
|
+
e: string;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
d?: undefined;
|
|
41
|
+
};
|
|
42
|
+
a?: undefined;
|
|
43
|
+
} | {
|
|
44
|
+
b: {
|
|
45
|
+
d: {
|
|
46
|
+
e: {
|
|
47
|
+
f: string;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
c?: undefined;
|
|
51
|
+
};
|
|
52
|
+
a?: undefined;
|
|
53
|
+
})[];
|
|
54
|
+
params: {};
|
|
55
|
+
result: {
|
|
56
|
+
a: {
|
|
57
|
+
b: {
|
|
58
|
+
c: {
|
|
59
|
+
d: string;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
b: {
|
|
64
|
+
c: {
|
|
65
|
+
d: {
|
|
66
|
+
e: string;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
d: {
|
|
70
|
+
e: {
|
|
71
|
+
f: string;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
})[];
|
|
77
|
+
description: string;
|
|
78
|
+
category: never[];
|
|
79
|
+
author: string;
|
|
80
|
+
repository: string;
|
|
81
|
+
license: string;
|
|
82
|
+
};
|
|
83
|
+
export default dataObjectMergeTemplateAgentInfo;
|
|
@@ -11,3 +11,40 @@ const dataObjectMergeTemplateAgent = async ({ inputs }) => {
|
|
|
11
11
|
}, {});
|
|
12
12
|
};
|
|
13
13
|
exports.dataObjectMergeTemplateAgent = dataObjectMergeTemplateAgent;
|
|
14
|
+
// for test and document
|
|
15
|
+
const sampleInputs = [
|
|
16
|
+
{ a: 1, b: 1 },
|
|
17
|
+
{ a: 2, b: 2 },
|
|
18
|
+
{ a: 3, b: 0, c: 5 },
|
|
19
|
+
];
|
|
20
|
+
const sampleParams = {};
|
|
21
|
+
const sampleResult = { a: 3, b: 0, c: 5 };
|
|
22
|
+
const dataObjectMergeTemplateAgentInfo = {
|
|
23
|
+
name: "dataObjectMergeTemplateAgent",
|
|
24
|
+
agent: exports.dataObjectMergeTemplateAgent,
|
|
25
|
+
mock: exports.dataObjectMergeTemplateAgent,
|
|
26
|
+
samples: [
|
|
27
|
+
{
|
|
28
|
+
inputs: sampleInputs,
|
|
29
|
+
params: sampleParams,
|
|
30
|
+
result: sampleResult,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
inputs: [{ a: { b: { c: { d: "e" } } } }, { b: { c: { d: { e: "f" } } } }, { b: { d: { e: { f: "g" } } } }],
|
|
34
|
+
params: {},
|
|
35
|
+
result: {
|
|
36
|
+
a: { b: { c: { d: "e" } } },
|
|
37
|
+
b: {
|
|
38
|
+
c: { d: { e: "f" } },
|
|
39
|
+
d: { e: { f: "g" } },
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
description: "Merge object",
|
|
45
|
+
category: [],
|
|
46
|
+
author: "Satoshi Nakajima",
|
|
47
|
+
repository: "https://github.com/receptron/graphai",
|
|
48
|
+
license: "MIT",
|
|
49
|
+
};
|
|
50
|
+
exports.default = dataObjectMergeTemplateAgentInfo;
|