jarviscore-framework 0.1.0__tar.gz → 0.2.0__tar.gz

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 (145) hide show
  1. jarviscore_framework-0.2.0/PKG-INFO +143 -0
  2. jarviscore_framework-0.2.0/README.md +100 -0
  3. jarviscore_framework-0.2.0/examples/autoagent_distributed_example.py +211 -0
  4. jarviscore_framework-0.2.0/examples/custom_profile_decorator.py +134 -0
  5. jarviscore_framework-0.2.0/examples/custom_profile_wrap.py +168 -0
  6. jarviscore_framework-0.2.0/examples/customagent_distributed_example.py +362 -0
  7. jarviscore_framework-0.2.0/examples/customagent_p2p_example.py +347 -0
  8. jarviscore_framework-0.2.0/jarviscore/__init__.py +99 -0
  9. jarviscore_framework-0.2.0/jarviscore/adapter/__init__.py +40 -0
  10. jarviscore_framework-0.2.0/jarviscore/adapter/decorator.py +336 -0
  11. jarviscore_framework-0.2.0/jarviscore/adapter/wrapper.py +303 -0
  12. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/cli/check.py +18 -13
  13. jarviscore_framework-0.2.0/jarviscore/cli/scaffold.py +178 -0
  14. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/cli/smoketest.py +3 -2
  15. jarviscore_framework-0.2.0/jarviscore/context/__init__.py +40 -0
  16. jarviscore_framework-0.2.0/jarviscore/context/dependency.py +160 -0
  17. jarviscore_framework-0.2.0/jarviscore/context/jarvis_context.py +207 -0
  18. jarviscore_framework-0.2.0/jarviscore/context/memory.py +155 -0
  19. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/core/agent.py +44 -1
  20. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/core/mesh.py +196 -35
  21. jarviscore_framework-0.2.0/jarviscore/data/.env.example +146 -0
  22. jarviscore_framework-0.2.0/jarviscore/data/__init__.py +7 -0
  23. jarviscore_framework-0.2.0/jarviscore/data/examples/autoagent_distributed_example.py +211 -0
  24. jarviscore_framework-0.2.0/jarviscore/data/examples/calculator_agent_example.py +77 -0
  25. jarviscore_framework-0.2.0/jarviscore/data/examples/customagent_distributed_example.py +362 -0
  26. jarviscore_framework-0.2.0/jarviscore/data/examples/customagent_p2p_example.py +347 -0
  27. jarviscore_framework-0.2.0/jarviscore/data/examples/multi_agent_workflow.py +132 -0
  28. jarviscore_framework-0.2.0/jarviscore/data/examples/research_agent_example.py +76 -0
  29. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/docs/API_REFERENCE.md +264 -51
  30. jarviscore_framework-0.2.0/jarviscore/docs/AUTOAGENT_GUIDE.md +198 -0
  31. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/docs/CONFIGURATION.md +41 -23
  32. jarviscore_framework-0.2.0/jarviscore/docs/CUSTOMAGENT_GUIDE.md +415 -0
  33. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/docs/GETTING_STARTED.md +113 -17
  34. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/docs/TROUBLESHOOTING.md +155 -13
  35. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/docs/USER_GUIDE.md +144 -363
  36. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/execution/llm.py +23 -16
  37. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/orchestration/engine.py +20 -8
  38. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/p2p/__init__.py +10 -0
  39. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/p2p/coordinator.py +129 -0
  40. jarviscore_framework-0.2.0/jarviscore/p2p/messages.py +87 -0
  41. jarviscore_framework-0.2.0/jarviscore/p2p/peer_client.py +576 -0
  42. jarviscore_framework-0.2.0/jarviscore/p2p/peer_tool.py +268 -0
  43. jarviscore_framework-0.2.0/jarviscore_framework.egg-info/PKG-INFO +143 -0
  44. jarviscore_framework-0.2.0/jarviscore_framework.egg-info/SOURCES.txt +137 -0
  45. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore_framework.egg-info/requires.txt +1 -1
  46. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore_framework.egg-info/top_level.txt +2 -0
  47. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/pyproject.toml +5 -6
  48. jarviscore_framework-0.2.0/test_logs/code_registry/functions/data_generator-558779ed_560ebc37.py +7 -0
  49. jarviscore_framework-0.2.0/test_logs/code_registry/functions/data_generator-5ed3609e_560ebc37.py +7 -0
  50. jarviscore_framework-0.2.0/test_logs/code_registry/functions/data_generator-66da0356_43970bb9.py +25 -0
  51. jarviscore_framework-0.2.0/test_logs/code_registry/functions/data_generator-7a2fac83_583709d9.py +36 -0
  52. jarviscore_framework-0.2.0/test_logs/code_registry/functions/data_generator-888b670f_aa235863.py +9 -0
  53. jarviscore_framework-0.2.0/test_logs/code_registry/functions/data_generator-9ca5f642_aa235863.py +9 -0
  54. jarviscore_framework-0.2.0/test_logs/code_registry/functions/data_generator-bfd90775_560ebc37.py +7 -0
  55. jarviscore_framework-0.2.0/test_logs/code_registry/functions/data_generator-e95d2f7d_aa235863.py +9 -0
  56. jarviscore_framework-0.2.0/test_logs/code_registry/functions/data_generator-f60ca8a2_327eb8c2.py +29 -0
  57. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-02adf9ee_958658d9.py +19 -0
  58. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-0706fb57_5df13441.py +23 -0
  59. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-153c9c4a_ba59c918.py +83 -0
  60. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-287e61c0_41daa793.py +18 -0
  61. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-2967af5a_863c2cc6.py +17 -0
  62. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-303ca6d6_5df13441.py +23 -0
  63. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-308a4afd_cbf5064d.py +73 -0
  64. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-353f16e2_0968bcf5.py +18 -0
  65. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-3c22475a_41daa793.py +17 -0
  66. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-5bac1029_0968bcf5.py +18 -0
  67. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-640f76b2_9198780b.py +19 -0
  68. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-752fa7ea_863c2cc6.py +17 -0
  69. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-baf9ef39_0968bcf5.py +18 -0
  70. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-bc8b2a2f_5df13441.py +23 -0
  71. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-c31e4686_41daa793.py +18 -0
  72. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-cc84c84c_863c2cc6.py +17 -0
  73. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-dd7c7144_9198780b.py +19 -0
  74. jarviscore_framework-0.2.0/test_logs/code_registry/functions/mathematician-e671c256_41ea4487.py +74 -0
  75. jarviscore_framework-0.2.0/test_logs/code_registry/functions/report_generator-1a878fcc_18d44bdc.py +47 -0
  76. jarviscore_framework-0.2.0/test_logs/code_registry/functions/report_generator-25c1c331_cea57d0d.py +35 -0
  77. jarviscore_framework-0.2.0/test_logs/code_registry/functions/report_generator-37552117_e711c2b9.py +35 -0
  78. jarviscore_framework-0.2.0/test_logs/code_registry/functions/report_generator-bc662768_e711c2b9.py +35 -0
  79. jarviscore_framework-0.2.0/test_logs/code_registry/functions/report_generator-d6c0e76b_5e7722ec.py +44 -0
  80. jarviscore_framework-0.2.0/test_logs/code_registry/functions/report_generator-f270fb02_680529c3.py +44 -0
  81. jarviscore_framework-0.2.0/test_logs/code_registry/functions/text_processor-11393b14_4370d3ed.py +40 -0
  82. jarviscore_framework-0.2.0/test_logs/code_registry/functions/text_processor-7d02dfc3_d3b569be.py +37 -0
  83. jarviscore_framework-0.2.0/test_logs/code_registry/functions/text_processor-8adb5e32_9168c5fe.py +13 -0
  84. jarviscore_framework-0.2.0/test_logs/code_registry/functions/text_processor-c58ffc19_78b4ceac.py +42 -0
  85. jarviscore_framework-0.2.0/test_logs/code_registry/functions/text_processor-cd5977b1_9168c5fe.py +13 -0
  86. jarviscore_framework-0.2.0/test_logs/code_registry/functions/text_processor-ec1c8773_9168c5fe.py +13 -0
  87. jarviscore_framework-0.2.0/tests/test_01_analyst_standalone.py +124 -0
  88. jarviscore_framework-0.2.0/tests/test_02_assistant_standalone.py +164 -0
  89. jarviscore_framework-0.2.0/tests/test_03_analyst_with_framework.py +945 -0
  90. jarviscore_framework-0.2.0/tests/test_04_assistant_with_framework.py +1002 -0
  91. jarviscore_framework-0.2.0/tests/test_05_integration.py +1301 -0
  92. jarviscore_framework-0.2.0/tests/test_06_real_llm_integration.py +760 -0
  93. jarviscore_framework-0.2.0/tests/test_07_distributed_single_node.py +578 -0
  94. jarviscore_framework-0.2.0/tests/test_08_distributed_multi_node.py +454 -0
  95. jarviscore_framework-0.2.0/tests/test_09_distributed_autoagent.py +509 -0
  96. jarviscore_framework-0.2.0/tests/test_10_distributed_customagent.py +787 -0
  97. jarviscore_framework-0.2.0/tests/test_context.py +467 -0
  98. jarviscore_framework-0.2.0/tests/test_decorator.py +622 -0
  99. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/tests/test_mesh.py +35 -4
  100. jarviscore_framework-0.1.0/PKG-INFO +0 -136
  101. jarviscore_framework-0.1.0/README.md +0 -92
  102. jarviscore_framework-0.1.0/TESTING_GUIDE.md +0 -420
  103. jarviscore_framework-0.1.0/jarviscore/__init__.py +0 -54
  104. jarviscore_framework-0.1.0/jarviscore_framework.egg-info/PKG-INFO +0 -136
  105. jarviscore_framework-0.1.0/jarviscore_framework.egg-info/SOURCES.txt +0 -61
  106. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/.env.example +0 -0
  107. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/LICENSE +0 -0
  108. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/MANIFEST.in +0 -0
  109. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/examples/calculator_agent_example.py +0 -0
  110. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/examples/multi_agent_workflow.py +0 -0
  111. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/examples/research_agent_example.py +0 -0
  112. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/cli/__init__.py +0 -0
  113. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/cli/__main__.py +0 -0
  114. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/config/__init__.py +0 -0
  115. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/config/settings.py +0 -0
  116. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/core/__init__.py +0 -0
  117. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/core/profile.py +0 -0
  118. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/execution/__init__.py +0 -0
  119. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/execution/code_registry.py +0 -0
  120. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/execution/generator.py +0 -0
  121. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/execution/repair.py +0 -0
  122. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/execution/result_handler.py +0 -0
  123. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/execution/sandbox.py +0 -0
  124. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/execution/search.py +0 -0
  125. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/orchestration/__init__.py +0 -0
  126. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/orchestration/claimer.py +0 -0
  127. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/orchestration/dependency.py +0 -0
  128. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/orchestration/status.py +0 -0
  129. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/p2p/broadcaster.py +0 -0
  130. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/p2p/keepalive.py +0 -0
  131. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/p2p/swim_manager.py +0 -0
  132. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/profiles/__init__.py +0 -0
  133. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/profiles/autoagent.py +0 -0
  134. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore/profiles/customagent.py +0 -0
  135. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/jarviscore_framework.egg-info/dependency_links.txt +0 -0
  136. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/setup.cfg +0 -0
  137. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/tests/conftest.py +0 -0
  138. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/tests/test_agent.py +0 -0
  139. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/tests/test_autoagent.py +0 -0
  140. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/tests/test_autoagent_day4.py +0 -0
  141. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/tests/test_customagent.py +0 -0
  142. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/tests/test_integration.py +0 -0
  143. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/tests/test_llm_fallback.py +0 -0
  144. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/tests/test_p2p_integration.py +0 -0
  145. {jarviscore_framework-0.1.0 → jarviscore_framework-0.2.0}/tests/test_remote_sandbox.py +0 -0
