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.
Files changed (99) 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 +60 -15
  7. jarviscore/adapter/__init__.py +40 -0
  8. jarviscore/adapter/decorator.py +336 -0
  9. jarviscore/adapter/wrapper.py +303 -0
  10. jarviscore/cli/check.py +18 -13
  11. jarviscore/cli/scaffold.py +178 -0
  12. jarviscore/cli/smoketest.py +3 -2
  13. jarviscore/context/__init__.py +40 -0
  14. jarviscore/context/dependency.py +160 -0
  15. jarviscore/context/jarvis_context.py +207 -0
  16. jarviscore/context/memory.py +155 -0
  17. jarviscore/core/agent.py +44 -1
  18. jarviscore/core/mesh.py +196 -35
  19. jarviscore/data/.env.example +146 -0
  20. jarviscore/data/__init__.py +7 -0
  21. jarviscore/data/examples/autoagent_distributed_example.py +211 -0
  22. jarviscore/data/examples/calculator_agent_example.py +77 -0
  23. jarviscore/data/examples/customagent_distributed_example.py +362 -0
  24. jarviscore/data/examples/customagent_p2p_example.py +347 -0
  25. jarviscore/data/examples/multi_agent_workflow.py +132 -0
  26. jarviscore/data/examples/research_agent_example.py +76 -0
  27. jarviscore/docs/API_REFERENCE.md +264 -51
  28. jarviscore/docs/AUTOAGENT_GUIDE.md +198 -0
  29. jarviscore/docs/CONFIGURATION.md +41 -23
  30. jarviscore/docs/CUSTOMAGENT_GUIDE.md +415 -0
  31. jarviscore/docs/GETTING_STARTED.md +113 -17
  32. jarviscore/docs/TROUBLESHOOTING.md +155 -13
  33. jarviscore/docs/USER_GUIDE.md +144 -363
  34. jarviscore/execution/llm.py +23 -16
  35. jarviscore/orchestration/engine.py +20 -8
  36. jarviscore/p2p/__init__.py +10 -0
  37. jarviscore/p2p/coordinator.py +129 -0
  38. jarviscore/p2p/messages.py +87 -0
  39. jarviscore/p2p/peer_client.py +576 -0
  40. jarviscore/p2p/peer_tool.py +268 -0
  41. jarviscore_framework-0.2.0.dist-info/METADATA +143 -0
  42. jarviscore_framework-0.2.0.dist-info/RECORD +132 -0
  43. {jarviscore_framework-0.1.0.dist-info → jarviscore_framework-0.2.0.dist-info}/WHEEL +1 -1
  44. {jarviscore_framework-0.1.0.dist-info → jarviscore_framework-0.2.0.dist-info}/top_level.txt +1 -0
  45. test_logs/code_registry/functions/data_generator-558779ed_560ebc37.py +7 -0
  46. test_logs/code_registry/functions/data_generator-5ed3609e_560ebc37.py +7 -0
  47. test_logs/code_registry/functions/data_generator-66da0356_43970bb9.py +25 -0
  48. test_logs/code_registry/functions/data_generator-7a2fac83_583709d9.py +36 -0
  49. test_logs/code_registry/functions/data_generator-888b670f_aa235863.py +9 -0
  50. test_logs/code_registry/functions/data_generator-9ca5f642_aa235863.py +9 -0
  51. test_logs/code_registry/functions/data_generator-bfd90775_560ebc37.py +7 -0
  52. test_logs/code_registry/functions/data_generator-e95d2f7d_aa235863.py +9 -0
  53. test_logs/code_registry/functions/data_generator-f60ca8a2_327eb8c2.py +29 -0
  54. test_logs/code_registry/functions/mathematician-02adf9ee_958658d9.py +19 -0
  55. test_logs/code_registry/functions/mathematician-0706fb57_5df13441.py +23 -0
  56. test_logs/code_registry/functions/mathematician-153c9c4a_ba59c918.py +83 -0
  57. test_logs/code_registry/functions/mathematician-287e61c0_41daa793.py +18 -0
  58. test_logs/code_registry/functions/mathematician-2967af5a_863c2cc6.py +17 -0
  59. test_logs/code_registry/functions/mathematician-303ca6d6_5df13441.py +23 -0
  60. test_logs/code_registry/functions/mathematician-308a4afd_cbf5064d.py +73 -0
  61. test_logs/code_registry/functions/mathematician-353f16e2_0968bcf5.py +18 -0
  62. test_logs/code_registry/functions/mathematician-3c22475a_41daa793.py +17 -0
  63. test_logs/code_registry/functions/mathematician-5bac1029_0968bcf5.py +18 -0
  64. test_logs/code_registry/functions/mathematician-640f76b2_9198780b.py +19 -0
  65. test_logs/code_registry/functions/mathematician-752fa7ea_863c2cc6.py +17 -0
  66. test_logs/code_registry/functions/mathematician-baf9ef39_0968bcf5.py +18 -0
  67. test_logs/code_registry/functions/mathematician-bc8b2a2f_5df13441.py +23 -0
  68. test_logs/code_registry/functions/mathematician-c31e4686_41daa793.py +18 -0
  69. test_logs/code_registry/functions/mathematician-cc84c84c_863c2cc6.py +17 -0
  70. test_logs/code_registry/functions/mathematician-dd7c7144_9198780b.py +19 -0
  71. test_logs/code_registry/functions/mathematician-e671c256_41ea4487.py +74 -0
  72. test_logs/code_registry/functions/report_generator-1a878fcc_18d44bdc.py +47 -0
  73. test_logs/code_registry/functions/report_generator-25c1c331_cea57d0d.py +35 -0
  74. test_logs/code_registry/functions/report_generator-37552117_e711c2b9.py +35 -0
  75. test_logs/code_registry/functions/report_generator-bc662768_e711c2b9.py +35 -0
  76. test_logs/code_registry/functions/report_generator-d6c0e76b_5e7722ec.py +44 -0
  77. test_logs/code_registry/functions/report_generator-f270fb02_680529c3.py +44 -0
  78. test_logs/code_registry/functions/text_processor-11393b14_4370d3ed.py +40 -0
  79. test_logs/code_registry/functions/text_processor-7d02dfc3_d3b569be.py +37 -0
  80. test_logs/code_registry/functions/text_processor-8adb5e32_9168c5fe.py +13 -0
  81. test_logs/code_registry/functions/text_processor-c58ffc19_78b4ceac.py +42 -0
  82. test_logs/code_registry/functions/text_processor-cd5977b1_9168c5fe.py +13 -0
  83. test_logs/code_registry/functions/text_processor-ec1c8773_9168c5fe.py +13 -0
  84. tests/test_01_analyst_standalone.py +124 -0
  85. tests/test_02_assistant_standalone.py +164 -0
  86. tests/test_03_analyst_with_framework.py +945 -0
  87. tests/test_04_assistant_with_framework.py +1002 -0
  88. tests/test_05_integration.py +1301 -0
  89. tests/test_06_real_llm_integration.py +760 -0
  90. tests/test_07_distributed_single_node.py +578 -0
  91. tests/test_08_distributed_multi_node.py +454 -0
  92. tests/test_09_distributed_autoagent.py +509 -0
  93. tests/test_10_distributed_customagent.py +787 -0
  94. tests/test_context.py +467 -0
  95. tests/test_decorator.py +622 -0
  96. tests/test_mesh.py +35 -4
  97. jarviscore_framework-0.1.0.dist-info/METADATA +0 -136
  98. jarviscore_framework-0.1.0.dist-info/RECORD +0 -55
  99. {jarviscore_framework-0.1.0.dist-info → jarviscore_framework-0.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,415 @@
1
+ # CustomAgent Guide
2
+
3
+ CustomAgent is for users who **already have working code** and want to integrate with JarvisCore.
4
+
5
+ You keep your execution logic. Framework provides:
6
+ - Agent discovery and communication
7
+ - Workflow orchestration (distributed mode)
8
+ - P2P peer tools (ask_peer, broadcast, etc.)
9
+
10
+ ---
11
+
12
+ ## Quick Reference
13
+
14
+ | Mode | Use Case | Agent Method |
15
+ |------|----------|--------------|
16
+ | **P2P** | Direct agent communication | `run()` loop |
17
+ | **Distributed** | Multi-node workflows | `execute_task()` |
18
+
19
+ ---
20
+
21
+ ## P2P Mode: Standalone → Framework
22
+
23
+ ### Your Standalone Agents (Before)
24
+
25
+ You have two agents that communicate directly:
26
+
27
+ ```python
28
+ # standalone_researcher.py
29
+ class StandaloneResearcher:
30
+ """Your existing researcher agent."""
31
+
32
+ def __init__(self):
33
+ self.llm = MyLLMClient()
34
+
35
+ def research(self, query: str) -> str:
36
+ """Your existing research logic."""
37
+ return self.llm.chat(f"Research: {query}")
38
+
39
+
40
+ # standalone_assistant.py
41
+ class StandaloneAssistant:
42
+ """Your existing assistant that needs researcher help."""
43
+
44
+ def __init__(self, researcher: StandaloneResearcher):
45
+ self.researcher = researcher # Direct reference
46
+ self.llm = MyLLMClient()
47
+
48
+ def help(self, question: str) -> str:
49
+ # Directly calls researcher
50
+ research = self.researcher.research(question)
51
+ return self.llm.chat(f"Based on: {research}\nAnswer: {question}")
52
+ ```
53
+
54
+ **Problem**: Agents are tightly coupled. Can't run on different machines.
55
+
56
+ ---
57
+
58
+ ### With JarvisCore P2P Mode (After)
59
+
60
+ **Step 1: Create `agents.py`** - Convert to CustomAgent
61
+
62
+ ```python
63
+ # agents.py
64
+ from jarviscore.profiles import CustomAgent
65
+
66
+ class ResearcherAgent(CustomAgent):
67
+ """Same logic, now framework-integrated."""
68
+ role = "researcher"
69
+ capabilities = ["research", "analysis"]
70
+
71
+ async def setup(self):
72
+ await super().setup()
73
+ self.llm = MyLLMClient() # Your existing LLM
74
+
75
+ async def run(self):
76
+ """REQUIRED for P2P: Listen for peer requests."""
77
+ while not self.shutdown_requested:
78
+ if self.peers:
79
+ msg = await self.peers.receive(timeout=0.5)
80
+ if msg and msg.is_request:
81
+ query = msg.data.get("question", "")
82
+ # Your existing logic
83
+ result = self.llm.chat(f"Research: {query}")
84
+ await self.peers.respond(msg, {"response": result})
85
+ else:
86
+ await asyncio.sleep(0.1)
87
+
88
+ async def execute_task(self, task):
89
+ return {"status": "success"} # Required but unused in P2P
90
+
91
+
92
+ class AssistantAgent(CustomAgent):
93
+ """Same logic, now uses peer tools instead of direct reference."""
94
+ role = "assistant"
95
+ capabilities = ["help", "coordination"]
96
+
97
+ async def setup(self):
98
+ await super().setup()
99
+ self.llm = MyLLMClient()
100
+
101
+ async def ask_researcher(self, question: str) -> str:
102
+ """Replaces direct self.researcher reference."""
103
+ if self.peers:
104
+ return await self.peers.as_tool().execute(
105
+ "ask_peer",
106
+ {"role": "researcher", "question": question}
107
+ )
108
+ return "No researcher available"
109
+
110
+ async def help(self, question: str) -> str:
111
+ """Your existing logic, now uses peer communication."""
112
+ research = await self.ask_researcher(question)
113
+ return self.llm.chat(f"Based on: {research}\nAnswer: {question}")
114
+
115
+ async def run(self):
116
+ """Listen for requests or external triggers."""
117
+ while not self.shutdown_requested:
118
+ # Your run loop - could listen for HTTP, websocket, etc.
119
+ await asyncio.sleep(0.1)
120
+
121
+ async def execute_task(self, task):
122
+ return {"status": "success"}
123
+ ```
124
+
125
+ **Step 2: Create `main.py`** - Run with mesh
126
+
127
+ ```python
128
+ # main.py
129
+ import asyncio
130
+ from jarviscore import Mesh
131
+ from agents import ResearcherAgent, AssistantAgent
132
+
133
+ async def main():
134
+ mesh = Mesh(
135
+ mode="p2p",
136
+ config={
137
+ 'bind_port': 7950,
138
+ 'node_name': 'my-agents',
139
+ }
140
+ )
141
+
142
+ mesh.add(ResearcherAgent)
143
+ mesh.add(AssistantAgent)
144
+
145
+ await mesh.start()
146
+
147
+ # Option 1: Run forever (agents handle their own work)
148
+ # await mesh.run_forever()
149
+
150
+ # Option 2: Manual interaction
151
+ assistant = mesh.get_agent("assistant")
152
+ result = await assistant.help("What is quantum computing?")
153
+ print(result)
154
+
155
+ await mesh.stop()
156
+
157
+ asyncio.run(main())
158
+ ```
159
+
160
+ ### What Changed
161
+
162
+ | Before | After |
163
+ |--------|-------|
164
+ | Direct object reference | `self.peers.as_tool().execute("ask_peer", ...)` |
165
+ | Tightly coupled | Loosely coupled via peer discovery |
166
+ | Same process only | Can run on different machines |
167
+ | No discovery | Automatic agent discovery |
168
+
169
+ ### Key Additions
170
+
171
+ 1. **Inherit from `CustomAgent`** instead of plain class
172
+ 2. **Add `role` and `capabilities`** class attributes
173
+ 3. **Implement `run()`** method for continuous listening
174
+ 4. **Use `self.peers`** for communication instead of direct references
175
+
176
+ ---
177
+
178
+ ## Distributed Mode: Standalone → Framework
179
+
180
+ ### Your Standalone Pipeline (Before)
181
+
182
+ You have agents that execute in a pipeline:
183
+
184
+ ```python
185
+ # standalone_pipeline.py
186
+ class StandaloneResearcher:
187
+ def __init__(self):
188
+ self.llm = MyLLMClient()
189
+
190
+ def execute(self, task: str) -> dict:
191
+ result = self.llm.chat(f"Research: {task}")
192
+ return {"output": result}
193
+
194
+
195
+ class StandaloneWriter:
196
+ def __init__(self):
197
+ self.llm = MyLLMClient()
198
+
199
+ def execute(self, task: str, context: dict = None) -> dict:
200
+ prompt = task
201
+ if context:
202
+ prompt = f"Based on: {context}\n\n{task}"
203
+ result = self.llm.chat(prompt)
204
+ return {"output": result}
205
+
206
+
207
+ # Manual orchestration
208
+ def run_pipeline():
209
+ researcher = StandaloneResearcher()
210
+ writer = StandaloneWriter()
211
+
212
+ # Step 1
213
+ research = researcher.execute("Research AI trends")
214
+
215
+ # Step 2 - manually pass context
216
+ article = writer.execute("Write article", context=research["output"])
217
+
218
+ return article
219
+ ```
220
+
221
+ **Problem**: Manual orchestration. No dependency management. Single machine.
222
+
223
+ ---
224
+
225
+ ### With JarvisCore Distributed Mode (After)
226
+
227
+ **Step 1: Create `agents.py`** - Convert to CustomAgent
228
+
229
+ ```python
230
+ # agents.py
231
+ from jarviscore.profiles import CustomAgent
232
+
233
+ class ResearcherAgent(CustomAgent):
234
+ role = "researcher"
235
+ capabilities = ["research"]
236
+
237
+ async def setup(self):
238
+ await super().setup()
239
+ self.llm = MyLLMClient()
240
+
241
+ async def execute_task(self, task):
242
+ """REQUIRED for Distributed: Called by workflow engine."""
243
+ task_desc = task.get("task", "")
244
+ # Your existing logic
245
+ result = self.llm.chat(f"Research: {task_desc}")
246
+ return {
247
+ "status": "success",
248
+ "output": result
249
+ }
250
+
251
+
252
+ class WriterAgent(CustomAgent):
253
+ role = "writer"
254
+ capabilities = ["writing"]
255
+
256
+ async def setup(self):
257
+ await super().setup()
258
+ self.llm = MyLLMClient()
259
+
260
+ async def execute_task(self, task):
261
+ """Context from previous steps is automatically passed."""
262
+ task_desc = task.get("task", "")
263
+ context = task.get("context", {}) # From depends_on steps
264
+
265
+ prompt = task_desc
266
+ if context:
267
+ prompt = f"Based on: {context}\n\n{task_desc}"
268
+
269
+ result = self.llm.chat(prompt)
270
+ return {
271
+ "status": "success",
272
+ "output": result
273
+ }
274
+ ```
275
+
276
+ **Step 2: Create `main.py`** - Run with mesh
277
+
278
+ ```python
279
+ # main.py
280
+ import asyncio
281
+ from jarviscore import Mesh
282
+ from agents import ResearcherAgent, WriterAgent
283
+
284
+ async def main():
285
+ mesh = Mesh(
286
+ mode="distributed",
287
+ config={
288
+ 'bind_port': 7950,
289
+ 'node_name': 'content-node',
290
+ }
291
+ )
292
+
293
+ mesh.add(ResearcherAgent)
294
+ mesh.add(WriterAgent)
295
+
296
+ await mesh.start()
297
+
298
+ # Workflow engine handles orchestration
299
+ results = await mesh.workflow("content-pipeline", [
300
+ {
301
+ "id": "research",
302
+ "agent": "researcher",
303
+ "task": "Research AI trends"
304
+ },
305
+ {
306
+ "id": "write",
307
+ "agent": "writer",
308
+ "task": "Write article about the research",
309
+ "depends_on": ["research"] # Auto-injects context
310
+ }
311
+ ])
312
+
313
+ print(results[0]["output"]) # Research
314
+ print(results[1]["output"]) # Article
315
+
316
+ await mesh.stop()
317
+
318
+ asyncio.run(main())
319
+ ```
320
+
321
+ ### What Changed
322
+
323
+ | Before | After |
324
+ |--------|-------|
325
+ | Manual `context` passing | `depends_on` + automatic injection |
326
+ | Manual orchestration | `mesh.workflow()` handles it |
327
+ | Same process only | Can span multiple machines |
328
+ | No retries | Framework handles failures |
329
+
330
+ ### Key Additions
331
+
332
+ 1. **Inherit from `CustomAgent`**
333
+ 2. **Add `role` and `capabilities`**
334
+ 3. **Implement `execute_task(task)`** - receives `task` dict with `context`
335
+ 4. **Use `mesh.workflow()`** with `depends_on` for dependencies
336
+
337
+ ---
338
+
339
+ ## Multi-Node Distributed
340
+
341
+ Same agents, different machines:
342
+
343
+ **Machine 1:**
344
+ ```python
345
+ mesh = Mesh(mode="distributed", config={
346
+ 'bind_host': '0.0.0.0',
347
+ 'bind_port': 7950,
348
+ 'node_name': 'research-node',
349
+ })
350
+ mesh.add(ResearcherAgent)
351
+ await mesh.start()
352
+ await mesh.serve_forever()
353
+ ```
354
+
355
+ **Machine 2:**
356
+ ```python
357
+ mesh = Mesh(mode="distributed", config={
358
+ 'bind_host': '0.0.0.0',
359
+ 'bind_port': 7950,
360
+ 'node_name': 'writer-node',
361
+ 'seed_nodes': '192.168.1.10:7950', # Machine 1
362
+ })
363
+ mesh.add(WriterAgent)
364
+ await mesh.start()
365
+ await mesh.serve_forever()
366
+ ```
367
+
368
+ Workflows automatically route to the right machine.
369
+
370
+ ---
371
+
372
+ ## P2P vs Distributed: Which to Use?
373
+
374
+ | Scenario | Mode |
375
+ |----------|------|
376
+ | Agents run continuously, self-coordinate | **P2P** |
377
+ | Chatbot with specialist agents | **P2P** |
378
+ | Task pipelines with dependencies | **Distributed** |
379
+ | Need workflow orchestration | **Distributed** |
380
+ | Both continuous + workflows | **Distributed** (supports both) |
381
+
382
+ ---
383
+
384
+ ## Summary
385
+
386
+ ### P2P Mode
387
+ ```python
388
+ class MyAgent(CustomAgent):
389
+ role = "my_role"
390
+ capabilities = ["my_cap"]
391
+
392
+ async def run(self): # Required
393
+ while not self.shutdown_requested:
394
+ msg = await self.peers.receive(timeout=0.5)
395
+ # Handle messages
396
+
397
+ mesh = Mesh(mode="p2p", config={'bind_port': 7950})
398
+ await mesh.run_forever()
399
+ ```
400
+
401
+ ### Distributed Mode
402
+ ```python
403
+ class MyAgent(CustomAgent):
404
+ role = "my_role"
405
+ capabilities = ["my_cap"]
406
+
407
+ async def execute_task(self, task): # Required
408
+ # Your logic
409
+ return {"status": "success", "output": result}
410
+
411
+ mesh = Mesh(mode="distributed", config={'bind_port': 7950})
412
+ results = await mesh.workflow("my-workflow", [...])
413
+ ```
414
+
415
+ See `examples/customagent_p2p_example.py` and `examples/customagent_distributed_example.py` for complete examples.
@@ -4,11 +4,32 @@ Build your first AI agent in 5 minutes!
4
4
 
5
5
  ---
6
6
 
7
+ ## Choose Your Path
8
+
9
+ ### Profiles (How agents execute)
10
+
11
+ | Profile | Best For | LLM Required |
12
+ |---------|----------|--------------|
13
+ | **AutoAgent** | Rapid prototyping, LLM generates code from prompts | Yes |
14
+ | **CustomAgent** | Existing code, full control (LangChain, CrewAI, etc.) | Optional |
15
+
16
+ ### Execution Modes (How agents are orchestrated)
17
+
18
+ | Mode | Use Case | Start Here |
19
+ |------|----------|------------|
20
+ | **Autonomous** | Single machine, simple pipelines | ✅ This guide |
21
+ | **P2P** | Direct agent communication, swarms | [CustomAgent Guide](CUSTOMAGENT_GUIDE.md) |
22
+ | **Distributed** | Multi-node production systems | [AutoAgent Guide](AUTOAGENT_GUIDE.md) |
23
+
24
+ **Recommendation:** Start with **AutoAgent + Autonomous mode** below, then explore other modes.
25
+
26
+ ---
27
+
7
28
  ## What You'll Build
8
29
 
9
30
  An **AutoAgent** that takes natural language prompts and automatically:
10
31
  1. Generates Python code using an LLM
11
- 2. Executes the code securely
32
+ 2. Executes the code securely in a sandbox
12
33
  3. Returns the result
13
34
 
14
35
  **No manual coding required** - just describe what you want!
@@ -29,17 +50,20 @@ An **AutoAgent** that takes natural language prompts and automatically:
29
50
  ## Step 1: Install JarvisCore (30 seconds)
30
51
 
31
52
  ```bash
32
- pip install jarviscore
53
+ pip install jarviscore-framework
33
54
  ```
34
55
 
35
56
  ---
36
57
 
37
58
  ## Step 2: Configure Your LLM (2 minutes)
38
59
 
39
- Create a `.env` file in your project directory:
60
+ Initialize your project and create configuration files:
40
61
 
41
62
  ```bash
42
- # Copy the example config
63
+ # Initialize project (creates .env.example and optionally examples)
64
+ python -m jarviscore.cli.scaffold --examples
65
+
66
+ # Copy and configure your environment
43
67
  cp .env.example .env
44
68
  ```
45
69
 
@@ -175,6 +199,56 @@ Execution time: 4.23s
175
199
 
176
200
  ---
177
201
 
202
+ ## Step 5: Try CustomAgent (Alternative Path)
203
+
204
+ If you have existing agents or don't need LLM code generation, use **CustomAgent**:
205
+
206
+ ```python
207
+ import asyncio
208
+ from jarviscore import Mesh
209
+ from jarviscore.profiles import CustomAgent
210
+
211
+
212
+ class MyAgent(CustomAgent):
213
+ role = "processor"
214
+ capabilities = ["data_processing"]
215
+
216
+ async def execute_task(self, task):
217
+ """Your existing logic goes here."""
218
+ data = task.get("params", {}).get("data", [])
219
+ result = [x * 2 for x in data]
220
+ return {"status": "success", "output": result}
221
+
222
+
223
+ async def main():
224
+ # CustomAgent uses "distributed" (workflow + P2P) or "p2p" (P2P only)
225
+ mesh = Mesh(mode="distributed", config={
226
+ 'bind_port': 7950,
227
+ 'node_name': 'custom-node',
228
+ })
229
+ mesh.add(MyAgent)
230
+ await mesh.start()
231
+
232
+ results = await mesh.workflow("custom-demo", [
233
+ {"agent": "processor", "task": "Process data", "params": {"data": [1, 2, 3]}}
234
+ ])
235
+
236
+ print(results[0]["output"]) # [2, 4, 6]
237
+ await mesh.stop()
238
+
239
+
240
+ asyncio.run(main())
241
+ ```
242
+
243
+ **Key Benefits:**
244
+ - No LLM API required (no costs!)
245
+ - Keep your existing logic
246
+ - Works with any framework (LangChain, CrewAI, etc.)
247
+
248
+ **For more:** See [CustomAgent Guide](CUSTOMAGENT_GUIDE.md) for P2P mode and multi-node examples.
249
+
250
+ ---
251
+
178
252
  ## What Just Happened?
179
253
 
180
254
  Behind the scenes, JarvisCore:
@@ -196,7 +270,7 @@ All from a single natural language prompt!
196
270
 
197
271
  ---
198
272
 
199
- ## Step 5: Try More Complex Examples
273
+ ## Step 5: Try More Complex AutoAgent Profile Examples
200
274
 
201
275
  ### Example 1: Data Processing
202
276
 
@@ -302,19 +376,42 @@ class MyAgent(AutoAgent):
302
376
  system_prompt = "Instructions for the LLM" # How to generate code
303
377
  ```
304
378
 
305
- ### 2. Mesh
379
+ ### 2. CustomAgent Profile
380
+
381
+ The `CustomAgent` profile lets you bring your own execution logic:
382
+
383
+ ```python
384
+ class MyAgent(CustomAgent):
385
+ role = "unique_name"
386
+ capabilities = ["skill1", "skill2"]
387
+
388
+ async def execute_task(self, task): # For workflow steps (distributed)
389
+ return {"status": "success", "output": ...}
390
+
391
+ async def run(self): # For continuous loop (p2p)
392
+ while not self.shutdown_requested:
393
+ msg = await self.peers.receive(timeout=0.5)
394
+ ...
395
+ ```
396
+
397
+ ### 3. Mesh
306
398
 
307
399
  The `Mesh` is the orchestrator that manages agents and workflows:
308
400
 
309
401
  ```python
310
- mesh = Mesh(mode="autonomous") # Autonomous mode for AutoAgent
402
+ mesh = Mesh(mode="autonomous") # Or "p2p", "distributed"
311
403
  mesh.add(MyAgent) # Register your agent
312
404
  await mesh.start() # Initialize
313
405
  results = await mesh.workflow(...) # Execute tasks
314
406
  await mesh.stop() # Cleanup
315
407
  ```
316
408
 
317
- ### 3. Workflow
409
+ **Modes:**
410
+ - `autonomous`: Workflow engine only (AutoAgent)
411
+ - `p2p`: P2P coordinator for agent-to-agent communication (CustomAgent)
412
+ - `distributed`: Both workflow engine AND P2P (CustomAgent)
413
+
414
+ ### 4. Workflow
318
415
 
319
416
  A workflow is a list of tasks to execute:
320
417
 
@@ -328,7 +425,7 @@ results = await mesh.workflow("workflow-id", [
328
425
  ])
329
426
  ```
330
427
 
331
- ### 4. Results
428
+ ### 5. Results
332
429
 
333
430
  Each task returns a result dict:
334
431
 
@@ -368,7 +465,7 @@ Fine-tune LLM behavior:
368
465
  # Model selection (provider-specific)
369
466
  CLAUDE_MODEL=claude-sonnet-4 # Claude
370
467
  AZURE_DEPLOYMENT=gpt-4o # Azure
371
- GEMINI_MODEL=gemini-1.5-flash # Gemini
468
+ GEMINI_MODEL=gemini-2.0-flash # Gemini
372
469
  LLM_MODEL=Qwen/Qwen2.5-Coder-32B # vLLM
373
470
 
374
471
  # Generation parameters
@@ -494,11 +591,12 @@ Check `repairs` in the result to see how many fixes were needed.
494
591
 
495
592
  ## Next Steps
496
593
 
497
- 1. **Read the User Guide**: Complete documentation at [USER_GUIDE.md](USER_GUIDE.md)
498
- 2. **Explore Examples**: Check out `examples/` directory
499
- 3. **Try the API Reference**: [API_REFERENCE.md](API_REFERENCE.md)
500
- 4. **Configuration Guide**: [CONFIGURATION.md](CONFIGURATION.md)
501
- 5. **Troubleshooting**: [TROUBLESHOOTING.md](TROUBLESHOOTING.md)
594
+ 1. **AutoAgent Guide**: Multi-node distributed mode [AUTOAGENT_GUIDE.md](AUTOAGENT_GUIDE.md)
595
+ 2. **CustomAgent Guide**: P2P and distributed with your code → [CUSTOMAGENT_GUIDE.md](CUSTOMAGENT_GUIDE.md)
596
+ 3. **User Guide**: Complete documentation [USER_GUIDE.md](USER_GUIDE.md)
597
+ 4. **API Reference**: [API_REFERENCE.md](API_REFERENCE.md)
598
+ 5. **Configuration**: [CONFIGURATION.md](CONFIGURATION.md)
599
+ 6. **Examples**: Check out `examples/` directory
502
600
 
503
601
  ---
504
602
 
@@ -596,5 +694,3 @@ Need help?
596
694
  ---
597
695
 
598
696
  **🚀 Happy building with JarvisCore!**
599
-
600
- *Built for the AutoAgent/Prompt-Dev generation - where AI writes the code, you write the prompts.*