jarviscore-framework 0.1.1__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 +49 -36
- jarviscore/adapter/__init__.py +15 -9
- jarviscore/adapter/decorator.py +23 -19
- jarviscore/adapter/wrapper.py +303 -0
- jarviscore/cli/scaffold.py +1 -1
- jarviscore/cli/smoketest.py +3 -2
- jarviscore/core/agent.py +44 -1
- jarviscore/core/mesh.py +196 -35
- jarviscore/data/examples/autoagent_distributed_example.py +211 -0
- jarviscore/data/examples/customagent_distributed_example.py +362 -0
- jarviscore/data/examples/customagent_p2p_example.py +347 -0
- jarviscore/docs/API_REFERENCE.md +264 -51
- jarviscore/docs/AUTOAGENT_GUIDE.md +198 -0
- jarviscore/docs/CONFIGURATION.md +35 -21
- jarviscore/docs/CUSTOMAGENT_GUIDE.md +415 -0
- jarviscore/docs/GETTING_STARTED.md +106 -13
- jarviscore/docs/TROUBLESHOOTING.md +144 -6
- jarviscore/docs/USER_GUIDE.md +138 -361
- 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.1.1.dist-info → jarviscore_framework-0.2.0.dist-info}/METADATA +60 -54
- jarviscore_framework-0.2.0.dist-info/RECORD +132 -0
- {jarviscore_framework-0.1.1.dist-info → jarviscore_framework-0.2.0.dist-info}/WHEEL +1 -1
- {jarviscore_framework-0.1.1.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_mesh.py +35 -4
- jarviscore_framework-0.1.1.dist-info/RECORD +0 -69
- {jarviscore_framework-0.1.1.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
|
|
|
@@ -84,39 +85,30 @@ import asyncio
|
|
|
84
85
|
from jarviscore import Mesh
|
|
85
86
|
from jarviscore.profiles import AutoAgent
|
|
86
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
|
+
|
|
87
93
|
async def main():
|
|
88
|
-
# Create mesh
|
|
89
94
|
mesh = Mesh(mode="autonomous")
|
|
90
|
-
|
|
91
|
-
# Add calculator agent
|
|
92
|
-
mesh.add_agent(
|
|
93
|
-
AutoAgent,
|
|
94
|
-
role="calculator",
|
|
95
|
-
capabilities=["math", "calculation"],
|
|
96
|
-
system_prompt="You are a math expert"
|
|
97
|
-
)
|
|
98
|
-
|
|
99
|
-
# Start mesh
|
|
95
|
+
mesh.add(CalculatorAgent)
|
|
100
96
|
await mesh.start()
|
|
101
97
|
|
|
102
|
-
|
|
103
|
-
results = await mesh.run_workflow([
|
|
98
|
+
results = await mesh.workflow("calc", [
|
|
104
99
|
{"agent": "calculator", "task": "Calculate the factorial of 10"}
|
|
105
100
|
])
|
|
106
101
|
|
|
107
102
|
print(results[0]['output']) # 3628800
|
|
108
|
-
|
|
109
|
-
# Cleanup
|
|
110
103
|
await mesh.stop()
|
|
111
104
|
|
|
112
|
-
|
|
113
|
-
asyncio.run(main())
|
|
105
|
+
asyncio.run(main())
|
|
114
106
|
```
|
|
115
107
|
|
|
116
|
-
**That's it!**
|
|
117
|
-
1.
|
|
118
|
-
2. Add
|
|
119
|
-
3. Run
|
|
108
|
+
**That's it!** Three steps:
|
|
109
|
+
1. Define agent class
|
|
110
|
+
2. Add to mesh
|
|
111
|
+
3. Run workflow
|
|
120
112
|
|
|
121
113
|
---
|
|
122
114
|
|
|
@@ -127,26 +119,40 @@ if __name__ == '__main__':
|
|
|
127
119
|
The **Mesh** is your control center. It manages agents and orchestrates workflows.
|
|
128
120
|
|
|
129
121
|
```python
|
|
130
|
-
# Autonomous mode (single machine)
|
|
122
|
+
# Autonomous mode (single machine, workflow engine only)
|
|
131
123
|
mesh = Mesh(mode="autonomous")
|
|
132
124
|
|
|
133
|
-
#
|
|
134
|
-
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})
|
|
135
130
|
```
|
|
136
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
|
+
|
|
137
139
|
### Agents
|
|
138
140
|
|
|
139
|
-
**Agents** are workers that execute tasks. JarvisCore
|
|
141
|
+
**Agents** are workers that execute tasks. JarvisCore offers two profiles:
|
|
140
142
|
|
|
141
|
-
|
|
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()` |
|
|
147
|
+
|
|
148
|
+
See [AutoAgent Guide](AUTOAGENT_GUIDE.md) and [CustomAgent Guide](CUSTOMAGENT_GUIDE.md) for details.
|
|
143
149
|
|
|
144
150
|
### Workflows
|
|
145
151
|
|
|
146
152
|
**Workflows** are sequences of tasks with dependencies:
|
|
147
153
|
|
|
148
154
|
```python
|
|
149
|
-
await mesh.
|
|
155
|
+
await mesh.workflow("pipeline-id", [
|
|
150
156
|
{"agent": "scraper", "task": "Scrape data"},
|
|
151
157
|
{"agent": "processor", "task": "Clean data", "depends_on": [0]},
|
|
152
158
|
{"agent": "storage", "task": "Save data", "depends_on": [1]}
|
|
@@ -157,6 +163,8 @@ await mesh.run_workflow([
|
|
|
157
163
|
|
|
158
164
|
## AutoAgent Tutorial
|
|
159
165
|
|
|
166
|
+
AutoAgent handles the "prompt → code → result" workflow automatically. See [AutoAgent Guide](AUTOAGENT_GUIDE.md) for distributed mode.
|
|
167
|
+
|
|
160
168
|
### Example 1: Simple Calculator
|
|
161
169
|
|
|
162
170
|
```python
|
|
@@ -164,25 +172,21 @@ import asyncio
|
|
|
164
172
|
from jarviscore import Mesh
|
|
165
173
|
from jarviscore.profiles import AutoAgent
|
|
166
174
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
AutoAgent,
|
|
172
|
-
role="calculator",
|
|
173
|
-
capabilities=["math", "calculation"],
|
|
174
|
-
system_prompt="You are a mathematical calculation expert"
|
|
175
|
-
)
|
|
175
|
+
class CalculatorAgent(AutoAgent):
|
|
176
|
+
role = "calculator"
|
|
177
|
+
capabilities = ["math", "calculation"]
|
|
178
|
+
system_prompt = "You are a mathematical calculation expert. Store results in 'result'."
|
|
176
179
|
|
|
180
|
+
async def calculator_demo():
|
|
181
|
+
mesh = Mesh(mode="autonomous")
|
|
182
|
+
mesh.add(CalculatorAgent)
|
|
177
183
|
await mesh.start()
|
|
178
184
|
|
|
179
|
-
|
|
180
|
-
result = await mesh.run_workflow([
|
|
185
|
+
result = await mesh.workflow("calc", [
|
|
181
186
|
{"agent": "calculator", "task": "Calculate 15!"}
|
|
182
187
|
])
|
|
183
188
|
|
|
184
189
|
print(f"15! = {result[0]['output']}")
|
|
185
|
-
|
|
186
190
|
await mesh.stop()
|
|
187
191
|
|
|
188
192
|
asyncio.run(calculator_demo())
|
|
@@ -191,19 +195,17 @@ asyncio.run(calculator_demo())
|
|
|
191
195
|
### Example 2: Data Analyst
|
|
192
196
|
|
|
193
197
|
```python
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
AutoAgent,
|
|
199
|
-
role="analyst",
|
|
200
|
-
capabilities=["data_analysis", "statistics"],
|
|
201
|
-
system_prompt="You are a data analyst expert"
|
|
202
|
-
)
|
|
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'."
|
|
203
202
|
|
|
203
|
+
async def data_analyst_demo():
|
|
204
|
+
mesh = Mesh(mode="autonomous")
|
|
205
|
+
mesh.add(AnalystAgent)
|
|
204
206
|
await mesh.start()
|
|
205
207
|
|
|
206
|
-
result = await mesh.
|
|
208
|
+
result = await mesh.workflow("analysis", [{
|
|
207
209
|
"agent": "analyst",
|
|
208
210
|
"task": """
|
|
209
211
|
Given this data: [23, 45, 12, 67, 89, 34, 56, 78, 90, 11]
|
|
@@ -212,287 +214,112 @@ async def data_analyst_demo():
|
|
|
212
214
|
}])
|
|
213
215
|
|
|
214
216
|
print(result[0]['output'])
|
|
215
|
-
# {'mean': 50.5, 'median': 50.5, 'std': 28.7, ...}
|
|
216
|
-
|
|
217
217
|
await mesh.stop()
|
|
218
218
|
|
|
219
219
|
asyncio.run(data_analyst_demo())
|
|
220
220
|
```
|
|
221
221
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
```python
|
|
225
|
-
async def text_processor_demo():
|
|
226
|
-
mesh = Mesh()
|
|
227
|
-
|
|
228
|
-
mesh.add_agent(
|
|
229
|
-
AutoAgent,
|
|
230
|
-
role="processor",
|
|
231
|
-
capabilities=["text_processing", "nlp"],
|
|
232
|
-
system_prompt="You are a text processing expert"
|
|
233
|
-
)
|
|
234
|
-
|
|
235
|
-
await mesh.start()
|
|
222
|
+
---
|
|
236
223
|
|
|
237
|
-
|
|
238
|
-
The quick brown fox jumps over the lazy dog.
|
|
239
|
-
Python is a popular programming language.
|
|
240
|
-
"""
|
|
241
|
-
|
|
242
|
-
result = await mesh.run_workflow([{
|
|
243
|
-
"agent": "processor",
|
|
244
|
-
"task": f"""
|
|
245
|
-
Analyze this text and return:
|
|
246
|
-
- Word count
|
|
247
|
-
- Sentence count
|
|
248
|
-
- Most common word
|
|
249
|
-
- Text: {text}
|
|
250
|
-
"""
|
|
251
|
-
}])
|
|
224
|
+
## Custom Profile Tutorial
|
|
252
225
|
|
|
253
|
-
|
|
226
|
+
The **Custom Profile** (decorator/wrap approach) is deprecated. Use **CustomAgent** instead.
|
|
254
227
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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
|
|
259
232
|
|
|
260
233
|
---
|
|
261
234
|
|
|
262
235
|
## CustomAgent Tutorial
|
|
263
236
|
|
|
264
|
-
|
|
237
|
+
CustomAgent gives you full control over execution logic. See [CustomAgent Guide](CUSTOMAGENT_GUIDE.md) for P2P and distributed modes.
|
|
265
238
|
|
|
266
|
-
|
|
267
|
-
from jarviscore.profiles import CustomAgent
|
|
268
|
-
import aiohttp
|
|
269
|
-
|
|
270
|
-
class WeatherAgent(CustomAgent):
|
|
271
|
-
"""Agent that fetches weather data from external API."""
|
|
272
|
-
|
|
273
|
-
async def setup(self):
|
|
274
|
-
"""Initialize API client."""
|
|
275
|
-
self.api_key = "your-api-key"
|
|
276
|
-
self.base_url = "https://api.weather.com"
|
|
277
|
-
|
|
278
|
-
async def execute_task(self, task):
|
|
279
|
-
"""Execute weather query."""
|
|
280
|
-
task_desc = task.get('task', '')
|
|
281
|
-
|
|
282
|
-
# Extract city from task description
|
|
283
|
-
city = self._extract_city(task_desc)
|
|
284
|
-
|
|
285
|
-
# Fetch weather data
|
|
286
|
-
async with aiohttp.ClientSession() as session:
|
|
287
|
-
async with session.get(
|
|
288
|
-
f"{self.base_url}/weather?city={city}&key={self.api_key}"
|
|
289
|
-
) as response:
|
|
290
|
-
data = await response.json()
|
|
291
|
-
|
|
292
|
-
# Track cost (optional)
|
|
293
|
-
self.track_cost(cost_usd=0.001)
|
|
294
|
-
|
|
295
|
-
return {
|
|
296
|
-
"status": "success",
|
|
297
|
-
"output": {
|
|
298
|
-
"city": city,
|
|
299
|
-
"temperature": data['temp'],
|
|
300
|
-
"conditions": data['conditions']
|
|
301
|
-
},
|
|
302
|
-
"agent": self.agent_id
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
def _extract_city(self, text):
|
|
306
|
-
"""Simple city extraction logic."""
|
|
307
|
-
# Your parsing logic here
|
|
308
|
-
return "New York"
|
|
309
|
-
|
|
310
|
-
# Usage
|
|
311
|
-
async def weather_demo():
|
|
312
|
-
mesh = Mesh()
|
|
313
|
-
|
|
314
|
-
mesh.add_agent(
|
|
315
|
-
WeatherAgent,
|
|
316
|
-
role="weather",
|
|
317
|
-
capabilities=["weather", "api"]
|
|
318
|
-
)
|
|
319
|
-
|
|
320
|
-
await mesh.start()
|
|
321
|
-
|
|
322
|
-
result = await mesh.run_workflow([
|
|
323
|
-
{"agent": "weather", "task": "Get weather for New York"}
|
|
324
|
-
])
|
|
325
|
-
|
|
326
|
-
print(result[0]['output'])
|
|
327
|
-
|
|
328
|
-
await mesh.stop()
|
|
329
|
-
|
|
330
|
-
asyncio.run(weather_demo())
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
### Example 2: Database Agent
|
|
239
|
+
### Quick Example
|
|
334
240
|
|
|
335
241
|
```python
|
|
242
|
+
from jarviscore import Mesh
|
|
336
243
|
from jarviscore.profiles import CustomAgent
|
|
337
|
-
import asyncpg
|
|
338
244
|
|
|
339
|
-
class
|
|
340
|
-
|
|
245
|
+
class MyAgent(CustomAgent):
|
|
246
|
+
role = "processor"
|
|
247
|
+
capabilities = ["data_processing"]
|
|
341
248
|
|
|
342
249
|
async def setup(self):
|
|
343
|
-
"""
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
database='mydb',
|
|
347
|
-
user='user',
|
|
348
|
-
password='password'
|
|
349
|
-
)
|
|
350
|
-
|
|
351
|
-
async def teardown(self):
|
|
352
|
-
"""Close database connection."""
|
|
353
|
-
await self.pool.close()
|
|
250
|
+
"""Initialize resources (DB connections, API clients, etc.)."""
|
|
251
|
+
await super().setup()
|
|
252
|
+
self.data = []
|
|
354
253
|
|
|
355
254
|
async def execute_task(self, task):
|
|
356
|
-
"""
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
async with self.pool.acquire() as conn:
|
|
360
|
-
# Execute query
|
|
361
|
-
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
|
|
362
258
|
|
|
363
|
-
|
|
364
|
-
|
|
259
|
+
# Your logic here
|
|
260
|
+
result = {"processed": task_desc.upper()}
|
|
365
261
|
|
|
366
262
|
return {
|
|
367
263
|
"status": "success",
|
|
368
|
-
"output":
|
|
369
|
-
"
|
|
264
|
+
"output": result,
|
|
265
|
+
"agent_id": self.agent_id
|
|
370
266
|
}
|
|
371
267
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
mesh
|
|
375
|
-
|
|
376
|
-
mesh.add_agent(
|
|
377
|
-
DatabaseAgent,
|
|
378
|
-
role="database",
|
|
379
|
-
capabilities=["database", "query"]
|
|
380
|
-
)
|
|
381
|
-
|
|
268
|
+
async def main():
|
|
269
|
+
mesh = Mesh(mode="autonomous")
|
|
270
|
+
mesh.add(MyAgent)
|
|
382
271
|
await mesh.start()
|
|
383
272
|
|
|
384
|
-
|
|
385
|
-
{"agent": "
|
|
273
|
+
results = await mesh.workflow("demo", [
|
|
274
|
+
{"agent": "processor", "task": "hello world"}
|
|
386
275
|
])
|
|
387
276
|
|
|
388
|
-
print(
|
|
389
|
-
|
|
277
|
+
print(results[0]["output"]) # {"processed": "HELLO WORLD"}
|
|
390
278
|
await mesh.stop()
|
|
391
|
-
|
|
392
|
-
asyncio.run(database_demo())
|
|
393
279
|
```
|
|
394
280
|
|
|
395
|
-
###
|
|
396
|
-
|
|
397
|
-
```python
|
|
398
|
-
from jarviscore.profiles import CustomAgent
|
|
399
|
-
from langchain_openai import ChatOpenAI
|
|
400
|
-
from langchain.prompts import ChatPromptTemplate
|
|
401
|
-
from langchain.schema.runnable import RunnableSequence
|
|
402
|
-
|
|
403
|
-
class LangChainAgent(CustomAgent):
|
|
404
|
-
"""Agent using LangChain for LLM interactions."""
|
|
281
|
+
### Key Methods
|
|
405
282
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
("user", "{input}")
|
|
413
|
-
])
|
|
414
|
-
|
|
415
|
-
self.chain = self.prompt | self.llm
|
|
416
|
-
|
|
417
|
-
async def execute_task(self, task):
|
|
418
|
-
"""Execute task using LangChain."""
|
|
419
|
-
task_desc = task.get('task', '')
|
|
420
|
-
|
|
421
|
-
# Run LangChain
|
|
422
|
-
response = await self.chain.ainvoke({"input": task_desc})
|
|
423
|
-
|
|
424
|
-
# Track tokens and cost
|
|
425
|
-
self.track_cost(
|
|
426
|
-
input_tokens=100,
|
|
427
|
-
output_tokens=50,
|
|
428
|
-
cost_usd=0.002
|
|
429
|
-
)
|
|
430
|
-
|
|
431
|
-
return {
|
|
432
|
-
"status": "success",
|
|
433
|
-
"output": response.content,
|
|
434
|
-
"agent": self.agent_id
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
# Usage
|
|
438
|
-
async def langchain_demo():
|
|
439
|
-
mesh = Mesh()
|
|
440
|
-
|
|
441
|
-
mesh.add_agent(
|
|
442
|
-
LangChainAgent,
|
|
443
|
-
role="assistant",
|
|
444
|
-
capabilities=["chat", "qa"]
|
|
445
|
-
)
|
|
446
|
-
|
|
447
|
-
await mesh.start()
|
|
448
|
-
|
|
449
|
-
result = await mesh.run_workflow([
|
|
450
|
-
{"agent": "assistant", "task": "Explain quantum computing"}
|
|
451
|
-
])
|
|
452
|
-
|
|
453
|
-
print(result[0]['output'])
|
|
454
|
-
|
|
455
|
-
await mesh.stop()
|
|
456
|
-
|
|
457
|
-
asyncio.run(langchain_demo())
|
|
458
|
-
```
|
|
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 |
|
|
459
289
|
|
|
460
290
|
---
|
|
461
291
|
|
|
462
292
|
## Multi-Agent Workflows
|
|
463
293
|
|
|
464
|
-
### Example
|
|
294
|
+
### Example: Data Pipeline
|
|
465
295
|
|
|
466
296
|
```python
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
# Add three agents
|
|
471
|
-
mesh.add_agent(
|
|
472
|
-
AutoAgent,
|
|
473
|
-
role="scraper",
|
|
474
|
-
capabilities=["web_scraping", "data_collection"],
|
|
475
|
-
system_prompt="You are a web scraping expert"
|
|
476
|
-
)
|
|
297
|
+
from jarviscore import Mesh
|
|
298
|
+
from jarviscore.profiles import AutoAgent
|
|
477
299
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
system_prompt="You are a data cleaning expert"
|
|
483
|
-
)
|
|
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'."
|
|
484
304
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
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'."
|
|
491
314
|
|
|
315
|
+
async def data_pipeline():
|
|
316
|
+
mesh = Mesh(mode="autonomous")
|
|
317
|
+
mesh.add(ScraperAgent)
|
|
318
|
+
mesh.add(ProcessorAgent)
|
|
319
|
+
mesh.add(AnalyzerAgent)
|
|
492
320
|
await mesh.start()
|
|
493
321
|
|
|
494
|
-
|
|
495
|
-
results = await mesh.run_workflow([
|
|
322
|
+
results = await mesh.workflow("pipeline", [
|
|
496
323
|
{
|
|
497
324
|
"id": "scrape",
|
|
498
325
|
"agent": "scraper",
|
|
@@ -512,61 +339,14 @@ async def data_pipeline():
|
|
|
512
339
|
}
|
|
513
340
|
])
|
|
514
341
|
|
|
515
|
-
|
|
516
|
-
print("
|
|
517
|
-
print("Clean result:", results[1]['output'])
|
|
342
|
+
print("Scrape:", results[0]['output'])
|
|
343
|
+
print("Clean:", results[1]['output'])
|
|
518
344
|
print("Analysis:", results[2]['output'])
|
|
519
|
-
|
|
520
345
|
await mesh.stop()
|
|
521
346
|
|
|
522
347
|
asyncio.run(data_pipeline())
|
|
523
348
|
```
|
|
524
349
|
|
|
525
|
-
### Example 2: Report Generator
|
|
526
|
-
|
|
527
|
-
```python
|
|
528
|
-
async def report_generator():
|
|
529
|
-
mesh = Mesh()
|
|
530
|
-
|
|
531
|
-
mesh.add_agent(
|
|
532
|
-
AutoAgent,
|
|
533
|
-
role="researcher",
|
|
534
|
-
capabilities=["research", "data_gathering"],
|
|
535
|
-
system_prompt="You are a researcher",
|
|
536
|
-
enable_search=True # Enable internet search
|
|
537
|
-
)
|
|
538
|
-
|
|
539
|
-
mesh.add_agent(
|
|
540
|
-
AutoAgent,
|
|
541
|
-
role="writer",
|
|
542
|
-
capabilities=["writing", "formatting"],
|
|
543
|
-
system_prompt="You are a technical writer"
|
|
544
|
-
)
|
|
545
|
-
|
|
546
|
-
await mesh.start()
|
|
547
|
-
|
|
548
|
-
results = await mesh.run_workflow([
|
|
549
|
-
{
|
|
550
|
-
"id": "research",
|
|
551
|
-
"agent": "researcher",
|
|
552
|
-
"task": "Research latest Python 3.12 features"
|
|
553
|
-
},
|
|
554
|
-
{
|
|
555
|
-
"id": "write",
|
|
556
|
-
"agent": "writer",
|
|
557
|
-
"task": "Write a 2-paragraph summary of the research findings",
|
|
558
|
-
"depends_on": ["research"]
|
|
559
|
-
}
|
|
560
|
-
])
|
|
561
|
-
|
|
562
|
-
print("Research:", results[0]['output'])
|
|
563
|
-
print("\nReport:", results[1]['output'])
|
|
564
|
-
|
|
565
|
-
await mesh.stop()
|
|
566
|
-
|
|
567
|
-
asyncio.run(report_generator())
|
|
568
|
-
```
|
|
569
|
-
|
|
570
350
|
---
|
|
571
351
|
|
|
572
352
|
## Internet Search
|
|
@@ -577,27 +357,23 @@ Enable web search for research tasks:
|
|
|
577
357
|
from jarviscore import Mesh
|
|
578
358
|
from jarviscore.profiles import AutoAgent
|
|
579
359
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
role="researcher",
|
|
586
|
-
capabilities=["research", "web_search"],
|
|
587
|
-
system_prompt="You are an expert researcher",
|
|
588
|
-
enable_search=True # ← Enable internet search
|
|
589
|
-
)
|
|
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
|
|
590
365
|
|
|
366
|
+
async def search_demo():
|
|
367
|
+
mesh = Mesh(mode="autonomous")
|
|
368
|
+
mesh.add(ResearcherAgent)
|
|
591
369
|
await mesh.start()
|
|
592
370
|
|
|
593
|
-
result = await mesh.
|
|
371
|
+
result = await mesh.workflow("search", [{
|
|
594
372
|
"agent": "researcher",
|
|
595
|
-
"task": "Search for 'Python asyncio best practices' and summarize
|
|
373
|
+
"task": "Search for 'Python asyncio best practices' and summarize top 3 results"
|
|
596
374
|
}])
|
|
597
375
|
|
|
598
376
|
print(result[0]['output'])
|
|
599
|
-
# Returns: Summary of top 3 search results
|
|
600
|
-
|
|
601
377
|
await mesh.stop()
|
|
602
378
|
|
|
603
379
|
asyncio.run(search_demo())
|
|
@@ -973,15 +749,16 @@ mesh = Mesh(config=config)
|
|
|
973
749
|
|
|
974
750
|
## Next Steps
|
|
975
751
|
|
|
976
|
-
1. **
|
|
977
|
-
2. **
|
|
978
|
-
3. **
|
|
979
|
-
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
|
|
980
757
|
|
|
981
758
|
---
|
|
982
759
|
|
|
983
760
|
## Version
|
|
984
761
|
|
|
985
|
-
User Guide for JarvisCore v0.
|
|
762
|
+
User Guide for JarvisCore v0.2.0
|
|
986
763
|
|
|
987
|
-
Last Updated: 2026-01-
|
|
764
|
+
Last Updated: 2026-01-22
|