@@ -0,0 +1,143 @@
1
+ Metadata-Version: 2.4
2
+ Name: jarviscore-framework
3
+ Version: 0.2.0
4
+ Summary: Build autonomous AI agents in 3 lines of code. Production-ready orchestration with P2P mesh networking.
5
+ Author-email: Ruth Mutua <mutuandinda82@gmail.com>, Muyukani Kizito <muyukani@prescottdata.io>
6
+ Maintainer-email: Prescott Data <info@prescottdata.io>
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/yourusername/jarviscore
9
+ Project-URL: Documentation, https://jarviscore.readthedocs.io
10
+ Project-URL: Repository, https://github.com/yourusername/jarviscore
11
+ Project-URL: Issues, https://github.com/yourusername/jarviscore/issues
12
+ Keywords: agents,p2p,llm,distributed,workflow,orchestration
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: pydantic>=2.0.0
23
+ Requires-Dist: pydantic-settings>=2.0.0
24
+ Requires-Dist: swim-p2p
25
+ Requires-Dist: pyzmq
26
+ Requires-Dist: python-dotenv>=1.0.0
27
+ Requires-Dist: aiohttp>=3.9.0
28
+ Requires-Dist: beautifulsoup4>=4.12.0
29
+ Requires-Dist: anthropic>=0.18.0
30
+ Requires-Dist: openai>=1.0.0
31
+ Requires-Dist: google-genai>=1.0.0
32
+ Requires-Dist: httpx>=0.25.0
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest>=7.4.0; extra == "dev"
35
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
36
+ Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
37
+ Requires-Dist: black>=23.0.0; extra == "dev"
38
+ Requires-Dist: mypy>=1.5.0; extra == "dev"
39
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
40
+ Provides-Extra: all
41
+ Requires-Dist: jarviscore[dev]; extra == "all"
42
+ Dynamic: license-file
43
+
44
+ # JarvisCore Framework
45
+
46
+ **Build autonomous AI agents with P2P mesh networking.**
47
+
48
+ ## Features
49
+
50
+ - ✅ **AutoAgent** - LLM generates and executes code from natural language
51
+ - ✅ **CustomAgent** - Bring your own logic (LangChain, CrewAI, etc.)
52
+ - ✅ **P2P Mesh** - Agent discovery and communication via SWIM protocol
53
+ - ✅ **Workflow Orchestration** - Dependencies, context passing, multi-step pipelines
54
+
55
+ ## Installation
56
+
57
+ ```bash
58
+ pip install jarviscore-framework
59
+ ```
60
+
61
+ ## Setup
62
+
63
+ ```bash
64
+ # Initialize project
65
+ python -m jarviscore.cli.scaffold --examples
66
+ cp .env.example .env
67
+ # Add your LLM API key to .env
68
+
69
+ # Validate
70
+ python -m jarviscore.cli.check --validate-llm
71
+ python -m jarviscore.cli.smoketest
72
+ ```
73
+
74
+ ## Quick Start
75
+
76
+ ### AutoAgent (LLM-Powered)
77
+
78
+ ```python
79
+ from jarviscore import Mesh
80
+ from jarviscore.profiles import AutoAgent
81
+
82
+ class CalculatorAgent(AutoAgent):
83
+ role = "calculator"
84
+ capabilities = ["math"]
85
+ system_prompt = "You are a math expert. Store result in 'result'."
86
+
87
+ mesh = Mesh(mode="autonomous")
88
+ mesh.add(CalculatorAgent)
89
+ await mesh.start()
90
+
91
+ results = await mesh.workflow("calc", [
92
+ {"agent": "calculator", "task": "Calculate factorial of 10"}
93
+ ])
94
+ print(results[0]["output"]) # 3628800
95
+ ```
96
+
97
+ ### CustomAgent (Your Code)
98
+
99
+ ```python
100
+ from jarviscore import Mesh
101
+ from jarviscore.profiles import CustomAgent
102
+
103
+ class ProcessorAgent(CustomAgent):
104
+ role = "processor"
105
+ capabilities = ["processing"]
106
+
107
+ async def execute_task(self, task):
108
+ data = task.get("params", {}).get("data", [])
109
+ return {"status": "success", "output": [x * 2 for x in data]}
110
+
111
+ mesh = Mesh(mode="distributed", config={'bind_port': 7950})
112
+ mesh.add(ProcessorAgent)
113
+ await mesh.start()
114
+
115
+ results = await mesh.workflow("demo", [
116
+ {"agent": "processor", "task": "Process", "params": {"data": [1, 2, 3]}}
117
+ ])
118
+ print(results[0]["output"]) # [2, 4, 6]
119
+ ```
120
+
121
+ ## Execution Modes
122
+
123
+ | Mode | Profile | Use Case |
124
+ |------|---------|----------|
125
+ | `autonomous` | AutoAgent | Single machine, LLM code generation |
126
+ | `p2p` | CustomAgent | Agent-to-agent communication, swarms |
127
+ | `distributed` | CustomAgent | Multi-node workflows + P2P |
128
+
129
+ ## Documentation
130
+
131
+ - [Getting Started](jarviscore/docs/GETTING_STARTED.md) - 5-minute quickstart
132
+ - [AutoAgent Guide](jarviscore/docs/AUTOAGENT_GUIDE.md) - LLM-powered agents
133
+ - [CustomAgent Guide](jarviscore/docs/CUSTOMAGENT_GUIDE.md) - Bring your own code
134
+ - [API Reference](jarviscore/docs/API_REFERENCE.md) - Detailed API docs
135
+ - [Configuration](jarviscore/docs/CONFIGURATION.md) - Settings reference
136
+
137
+ ## Version
138
+
139
+ **0.2.0**
140
+
141
+ ## License
142
+
143
+ MIT License
@@ -0,0 +1,100 @@
1
+ # JarvisCore Framework
2
+
3
+ **Build autonomous AI agents with P2P mesh networking.**
4
+
5
+ ## Features
6
+
7
+ - ✅ **AutoAgent** - LLM generates and executes code from natural language
8
+ - ✅ **CustomAgent** - Bring your own logic (LangChain, CrewAI, etc.)
9
+ - ✅ **P2P Mesh** - Agent discovery and communication via SWIM protocol
10
+ - ✅ **Workflow Orchestration** - Dependencies, context passing, multi-step pipelines
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ pip install jarviscore-framework
16
+ ```
17
+
18
+ ## Setup
19
+
20
+ ```bash
21
+ # Initialize project
22
+ python -m jarviscore.cli.scaffold --examples
23
+ cp .env.example .env
24
+ # Add your LLM API key to .env
25
+
26
+ # Validate
27
+ python -m jarviscore.cli.check --validate-llm
28
+ python -m jarviscore.cli.smoketest
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ### AutoAgent (LLM-Powered)
34
+
35
+ ```python
36
+ from jarviscore import Mesh
37
+ from jarviscore.profiles import AutoAgent
38
+
39
+ class CalculatorAgent(AutoAgent):
40
+ role = "calculator"
41
+ capabilities = ["math"]
42
+ system_prompt = "You are a math expert. Store result in 'result'."
43
+
44
+ mesh = Mesh(mode="autonomous")
45
+ mesh.add(CalculatorAgent)
46
+ await mesh.start()
47
+
48
+ results = await mesh.workflow("calc", [
49
+ {"agent": "calculator", "task": "Calculate factorial of 10"}
50
+ ])
51
+ print(results[0]["output"]) # 3628800
52
+ ```
53
+
54
+ ### CustomAgent (Your Code)
55
+
56
+ ```python
57
+ from jarviscore import Mesh
58
+ from jarviscore.profiles import CustomAgent
59
+
60
+ class ProcessorAgent(CustomAgent):
61
+ role = "processor"
62
+ capabilities = ["processing"]
63
+
64
+ async def execute_task(self, task):
65
+ data = task.get("params", {}).get("data", [])
66
+ return {"status": "success", "output": [x * 2 for x in data]}
67
+
68
+ mesh = Mesh(mode="distributed", config={'bind_port': 7950})
69
+ mesh.add(ProcessorAgent)
70
+ await mesh.start()
71
+
72
+ results = await mesh.workflow("demo", [
73
+ {"agent": "processor", "task": "Process", "params": {"data": [1, 2, 3]}}
74
+ ])
75
+ print(results[0]["output"]) # [2, 4, 6]
76
+ ```
77
+
78
+ ## Execution Modes
79
+
80
+ | Mode | Profile | Use Case |
81
+ |------|---------|----------|
82
+ | `autonomous` | AutoAgent | Single machine, LLM code generation |
83
+ | `p2p` | CustomAgent | Agent-to-agent communication, swarms |
84
+ | `distributed` | CustomAgent | Multi-node workflows + P2P |
85
+
86
+ ## Documentation
87
+
88
+ - [Getting Started](jarviscore/docs/GETTING_STARTED.md) - 5-minute quickstart
89
+ - [AutoAgent Guide](jarviscore/docs/AUTOAGENT_GUIDE.md) - LLM-powered agents
90
+ - [CustomAgent Guide](jarviscore/docs/CUSTOMAGENT_GUIDE.md) - Bring your own code
91
+ - [API Reference](jarviscore/docs/API_REFERENCE.md) - Detailed API docs
92
+ - [Configuration](jarviscore/docs/CONFIGURATION.md) - Settings reference
93
+
94
+ ## Version
95
+
96
+ **0.2.0**
97
+
98
+ ## License
99
+
100
+ MIT License
@@ -0,0 +1,211 @@
1
+ """
2
+ AutoAgent Distributed Mode Example
3
+
4
+ Demonstrates AutoAgent in distributed mode, which combines:
5
+ - P2P network layer (SWIM protocol, ZMQ messaging)
6
+ - Workflow orchestration (step execution, dependencies)
7
+
8
+ This is ideal for multi-node deployments where agents can:
9
+ - Execute on different machines
10
+ - Discover each other via SWIM
11
+ - Run orchestrated workflows across the network
12
+
13
+ Usage:
14
+ python examples/autoagent_distributed_example.py
15
+
16
+ Prerequisites:
17
+ - .env file with LLM API key (CLAUDE_API_KEY, etc.)
18
+ """
19
+ import asyncio
20
+ import sys
21
+ from pathlib import Path
22
+
23
+ sys.path.insert(0, str(Path(__file__).parent.parent))
24
+
25
+ from jarviscore import Mesh
26
+ from jarviscore.profiles import AutoAgent
27
+
28
+
29
+ # ═══════════════════════════════════════════════════════════════════════════════
30
+ # AUTOAGENT DEFINITIONS
31
+ # ═══════════════════════════════════════════════════════════════════════════════
32
+
33
+ class DataCollectorAgent(AutoAgent):
34
+ """Collects and generates data."""
35
+ role = "collector"
36
+ capabilities = ["data_collection", "sampling"]
37
+ system_prompt = """
38
+ You are a data collection specialist. Generate sample datasets
39
+ based on specifications. Use Python's standard library only.
40
+ Store results in a variable named 'result' as a dictionary.
41
+ """
42
+
43
+
44
+ class DataProcessorAgent(AutoAgent):
45
+ """Processes and transforms data."""
46
+ role = "processor"
47
+ capabilities = ["data_processing", "transformation"]
48
+ system_prompt = """
49
+ You are a data processing expert. Transform and clean datasets.
50
+ Apply filters, aggregations, and transformations as needed.
51
+ Use Python's standard library only. Store results in 'result'.
52
+ """
53
+
54
+
55
+ class ReportWriterAgent(AutoAgent):
56
+ """Generates reports from processed data."""
57
+ role = "reporter"
58
+ capabilities = ["reporting", "documentation"]
59
+ system_prompt = """
60
+ You are a technical writer. Create clear, well-formatted reports
61
+ from data. Use markdown formatting. Store the report in 'result'.
62
+ """
63
+
64
+
65
+ # ═══════════════════════════════════════════════════════════════════════════════
66
+ # MAIN EXAMPLE
67
+ # ═══════════════════════════════════════════════════════════════════════════════
68
+
69
+ async def main():
70
+ """Run AutoAgent distributed mode example."""
71
+ print("\n" + "="*70)
72
+ print("JarvisCore: AutoAgent in Distributed Mode")
73
+ print("="*70)
74
+
75
+ # ─────────────────────────────────────────────────────────────────────────
76
+ # KEY DIFFERENCE: mode="distributed" with P2P configuration
77
+ # ─────────────────────────────────────────────────────────────────────────
78
+ mesh = Mesh(
79
+ mode="distributed", # Enables P2P + Workflow Engine
80
+ config={
81
+ # P2P Network Configuration
82
+ 'bind_host': '127.0.0.1', # Interface to bind to
83
+ 'bind_port': 7950, # SWIM protocol port (ZMQ uses +1000)
84
+ 'node_name': 'autoagent-node',
85
+
86
+ # For multi-node: uncomment to join existing cluster
87
+ # 'seed_nodes': '192.168.1.10:7950,192.168.1.11:7950',
88
+
89
+ # AutoAgent Configuration
90
+ 'execution_timeout': 60, # Max seconds per task
91
+ 'max_repair_attempts': 2, # Auto-repair on failure
92
+ 'log_directory': './logs', # Result storage
93
+ }
94
+ )
95
+
96
+ # Add agents - same as autonomous mode
97
+ mesh.add(DataCollectorAgent)
98
+ mesh.add(DataProcessorAgent)
99
+ mesh.add(ReportWriterAgent)
100
+
101
+ try:
102
+ await mesh.start()
103
+
104
+ print("\n[INFO] Mesh started in DISTRIBUTED mode")
105
+ print(f" - P2P Coordinator: Active (port {mesh.config.get('bind_port', 7950)})")
106
+ print(f" - Workflow Engine: Active")
107
+ print(f" - Agents: {len(mesh.agents)}")
108
+
109
+ # ─────────────────────────────────────────────────────────────────────
110
+ # WORKFLOW EXECUTION - Same API as autonomous mode
111
+ # ─────────────────────────────────────────────────────────────────────
112
+ print("\n" + "-"*70)
113
+ print("Executing Pipeline: Collect → Process → Report")
114
+ print("-"*70)
115
+
116
+ results = await mesh.workflow("distributed-pipeline", [
117
+ {
118
+ "id": "collect",
119
+ "agent": "collector",
120
+ "task": "Generate a dataset of 10 products with name, price, and category"
121
+ },
122
+ {
123
+ "id": "process",
124
+ "agent": "processor",
125
+ "task": "Calculate total value, average price, and count by category",
126
+ "depends_on": ["collect"]
127
+ },
128
+ {
129
+ "id": "report",
130
+ "agent": "reporter",
131
+ "task": "Create a summary report with the statistics",
132
+ "depends_on": ["process"]
133
+ }
134
+ ])
135
+
136
+ # Display results
137
+ print("\n" + "="*70)
138
+ print("RESULTS")
139
+ print("="*70)
140
+
141
+ for i, result in enumerate(results):
142
+ step_names = ["Data Collection", "Data Processing", "Report Generation"]
143
+ print(f"\n{step_names[i]}:")
144
+ print(f" Status: {result['status']}")
145
+ if result['status'] == 'success':
146
+ output = str(result.get('output', ''))[:200]
147
+ print(f" Output: {output}...")
148
+ else:
149
+ print(f" Error: {result.get('error')}")
150
+
151
+ # Summary
152
+ successes = sum(1 for r in results if r['status'] == 'success')
153
+ print(f"\n{'='*70}")
154
+ print(f"Pipeline Complete: {successes}/{len(results)} steps successful")
155
+ print(f"{'='*70}")
156
+
157
+ await mesh.stop()
158
+
159
+ except Exception as e:
160
+ print(f"\nError: {e}")
161
+ import traceback
162
+ traceback.print_exc()
163
+
164
+
165
+ # ═══════════════════════════════════════════════════════════════════════════════
166
+ # MULTI-NODE EXAMPLE (Reference)
167
+ # ═══════════════════════════════════════════════════════════════════════════════
168
+
169
+ async def multi_node_example():
170
+ """
171
+ Example: Running agents across multiple machines.
172
+
173
+ Node 1 (seed node):
174
+ mesh = Mesh(mode="distributed", config={
175
+ 'bind_host': '0.0.0.0',
176
+ 'bind_port': 7950,
177
+ 'node_name': 'node-1',
178
+ })
179
+ mesh.add(DataCollectorAgent)
180
+ await mesh.start()
181
+ await mesh.serve_forever() # Keep running
182
+
183
+ Node 2 (joins cluster):
184
+ mesh = Mesh(mode="distributed", config={
185
+ 'bind_host': '0.0.0.0',
186
+ 'bind_port': 7950,
187
+ 'node_name': 'node-2',
188
+ 'seed_nodes': '192.168.1.10:7950', # Node 1's address
189
+ })
190
+ mesh.add(DataProcessorAgent)
191
+ await mesh.start()
192
+ await mesh.serve_forever()
193
+
194
+ Node 3 (joins cluster):
195
+ mesh = Mesh(mode="distributed", config={
196
+ 'bind_host': '0.0.0.0',
197
+ 'bind_port': 7950,
198
+ 'node_name': 'node-3',
199
+ 'seed_nodes': '192.168.1.10:7950',
200
+ })
201
+ mesh.add(ReportWriterAgent)
202
+ await mesh.start()
203
+ await mesh.serve_forever()
204
+
205
+ Any node can now execute workflows that span all three!
206
+ """
207
+ pass
208
+
209
+
210
+ if __name__ == "__main__":
211
+ asyncio.run(main())
@@ -0,0 +1,134 @@
1
+ """
2
+ Custom Profile Example: Using @jarvis_agent Decorator
3
+
4
+ This example shows how to use the @jarvis_agent decorator to convert
5
+ any Python class into a JarvisCore agent without modifying the class.
6
+
7
+ Use Case: You have existing Python classes/agents and want JarvisCore
8
+ to handle orchestration (data handoff, dependencies, shared memory).
9
+ """
10
+ import asyncio
11
+ from jarviscore import Mesh, jarvis_agent, JarvisContext
12
+
13
+
14
+ # Example 1: Simple decorator (no context needed)
15
+ @jarvis_agent(role="processor", capabilities=["data_processing"])
16
+ class DataProcessor:
17
+ """Simple data processor - doubles input values."""
18
+
19
+ def run(self, data):
20
+ """Process data by doubling values."""
21
+ if isinstance(data, list):
22
+ return {"processed": [x * 2 for x in data]}
23
+ return {"processed": data * 2}
24
+
25
+
26
+ # Example 2: Decorator with context access
27
+ @jarvis_agent(role="aggregator", capabilities=["aggregation"])
28
+ class Aggregator:
29
+ """Aggregates results from previous steps using JarvisContext."""
30
+
31
+ def run(self, task, ctx: JarvisContext):
32
+ """
33
+ Access previous step results via ctx.previous().
34
+
35
+ Args:
36
+ task: The task description
37
+ ctx: JarvisContext with memory and dependency access
38
+ """
39
+ # Get output from a specific previous step
40
+ processed = ctx.previous("step1")
41
+
42
+ if processed:
43
+ data = processed.get("processed", [])
44
+ return {
45
+ "sum": sum(data) if isinstance(data, list) else data,
46
+ "count": len(data) if isinstance(data, list) else 1,
47
+ "source_step": "step1"
48
+ }
49
+
50
+ return {"error": "No previous data found"}
51
+
52
+
53
+ # Example 3: Decorator with custom execute method
54
+ @jarvis_agent(role="validator", capabilities=["validation"], execute_method="validate")
55
+ class DataValidator:
56
+ """Validates data using a custom method name."""
57
+
58
+ def validate(self, data):
59
+ """Custom execute method - validates input data."""
60
+ if isinstance(data, list):
61
+ return {
62
+ "valid": all(isinstance(x, (int, float)) for x in data),
63
+ "count": len(data),
64
+ "type": "list"
65
+ }
66
+ return {
67
+ "valid": isinstance(data, (int, float)),
68
+ "type": type(data).__name__
69
+ }
70
+
71
+
72
+ async def main():
73
+ """Run a multi-step workflow with custom profile agents."""
74
+ print("=" * 60)
75
+ print(" Custom Profile Example: @jarvis_agent Decorator")
76
+ print("=" * 60)
77
+
78
+ # Create mesh in autonomous mode
79
+ mesh = Mesh(mode="autonomous")
80
+
81
+ # Add our decorated agents
82
+ mesh.add(DataProcessor)
83
+ mesh.add(Aggregator)
84
+ mesh.add(DataValidator)
85
+
86
+ # Start the mesh
87
+ await mesh.start()
88
+
89
+ try:
90
+ # Execute a multi-step workflow
91
+ print("\nExecuting workflow with 3 steps...\n")
92
+
93
+ results = await mesh.workflow("custom-profile-demo", [
94
+ {
95
+ "id": "step1",
96
+ "agent": "processor",
97
+ "task": "Process input data",
98
+ "params": {"data": [1, 2, 3, 4, 5]}
99
+ },
100
+ {
101
+ "id": "step2",
102
+ "agent": "aggregator",
103
+ "task": "Aggregate processed results",
104
+ "depends_on": ["step1"] # Wait for step1
105
+ },
106
+ {
107
+ "id": "step3",
108
+ "agent": "validator",
109
+ "task": "Validate original data",
110
+ "params": {"data": [1, 2, 3, 4, 5]}
111
+ }
112
+ ])
113
+
114
+ # Print results
115
+ print("Results:")
116
+ print("-" * 40)
117
+
118
+ for i, result in enumerate(results):
119
+ step_name = ["Processor", "Aggregator", "Validator"][i]
120
+ print(f"\n{step_name} (step{i+1}):")
121
+ print(f" Status: {result.get('status')}")
122
+ print(f" Output: {result.get('output')}")
123
+
124
+ print("\n" + "=" * 60)
125
+ print(" Workflow completed successfully!")
126
+ print("=" * 60)
127
+
128
+ finally:
129
+ # Stop the mesh
130
+ await mesh.stop()
131
+
132
+
133
+ if __name__ == "__main__":
134
+ asyncio.run(main())