jarviscore-framework 0.1.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 (55) hide show
  1. examples/calculator_agent_example.py +77 -0
  2. examples/multi_agent_workflow.py +132 -0
  3. examples/research_agent_example.py +76 -0
  4. jarviscore/__init__.py +54 -0
  5. jarviscore/cli/__init__.py +7 -0
  6. jarviscore/cli/__main__.py +33 -0
  7. jarviscore/cli/check.py +404 -0
  8. jarviscore/cli/smoketest.py +371 -0
  9. jarviscore/config/__init__.py +7 -0
  10. jarviscore/config/settings.py +128 -0
  11. jarviscore/core/__init__.py +7 -0
  12. jarviscore/core/agent.py +163 -0
  13. jarviscore/core/mesh.py +463 -0
  14. jarviscore/core/profile.py +64 -0
  15. jarviscore/docs/API_REFERENCE.md +932 -0
  16. jarviscore/docs/CONFIGURATION.md +753 -0
  17. jarviscore/docs/GETTING_STARTED.md +600 -0
  18. jarviscore/docs/TROUBLESHOOTING.md +424 -0
  19. jarviscore/docs/USER_GUIDE.md +983 -0
  20. jarviscore/execution/__init__.py +94 -0
  21. jarviscore/execution/code_registry.py +298 -0
  22. jarviscore/execution/generator.py +268 -0
  23. jarviscore/execution/llm.py +430 -0
  24. jarviscore/execution/repair.py +283 -0
  25. jarviscore/execution/result_handler.py +332 -0
  26. jarviscore/execution/sandbox.py +555 -0
  27. jarviscore/execution/search.py +281 -0
  28. jarviscore/orchestration/__init__.py +18 -0
  29. jarviscore/orchestration/claimer.py +101 -0
  30. jarviscore/orchestration/dependency.py +143 -0
  31. jarviscore/orchestration/engine.py +292 -0
  32. jarviscore/orchestration/status.py +96 -0
  33. jarviscore/p2p/__init__.py +23 -0
  34. jarviscore/p2p/broadcaster.py +353 -0
  35. jarviscore/p2p/coordinator.py +364 -0
  36. jarviscore/p2p/keepalive.py +361 -0
  37. jarviscore/p2p/swim_manager.py +290 -0
  38. jarviscore/profiles/__init__.py +6 -0
  39. jarviscore/profiles/autoagent.py +264 -0
  40. jarviscore/profiles/customagent.py +137 -0
  41. jarviscore_framework-0.1.0.dist-info/METADATA +136 -0
  42. jarviscore_framework-0.1.0.dist-info/RECORD +55 -0
  43. jarviscore_framework-0.1.0.dist-info/WHEEL +5 -0
  44. jarviscore_framework-0.1.0.dist-info/licenses/LICENSE +21 -0
  45. jarviscore_framework-0.1.0.dist-info/top_level.txt +3 -0
  46. tests/conftest.py +44 -0
  47. tests/test_agent.py +165 -0
  48. tests/test_autoagent.py +140 -0
  49. tests/test_autoagent_day4.py +186 -0
  50. tests/test_customagent.py +248 -0
  51. tests/test_integration.py +293 -0
  52. tests/test_llm_fallback.py +185 -0
  53. tests/test_mesh.py +356 -0
  54. tests/test_p2p_integration.py +375 -0
  55. tests/test_remote_sandbox.py +116 -0
