jarviscore-framework 0.1.0__py3-none-any.whl → 0.2.0__py3-none-any.whl
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.
- examples/autoagent_distributed_example.py +211 -0
- examples/custom_profile_decorator.py +134 -0
- examples/custom_profile_wrap.py +168 -0
- examples/customagent_distributed_example.py +362 -0
- examples/customagent_p2p_example.py +347 -0
- jarviscore/__init__.py +60 -15
- jarviscore/adapter/__init__.py +40 -0
- jarviscore/adapter/decorator.py +336 -0
- jarviscore/adapter/wrapper.py +303 -0
- jarviscore/cli/check.py +18 -13
- jarviscore/cli/scaffold.py +178 -0
- jarviscore/cli/smoketest.py +3 -2
- jarviscore/context/__init__.py +40 -0
- jarviscore/context/dependency.py +160 -0
- jarviscore/context/jarvis_context.py +207 -0
- jarviscore/context/memory.py +155 -0
- jarviscore/core/agent.py +44 -1
- jarviscore/core/mesh.py +196 -35
- jarviscore/data/.env.example +146 -0
- jarviscore/data/__init__.py +7 -0
- jarviscore/data/examples/autoagent_distributed_example.py +211 -0
- jarviscore/data/examples/calculator_agent_example.py +77 -0
- jarviscore/data/examples/customagent_distributed_example.py +362 -0
- jarviscore/data/examples/customagent_p2p_example.py +347 -0
- jarviscore/data/examples/multi_agent_workflow.py +132 -0
- jarviscore/data/examples/research_agent_example.py +76 -0
- jarviscore/docs/API_REFERENCE.md +264 -51
- jarviscore/docs/AUTOAGENT_GUIDE.md +198 -0
- jarviscore/docs/CONFIGURATION.md +41 -23
- jarviscore/docs/CUSTOMAGENT_GUIDE.md +415 -0
- jarviscore/docs/GETTING_STARTED.md +113 -17
- jarviscore/docs/TROUBLESHOOTING.md +155 -13
- jarviscore/docs/USER_GUIDE.md +144 -363
- jarviscore/execution/llm.py +23 -16
- jarviscore/orchestration/engine.py +20 -8
- jarviscore/p2p/__init__.py +10 -0
- jarviscore/p2p/coordinator.py +129 -0
- jarviscore/p2p/messages.py +87 -0
- jarviscore/p2p/peer_client.py +576 -0
- jarviscore/p2p/peer_tool.py +268 -0
- jarviscore_framework-0.2.0.dist-info/METADATA +143 -0
- jarviscore_framework-0.2.0.dist-info/RECORD +132 -0
- {jarviscore_framework-0.1.0.dist-info → jarviscore_framework-0.2.0.dist-info}/WHEEL +1 -1
- {jarviscore_framework-0.1.0.dist-info → jarviscore_framework-0.2.0.dist-info}/top_level.txt +1 -0
- test_logs/code_registry/functions/data_generator-558779ed_560ebc37.py +7 -0
- test_logs/code_registry/functions/data_generator-5ed3609e_560ebc37.py +7 -0
- test_logs/code_registry/functions/data_generator-66da0356_43970bb9.py +25 -0
- test_logs/code_registry/functions/data_generator-7a2fac83_583709d9.py +36 -0
- test_logs/code_registry/functions/data_generator-888b670f_aa235863.py +9 -0
- test_logs/code_registry/functions/data_generator-9ca5f642_aa235863.py +9 -0
- test_logs/code_registry/functions/data_generator-bfd90775_560ebc37.py +7 -0
- test_logs/code_registry/functions/data_generator-e95d2f7d_aa235863.py +9 -0
- test_logs/code_registry/functions/data_generator-f60ca8a2_327eb8c2.py +29 -0
- test_logs/code_registry/functions/mathematician-02adf9ee_958658d9.py +19 -0
- test_logs/code_registry/functions/mathematician-0706fb57_5df13441.py +23 -0
- test_logs/code_registry/functions/mathematician-153c9c4a_ba59c918.py +83 -0
- test_logs/code_registry/functions/mathematician-287e61c0_41daa793.py +18 -0
- test_logs/code_registry/functions/mathematician-2967af5a_863c2cc6.py +17 -0
- test_logs/code_registry/functions/mathematician-303ca6d6_5df13441.py +23 -0
- test_logs/code_registry/functions/mathematician-308a4afd_cbf5064d.py +73 -0
- test_logs/code_registry/functions/mathematician-353f16e2_0968bcf5.py +18 -0
- test_logs/code_registry/functions/mathematician-3c22475a_41daa793.py +17 -0
- test_logs/code_registry/functions/mathematician-5bac1029_0968bcf5.py +18 -0
- test_logs/code_registry/functions/mathematician-640f76b2_9198780b.py +19 -0
- test_logs/code_registry/functions/mathematician-752fa7ea_863c2cc6.py +17 -0
- test_logs/code_registry/functions/mathematician-baf9ef39_0968bcf5.py +18 -0
- test_logs/code_registry/functions/mathematician-bc8b2a2f_5df13441.py +23 -0
- test_logs/code_registry/functions/mathematician-c31e4686_41daa793.py +18 -0
- test_logs/code_registry/functions/mathematician-cc84c84c_863c2cc6.py +17 -0
- test_logs/code_registry/functions/mathematician-dd7c7144_9198780b.py +19 -0
- test_logs/code_registry/functions/mathematician-e671c256_41ea4487.py +74 -0
- test_logs/code_registry/functions/report_generator-1a878fcc_18d44bdc.py +47 -0
- test_logs/code_registry/functions/report_generator-25c1c331_cea57d0d.py +35 -0
- test_logs/code_registry/functions/report_generator-37552117_e711c2b9.py +35 -0
- test_logs/code_registry/functions/report_generator-bc662768_e711c2b9.py +35 -0
- test_logs/code_registry/functions/report_generator-d6c0e76b_5e7722ec.py +44 -0
- test_logs/code_registry/functions/report_generator-f270fb02_680529c3.py +44 -0
- test_logs/code_registry/functions/text_processor-11393b14_4370d3ed.py +40 -0
- test_logs/code_registry/functions/text_processor-7d02dfc3_d3b569be.py +37 -0
- test_logs/code_registry/functions/text_processor-8adb5e32_9168c5fe.py +13 -0
- test_logs/code_registry/functions/text_processor-c58ffc19_78b4ceac.py +42 -0
- test_logs/code_registry/functions/text_processor-cd5977b1_9168c5fe.py +13 -0
- test_logs/code_registry/functions/text_processor-ec1c8773_9168c5fe.py +13 -0
- tests/test_01_analyst_standalone.py +124 -0
- tests/test_02_assistant_standalone.py +164 -0
- tests/test_03_analyst_with_framework.py +945 -0
- tests/test_04_assistant_with_framework.py +1002 -0
- tests/test_05_integration.py +1301 -0
- tests/test_06_real_llm_integration.py +760 -0
- tests/test_07_distributed_single_node.py +578 -0
- tests/test_08_distributed_multi_node.py +454 -0
- tests/test_09_distributed_autoagent.py +509 -0
- tests/test_10_distributed_customagent.py +787 -0
- tests/test_context.py +467 -0
- tests/test_decorator.py +622 -0
- tests/test_mesh.py +35 -4
- jarviscore_framework-0.1.0.dist-info/METADATA +0 -136
- jarviscore_framework-0.1.0.dist-info/RECORD +0 -55
- {jarviscore_framework-0.1.0.dist-info → jarviscore_framework-0.2.0.dist-info}/licenses/LICENSE +0 -0
jarviscore/docs/USER_GUIDE.md
CHANGED
|
@@ -9,15 +9,16 @@ Practical guide to building agent systems with JarvisCore.
|
|
|
9
9
|
1. [Quick Start](#quick-start)
|
|
10
10
|
2. [Basic Concepts](#basic-concepts)
|
|
11
11
|
3. [AutoAgent Tutorial](#autoagent-tutorial)
|
|
12
|
-
4. [
|
|
13
|
-
5. [
|
|
14
|
-
6. [
|
|
15
|
-
7. [
|
|
16
|
-
8. [
|
|
17
|
-
9. [
|
|
18
|
-
10. [
|
|
19
|
-
11. [
|
|
20
|
-
12. [
|
|
12
|
+
4. [Custom Profile Tutorial](#custom-profile-tutorial)
|
|
13
|
+
5. [CustomAgent Tutorial](#customagent-tutorial)
|
|
14
|
+
6. [Multi-Agent Workflows](#multi-agent-workflows)
|
|
15
|
+
7. [Internet Search](#internet-search)
|
|
16
|
+
8. [Remote Sandbox](#remote-sandbox)
|
|
17
|
+
9. [Result Storage](#result-storage)
|
|
18
|
+
10. [Code Registry](#code-registry)
|
|
19
|
+
11. [Best Practices](#best-practices)
|
|
20
|
+
12. [Common Patterns](#common-patterns)
|
|
21
|
+
13. [Troubleshooting](#troubleshooting)
|
|
21
22
|
|
|
22
23
|
---
|
|
23
24
|
|
|
@@ -26,14 +27,18 @@ Practical guide to building agent systems with JarvisCore.
|
|
|
26
27
|
### Step 1: Installation (1 minute)
|
|
27
28
|
|
|
28
29
|
```bash
|
|
29
|
-
pip install jarviscore
|
|
30
|
+
pip install jarviscore-framework
|
|
30
31
|
```
|
|
31
32
|
|
|
32
33
|
### Step 2: Configuration (2 minutes)
|
|
33
34
|
|
|
34
|
-
JarvisCore needs an LLM provider to generate code for AutoAgent.
|
|
35
|
+
JarvisCore needs an LLM provider to generate code for AutoAgent. Initialize your project:
|
|
35
36
|
|
|
36
37
|
```bash
|
|
38
|
+
# Initialize project (creates .env.example and examples)
|
|
39
|
+
python -m jarviscore.cli.scaffold --examples
|
|
40
|
+
|
|
41
|
+
# Copy and configure your environment
|
|
37
42
|
cp .env.example .env
|
|
38
43
|
```
|
|
39
44
|
|
|
@@ -80,39 +85,30 @@ import asyncio
|
|
|
80
85
|
from jarviscore import Mesh
|
|
81
86
|
from jarviscore.profiles import AutoAgent
|
|
82
87
|
|
|
88
|
+
class CalculatorAgent(AutoAgent):
|
|
89
|
+
role = "calculator"
|
|
90
|
+
capabilities = ["math", "calculation"]
|
|
91
|
+
system_prompt = "You are a math expert. Store results in 'result' variable."
|
|
92
|
+
|
|
83
93
|
async def main():
|
|
84
|
-
# Create mesh
|
|
85
94
|
mesh = Mesh(mode="autonomous")
|
|
86
|
-
|
|
87
|
-
# Add calculator agent
|
|
88
|
-
mesh.add_agent(
|
|
89
|
-
AutoAgent,
|
|
90
|
-
role="calculator",
|
|
91
|
-
capabilities=["math", "calculation"],
|
|
92
|
-
system_prompt="You are a math expert"
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
# Start mesh
|
|
95
|
+
mesh.add(CalculatorAgent)
|
|
96
96
|
await mesh.start()
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
results = await mesh.run_workflow([
|
|
98
|
+
results = await mesh.workflow("calc", [
|
|
100
99
|
{"agent": "calculator", "task": "Calculate the factorial of 10"}
|
|
101
100
|
])
|
|
102
101
|
|
|
103
102
|
print(results[0]['output']) # 3628800
|
|
104
|
-
|
|
105
|
-
# Cleanup
|
|
106
103
|
await mesh.stop()
|
|
107
104
|
|
|
108
|
-
|
|
109
|
-
asyncio.run(main())
|
|
105
|
+
asyncio.run(main())
|
|
110
106
|
```
|
|
111
107
|
|
|
112
|
-
**That's it!**
|
|
113
|
-
1.
|
|
114
|
-
2. Add
|
|
115
|
-
3. Run
|
|
108
|
+
**That's it!** Three steps:
|
|
109
|
+
1. Define agent class
|
|
110
|
+
2. Add to mesh
|
|
111
|
+
3. Run workflow
|
|
116
112
|
|
|
117
113
|
---
|
|
118
114
|
|
|
@@ -123,26 +119,40 @@ if __name__ == '__main__':
|
|
|
123
119
|
The **Mesh** is your control center. It manages agents and orchestrates workflows.
|
|
124
120
|
|
|
125
121
|
```python
|
|
126
|
-
# Autonomous mode (single machine)
|
|
122
|
+
# Autonomous mode (single machine, workflow engine only)
|
|
127
123
|
mesh = Mesh(mode="autonomous")
|
|
128
124
|
|
|
129
|
-
#
|
|
130
|
-
mesh = Mesh(mode="
|
|
125
|
+
# P2P mode (agent-to-agent communication via SWIM/ZMQ)
|
|
126
|
+
mesh = Mesh(mode="p2p", config={'bind_port': 7950})
|
|
127
|
+
|
|
128
|
+
# Distributed mode (both workflow engine AND P2P networking)
|
|
129
|
+
mesh = Mesh(mode="distributed", config={'bind_port': 7950})
|
|
131
130
|
```
|
|
132
131
|
|
|
132
|
+
**Mode Selection:**
|
|
133
|
+
| Mode | Use Case | Components |
|
|
134
|
+
|------|----------|------------|
|
|
135
|
+
| `autonomous` | Single machine, simple pipelines | Workflow Engine |
|
|
136
|
+
| `p2p` | Agent swarms, real-time coordination | P2P Coordinator |
|
|
137
|
+
| `distributed` | Multi-node production systems | Both |
|
|
138
|
+
|
|
133
139
|
### Agents
|
|
134
140
|
|
|
135
|
-
**Agents** are workers that execute tasks. JarvisCore
|
|
141
|
+
**Agents** are workers that execute tasks. JarvisCore offers two profiles:
|
|
142
|
+
|
|
143
|
+
| Profile | Best For | How It Works |
|
|
144
|
+
|---------|----------|--------------|
|
|
145
|
+
| **AutoAgent** | Rapid prototyping | LLM generates + executes code from prompts |
|
|
146
|
+
| **CustomAgent** | Existing code | You provide `execute_task()` or `run()` |
|
|
136
147
|
|
|
137
|
-
|
|
138
|
-
2. **CustomAgent**: Full control (for production systems)
|
|
148
|
+
See [AutoAgent Guide](AUTOAGENT_GUIDE.md) and [CustomAgent Guide](CUSTOMAGENT_GUIDE.md) for details.
|
|
139
149
|
|
|
140
150
|
### Workflows
|
|
141
151
|
|
|
142
152
|
**Workflows** are sequences of tasks with dependencies:
|
|
143
153
|
|
|
144
154
|
```python
|
|
145
|
-
await mesh.
|
|
155
|
+
await mesh.workflow("pipeline-id", [
|
|
146
156
|
{"agent": "scraper", "task": "Scrape data"},
|
|
147
157
|
{"agent": "processor", "task": "Clean data", "depends_on": [0]},
|
|
148
158
|
{"agent": "storage", "task": "Save data", "depends_on": [1]}
|
|
@@ -153,6 +163,8 @@ await mesh.run_workflow([
|
|
|
153
163
|
|
|
154
164
|
## AutoAgent Tutorial
|
|
155
165
|
|
|
166
|
+
AutoAgent handles the "prompt → code → result" workflow automatically. See [AutoAgent Guide](AUTOAGENT_GUIDE.md) for distributed mode.
|
|
167
|
+
|
|
156
168
|
### Example 1: Simple Calculator
|
|
157
169
|
|
|
158
170
|
```python
|
|
@@ -160,25 +172,21 @@ import asyncio
|
|
|
160
172
|
from jarviscore import Mesh
|
|
161
173
|
from jarviscore.profiles import AutoAgent
|
|
162
174
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
AutoAgent,
|
|
168
|
-
role="calculator",
|
|
169
|
-
capabilities=["math", "calculation"],
|
|
170
|
-
system_prompt="You are a mathematical calculation expert"
|
|
171
|
-
)
|
|
175
|
+
class CalculatorAgent(AutoAgent):
|
|
176
|
+
role = "calculator"
|
|
177
|
+
capabilities = ["math", "calculation"]
|
|
178
|
+
system_prompt = "You are a mathematical calculation expert. Store results in 'result'."
|
|
172
179
|
|
|
180
|
+
async def calculator_demo():
|
|
181
|
+
mesh = Mesh(mode="autonomous")
|
|
182
|
+
mesh.add(CalculatorAgent)
|
|
173
183
|
await mesh.start()
|
|
174
184
|
|
|
175
|
-
|
|
176
|
-
result = await mesh.run_workflow([
|
|
185
|
+
result = await mesh.workflow("calc", [
|
|
177
186
|
{"agent": "calculator", "task": "Calculate 15!"}
|
|
178
187
|
])
|
|
179
188
|
|
|
180
189
|
print(f"15! = {result[0]['output']}")
|
|
181
|
-
|
|
182
190
|
await mesh.stop()
|
|
183
191
|
|
|
184
192
|
asyncio.run(calculator_demo())
|
|
@@ -187,19 +195,17 @@ asyncio.run(calculator_demo())
|
|
|
187
195
|
### Example 2: Data Analyst
|
|
188
196
|
|
|
189
197
|
```python
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
AutoAgent,
|
|
195
|
-
role="analyst",
|
|
196
|
-
capabilities=["data_analysis", "statistics"],
|
|
197
|
-
system_prompt="You are a data analyst expert"
|
|
198
|
-
)
|
|
198
|
+
class AnalystAgent(AutoAgent):
|
|
199
|
+
role = "analyst"
|
|
200
|
+
capabilities = ["data_analysis", "statistics"]
|
|
201
|
+
system_prompt = "You are a data analyst expert. Store results in 'result'."
|
|
199
202
|
|
|
203
|
+
async def data_analyst_demo():
|
|
204
|
+
mesh = Mesh(mode="autonomous")
|
|
205
|
+
mesh.add(AnalystAgent)
|
|
200
206
|
await mesh.start()
|
|
201
207
|
|
|
202
|
-
result = await mesh.
|
|
208
|
+
result = await mesh.workflow("analysis", [{
|
|
203
209
|
"agent": "analyst",
|
|
204
210
|
"task": """
|
|
205
211
|
Given this data: [23, 45, 12, 67, 89, 34, 56, 78, 90, 11]
|
|
@@ -208,287 +214,112 @@ async def data_analyst_demo():
|
|
|
208
214
|
}])
|
|
209
215
|
|
|
210
216
|
print(result[0]['output'])
|
|
211
|
-
# {'mean': 50.5, 'median': 50.5, 'std': 28.7, ...}
|
|
212
|
-
|
|
213
217
|
await mesh.stop()
|
|
214
218
|
|
|
215
219
|
asyncio.run(data_analyst_demo())
|
|
216
220
|
```
|
|
217
221
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
```python
|
|
221
|
-
async def text_processor_demo():
|
|
222
|
-
mesh = Mesh()
|
|
223
|
-
|
|
224
|
-
mesh.add_agent(
|
|
225
|
-
AutoAgent,
|
|
226
|
-
role="processor",
|
|
227
|
-
capabilities=["text_processing", "nlp"],
|
|
228
|
-
system_prompt="You are a text processing expert"
|
|
229
|
-
)
|
|
230
|
-
|
|
231
|
-
await mesh.start()
|
|
232
|
-
|
|
233
|
-
text = """
|
|
234
|
-
The quick brown fox jumps over the lazy dog.
|
|
235
|
-
Python is a popular programming language.
|
|
236
|
-
"""
|
|
237
|
-
|
|
238
|
-
result = await mesh.run_workflow([{
|
|
239
|
-
"agent": "processor",
|
|
240
|
-
"task": f"""
|
|
241
|
-
Analyze this text and return:
|
|
242
|
-
- Word count
|
|
243
|
-
- Sentence count
|
|
244
|
-
- Most common word
|
|
245
|
-
- Text: {text}
|
|
246
|
-
"""
|
|
247
|
-
}])
|
|
222
|
+
---
|
|
248
223
|
|
|
249
|
-
|
|
224
|
+
## Custom Profile Tutorial
|
|
250
225
|
|
|
251
|
-
|
|
226
|
+
The **Custom Profile** (decorator/wrap approach) is deprecated. Use **CustomAgent** instead.
|
|
252
227
|
|
|
253
|
-
|
|
254
|
-
|
|
228
|
+
See [CustomAgent Guide](CUSTOMAGENT_GUIDE.md) for:
|
|
229
|
+
- Converting standalone agents to JarvisCore
|
|
230
|
+
- P2P mode for agent-to-agent communication
|
|
231
|
+
- Distributed mode for multi-node systems
|
|
255
232
|
|
|
256
233
|
---
|
|
257
234
|
|
|
258
235
|
## CustomAgent Tutorial
|
|
259
236
|
|
|
260
|
-
|
|
237
|
+
CustomAgent gives you full control over execution logic. See [CustomAgent Guide](CUSTOMAGENT_GUIDE.md) for P2P and distributed modes.
|
|
261
238
|
|
|
262
|
-
|
|
263
|
-
from jarviscore.profiles import CustomAgent
|
|
264
|
-
import aiohttp
|
|
265
|
-
|
|
266
|
-
class WeatherAgent(CustomAgent):
|
|
267
|
-
"""Agent that fetches weather data from external API."""
|
|
268
|
-
|
|
269
|
-
async def setup(self):
|
|
270
|
-
"""Initialize API client."""
|
|
271
|
-
self.api_key = "your-api-key"
|
|
272
|
-
self.base_url = "https://api.weather.com"
|
|
273
|
-
|
|
274
|
-
async def execute_task(self, task):
|
|
275
|
-
"""Execute weather query."""
|
|
276
|
-
task_desc = task.get('task', '')
|
|
277
|
-
|
|
278
|
-
# Extract city from task description
|
|
279
|
-
city = self._extract_city(task_desc)
|
|
280
|
-
|
|
281
|
-
# Fetch weather data
|
|
282
|
-
async with aiohttp.ClientSession() as session:
|
|
283
|
-
async with session.get(
|
|
284
|
-
f"{self.base_url}/weather?city={city}&key={self.api_key}"
|
|
285
|
-
) as response:
|
|
286
|
-
data = await response.json()
|
|
287
|
-
|
|
288
|
-
# Track cost (optional)
|
|
289
|
-
self.track_cost(cost_usd=0.001)
|
|
290
|
-
|
|
291
|
-
return {
|
|
292
|
-
"status": "success",
|
|
293
|
-
"output": {
|
|
294
|
-
"city": city,
|
|
295
|
-
"temperature": data['temp'],
|
|
296
|
-
"conditions": data['conditions']
|
|
297
|
-
},
|
|
298
|
-
"agent": self.agent_id
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
def _extract_city(self, text):
|
|
302
|
-
"""Simple city extraction logic."""
|
|
303
|
-
# Your parsing logic here
|
|
304
|
-
return "New York"
|
|
305
|
-
|
|
306
|
-
# Usage
|
|
307
|
-
async def weather_demo():
|
|
308
|
-
mesh = Mesh()
|
|
309
|
-
|
|
310
|
-
mesh.add_agent(
|
|
311
|
-
WeatherAgent,
|
|
312
|
-
role="weather",
|
|
313
|
-
capabilities=["weather", "api"]
|
|
314
|
-
)
|
|
315
|
-
|
|
316
|
-
await mesh.start()
|
|
317
|
-
|
|
318
|
-
result = await mesh.run_workflow([
|
|
319
|
-
{"agent": "weather", "task": "Get weather for New York"}
|
|
320
|
-
])
|
|
321
|
-
|
|
322
|
-
print(result[0]['output'])
|
|
323
|
-
|
|
324
|
-
await mesh.stop()
|
|
325
|
-
|
|
326
|
-
asyncio.run(weather_demo())
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
### Example 2: Database Agent
|
|
239
|
+
### Quick Example
|
|
330
240
|
|
|
331
241
|
```python
|
|
242
|
+
from jarviscore import Mesh
|
|
332
243
|
from jarviscore.profiles import CustomAgent
|
|
333
|
-
import asyncpg
|
|
334
244
|
|
|
335
|
-
class
|
|
336
|
-
|
|
245
|
+
class MyAgent(CustomAgent):
|
|
246
|
+
role = "processor"
|
|
247
|
+
capabilities = ["data_processing"]
|
|
337
248
|
|
|
338
249
|
async def setup(self):
|
|
339
|
-
"""
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
database='mydb',
|
|
343
|
-
user='user',
|
|
344
|
-
password='password'
|
|
345
|
-
)
|
|
346
|
-
|
|
347
|
-
async def teardown(self):
|
|
348
|
-
"""Close database connection."""
|
|
349
|
-
await self.pool.close()
|
|
250
|
+
"""Initialize resources (DB connections, API clients, etc.)."""
|
|
251
|
+
await super().setup()
|
|
252
|
+
self.data = []
|
|
350
253
|
|
|
351
254
|
async def execute_task(self, task):
|
|
352
|
-
"""
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
async with self.pool.acquire() as conn:
|
|
356
|
-
# Execute query
|
|
357
|
-
rows = await conn.fetch(query)
|
|
255
|
+
"""Called by workflow engine for each task."""
|
|
256
|
+
task_desc = task.get("task", "")
|
|
257
|
+
context = task.get("context", {}) # From depends_on steps
|
|
358
258
|
|
|
359
|
-
|
|
360
|
-
|
|
259
|
+
# Your logic here
|
|
260
|
+
result = {"processed": task_desc.upper()}
|
|
361
261
|
|
|
362
262
|
return {
|
|
363
263
|
"status": "success",
|
|
364
|
-
"output":
|
|
365
|
-
"
|
|
264
|
+
"output": result,
|
|
265
|
+
"agent_id": self.agent_id
|
|
366
266
|
}
|
|
367
267
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
mesh
|
|
371
|
-
|
|
372
|
-
mesh.add_agent(
|
|
373
|
-
DatabaseAgent,
|
|
374
|
-
role="database",
|
|
375
|
-
capabilities=["database", "query"]
|
|
376
|
-
)
|
|
377
|
-
|
|
268
|
+
async def main():
|
|
269
|
+
mesh = Mesh(mode="autonomous")
|
|
270
|
+
mesh.add(MyAgent)
|
|
378
271
|
await mesh.start()
|
|
379
272
|
|
|
380
|
-
|
|
381
|
-
{"agent": "
|
|
273
|
+
results = await mesh.workflow("demo", [
|
|
274
|
+
{"agent": "processor", "task": "hello world"}
|
|
382
275
|
])
|
|
383
276
|
|
|
384
|
-
print(
|
|
385
|
-
|
|
277
|
+
print(results[0]["output"]) # {"processed": "HELLO WORLD"}
|
|
386
278
|
await mesh.stop()
|
|
387
|
-
|
|
388
|
-
asyncio.run(database_demo())
|
|
389
279
|
```
|
|
390
280
|
|
|
391
|
-
###
|
|
392
|
-
|
|
393
|
-
```python
|
|
394
|
-
from jarviscore.profiles import CustomAgent
|
|
395
|
-
from langchain_openai import ChatOpenAI
|
|
396
|
-
from langchain.prompts import ChatPromptTemplate
|
|
397
|
-
from langchain.schema.runnable import RunnableSequence
|
|
398
|
-
|
|
399
|
-
class LangChainAgent(CustomAgent):
|
|
400
|
-
"""Agent using LangChain for LLM interactions."""
|
|
281
|
+
### Key Methods
|
|
401
282
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
("user", "{input}")
|
|
409
|
-
])
|
|
410
|
-
|
|
411
|
-
self.chain = self.prompt | self.llm
|
|
412
|
-
|
|
413
|
-
async def execute_task(self, task):
|
|
414
|
-
"""Execute task using LangChain."""
|
|
415
|
-
task_desc = task.get('task', '')
|
|
416
|
-
|
|
417
|
-
# Run LangChain
|
|
418
|
-
response = await self.chain.ainvoke({"input": task_desc})
|
|
419
|
-
|
|
420
|
-
# Track tokens and cost
|
|
421
|
-
self.track_cost(
|
|
422
|
-
input_tokens=100,
|
|
423
|
-
output_tokens=50,
|
|
424
|
-
cost_usd=0.002
|
|
425
|
-
)
|
|
426
|
-
|
|
427
|
-
return {
|
|
428
|
-
"status": "success",
|
|
429
|
-
"output": response.content,
|
|
430
|
-
"agent": self.agent_id
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
# Usage
|
|
434
|
-
async def langchain_demo():
|
|
435
|
-
mesh = Mesh()
|
|
436
|
-
|
|
437
|
-
mesh.add_agent(
|
|
438
|
-
LangChainAgent,
|
|
439
|
-
role="assistant",
|
|
440
|
-
capabilities=["chat", "qa"]
|
|
441
|
-
)
|
|
442
|
-
|
|
443
|
-
await mesh.start()
|
|
444
|
-
|
|
445
|
-
result = await mesh.run_workflow([
|
|
446
|
-
{"agent": "assistant", "task": "Explain quantum computing"}
|
|
447
|
-
])
|
|
448
|
-
|
|
449
|
-
print(result[0]['output'])
|
|
450
|
-
|
|
451
|
-
await mesh.stop()
|
|
452
|
-
|
|
453
|
-
asyncio.run(langchain_demo())
|
|
454
|
-
```
|
|
283
|
+
| Method | Purpose | Mode |
|
|
284
|
+
|--------|---------|------|
|
|
285
|
+
| `setup()` | Initialize resources | All |
|
|
286
|
+
| `execute_task(task)` | Handle workflow steps | Autonomous/Distributed |
|
|
287
|
+
| `run()` | Continuous loop | P2P |
|
|
288
|
+
| `teardown()` | Cleanup resources | All |
|
|
455
289
|
|
|
456
290
|
---
|
|
457
291
|
|
|
458
292
|
## Multi-Agent Workflows
|
|
459
293
|
|
|
460
|
-
### Example
|
|
294
|
+
### Example: Data Pipeline
|
|
461
295
|
|
|
462
296
|
```python
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
# Add three agents
|
|
467
|
-
mesh.add_agent(
|
|
468
|
-
AutoAgent,
|
|
469
|
-
role="scraper",
|
|
470
|
-
capabilities=["web_scraping", "data_collection"],
|
|
471
|
-
system_prompt="You are a web scraping expert"
|
|
472
|
-
)
|
|
297
|
+
from jarviscore import Mesh
|
|
298
|
+
from jarviscore.profiles import AutoAgent
|
|
473
299
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
system_prompt="You are a data cleaning expert"
|
|
479
|
-
)
|
|
300
|
+
class ScraperAgent(AutoAgent):
|
|
301
|
+
role = "scraper"
|
|
302
|
+
capabilities = ["web_scraping", "data_collection"]
|
|
303
|
+
system_prompt = "You are a web scraping expert. Store results in 'result'."
|
|
480
304
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
305
|
+
class ProcessorAgent(AutoAgent):
|
|
306
|
+
role = "processor"
|
|
307
|
+
capabilities = ["data_processing", "cleaning"]
|
|
308
|
+
system_prompt = "You are a data cleaning expert. Store results in 'result'."
|
|
309
|
+
|
|
310
|
+
class AnalyzerAgent(AutoAgent):
|
|
311
|
+
role = "analyzer"
|
|
312
|
+
capabilities = ["analysis", "statistics"]
|
|
313
|
+
system_prompt = "You are a data analysis expert. Store results in 'result'."
|
|
487
314
|
|
|
315
|
+
async def data_pipeline():
|
|
316
|
+
mesh = Mesh(mode="autonomous")
|
|
317
|
+
mesh.add(ScraperAgent)
|
|
318
|
+
mesh.add(ProcessorAgent)
|
|
319
|
+
mesh.add(AnalyzerAgent)
|
|
488
320
|
await mesh.start()
|
|
489
321
|
|
|
490
|
-
|
|
491
|
-
results = await mesh.run_workflow([
|
|
322
|
+
results = await mesh.workflow("pipeline", [
|
|
492
323
|
{
|
|
493
324
|
"id": "scrape",
|
|
494
325
|
"agent": "scraper",
|
|
@@ -508,61 +339,14 @@ async def data_pipeline():
|
|
|
508
339
|
}
|
|
509
340
|
])
|
|
510
341
|
|
|
511
|
-
|
|
512
|
-
print("
|
|
513
|
-
print("Clean result:", results[1]['output'])
|
|
342
|
+
print("Scrape:", results[0]['output'])
|
|
343
|
+
print("Clean:", results[1]['output'])
|
|
514
344
|
print("Analysis:", results[2]['output'])
|
|
515
|
-
|
|
516
345
|
await mesh.stop()
|
|
517
346
|
|
|
518
347
|
asyncio.run(data_pipeline())
|
|
519
348
|
```
|
|
520
349
|
|
|
521
|
-
### Example 2: Report Generator
|
|
522
|
-
|
|
523
|
-
```python
|
|
524
|
-
async def report_generator():
|
|
525
|
-
mesh = Mesh()
|
|
526
|
-
|
|
527
|
-
mesh.add_agent(
|
|
528
|
-
AutoAgent,
|
|
529
|
-
role="researcher",
|
|
530
|
-
capabilities=["research", "data_gathering"],
|
|
531
|
-
system_prompt="You are a researcher",
|
|
532
|
-
enable_search=True # Enable internet search
|
|
533
|
-
)
|
|
534
|
-
|
|
535
|
-
mesh.add_agent(
|
|
536
|
-
AutoAgent,
|
|
537
|
-
role="writer",
|
|
538
|
-
capabilities=["writing", "formatting"],
|
|
539
|
-
system_prompt="You are a technical writer"
|
|
540
|
-
)
|
|
541
|
-
|
|
542
|
-
await mesh.start()
|
|
543
|
-
|
|
544
|
-
results = await mesh.run_workflow([
|
|
545
|
-
{
|
|
546
|
-
"id": "research",
|
|
547
|
-
"agent": "researcher",
|
|
548
|
-
"task": "Research latest Python 3.12 features"
|
|
549
|
-
},
|
|
550
|
-
{
|
|
551
|
-
"id": "write",
|
|
552
|
-
"agent": "writer",
|
|
553
|
-
"task": "Write a 2-paragraph summary of the research findings",
|
|
554
|
-
"depends_on": ["research"]
|
|
555
|
-
}
|
|
556
|
-
])
|
|
557
|
-
|
|
558
|
-
print("Research:", results[0]['output'])
|
|
559
|
-
print("\nReport:", results[1]['output'])
|
|
560
|
-
|
|
561
|
-
await mesh.stop()
|
|
562
|
-
|
|
563
|
-
asyncio.run(report_generator())
|
|
564
|
-
```
|
|
565
|
-
|
|
566
350
|
---
|
|
567
351
|
|
|
568
352
|
## Internet Search
|
|
@@ -573,27 +357,23 @@ Enable web search for research tasks:
|
|
|
573
357
|
from jarviscore import Mesh
|
|
574
358
|
from jarviscore.profiles import AutoAgent
|
|
575
359
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
role="researcher",
|
|
582
|
-
capabilities=["research", "web_search"],
|
|
583
|
-
system_prompt="You are an expert researcher",
|
|
584
|
-
enable_search=True # ← Enable internet search
|
|
585
|
-
)
|
|
360
|
+
class ResearcherAgent(AutoAgent):
|
|
361
|
+
role = "researcher"
|
|
362
|
+
capabilities = ["research", "web_search"]
|
|
363
|
+
system_prompt = "You are an expert researcher. Store results in 'result'."
|
|
364
|
+
enable_search = True # ← Enable internet search
|
|
586
365
|
|
|
366
|
+
async def search_demo():
|
|
367
|
+
mesh = Mesh(mode="autonomous")
|
|
368
|
+
mesh.add(ResearcherAgent)
|
|
587
369
|
await mesh.start()
|
|
588
370
|
|
|
589
|
-
result = await mesh.
|
|
371
|
+
result = await mesh.workflow("search", [{
|
|
590
372
|
"agent": "researcher",
|
|
591
|
-
"task": "Search for 'Python asyncio best practices' and summarize
|
|
373
|
+
"task": "Search for 'Python asyncio best practices' and summarize top 3 results"
|
|
592
374
|
}])
|
|
593
375
|
|
|
594
376
|
print(result[0]['output'])
|
|
595
|
-
# Returns: Summary of top 3 search results
|
|
596
|
-
|
|
597
377
|
await mesh.stop()
|
|
598
378
|
|
|
599
379
|
asyncio.run(search_demo())
|
|
@@ -969,15 +749,16 @@ mesh = Mesh(config=config)
|
|
|
969
749
|
|
|
970
750
|
## Next Steps
|
|
971
751
|
|
|
972
|
-
1. **
|
|
973
|
-
2. **
|
|
974
|
-
3. **
|
|
975
|
-
4. **
|
|
752
|
+
1. **[AutoAgent Guide](AUTOAGENT_GUIDE.md)** - Multi-node distributed mode
|
|
753
|
+
2. **[CustomAgent Guide](CUSTOMAGENT_GUIDE.md)** - P2P and distributed with your code
|
|
754
|
+
3. **[API Reference](API_REFERENCE.md)** - Detailed component documentation
|
|
755
|
+
4. **[Configuration Guide](CONFIGURATION.md)** - Environment setup
|
|
756
|
+
5. **Explore `examples/`** directory for more code samples
|
|
976
757
|
|
|
977
758
|
---
|
|
978
759
|
|
|
979
760
|
## Version
|
|
980
761
|
|
|
981
|
-
User Guide for JarvisCore v0.
|
|
762
|
+
User Guide for JarvisCore v0.2.0
|
|
982
763
|
|
|
983
|
-
Last Updated: 2026-01-
|
|
764
|
+
Last Updated: 2026-01-22
|