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.
Files changed (94) hide show
  1. package/README.md +145 -106
  2. package/lib/experimental_agents/array_agents/packages.d.ts +4 -0
  3. package/lib/experimental_agents/array_agents/packages.js +12 -0
  4. package/lib/experimental_agents/array_agents/pop_agent.d.ts +26 -0
  5. package/lib/experimental_agents/array_agents/pop_agent.js +40 -0
  6. package/lib/experimental_agents/array_agents/push_agent.d.ts +16 -0
  7. package/lib/experimental_agents/array_agents/push_agent.js +18 -0
  8. package/lib/experimental_agents/array_agents/shift_agent.d.ts +26 -0
  9. package/lib/experimental_agents/array_agents/shift_agent.js +29 -0
  10. package/lib/experimental_agents/data_agents/data_object_merge_template_agent.d.ts +81 -0
  11. package/lib/experimental_agents/data_agents/data_object_merge_template_agent.js +37 -0
  12. package/lib/experimental_agents/data_agents/data_sum_template_agent.d.ts +1 -0
  13. package/lib/experimental_agents/data_agents/data_sum_template_agent.js +2 -1
  14. package/lib/experimental_agents/data_agents/packages.d.ts +4 -0
  15. package/lib/experimental_agents/data_agents/packages.js +12 -0
  16. package/lib/experimental_agents/data_agents/total_agent.d.ts +1 -0
  17. package/lib/experimental_agents/data_agents/total_agent.js +1 -0
  18. package/lib/experimental_agents/embedding_agent.d.ts +17 -3
  19. package/lib/experimental_agents/embedding_agent.js +13 -1
  20. package/lib/experimental_agents/graph_agents/index.d.ts +2 -0
  21. package/lib/experimental_agents/graph_agents/index.js +7 -0
  22. package/lib/experimental_agents/graph_agents/map_agent.d.ts +20 -0
  23. package/lib/experimental_agents/{map_agent.js → graph_agents/map_agent.js} +31 -10
  24. package/lib/experimental_agents/graph_agents/nested_agent.d.ts +22 -0
  25. package/lib/experimental_agents/graph_agents/nested_agent.js +70 -0
  26. package/lib/experimental_agents/graph_agents/packages.d.ts +3 -0
  27. package/lib/experimental_agents/graph_agents/packages.js +10 -0
  28. package/lib/experimental_agents/index.d.ts +4 -5
  29. package/lib/experimental_agents/index.js +4 -5
  30. package/lib/experimental_agents/matrix_agents/dot_product_agent.d.ts +18 -0
  31. package/lib/experimental_agents/{matrix_agent.js → matrix_agents/dot_product_agent.js} +26 -27
  32. package/lib/experimental_agents/matrix_agents/index.d.ts +2 -0
  33. package/lib/experimental_agents/matrix_agents/index.js +7 -0
  34. package/lib/experimental_agents/matrix_agents/packages.d.ts +3 -0
  35. package/lib/experimental_agents/matrix_agents/packages.js +10 -0
  36. package/lib/experimental_agents/matrix_agents/sort_by_values_agent.d.ts +20 -0
  37. package/lib/experimental_agents/matrix_agents/sort_by_values_agent.js +41 -0
  38. package/lib/experimental_agents/packages.d.ts +11 -0
  39. package/lib/experimental_agents/packages.js +33 -0
  40. package/lib/experimental_agents/slashgpt_agent.d.ts +24 -0
  41. package/lib/experimental_agents/slashgpt_agent.js +12 -0
  42. package/lib/experimental_agents/sleeper_agents/packages.d.ts +3 -0
  43. package/lib/experimental_agents/sleeper_agents/packages.js +10 -0
  44. package/lib/experimental_agents/sleeper_agents/sleeper_agent.d.ts +18 -0
  45. package/lib/experimental_agents/sleeper_agents/sleeper_agent.js +12 -0
  46. package/lib/experimental_agents/sleeper_agents/sleeper_agent_debug.d.ts +20 -0
  47. package/lib/experimental_agents/sleeper_agents/sleeper_agent_debug.js +13 -1
  48. package/lib/experimental_agents/string_agents/packages.d.ts +3 -0
  49. package/lib/experimental_agents/string_agents/packages.js +10 -0
  50. package/lib/experimental_agents/string_agents/string_splitter_agent.d.ts +33 -0
  51. package/lib/experimental_agents/string_agents/string_splitter_agent.js +41 -0
  52. package/lib/experimental_agents/string_agents/string_template_agent.d.ts +24 -0
  53. package/lib/experimental_agents/string_agents/string_template_agent.js +22 -0
  54. package/lib/experimental_agents/test_agents/bypass_agent.d.ts +3 -0
  55. package/lib/experimental_agents/test_agents/bypass_agent.js +24 -0
  56. package/lib/experimental_agents/test_agents/copy2array_agent.d.ts +7 -0
  57. package/lib/experimental_agents/test_agents/copy2array_agent.js +39 -0
  58. package/lib/experimental_agents/test_agents/copy_message_agent.d.ts +9 -1
  59. package/lib/experimental_agents/test_agents/copy_message_agent.js +19 -0
  60. package/lib/experimental_agents/test_agents/counting_agent.d.ts +8 -1
  61. package/lib/experimental_agents/test_agents/counting_agent.js +19 -0
  62. package/lib/experimental_agents/test_agents/echo_agent.d.ts +3 -0
  63. package/lib/experimental_agents/test_agents/echo_agent.js +13 -0
  64. package/lib/experimental_agents/test_agents/index.d.ts +1 -0
  65. package/lib/experimental_agents/test_agents/index.js +3 -1
  66. package/lib/experimental_agents/test_agents/merge_node_id_agent.d.ts +3 -0
  67. package/lib/experimental_agents/test_agents/merge_node_id_agent.js +22 -0
  68. package/lib/experimental_agents/test_agents/packages.d.ts +7 -0
  69. package/lib/experimental_agents/test_agents/packages.js +18 -0
  70. package/lib/experimental_agents/token_agent.d.ts +20 -0
  71. package/lib/experimental_agents/token_agent.js +12 -0
  72. package/lib/graphai.d.ts +1 -1
  73. package/lib/graphai.js +9 -16
  74. package/lib/node.d.ts +2 -2
  75. package/lib/node.js +19 -21
  76. package/lib/transaction_log.js +1 -1
  77. package/lib/type.d.ts +4 -3
  78. package/lib/utils/test_agents.d.ts +2 -0
  79. package/lib/utils/test_agents.js +20 -0
  80. package/lib/utils/test_utils.d.ts +12 -0
  81. package/lib/utils/test_utils.js +34 -0
  82. package/lib/utils/utils.d.ts +3 -1
  83. package/lib/utils/utils.js +30 -2
  84. package/package.json +10 -11
  85. package/lib/experimental_agents/map_agent.d.ts +0 -4
  86. package/lib/experimental_agents/matrix_agent.d.ts +0 -9
  87. package/lib/experimental_agents/nested_agent.d.ts +0 -6
  88. package/lib/experimental_agents/nested_agent.js +0 -30
  89. package/lib/experimental_agents/test_agents/echo_fork_index_agent.d.ts +0 -2
  90. package/lib/experimental_agents/test_agents/echo_fork_index_agent.js +0 -7
  91. package/lib/log.d.ts +0 -22
  92. package/lib/log.js +0 -49
  93. package/lib/task.d.ts +0 -18
  94. 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 makes it easy to create AI applications that need to make asynchronous AI API calls multiple times with some dependencies among them, such as giving the answer from one LLM call to another LLM call as a prompt.
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
- You just need to describe dependencies among those API calls in a single data flow graph, create a GraphAI object with that graph, and run it.
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 example:
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
- taskA:
14
- agentId: sample
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
- // agent-specific parameters for taskA
17
- taskB:
18
- agentId: sample
45
+ limit: 5000
46
+ prompt: // Generate a prompt with that reference text
47
+ agentId: stringTemplateAgent
48
+ inputs: [source, referenceText]
19
49
  params:
20
- // agent-specific parameters for taskB
21
- taskC:
22
- agentId: sample
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
- // agent-specific parameters for taskC
25
- inputs: [taskA, taskB]
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
- ``` TypeScript
29
- const sampleAgentFunction = async (context: AgentFunctionContext) => {
30
- const {
31
- nodeId, // taskA, taskB or taskC
32
- params, // agent-specific parameters specified in the graph definition file
33
- inputs // inputs from previous nodes
34
- } = context;
35
- // Agent-specific code (such as calling OpenAI's chat.completions API)
36
- ...
37
- return result;
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
- ## Background
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
- ## Collaboration
91
+ ## Data Flow Graph
71
92
 
72
- Step 1. Install git, node and yarn
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
- Step 2. Clone the project and install necessary node modules
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
- Step 3. Set the environment variable OPENAI_API_KEY to your own key (=sk-...)
99
+ ### DFG Structure
83
100
 
84
- You need to set ANTHROPIC_API_KEY as well, if you want to use Claude.
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
- Step 4. Run the test script
105
+ ## Agent
87
106
 
88
- Start web server for http agent
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
- then run the test
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
- npm run test
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
- Step 5. Run one of sample scripts
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
- Step 6. Write some code and send pull requests
120
+ ### Computed Node
108
121
 
109
- Key principles:
122
+ A *computed node* have following properties.
110
123
 
111
- 1. Keep the core (Node and GraphAI classes) small and simple.
112
- 2. Enhance the platform by adding 'agents' (plug ins).
113
- 3. Simple but effective test scripts make it easy to maintain.
114
- 4. Run "npm run format" before submitting pull requests.
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
- ## Data Flow Graph
131
+ ### Static Node
117
132
 
118
- 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.
133
+ A *static* node have following properties.
119
134
 
120
- 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, anyInput, retry, timeout, agentId, fork, value, update) that dictate the node's behavior and its relationship with other nodes.
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
- 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").
138
+ ## Flow Control
123
139
 
124
- ### DFG Structure
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
- - 'nodes': A list of node. Required.
127
- - '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.
128
- - 'loop': An optional property, which specifies if the graph needs to be executed multiple times. The loop is an JavaScript object, which has two optinoal 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.
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: 指定した人について日本語で400字以内で答えて
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
- ## Agent
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
- ## Agent function
176
+ To be filled.
162
177
 
163
- An agent function is a TypeScript function, which implements an agent. A DFG is associated one or more agent functions. If the DFG is associated with multiple agent functions, each node needs to be associated only one of them (either explicitly with 'agentId' or implicitly to the default Agent function).
178
+ ### Mapping
164
179
 
165
- An agent function receives two set of parameters via AgentFunctionContext, agent specific parameters specified in the DFG and input data came from other nodes.
180
+ To be filled.
166
181
 
167
- ## Node Structure
182
+ ### Conditional Flow
168
183
 
169
- 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 injected by an external program, or is retrived from a *data source* (in case of interations).
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;
@@ -10,6 +10,7 @@ declare const dataSumTemplateAgentInfo: {
10
10
  result: number;
11
11
  }[];
12
12
  description: string;
13
+ category: never[];
13
14
  author: string;
14
15
  repository: string;
15
16
  license: string;