@@ -0,0 +1,983 @@
1
+ # JarvisCore User Guide
2
+
3
+ Practical guide to building agent systems with JarvisCore.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [Quick Start](#quick-start)
10
+ 2. [Basic Concepts](#basic-concepts)
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)
21
+
22
+ ---
23
+
24
+ ## Quick Start
25
+
26
+ ### Step 1: Installation (1 minute)
27
+
28
+ ```bash
29
+ pip install jarviscore
30
+ ```
31
+
32
+ ### Step 2: Configuration (2 minutes)
33
+
34
+ JarvisCore needs an LLM provider to generate code for AutoAgent. Copy the example config:
35
+
36
+ ```bash
37
+ cp .env.example .env
38
+ ```
39
+
40
+ Edit `.env` and add **one** of these API keys:
41
+
42
+ ```bash
43
+ # Option 1: Claude (Recommended)
44
+ CLAUDE_API_KEY=sk-ant-your-key-here
45
+
46
+ # Option 2: Azure OpenAI
47
+ AZURE_API_KEY=your-key-here
48
+ AZURE_ENDPOINT=https://your-resource.openai.azure.com
49
+ AZURE_DEPLOYMENT=gpt-4o
50
+
51
+ # Option 3: Google Gemini
52
+ GEMINI_API_KEY=your-key-here
53
+
54
+ # Option 4: Local vLLM
55
+ LLM_ENDPOINT=http://localhost:8000
56
+ ```
57
+
58
+ ### Step 3: Validate Setup (30 seconds)
59
+
60
+ Run the health check to ensure everything works:
61
+
62
+ ```bash
63
+ # Basic check
64
+ python -m jarviscore.cli.check
65
+
66
+ # Test LLM connectivity
67
+ python -m jarviscore.cli.check --validate-llm
68
+ ```
69
+
70
+ Run the smoke test to validate end-to-end:
71
+
72
+ ```bash
73
+ python -m jarviscore.cli.smoketest
74
+ ```
75
+
76
+ ### Step 4: Your First Agent (30 seconds)
77
+
78
+ ```python
79
+ import asyncio
80
+ from jarviscore import Mesh
81
+ from jarviscore.profiles import AutoAgent
82
+
83
+ async def main():
84
+ # Create mesh
85
+ 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
96
+ await mesh.start()
97
+
98
+ # Execute task
99
+ results = await mesh.run_workflow([
100
+ {"agent": "calculator", "task": "Calculate the factorial of 10"}
101
+ ])
102
+
103
+ print(results[0]['output']) # 3628800
104
+
105
+ # Cleanup
106
+ await mesh.stop()
107
+
108
+ if __name__ == '__main__':
109
+ asyncio.run(main())
110
+ ```
111
+
112
+ **That's it!** No configuration files, no setup, just three steps:
113
+ 1. Create mesh
114
+ 2. Add agent
115
+ 3. Run task
116
+
117
+ ---
118
+
119
+ ## Basic Concepts
120
+
121
+ ### The Mesh
122
+
123
+ The **Mesh** is your control center. It manages agents and orchestrates workflows.
124
+
125
+ ```python
126
+ # Autonomous mode (single machine)
127
+ mesh = Mesh(mode="autonomous")
128
+
129
+ # Distributed mode (P2P mesh across network)
130
+ mesh = Mesh(mode="distributed")
131
+ ```
132
+
133
+ ### Agents
134
+
135
+ **Agents** are workers that execute tasks. JarvisCore has two agent types:
136
+
137
+ 1. **AutoAgent**: Zero-config, LLM-powered (for rapid prototyping)
138
+ 2. **CustomAgent**: Full control (for production systems)
139
+
140
+ ### Workflows
141
+
142
+ **Workflows** are sequences of tasks with dependencies:
143
+
144
+ ```python
145
+ await mesh.run_workflow([
146
+ {"agent": "scraper", "task": "Scrape data"},
147
+ {"agent": "processor", "task": "Clean data", "depends_on": [0]},
148
+ {"agent": "storage", "task": "Save data", "depends_on": [1]}
149
+ ])
150
+ ```
151
+
152
+ ---
153
+
154
+ ## AutoAgent Tutorial
155
+
156
+ ### Example 1: Simple Calculator
157
+
158
+ ```python
159
+ import asyncio
160
+ from jarviscore import Mesh
161
+ from jarviscore.profiles import AutoAgent
162
+
163
+ async def calculator_demo():
164
+ mesh = Mesh()
165
+
166
+ mesh.add_agent(
167
+ AutoAgent,
168
+ role="calculator",
169
+ capabilities=["math", "calculation"],
170
+ system_prompt="You are a mathematical calculation expert"
171
+ )
172
+
173
+ await mesh.start()
174
+
175
+ # Single calculation
176
+ result = await mesh.run_workflow([
177
+ {"agent": "calculator", "task": "Calculate 15!"}
178
+ ])
179
+
180
+ print(f"15! = {result[0]['output']}")
181
+
182
+ await mesh.stop()
183
+
184
+ asyncio.run(calculator_demo())
185
+ ```
186
+
187
+ ### Example 2: Data Analyst
188
+
189
+ ```python
190
+ async def data_analyst_demo():
191
+ mesh = Mesh()
192
+
193
+ mesh.add_agent(
194
+ AutoAgent,
195
+ role="analyst",
196
+ capabilities=["data_analysis", "statistics"],
197
+ system_prompt="You are a data analyst expert"
198
+ )
199
+
200
+ await mesh.start()
201
+
202
+ result = await mesh.run_workflow([{
203
+ "agent": "analyst",
204
+ "task": """
205
+ Given this data: [23, 45, 12, 67, 89, 34, 56, 78, 90, 11]
206
+ Calculate: mean, median, mode, standard deviation, and min/max
207
+ """
208
+ }])
209
+
210
+ print(result[0]['output'])
211
+ # {'mean': 50.5, 'median': 50.5, 'std': 28.7, ...}
212
+
213
+ await mesh.stop()
214
+
215
+ asyncio.run(data_analyst_demo())
216
+ ```
217
+
218
+ ### Example 3: Text Processor
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
+ }])
248
+
249
+ print(result[0]['output'])
250
+
251
+ await mesh.stop()
252
+
253
+ asyncio.run(text_processor_demo())
254
+ ```
255
+
256
+ ---
257
+
258
+ ## CustomAgent Tutorial
259
+
260
+ ### Example 1: API Integration
261
+
262
+ ```python
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
330
+
331
+ ```python
332
+ from jarviscore.profiles import CustomAgent
333
+ import asyncpg
334
+
335
+ class DatabaseAgent(CustomAgent):
336
+ """Agent that queries PostgreSQL database."""
337
+
338
+ async def setup(self):
339
+ """Connect to database."""
340
+ self.pool = await asyncpg.create_pool(
341
+ host='localhost',
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()
350
+
351
+ async def execute_task(self, task):
352
+ """Execute database query."""
353
+ query = task.get('task', '')
354
+
355
+ async with self.pool.acquire() as conn:
356
+ # Execute query
357
+ rows = await conn.fetch(query)
358
+
359
+ # Convert to list of dicts
360
+ results = [dict(row) for row in rows]
361
+
362
+ return {
363
+ "status": "success",
364
+ "output": results,
365
+ "agent": self.agent_id
366
+ }
367
+
368
+ # Usage
369
+ async def database_demo():
370
+ mesh = Mesh()
371
+
372
+ mesh.add_agent(
373
+ DatabaseAgent,
374
+ role="database",
375
+ capabilities=["database", "query"]
376
+ )
377
+
378
+ await mesh.start()
379
+
380
+ result = await mesh.run_workflow([
381
+ {"agent": "database", "task": "SELECT * FROM users LIMIT 10"}
382
+ ])
383
+
384
+ print(f"Found {len(result[0]['output'])} users")
385
+
386
+ await mesh.stop()
387
+
388
+ asyncio.run(database_demo())
389
+ ```
390
+
391
+ ### Example 3: LangChain Integration
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."""
401
+
402
+ async def setup(self):
403
+ """Initialize LangChain components."""
404
+ self.llm = ChatOpenAI(model="gpt-4")
405
+
406
+ self.prompt = ChatPromptTemplate.from_messages([
407
+ ("system", "You are a helpful assistant"),
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
+ ```
455
+
456
+ ---
457
+
458
+ ## Multi-Agent Workflows
459
+
460
+ ### Example 1: Data Pipeline
461
+
462
+ ```python
463
+ async def data_pipeline():
464
+ mesh = Mesh()
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
+ )
473
+
474
+ mesh.add_agent(
475
+ AutoAgent,
476
+ role="processor",
477
+ capabilities=["data_processing", "cleaning"],
478
+ system_prompt="You are a data cleaning expert"
479
+ )
480
+
481
+ mesh.add_agent(
482
+ AutoAgent,
483
+ role="analyzer",
484
+ capabilities=["analysis", "statistics"],
485
+ system_prompt="You are a data analysis expert"
486
+ )
487
+
488
+ await mesh.start()
489
+
490
+ # Run workflow with dependencies
491
+ results = await mesh.run_workflow([
492
+ {
493
+ "id": "scrape",
494
+ "agent": "scraper",
495
+ "task": "Generate sample e-commerce data (10 products with prices)"
496
+ },
497
+ {
498
+ "id": "clean",
499
+ "agent": "processor",
500
+ "task": "Clean and normalize the product data",
501
+ "depends_on": ["scrape"]
502
+ },
503
+ {
504
+ "id": "analyze",
505
+ "agent": "analyzer",
506
+ "task": "Calculate price statistics (mean, median, range)",
507
+ "depends_on": ["clean"]
508
+ }
509
+ ])
510
+
511
+ # Each step gets context from previous steps
512
+ print("Scrape result:", results[0]['output'])
513
+ print("Clean result:", results[1]['output'])
514
+ print("Analysis:", results[2]['output'])
515
+
516
+ await mesh.stop()
517
+
518
+ asyncio.run(data_pipeline())
519
+ ```
520
+
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
+ ---
567
+
568
+ ## Internet Search
569
+
570
+ Enable web search for research tasks:
571
+
572
+ ```python
573
+ from jarviscore import Mesh
574
+ from jarviscore.profiles import AutoAgent
575
+
576
+ async def search_demo():
577
+ mesh = Mesh()
578
+
579
+ mesh.add_agent(
580
+ AutoAgent,
581
+ role="researcher",
582
+ capabilities=["research", "web_search"],
583
+ system_prompt="You are an expert researcher",
584
+ enable_search=True # ← Enable internet search
585
+ )
586
+
587
+ await mesh.start()
588
+
589
+ result = await mesh.run_workflow([{
590
+ "agent": "researcher",
591
+ "task": "Search for 'Python asyncio best practices' and summarize the top 3 results"
592
+ }])
593
+
594
+ print(result[0]['output'])
595
+ # Returns: Summary of top 3 search results
596
+
597
+ await mesh.stop()
598
+
599
+ asyncio.run(search_demo())
600
+ ```
601
+
602
+ **Search Capabilities:**
603
+ - DuckDuckGo web search
604
+ - Content extraction from URLs
605
+ - Automatic summarization
606
+ - No API keys required
607
+
608
+ ---
609
+
610
+ ## Remote Sandbox
611
+
612
+ Use remote code execution for better security:
613
+
614
+ ### Enable Remote Sandbox
615
+
616
+ ```bash
617
+ # .env file
618
+ SANDBOX_MODE=remote
619
+ SANDBOX_SERVICE_URL=https://browser-task-executor.bravesea-3f5f7e75.eastus.azurecontainerapps.io
620
+ ```
621
+
622
+ ### Test Remote Execution
623
+
624
+ ```python
625
+ from jarviscore.execution import create_sandbox_executor
626
+
627
+ async def test_remote():
628
+ executor = create_sandbox_executor(
629
+ timeout=30,
630
+ config={
631
+ 'sandbox_mode': 'remote',
632
+ 'sandbox_service_url': 'https://...'
633
+ }
634
+ )
635
+
636
+ code = "result = 2 + 2"
637
+ result = await executor.execute(code)
638
+
639
+ print(f"Mode: {result['mode']}") # "remote"
640
+ print(f"Output: {result['output']}") # 4
641
+ print(f"Time: {result['execution_time']}s")
642
+
643
+ asyncio.run(test_remote())
644
+ ```
645
+
646
+ **Benefits:**
647
+ - Full process isolation
648
+ - Better security
649
+ - Azure Container Apps hosting
650
+ - Automatic fallback to local
651
+
652
+ **When to use:**
653
+ - Production deployments
654
+ - Untrusted code execution
655
+ - Multi-tenant systems
656
+ - High security requirements
657
+
658
+ ---
659
+
660
+ ## Result Storage
661
+
662
+ All execution results are automatically stored:
663
+
664
+ ### Access Result Storage
665
+
666
+ ```python
667
+ from jarviscore.execution import create_result_handler
668
+
669
+ handler = create_result_handler()
670
+
671
+ # Get specific result
672
+ result = handler.get_result("calculator-abc123_2026-01-12T12-00-00_123456")
673
+
674
+ # Get agent's recent results
675
+ recent = handler.get_agent_results("calculator-abc123", limit=10)
676
+
677
+ for r in recent:
678
+ print(f"{r['task']}: {r['output']}")
679
+ ```
680
+
681
+ ### Storage Location
682
+
683
+ ```
684
+ logs/
685
+ ├── calculator-abc123/
686
+ │ ├── calculator-abc123_2026-01-12T12-00-00_123456.json
687
+ │ └── calculator-abc123_2026-01-12T12-05-30_789012.json
688
+ ├── analyzer-def456/
689
+ │ └── analyzer-def456_2026-01-12T12-10-00_345678.json
690
+ └── code_registry/
691
+ ├── index.json
692
+ └── functions/
693
+ ├── calculator-abc123_3a5b2f76.py
694
+ └── analyzer-def456_8b2c4d91.py
695
+ ```
696
+
697
+ **What's Stored:**
698
+ - Task description
699
+ - Generated code
700
+ - Execution output
701
+ - Status (success/failure)
702
+ - Execution time
703
+ - Token usage
704
+ - Cost (if tracked)
705
+ - Repair attempts
706
+ - Timestamp
707
+
708
+ ---
709
+
710
+ ## Code Registry
711
+
712
+ Reuse successful code across agents:
713
+
714
+ ### Search Registry
715
+
716
+ ```python
717
+ from jarviscore.execution import create_code_registry
718
+
719
+ registry = create_code_registry()
720
+
721
+ # Search for math functions
722
+ matches = registry.search(
723
+ query="factorial calculation",
724
+ capabilities=["math"],
725
+ limit=3
726
+ )
727
+
728
+ for match in matches:
729
+ print(f"Function: {match['function_id']}")
730
+ print(f"Task: {match['task']}")
731
+ print(f"Output sample: {match['output_sample']}")
732
+ ```
733
+
734
+ ### Get Function Code
735
+
736
+ ```python
737
+ # Get specific function
738
+ func = registry.get("calculator-abc123_3a5b2f76")
739
+
740
+ print("Code:")
741
+ print(func['code'])
742
+
743
+ print("\nMetadata:")
744
+ print(f"Agent: {func['agent_id']}")
745
+ print(f"Capabilities: {func['capabilities']}")
746
+ print(f"Registered: {func['registered_at']}")
747
+ ```
748
+
749
+ **Use Cases:**
750
+ - Share functions between agents
751
+ - Build function library
752
+ - Audit generated code
753
+ - Performance analysis
754
+
755
+ ---
756
+
757
+ ## Best Practices
758
+
759
+ ### 1. Always Use Context Managers
760
+
761
+ ```python
762
+ # Good
763
+ async with Mesh() as mesh:
764
+ mesh.add_agent(AutoAgent, ...)
765
+ await mesh.start()
766
+ results = await mesh.run_workflow([...])
767
+ # Automatic cleanup
768
+
769
+ # Manual (also works)
770
+ mesh = Mesh()
771
+ try:
772
+ await mesh.start()
773
+ results = await mesh.run_workflow([...])
774
+ finally:
775
+ await mesh.stop()
776
+ ```
777
+
778
+ ### 2. Handle Errors Gracefully
779
+
780
+ ```python
781
+ try:
782
+ results = await mesh.run_workflow([...])
783
+
784
+ for i, result in enumerate(results):
785
+ if result['status'] == 'failure':
786
+ print(f"Step {i} failed: {result['error']}")
787
+ else:
788
+ print(f"Step {i} succeeded: {result['output']}")
789
+
790
+ except TimeoutError:
791
+ print("Workflow timed out")
792
+ except RuntimeError as e:
793
+ print(f"Runtime error: {e}")
794
+ ```
795
+
796
+ ### 3. Use Clear System Prompts
797
+
798
+ ```python
799
+ # Good
800
+ system_prompt = """
801
+ You are a financial data analyst expert.
802
+ Your task is to analyze stock data and provide insights.
803
+ Always return results as structured JSON.
804
+ """
805
+
806
+ # Bad
807
+ system_prompt = "You are helpful"
808
+ ```
809
+
810
+ ### 4. Set Appropriate Timeouts
811
+
812
+ ```python
813
+ # Short tasks
814
+ mesh.add_agent(AutoAgent, ..., max_repair_attempts=1)
815
+
816
+ # Long-running tasks
817
+ config = {'execution_timeout': 600} # 10 minutes
818
+ mesh = Mesh(config=config)
819
+ ```
820
+
821
+ ### 5. Monitor Costs
822
+
823
+ ```python
824
+ class MyAgent(CustomAgent):
825
+ async def execute_task(self, task):
826
+ # ... do work ...
827
+
828
+ # Track costs
829
+ self.track_cost(
830
+ input_tokens=500,
831
+ output_tokens=200,
832
+ cost_usd=0.015
833
+ )
834
+
835
+ return result
836
+ ```
837
+
838
+ ---
839
+
840
+ ## Common Patterns
841
+
842
+ ### Pattern 1: Fan-Out, Fan-In
843
+
844
+ ```python
845
+ # Process multiple items in parallel, then aggregate
846
+ results = await mesh.run_workflow([
847
+ # Fan-out: Process items
848
+ {"id": "item1", "agent": "processor", "task": "Process item 1"},
849
+ {"id": "item2", "agent": "processor", "task": "Process item 2"},
850
+ {"id": "item3", "agent": "processor", "task": "Process item 3"},
851
+
852
+ # Fan-in: Aggregate results
853
+ {
854
+ "id": "aggregate",
855
+ "agent": "aggregator",
856
+ "task": "Combine all processed items",
857
+ "depends_on": ["item1", "item2", "item3"]
858
+ }
859
+ ])
860
+ ```
861
+
862
+ ### Pattern 2: Conditional Execution
863
+
864
+ ```python
865
+ # Execute step 1
866
+ results = await mesh.run_workflow([
867
+ {"id": "check", "agent": "validator", "task": "Validate input data"}
868
+ ])
869
+
870
+ # Decide next step based on result
871
+ if results[0]['output']['valid']:
872
+ results = await mesh.run_workflow([
873
+ {"agent": "processor", "task": "Process valid data"}
874
+ ])
875
+ else:
876
+ print("Validation failed, skipping processing")
877
+ ```
878
+
879
+ ### Pattern 3: Retry with Different Agent
880
+
881
+ ```python
882
+ try:
883
+ # Try primary agent
884
+ result = await mesh.run_workflow([
885
+ {"agent": "primary_scraper", "task": "Scrape website"}
886
+ ])
887
+ except Exception:
888
+ # Fallback to backup agent
889
+ result = await mesh.run_workflow([
890
+ {"agent": "backup_scraper", "task": "Scrape website"}
891
+ ])
892
+ ```
893
+
894
+ ---
895
+
896
+ ## Troubleshooting
897
+
898
+ ### Issue: Agent not found
899
+
900
+ ```python
901
+ # Error: No agent found for step
902
+ # Solution: Check role/capability spelling
903
+ mesh.add_agent(AutoAgent, role="calculator", capabilities=["math"])
904
+
905
+ # This will fail
906
+ await mesh.run_workflow([
907
+ {"agent": "calcul", "task": "..."} # Typo!
908
+ ])
909
+
910
+ # This works
911
+ await mesh.run_workflow([
912
+ {"agent": "calculator", "task": "..."} # Correct role
913
+ ])
914
+
915
+ # This also works
916
+ await mesh.run_workflow([
917
+ {"agent": "math", "task": "..."} # Uses capability
918
+ ])
919
+ ```
920
+
921
+ ### Issue: Mesh not started
922
+
923
+ ```python
924
+ # Error: RuntimeError: Workflow engine not started
925
+ # Solution: Call mesh.start() before run_workflow()
926
+
927
+ mesh = Mesh()
928
+ mesh.add_agent(...)
929
+ await mesh.start() # ← Don't forget this!
930
+ await mesh.run_workflow([...])
931
+ ```
932
+
933
+ ### Issue: Timeout
934
+
935
+ ```python
936
+ # Error: TimeoutError: Execution exceeded 300 seconds
937
+ # Solution: Increase timeout
938
+
939
+ config = {'execution_timeout': 600} # 10 minutes
940
+ mesh = Mesh(config=config)
941
+ ```
942
+
943
+ ### Issue: No LLM provider configured
944
+
945
+ ```python
946
+ # Error: RuntimeError: No LLM provider configured
947
+ # Solution: Set environment variables
948
+
949
+ # .env file
950
+ CLAUDE_API_KEY=your-key
951
+ # or
952
+ AZURE_API_KEY=your-key
953
+ AZURE_ENDPOINT=https://...
954
+ ```
955
+
956
+ ### Issue: Code execution fails
957
+
958
+ ```python
959
+ # Check logs for details
960
+ import logging
961
+ logging.basicConfig(level=logging.DEBUG)
962
+
963
+ # Enable verbose output
964
+ config = {'log_level': 'DEBUG'}
965
+ mesh = Mesh(config=config)
966
+ ```
967
+
968
+ ---
969
+
970
+ ## Next Steps
971
+
972
+ 1. **Read the [API Reference](API_REFERENCE.md)** for detailed component documentation
973
+ 2. **Check the [Configuration Guide](CONFIGURATION.md)** for environment setup
974
+ 3. **Explore examples/** directory for more code samples
975
+ 4. **Join the community** on GitHub for support
976
+
977
+ ---
978
+
979
+ ## Version
980
+
981
+ User Guide for JarvisCore v0.1.0
982
+
983
+ Last Updated: 2026-01-12