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.
Files changed (85) hide show
  1. examples/autoagent_distributed_example.py +211 -0
  2. examples/custom_profile_decorator.py +134 -0
  3. examples/custom_profile_wrap.py +168 -0
  4. examples/customagent_distributed_example.py +362 -0
  5. examples/customagent_p2p_example.py +347 -0
  6. jarviscore/__init__.py +49 -36
  7. jarviscore/adapter/__init__.py +15 -9
  8. jarviscore/adapter/decorator.py +23 -19
  9. jarviscore/adapter/wrapper.py +303 -0
  10. jarviscore/cli/scaffold.py +1 -1
  11. jarviscore/cli/smoketest.py +3 -2
  12. jarviscore/core/agent.py +44 -1
  13. jarviscore/core/mesh.py +196 -35
  14. jarviscore/data/examples/autoagent_distributed_example.py +211 -0
  15. jarviscore/data/examples/customagent_distributed_example.py +362 -0
  16. jarviscore/data/examples/customagent_p2p_example.py +347 -0
  17. jarviscore/docs/API_REFERENCE.md +264 -51
  18. jarviscore/docs/AUTOAGENT_GUIDE.md +198 -0
  19. jarviscore/docs/CONFIGURATION.md +35 -21
  20. jarviscore/docs/CUSTOMAGENT_GUIDE.md +415 -0
  21. jarviscore/docs/GETTING_STARTED.md +106 -13
  22. jarviscore/docs/TROUBLESHOOTING.md +144 -6
  23. jarviscore/docs/USER_GUIDE.md +138 -361
  24. jarviscore/orchestration/engine.py +20 -8
  25. jarviscore/p2p/__init__.py +10 -0
  26. jarviscore/p2p/coordinator.py +129 -0
  27. jarviscore/p2p/messages.py +87 -0
  28. jarviscore/p2p/peer_client.py +576 -0
  29. jarviscore/p2p/peer_tool.py +268 -0
  30. {jarviscore_framework-0.1.1.dist-info → jarviscore_framework-0.2.0.dist-info}/METADATA +60 -54
  31. jarviscore_framework-0.2.0.dist-info/RECORD +132 -0
  32. {jarviscore_framework-0.1.1.dist-info → jarviscore_framework-0.2.0.dist-info}/WHEEL +1 -1
  33. {jarviscore_framework-0.1.1.dist-info → jarviscore_framework-0.2.0.dist-info}/top_level.txt +1 -0
  34. test_logs/code_registry/functions/data_generator-558779ed_560ebc37.py +7 -0
  35. test_logs/code_registry/functions/data_generator-5ed3609e_560ebc37.py +7 -0
  36. test_logs/code_registry/functions/data_generator-66da0356_43970bb9.py +25 -0
  37. test_logs/code_registry/functions/data_generator-7a2fac83_583709d9.py +36 -0
  38. test_logs/code_registry/functions/data_generator-888b670f_aa235863.py +9 -0
  39. test_logs/code_registry/functions/data_generator-9ca5f642_aa235863.py +9 -0
  40. test_logs/code_registry/functions/data_generator-bfd90775_560ebc37.py +7 -0
  41. test_logs/code_registry/functions/data_generator-e95d2f7d_aa235863.py +9 -0
  42. test_logs/code_registry/functions/data_generator-f60ca8a2_327eb8c2.py +29 -0
  43. test_logs/code_registry/functions/mathematician-02adf9ee_958658d9.py +19 -0
  44. test_logs/code_registry/functions/mathematician-0706fb57_5df13441.py +23 -0
  45. test_logs/code_registry/functions/mathematician-153c9c4a_ba59c918.py +83 -0
  46. test_logs/code_registry/functions/mathematician-287e61c0_41daa793.py +18 -0
  47. test_logs/code_registry/functions/mathematician-2967af5a_863c2cc6.py +17 -0
  48. test_logs/code_registry/functions/mathematician-303ca6d6_5df13441.py +23 -0
  49. test_logs/code_registry/functions/mathematician-308a4afd_cbf5064d.py +73 -0
  50. test_logs/code_registry/functions/mathematician-353f16e2_0968bcf5.py +18 -0
  51. test_logs/code_registry/functions/mathematician-3c22475a_41daa793.py +17 -0
  52. test_logs/code_registry/functions/mathematician-5bac1029_0968bcf5.py +18 -0
  53. test_logs/code_registry/functions/mathematician-640f76b2_9198780b.py +19 -0
  54. test_logs/code_registry/functions/mathematician-752fa7ea_863c2cc6.py +17 -0
  55. test_logs/code_registry/functions/mathematician-baf9ef39_0968bcf5.py +18 -0
  56. test_logs/code_registry/functions/mathematician-bc8b2a2f_5df13441.py +23 -0
  57. test_logs/code_registry/functions/mathematician-c31e4686_41daa793.py +18 -0
  58. test_logs/code_registry/functions/mathematician-cc84c84c_863c2cc6.py +17 -0
  59. test_logs/code_registry/functions/mathematician-dd7c7144_9198780b.py +19 -0
  60. test_logs/code_registry/functions/mathematician-e671c256_41ea4487.py +74 -0
  61. test_logs/code_registry/functions/report_generator-1a878fcc_18d44bdc.py +47 -0
  62. test_logs/code_registry/functions/report_generator-25c1c331_cea57d0d.py +35 -0
  63. test_logs/code_registry/functions/report_generator-37552117_e711c2b9.py +35 -0
  64. test_logs/code_registry/functions/report_generator-bc662768_e711c2b9.py +35 -0
  65. test_logs/code_registry/functions/report_generator-d6c0e76b_5e7722ec.py +44 -0
  66. test_logs/code_registry/functions/report_generator-f270fb02_680529c3.py +44 -0
  67. test_logs/code_registry/functions/text_processor-11393b14_4370d3ed.py +40 -0
  68. test_logs/code_registry/functions/text_processor-7d02dfc3_d3b569be.py +37 -0
  69. test_logs/code_registry/functions/text_processor-8adb5e32_9168c5fe.py +13 -0
  70. test_logs/code_registry/functions/text_processor-c58ffc19_78b4ceac.py +42 -0
  71. test_logs/code_registry/functions/text_processor-cd5977b1_9168c5fe.py +13 -0
  72. test_logs/code_registry/functions/text_processor-ec1c8773_9168c5fe.py +13 -0
  73. tests/test_01_analyst_standalone.py +124 -0
  74. tests/test_02_assistant_standalone.py +164 -0
  75. tests/test_03_analyst_with_framework.py +945 -0
  76. tests/test_04_assistant_with_framework.py +1002 -0
  77. tests/test_05_integration.py +1301 -0
  78. tests/test_06_real_llm_integration.py +760 -0
  79. tests/test_07_distributed_single_node.py +578 -0
  80. tests/test_08_distributed_multi_node.py +454 -0
  81. tests/test_09_distributed_autoagent.py +509 -0
  82. tests/test_10_distributed_customagent.py +787 -0
  83. tests/test_mesh.py +35 -4
  84. jarviscore_framework-0.1.1.dist-info/RECORD +0 -69
  85. {jarviscore_framework-0.1.1.dist-info → jarviscore_framework-0.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -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. [CustomAgent Tutorial](#customagent-tutorial)
13
- 5. [Multi-Agent Workflows](#multi-agent-workflows)
14
- 6. [Internet Search](#internet-search)
15
- 7. [Remote Sandbox](#remote-sandbox)
16
- 8. [Result Storage](#result-storage)
17
- 9. [Code Registry](#code-registry)
18
- 10. [Best Practices](#best-practices)
19
- 11. [Common Patterns](#common-patterns)
20
- 12. [Troubleshooting](#troubleshooting)
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
- # Execute task
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
- if __name__ == '__main__':
113
- asyncio.run(main())
105
+ asyncio.run(main())
114
106
  ```
115
107
 
116
- **That's it!** No configuration files, no setup, just three steps:
117
- 1. Create mesh
118
- 2. Add agent
119
- 3. Run task
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
- # Distributed mode (P2P mesh across network)
134
- mesh = Mesh(mode="distributed")
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 has two agent types:
141
+ **Agents** are workers that execute tasks. JarvisCore offers two profiles:
140
142
 
141
- 1. **AutoAgent**: Zero-config, LLM-powered (for rapid prototyping)
142
- 2. **CustomAgent**: Full control (for production systems)
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.run_workflow([
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
- async def calculator_demo():
168
- mesh = Mesh()
169
-
170
- mesh.add_agent(
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
- # Single calculation
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
- async def data_analyst_demo():
195
- mesh = Mesh()
196
-
197
- mesh.add_agent(
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.run_workflow([{
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
- ### Example 3: Text Processor
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
- text = """
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
- print(result[0]['output'])
226
+ The **Custom Profile** (decorator/wrap approach) is deprecated. Use **CustomAgent** instead.
254
227
 
255
- await mesh.stop()
256
-
257
- asyncio.run(text_processor_demo())
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
- ### Example 1: API Integration
237
+ CustomAgent gives you full control over execution logic. See [CustomAgent Guide](CUSTOMAGENT_GUIDE.md) for P2P and distributed modes.
265
238
 
266
- ```python
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 DatabaseAgent(CustomAgent):
340
- """Agent that queries PostgreSQL database."""
245
+ class MyAgent(CustomAgent):
246
+ role = "processor"
247
+ capabilities = ["data_processing"]
341
248
 
342
249
  async def setup(self):
343
- """Connect to database."""
344
- self.pool = await asyncpg.create_pool(
345
- host='localhost',
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
- """Execute database query."""
357
- query = task.get('task', '')
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
- # Convert to list of dicts
364
- results = [dict(row) for row in rows]
259
+ # Your logic here
260
+ result = {"processed": task_desc.upper()}
365
261
 
366
262
  return {
367
263
  "status": "success",
368
- "output": results,
369
- "agent": self.agent_id
264
+ "output": result,
265
+ "agent_id": self.agent_id
370
266
  }
371
267
 
372
- # Usage
373
- async def database_demo():
374
- mesh = 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
- result = await mesh.run_workflow([
385
- {"agent": "database", "task": "SELECT * FROM users LIMIT 10"}
273
+ results = await mesh.workflow("demo", [
274
+ {"agent": "processor", "task": "hello world"}
386
275
  ])
387
276
 
388
- print(f"Found {len(result[0]['output'])} users")
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
- ### Example 3: LangChain Integration
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
- async def setup(self):
407
- """Initialize LangChain components."""
408
- self.llm = ChatOpenAI(model="gpt-4")
409
-
410
- self.prompt = ChatPromptTemplate.from_messages([
411
- ("system", "You are a helpful assistant"),
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 1: Data Pipeline
294
+ ### Example: Data Pipeline
465
295
 
466
296
  ```python
467
- async def data_pipeline():
468
- mesh = Mesh()
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
- mesh.add_agent(
479
- AutoAgent,
480
- role="processor",
481
- capabilities=["data_processing", "cleaning"],
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
- mesh.add_agent(
486
- AutoAgent,
487
- role="analyzer",
488
- capabilities=["analysis", "statistics"],
489
- system_prompt="You are a data analysis expert"
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
- # Run workflow with dependencies
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
- # Each step gets context from previous steps
516
- print("Scrape result:", results[0]['output'])
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
- async def search_demo():
581
- mesh = Mesh()
582
-
583
- mesh.add_agent(
584
- AutoAgent,
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.run_workflow([{
371
+ result = await mesh.workflow("search", [{
594
372
  "agent": "researcher",
595
- "task": "Search for 'Python asyncio best practices' and summarize the top 3 results"
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. **Read the [API Reference](API_REFERENCE.md)** for detailed component documentation
977
- 2. **Check the [Configuration Guide](CONFIGURATION.md)** for environment setup
978
- 3. **Explore examples/** directory for more code samples
979
- 4. **Join the community** on GitHub for support
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.1.0
762
+ User Guide for JarvisCore v0.2.0
986
763
 
987
- Last Updated: 2026-01-12
764
+ Last Updated: 2026-01-22