jarviscore-framework 0.3.0__tar.gz → 0.3.2__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 (166) hide show
  1. {jarviscore_framework-0.3.0/jarviscore_framework.egg-info → jarviscore_framework-0.3.2}/PKG-INFO +61 -46
  2. jarviscore_framework-0.3.2/README.md +147 -0
  3. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/examples/cloud_deployment_example.py +3 -3
  4. jarviscore_framework-0.3.0/jarviscore/data/examples/listeneragent_cognitive_discovery_example.py → jarviscore_framework-0.3.2/examples/customagent_cognitive_discovery_example.py +55 -14
  5. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/examples/customagent_distributed_example.py +140 -1
  6. {jarviscore_framework-0.3.0/jarviscore/data → jarviscore_framework-0.3.2}/examples/fastapi_integration_example.py +74 -11
  7. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/__init__.py +8 -11
  8. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/cli/smoketest.py +1 -1
  9. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/core/mesh.py +158 -0
  10. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/data/examples/cloud_deployment_example.py +3 -3
  11. jarviscore_framework-0.3.2/jarviscore/data/examples/custom_profile_decorator.py +134 -0
  12. jarviscore_framework-0.3.2/jarviscore/data/examples/custom_profile_wrap.py +168 -0
  13. jarviscore_framework-0.3.0/examples/listeneragent_cognitive_discovery_example.py → jarviscore_framework-0.3.2/jarviscore/data/examples/customagent_cognitive_discovery_example.py +55 -14
  14. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/data/examples/customagent_distributed_example.py +140 -1
  15. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2/jarviscore/data}/examples/fastapi_integration_example.py +74 -11
  16. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/docs/API_REFERENCE.md +576 -47
  17. jarviscore_framework-0.3.2/jarviscore/docs/CHANGELOG.md +228 -0
  18. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/docs/CONFIGURATION.md +1 -1
  19. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/docs/CUSTOMAGENT_GUIDE.md +591 -153
  20. jarviscore_framework-0.3.2/jarviscore/docs/GETTING_STARTED.md +657 -0
  21. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/docs/TROUBLESHOOTING.md +1 -1
  22. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/docs/USER_GUIDE.md +292 -12
  23. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/integrations/fastapi.py +4 -4
  24. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/p2p/coordinator.py +36 -7
  25. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/p2p/messages.py +13 -0
  26. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/p2p/peer_client.py +380 -21
  27. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/p2p/peer_tool.py +17 -11
  28. jarviscore_framework-0.3.2/jarviscore/profiles/__init__.py +12 -0
  29. jarviscore_framework-0.3.0/jarviscore/profiles/listeneragent.py → jarviscore_framework-0.3.2/jarviscore/profiles/customagent.py +365 -292
  30. jarviscore_framework-0.3.2/jarviscore/testing/__init__.py +35 -0
  31. jarviscore_framework-0.3.2/jarviscore/testing/mocks.py +578 -0
  32. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2/jarviscore_framework.egg-info}/PKG-INFO +61 -46
  33. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore_framework.egg-info/SOURCES.txt +11 -3
  34. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore_framework.egg-info/requires.txt +2 -0
  35. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/pyproject.toml +3 -1
  36. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_13_dx_improvements.py +37 -37
  37. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_15_llm_cognitive_discovery.py +18 -18
  38. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_16_unified_dx_flow.py +3 -3
  39. jarviscore_framework-0.3.2/tests/test_17_session_context.py +489 -0
  40. jarviscore_framework-0.3.2/tests/test_18_mesh_diagnostics.py +465 -0
  41. jarviscore_framework-0.3.2/tests/test_19_async_requests.py +516 -0
  42. jarviscore_framework-0.3.2/tests/test_20_load_balancing.py +546 -0
  43. jarviscore_framework-0.3.2/tests/test_21_mock_testing.py +776 -0
  44. jarviscore_framework-0.3.0/README.md +0 -134
  45. jarviscore_framework-0.3.0/jarviscore/docs/CHANGELOG.md +0 -97
  46. jarviscore_framework-0.3.0/jarviscore/docs/GETTING_STARTED.md +0 -800
  47. jarviscore_framework-0.3.0/jarviscore/profiles/__init__.py +0 -14
  48. jarviscore_framework-0.3.0/jarviscore/profiles/customagent.py +0 -137
  49. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/.env.example +0 -0
  50. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/LICENSE +0 -0
  51. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/MANIFEST.in +0 -0
  52. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/examples/autoagent_distributed_example.py +0 -0
  53. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/examples/calculator_agent_example.py +0 -0
  54. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/examples/custom_profile_decorator.py +0 -0
  55. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/examples/custom_profile_wrap.py +0 -0
  56. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/examples/customagent_p2p_example.py +0 -0
  57. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/examples/multi_agent_workflow.py +0 -0
  58. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/examples/research_agent_example.py +0 -0
  59. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/adapter/__init__.py +0 -0
  60. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/adapter/decorator.py +0 -0
  61. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/adapter/wrapper.py +0 -0
  62. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/cli/__init__.py +0 -0
  63. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/cli/__main__.py +0 -0
  64. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/cli/check.py +0 -0
  65. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/cli/scaffold.py +0 -0
  66. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/config/__init__.py +0 -0
  67. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/config/settings.py +0 -0
  68. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/context/__init__.py +0 -0
  69. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/context/dependency.py +0 -0
  70. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/context/jarvis_context.py +0 -0
  71. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/context/memory.py +0 -0
  72. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/core/__init__.py +0 -0
  73. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/core/agent.py +0 -0
  74. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/core/profile.py +0 -0
  75. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/data/.env.example +0 -0
  76. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/data/__init__.py +0 -0
  77. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/data/examples/autoagent_distributed_example.py +0 -0
  78. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/data/examples/calculator_agent_example.py +0 -0
  79. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/data/examples/customagent_p2p_example.py +0 -0
  80. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/data/examples/multi_agent_workflow.py +0 -0
  81. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/data/examples/research_agent_example.py +0 -0
  82. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/docs/AUTOAGENT_GUIDE.md +0 -0
  83. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/execution/__init__.py +0 -0
  84. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/execution/code_registry.py +0 -0
  85. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/execution/generator.py +0 -0
  86. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/execution/llm.py +0 -0
  87. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/execution/repair.py +0 -0
  88. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/execution/result_handler.py +0 -0
  89. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/execution/sandbox.py +0 -0
  90. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/execution/search.py +0 -0
  91. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/integrations/__init__.py +0 -0
  92. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/orchestration/__init__.py +0 -0
  93. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/orchestration/claimer.py +0 -0
  94. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/orchestration/dependency.py +0 -0
  95. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/orchestration/engine.py +0 -0
  96. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/orchestration/status.py +0 -0
  97. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/p2p/__init__.py +0 -0
  98. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/p2p/broadcaster.py +0 -0
  99. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/p2p/keepalive.py +0 -0
  100. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/p2p/swim_manager.py +0 -0
  101. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore/profiles/autoagent.py +0 -0
  102. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore_framework.egg-info/dependency_links.txt +0 -0
  103. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/jarviscore_framework.egg-info/top_level.txt +0 -0
  104. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/setup.cfg +0 -0
  105. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/data_generator-558779ed_560ebc37.py +0 -0
  106. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/data_generator-5ed3609e_560ebc37.py +0 -0
  107. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/data_generator-66da0356_43970bb9.py +0 -0
  108. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/data_generator-7a2fac83_583709d9.py +0 -0
  109. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/data_generator-888b670f_aa235863.py +0 -0
  110. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/data_generator-9ca5f642_aa235863.py +0 -0
  111. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/data_generator-bfd90775_560ebc37.py +0 -0
  112. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/data_generator-e95d2f7d_aa235863.py +0 -0
  113. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/data_generator-f60ca8a2_327eb8c2.py +0 -0
  114. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-02adf9ee_958658d9.py +0 -0
  115. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-0706fb57_5df13441.py +0 -0
  116. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-153c9c4a_ba59c918.py +0 -0
  117. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-287e61c0_41daa793.py +0 -0
  118. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-2967af5a_863c2cc6.py +0 -0
  119. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-303ca6d6_5df13441.py +0 -0
  120. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-308a4afd_cbf5064d.py +0 -0
  121. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-353f16e2_0968bcf5.py +0 -0
  122. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-3c22475a_41daa793.py +0 -0
  123. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-5bac1029_0968bcf5.py +0 -0
  124. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-640f76b2_9198780b.py +0 -0
  125. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-752fa7ea_863c2cc6.py +0 -0
  126. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-baf9ef39_0968bcf5.py +0 -0
  127. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-bc8b2a2f_5df13441.py +0 -0
  128. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-c31e4686_41daa793.py +0 -0
  129. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-cc84c84c_863c2cc6.py +0 -0
  130. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-dd7c7144_9198780b.py +0 -0
  131. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/mathematician-e671c256_41ea4487.py +0 -0
  132. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/report_generator-1a878fcc_18d44bdc.py +0 -0
  133. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/report_generator-25c1c331_cea57d0d.py +0 -0
  134. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/report_generator-37552117_e711c2b9.py +0 -0
  135. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/report_generator-bc662768_e711c2b9.py +0 -0
  136. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/report_generator-d6c0e76b_5e7722ec.py +0 -0
  137. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/report_generator-f270fb02_680529c3.py +0 -0
  138. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/text_processor-11393b14_4370d3ed.py +0 -0
  139. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/text_processor-7d02dfc3_d3b569be.py +0 -0
  140. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/text_processor-8adb5e32_9168c5fe.py +0 -0
  141. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/text_processor-c58ffc19_78b4ceac.py +0 -0
  142. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/text_processor-cd5977b1_9168c5fe.py +0 -0
  143. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/test_logs/code_registry/functions/text_processor-ec1c8773_9168c5fe.py +0 -0
  144. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/conftest.py +0 -0
  145. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_01_analyst_standalone.py +0 -0
  146. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_02_assistant_standalone.py +0 -0
  147. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_03_analyst_with_framework.py +0 -0
  148. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_04_assistant_with_framework.py +0 -0
  149. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_05_integration.py +0 -0
  150. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_06_real_llm_integration.py +0 -0
  151. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_07_distributed_single_node.py +0 -0
  152. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_08_distributed_multi_node.py +0 -0
  153. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_09_distributed_autoagent.py +0 -0
  154. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_10_distributed_customagent.py +0 -0
  155. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_14_cloud_deployment.py +0 -0
  156. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_agent.py +0 -0
  157. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_autoagent.py +0 -0
  158. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_autoagent_day4.py +0 -0
  159. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_context.py +0 -0
  160. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_customagent.py +0 -0
  161. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_decorator.py +0 -0
  162. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_integration.py +0 -0
  163. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_llm_fallback.py +0 -0
  164. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_mesh.py +0 -0
  165. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_p2p_integration.py +0 -0
  166. {jarviscore_framework-0.3.0 → jarviscore_framework-0.3.2}/tests/test_remote_sandbox.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jarviscore-framework
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: Build autonomous AI agents in 3 lines of code. Production-ready orchestration with P2P mesh networking.
5
5
  Author-email: Ruth Mutua <mutuandinda82@gmail.com>, Muyukani Kizito <muyukani@prescottdata.io>
6
6
  Maintainer-email: Prescott Data <info@prescottdata.io>
@@ -26,6 +26,8 @@ Requires-Dist: pyzmq
26
26
  Requires-Dist: python-dotenv>=1.0.0
27
27
  Requires-Dist: aiohttp>=3.9.0
28
28
  Requires-Dist: beautifulsoup4>=4.12.0
29
+ Requires-Dist: fastapi>=0.104.0
30
+ Requires-Dist: uvicorn>=0.29.0
29
31
  Requires-Dist: anthropic>=0.18.0
30
32
  Requires-Dist: openai>=1.0.0
31
33
  Requires-Dist: google-genai>=1.0.0
@@ -47,13 +49,13 @@ Dynamic: license-file
47
49
 
48
50
  ## Features
49
51
 
50
- - **AutoAgent** - LLM generates and executes code from natural language
51
- - **CustomAgent** - Bring your own logic (LangChain, CrewAI, etc.)
52
- - **ListenerAgent** - API-first agents with background P2P (just implement handlers)
53
- - **P2P Mesh** - Agent discovery and communication via SWIM protocol
54
- - **Workflow Orchestration** - Dependencies, context passing, multi-step pipelines
55
- - **FastAPI Integration** - 3-line setup with JarvisLifespan
56
- - **Cloud Deployment** - Self-registering agents for Docker/K8s
52
+ - **AutoAgent** - LLM generates and executes code from natural language
53
+ - **CustomAgent** - Bring your own logic with P2P message handlers
54
+ - **P2P Mesh** - Agent discovery and communication via SWIM protocol
55
+ - **Workflow Orchestration** - Dependencies, context passing, multi-step pipelines
56
+ - **FastAPI Integration** - 3-line setup with JarvisLifespan
57
+ - **Cognitive Discovery** - LLM-ready peer descriptions for autonomous delegation
58
+ - **Cloud Deployment** - Self-registering agents for Docker/K8s
57
59
 
58
60
  ## Installation
59
61
 
@@ -97,7 +99,26 @@ results = await mesh.workflow("calc", [
97
99
  print(results[0]["output"]) # 3628800
98
100
  ```
99
101
 
100
- ### CustomAgent (Your Code)
102
+ ### CustomAgent + FastAPI (Recommended)
103
+
104
+ ```python
105
+ from fastapi import FastAPI
106
+ from jarviscore.profiles import CustomAgent
107
+ from jarviscore.integrations.fastapi import JarvisLifespan
108
+
109
+ class ProcessorAgent(CustomAgent):
110
+ role = "processor"
111
+ capabilities = ["processing"]
112
+
113
+ async def on_peer_request(self, msg):
114
+ # Handle requests from other agents
115
+ return {"result": msg.data.get("task", "").upper()}
116
+
117
+ # 3 lines to integrate with FastAPI
118
+ app = FastAPI(lifespan=JarvisLifespan(ProcessorAgent(), mode="p2p"))
119
+ ```
120
+
121
+ ### CustomAgent (Workflow Mode)
101
122
 
102
123
  ```python
103
124
  from jarviscore import Mesh
@@ -121,56 +142,50 @@ results = await mesh.workflow("demo", [
121
142
  print(results[0]["output"]) # [2, 4, 6]
122
143
  ```
123
144
 
124
- ### ListenerAgent + FastAPI (API-First)
145
+ ## Profiles
125
146
 
126
- ```python
127
- from fastapi import FastAPI
128
- from jarviscore.profiles import ListenerAgent
129
- from jarviscore.integrations.fastapi import JarvisLifespan
130
-
131
- class ProcessorAgent(ListenerAgent):
132
- role = "processor"
133
- capabilities = ["processing"]
134
-
135
- async def on_peer_request(self, msg):
136
- # Handle requests from other agents
137
- return {"result": msg.data.get("task", "").upper()}
138
-
139
- # That's it - 3 lines to integrate with FastAPI
140
- app = FastAPI(lifespan=JarvisLifespan(ProcessorAgent(), mode="p2p"))
141
- ```
147
+ | Profile | You Write | JarvisCore Handles |
148
+ |---------|-----------|-------------------|
149
+ | **AutoAgent** | System prompt | LLM code generation, sandboxed execution |
150
+ | **CustomAgent** | `on_peer_request()` and/or `execute_task()` | Mesh, discovery, routing, lifecycle |
142
151
 
143
152
  ## Execution Modes
144
153
 
145
- | Mode | Profile | Use Case |
146
- |------|---------|----------|
147
- | `autonomous` | AutoAgent | Single machine, LLM code generation |
148
- | `p2p` | CustomAgent, ListenerAgent | Agent-to-agent communication, swarms |
149
- | `distributed` | CustomAgent, ListenerAgent | Multi-node workflows + P2P |
154
+ | Mode | Use Case |
155
+ |------|----------|
156
+ | `autonomous` | Single machine, LLM code generation (AutoAgent) |
157
+ | `p2p` | Agent-to-agent communication, swarms (CustomAgent) |
158
+ | `distributed` | Multi-node workflows + P2P (CustomAgent) |
150
159
 
151
- ## What's New in 0.3.0
160
+ ## Framework Integration
152
161
 
153
- **Developer Experience Improvements:**
154
- - **ListenerAgent** - No more writing `run()` loops. Just implement `on_peer_request()` and `on_peer_notify()` handlers.
155
- - **JarvisLifespan** - FastAPI integration reduced from ~100 lines to 3 lines.
156
- - **Cognitive Discovery** - `peers.get_cognitive_context()` generates LLM-ready peer descriptions. No more hardcoded agent names in prompts.
162
+ JarvisCore is **async-first**. Best experience with async frameworks.
157
163
 
158
- **Cloud Deployment:**
159
- - **Self-Registration** - `agent.join_mesh()` lets agents join existing meshes without central orchestrator.
160
- - **Remote Visibility** - Agents on different nodes are automatically discovered and callable.
164
+ | Framework | Integration |
165
+ |-----------|-------------|
166
+ | **FastAPI** | `JarvisLifespan` (3 lines) |
167
+ | **aiohttp, Quart, Tornado** | Manual lifecycle (see docs) |
168
+ | **Flask, Django** | Background thread pattern (see docs) |
161
169
 
162
170
  ## Documentation
163
171
 
164
- - [User Guide](jarviscore/docs/USER_GUIDE.md) - Complete documentation
165
- - [Getting Started](jarviscore/docs/GETTING_STARTED.md) - 5-minute quickstart
166
- - [AutoAgent Guide](jarviscore/docs/AUTOAGENT_GUIDE.md) - LLM-powered agents
167
- - [CustomAgent Guide](jarviscore/docs/CUSTOMAGENT_GUIDE.md) - Bring your own code
168
- - [API Reference](jarviscore/docs/API_REFERENCE.md) - Detailed API docs
169
- - [Configuration](jarviscore/docs/CONFIGURATION.md) - Settings reference
172
+ Documentation is included with the package:
173
+
174
+ ```bash
175
+ python -c "import jarviscore; print(jarviscore.__path__[0] + '/docs')"
176
+ ```
177
+
178
+ **Available guides:**
179
+ - `GETTING_STARTED.md` - 5-minute quickstart
180
+ - `CUSTOMAGENT_GUIDE.md` - CustomAgent patterns and framework integration
181
+ - `AUTOAGENT_GUIDE.md` - LLM-powered agents
182
+ - `USER_GUIDE.md` - Complete documentation
183
+ - `API_REFERENCE.md` - Detailed API docs
184
+ - `CONFIGURATION.md` - Settings reference
170
185
 
171
186
  ## Version
172
187
 
173
- **0.3.0**
188
+ **0.3.2**
174
189
 
175
190
  ## License
176
191
 
@@ -0,0 +1,147 @@
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 with P2P message handlers
9
+ - **P2P Mesh** - Agent discovery and communication via SWIM protocol
10
+ - **Workflow Orchestration** - Dependencies, context passing, multi-step pipelines
11
+ - **FastAPI Integration** - 3-line setup with JarvisLifespan
12
+ - **Cognitive Discovery** - LLM-ready peer descriptions for autonomous delegation
13
+ - **Cloud Deployment** - Self-registering agents for Docker/K8s
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pip install jarviscore-framework
19
+ ```
20
+
21
+ ## Setup
22
+
23
+ ```bash
24
+ # Initialize project
25
+ python -m jarviscore.cli.scaffold --examples
26
+ cp .env.example .env
27
+ # Add your LLM API key to .env
28
+
29
+ # Validate
30
+ python -m jarviscore.cli.check --validate-llm
31
+ python -m jarviscore.cli.smoketest
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ ### AutoAgent (LLM-Powered)
37
+
38
+ ```python
39
+ from jarviscore import Mesh
40
+ from jarviscore.profiles import AutoAgent
41
+
42
+ class CalculatorAgent(AutoAgent):
43
+ role = "calculator"
44
+ capabilities = ["math"]
45
+ system_prompt = "You are a math expert. Store result in 'result'."
46
+
47
+ mesh = Mesh(mode="autonomous")
48
+ mesh.add(CalculatorAgent)
49
+ await mesh.start()
50
+
51
+ results = await mesh.workflow("calc", [
52
+ {"agent": "calculator", "task": "Calculate factorial of 10"}
53
+ ])
54
+ print(results[0]["output"]) # 3628800
55
+ ```
56
+
57
+ ### CustomAgent + FastAPI (Recommended)
58
+
59
+ ```python
60
+ from fastapi import FastAPI
61
+ from jarviscore.profiles import CustomAgent
62
+ from jarviscore.integrations.fastapi import JarvisLifespan
63
+
64
+ class ProcessorAgent(CustomAgent):
65
+ role = "processor"
66
+ capabilities = ["processing"]
67
+
68
+ async def on_peer_request(self, msg):
69
+ # Handle requests from other agents
70
+ return {"result": msg.data.get("task", "").upper()}
71
+
72
+ # 3 lines to integrate with FastAPI
73
+ app = FastAPI(lifespan=JarvisLifespan(ProcessorAgent(), mode="p2p"))
74
+ ```
75
+
76
+ ### CustomAgent (Workflow Mode)
77
+
78
+ ```python
79
+ from jarviscore import Mesh
80
+ from jarviscore.profiles import CustomAgent
81
+
82
+ class ProcessorAgent(CustomAgent):
83
+ role = "processor"
84
+ capabilities = ["processing"]
85
+
86
+ async def execute_task(self, task):
87
+ data = task.get("params", {}).get("data", [])
88
+ return {"status": "success", "output": [x * 2 for x in data]}
89
+
90
+ mesh = Mesh(mode="distributed", config={'bind_port': 7950})
91
+ mesh.add(ProcessorAgent)
92
+ await mesh.start()
93
+
94
+ results = await mesh.workflow("demo", [
95
+ {"agent": "processor", "task": "Process", "params": {"data": [1, 2, 3]}}
96
+ ])
97
+ print(results[0]["output"]) # [2, 4, 6]
98
+ ```
99
+
100
+ ## Profiles
101
+
102
+ | Profile | You Write | JarvisCore Handles |
103
+ |---------|-----------|-------------------|
104
+ | **AutoAgent** | System prompt | LLM code generation, sandboxed execution |
105
+ | **CustomAgent** | `on_peer_request()` and/or `execute_task()` | Mesh, discovery, routing, lifecycle |
106
+
107
+ ## Execution Modes
108
+
109
+ | Mode | Use Case |
110
+ |------|----------|
111
+ | `autonomous` | Single machine, LLM code generation (AutoAgent) |
112
+ | `p2p` | Agent-to-agent communication, swarms (CustomAgent) |
113
+ | `distributed` | Multi-node workflows + P2P (CustomAgent) |
114
+
115
+ ## Framework Integration
116
+
117
+ JarvisCore is **async-first**. Best experience with async frameworks.
118
+
119
+ | Framework | Integration |
120
+ |-----------|-------------|
121
+ | **FastAPI** | `JarvisLifespan` (3 lines) |
122
+ | **aiohttp, Quart, Tornado** | Manual lifecycle (see docs) |
123
+ | **Flask, Django** | Background thread pattern (see docs) |
124
+
125
+ ## Documentation
126
+
127
+ Documentation is included with the package:
128
+
129
+ ```bash
130
+ python -c "import jarviscore; print(jarviscore.__path__[0] + '/docs')"
131
+ ```
132
+
133
+ **Available guides:**
134
+ - `GETTING_STARTED.md` - 5-minute quickstart
135
+ - `CUSTOMAGENT_GUIDE.md` - CustomAgent patterns and framework integration
136
+ - `AUTOAGENT_GUIDE.md` - LLM-powered agents
137
+ - `USER_GUIDE.md` - Complete documentation
138
+ - `API_REFERENCE.md` - Detailed API docs
139
+ - `CONFIGURATION.md` - Settings reference
140
+
141
+ ## Version
142
+
143
+ **0.3.2**
144
+
145
+ ## License
146
+
147
+ MIT License
@@ -28,10 +28,10 @@ import sys
28
28
 
29
29
  sys.path.insert(0, '.')
30
30
 
31
- from jarviscore.profiles import ListenerAgent
31
+ from jarviscore.profiles import CustomAgent
32
32
 
33
33
 
34
- class StandaloneProcessor(ListenerAgent):
34
+ class StandaloneProcessor(CustomAgent):
35
35
  """
36
36
  Example standalone agent that joins mesh independently.
37
37
 
@@ -143,7 +143,7 @@ async def main():
143
143
  print("Listening for peer requests...")
144
144
  print("Press Ctrl+C to stop.\n")
145
145
 
146
- # Run agent (ListenerAgent's run() handles the message loop)
146
+ # Run agent (CustomAgent's run() handles the message loop)
147
147
  try:
148
148
  await agent.run()
149
149
  except asyncio.CancelledError:
@@ -1,42 +1,47 @@
1
1
  """
2
- ListenerAgent + Cognitive Discovery Example
2
+ CustomAgent + Cognitive Discovery Example
3
3
 
4
- Demonstrates two v0.3.0 features:
4
+ Demonstrates v0.3.0 and v0.3.2 features:
5
5
 
6
- 1. ListenerAgent - Handler-based P2P agents (no run() loop needed)
6
+ 1. CustomAgent - Handler-based P2P agents (no run() loop needed)
7
7
  - on_peer_request() handles incoming requests
8
8
  - on_peer_notify() handles broadcast notifications
9
9
 
10
- 2. Cognitive Discovery - Dynamic peer awareness for LLMs
10
+ 2. Cognitive Discovery (v0.3.0) - Dynamic peer awareness for LLMs
11
11
  - get_cognitive_context() generates LLM-ready peer descriptions
12
12
  - No hardcoded agent names in prompts
13
13
  - LLM autonomously decides when to delegate
14
14
 
15
+ 3. Session Context (v0.3.2) - Request tracking with metadata
16
+ - Pass context={mission_id, request_id} with peer requests
17
+ - Track requests across agent boundaries for debugging/tracing
18
+
15
19
  Usage:
16
- python examples/listeneragent_cognitive_discovery_example.py
20
+ python examples/customagent_cognitive_discovery_example.py
17
21
 
18
22
  Prerequisites:
19
23
  - .env file with CLAUDE_API_KEY (or other LLM provider)
20
24
  """
21
25
  import asyncio
22
26
  import sys
27
+ import uuid
23
28
  from pathlib import Path
24
29
 
25
30
  sys.path.insert(0, str(Path(__file__).parent.parent))
26
31
 
27
32
  from jarviscore import Mesh
28
- from jarviscore.profiles import ListenerAgent
33
+ from jarviscore.profiles import CustomAgent
29
34
 
30
35
 
31
36
  # ═══════════════════════════════════════════════════════════════════════════════
32
37
  # SPECIALIST AGENT - Responds to requests from other agents
33
38
  # ═══════════════════════════════════════════════════════════════════════════════
34
39
 
35
- class AnalystAgent(ListenerAgent):
40
+ class AnalystAgent(CustomAgent):
36
41
  """
37
42
  Specialist agent that handles analysis requests.
38
43
 
39
- Uses ListenerAgent profile - just implement handlers, no run() loop needed.
44
+ Uses CustomAgent profile - just implement handlers, no run() loop needed.
40
45
  """
41
46
  role = "analyst"
42
47
  capabilities = ["data_analysis", "statistics", "insights"]
@@ -45,13 +50,21 @@ class AnalystAgent(ListenerAgent):
45
50
  async def on_peer_request(self, msg):
46
51
  """Handle incoming analysis requests."""
47
52
  query = msg.data.get("question", msg.data.get("query", ""))
48
- print(f"\n[Analyst] Received request: {query[:50]}...")
53
+
54
+ # v0.3.2: Access session context for request tracking
55
+ context = msg.context or {}
56
+ mission_id = context.get("mission_id", "unknown")
57
+ request_id = context.get("request_id", "unknown")
58
+
59
+ print(f"\n[Analyst] Received request (mission={mission_id[:8]}..., req={request_id[:8]}...)")
60
+ print(f"[Analyst] Query: {query[:50]}...")
49
61
 
50
62
  # Simulate analysis (in real usage, this would use an LLM)
51
63
  result = {
52
64
  "analysis": f"Analysis of '{query}': The data shows positive trends.",
53
65
  "confidence": 0.85,
54
- "insights": ["Trend is upward", "Growth rate: 15%", "Recommendation: Continue"]
66
+ "insights": ["Trend is upward", "Growth rate: 15%", "Recommendation: Continue"],
67
+ "context": {"mission_id": mission_id, "request_id": request_id} # Echo back for tracing
55
68
  }
56
69
 
57
70
  print(f"[Analyst] Sending response with {len(result['insights'])} insights")
@@ -62,7 +75,7 @@ class AnalystAgent(ListenerAgent):
62
75
  # COORDINATOR AGENT - Uses LLM with cognitive discovery
63
76
  # ═══════════════════════════════════════════════════════════════════════════════
64
77
 
65
- class CoordinatorAgent(ListenerAgent):
78
+ class CoordinatorAgent(CustomAgent):
66
79
  """
67
80
  Coordinator agent that uses LLM with dynamic peer discovery.
68
81
 
@@ -78,6 +91,9 @@ class CoordinatorAgent(ListenerAgent):
78
91
  async def setup(self):
79
92
  await super().setup()
80
93
  self.llm = self._create_llm_client()
94
+ # v0.3.2: Track missions for context propagation
95
+ self.mission_id = str(uuid.uuid4())
96
+ self.request_counter = 0
81
97
 
82
98
  def _create_llm_client(self):
83
99
  """Create LLM client with fallback to mock."""
@@ -167,10 +183,22 @@ Never try to do analysis yourself - always delegate to the analyst."""
167
183
  # Mock: simulate LLM deciding to delegate
168
184
  if any(word in user_query.lower() for word in ["analyze", "analysis", "statistics", "data"]):
169
185
  print("[Coordinator] Mock LLM decides to delegate to analyst")
186
+
187
+ # v0.3.2: Generate request context for tracking
188
+ self.request_counter += 1
189
+ request_context = {
190
+ "mission_id": self.mission_id,
191
+ "request_id": str(uuid.uuid4()),
192
+ "request_num": self.request_counter,
193
+ "source": "coordinator"
194
+ }
195
+ print(f"[Coordinator] Sending with context: mission={self.mission_id[:8]}...")
196
+
170
197
  response = await self.peers.request(
171
198
  "analyst",
172
199
  {"question": user_query},
173
- timeout=30
200
+ timeout=30,
201
+ context=request_context # v0.3.2: Pass context
174
202
  )
175
203
  return f"Based on the analyst's findings: {response.get('analysis', 'No response')}"
176
204
  return f"I can help with: {user_query}"
@@ -261,12 +289,24 @@ Never try to do analysis yourself - always delegate to the analyst."""
261
289
  role = args.get("role", "")
262
290
  question = args.get("question", "")
263
291
 
292
+ # v0.3.2: Generate request context for tracking
293
+ self.request_counter += 1
294
+ request_context = {
295
+ "mission_id": self.mission_id,
296
+ "request_id": str(uuid.uuid4()),
297
+ "request_num": self.request_counter,
298
+ "source": "coordinator",
299
+ "tool": "ask_peer"
300
+ }
301
+
264
302
  print(f"[Coordinator] Asking {role}: {question[:50]}...")
303
+ print(f"[Coordinator] Context: mission={self.mission_id[:8]}..., req_num={self.request_counter}")
265
304
 
266
305
  response = await self.peers.request(
267
306
  role,
268
307
  {"question": question},
269
- timeout=30
308
+ timeout=30,
309
+ context=request_context # v0.3.2: Pass context
270
310
  )
271
311
 
272
312
  return response
@@ -284,7 +324,8 @@ Never try to do analysis yourself - always delegate to the analyst."""
284
324
 
285
325
  async def main():
286
326
  print("=" * 60)
287
- print("LLM Cognitive Discovery Example")
327
+ print("CustomAgent + Cognitive Discovery + Session Context")
328
+ print("Features: v0.3.0 Cognitive Discovery, v0.3.2 Session Context")
288
329
  print("=" * 60)
289
330
 
290
331
  # Create mesh with both agents
@@ -6,6 +6,10 @@ Demonstrates CustomAgent in distributed mode, which combines:
6
6
  - Workflow orchestration (step execution, dependencies)
7
7
  - User-controlled execution logic (you write execute_task)
8
8
 
9
+ v0.3.2 Features Demonstrated:
10
+ - Async Requests (ask_async) - Non-blocking parallel requests to multiple agents
11
+ - Load Balancing (strategy="round_robin") - Distribute requests across agent instances
12
+
9
13
  This is ideal for:
10
14
  - Multi-node deployments with custom logic
11
15
  - Integrating external frameworks (LangChain, CrewAI, etc.)
@@ -231,6 +235,7 @@ async def main():
231
235
  """Run CustomAgent distributed mode example."""
232
236
  print("\n" + "="*70)
233
237
  print("JarvisCore: CustomAgent in Distributed Mode")
238
+ print("v0.3.2: Also supports --async and --load-balance demos")
234
239
  print("="*70)
235
240
 
236
241
  # ─────────────────────────────────────────────────────────────────────────
@@ -358,5 +363,139 @@ async def peer_communication_example():
358
363
  pass
359
364
 
360
365
 
366
+ # ═══════════════════════════════════════════════════════════════════════════════
367
+ # v0.3.2 FEATURES: ASYNC REQUESTS & LOAD BALANCING
368
+ # ═══════════════════════════════════════════════════════════════════════════════
369
+
370
+ async def async_requests_demo():
371
+ """
372
+ Demonstrate v0.3.2 async requests for parallel agent communication.
373
+
374
+ ask_async() returns a Future that can be awaited later, enabling:
375
+ - Fire multiple requests in parallel
376
+ - Continue other work while waiting
377
+ - Gather results when needed
378
+ """
379
+ print("\n" + "="*70)
380
+ print("v0.3.2 Feature: Async Requests (ask_async)")
381
+ print("="*70)
382
+
383
+ mesh = Mesh(mode="p2p", config={"bind_port": 7966})
384
+
385
+ # Add multiple agents
386
+ mesh.add(ContentResearcherAgent)
387
+ mesh.add(ContentWriterAgent)
388
+ mesh.add(ContentReviewerAgent)
389
+
390
+ try:
391
+ await mesh.start()
392
+
393
+ # Get an agent with peer access
394
+ researcher = next((a for a in mesh.agents if a.role == "content_researcher"), None)
395
+ if not researcher or not researcher.peers:
396
+ print("Peers not available")
397
+ return
398
+
399
+ print("\n[Demo] Firing parallel requests to multiple agents...")
400
+
401
+ # v0.3.2: ask_async returns a Future - doesn't block!
402
+ future1 = researcher.peers.ask_async(
403
+ "content_writer",
404
+ {"question": "What makes good technical writing?"}
405
+ )
406
+ future2 = researcher.peers.ask_async(
407
+ "content_reviewer",
408
+ {"question": "What are common writing mistakes?"}
409
+ )
410
+
411
+ print("[Demo] Requests sent! Doing other work while waiting...")
412
+ await asyncio.sleep(0.1) # Simulate other work
413
+
414
+ # Gather results when ready
415
+ print("[Demo] Gathering results...")
416
+ results = await asyncio.gather(future1, future2, return_exceptions=True)
417
+
418
+ for i, result in enumerate(results):
419
+ if isinstance(result, Exception):
420
+ print(f" Request {i+1}: Error - {result}")
421
+ else:
422
+ print(f" Request {i+1}: Got response")
423
+
424
+ print("\n[Demo] Async requests complete!")
425
+
426
+ finally:
427
+ await mesh.stop()
428
+
429
+
430
+ async def load_balancing_demo():
431
+ """
432
+ Demonstrate v0.3.2 load balancing strategies.
433
+
434
+ When multiple agents have the same capability, use strategy parameter:
435
+ - "random" (default): Random selection
436
+ - "round_robin": Distribute evenly across instances
437
+ """
438
+ print("\n" + "="*70)
439
+ print("v0.3.2 Feature: Load Balancing Strategies")
440
+ print("="*70)
441
+
442
+ mesh = Mesh(mode="p2p", config={"bind_port": 7967})
443
+
444
+ # Add agents
445
+ mesh.add(ContentResearcherAgent)
446
+ mesh.add(ContentWriterAgent)
447
+
448
+ try:
449
+ await mesh.start()
450
+
451
+ researcher = next((a for a in mesh.agents if a.role == "content_researcher"), None)
452
+ if not researcher or not researcher.peers:
453
+ print("Peers not available")
454
+ return
455
+
456
+ print("\n[Demo] Load balancing with strategy='round_robin'")
457
+ print("[Demo] Sending 3 requests to 'writing' capability...")
458
+
459
+ # v0.3.2: Use discover_one() with strategy for load balancing
460
+ for i in range(3):
461
+ # round_robin distributes requests evenly across matching peers
462
+ # First, discover which peer to use with the strategy
463
+ target = researcher.peers.discover_one(
464
+ role="content_writer",
465
+ strategy="round_robin" # v0.3.2: Load balancing
466
+ )
467
+
468
+ if target:
469
+ # Then make the request to that specific peer
470
+ response = await researcher.peers.request(
471
+ target.role,
472
+ {"question": f"Request #{i+1}"},
473
+ timeout=10
474
+ )
475
+ print(f" Request {i+1}: Handled by {target.agent_id[:8]}...")
476
+ else:
477
+ print(f" Request {i+1}: No peer found")
478
+
479
+ print("\n[Demo] Load balancing complete!")
480
+ print("[Demo] In a multi-node setup with multiple writers,")
481
+ print(" round_robin would distribute across all instances.")
482
+
483
+ finally:
484
+ await mesh.stop()
485
+
486
+
361
487
  if __name__ == "__main__":
362
- asyncio.run(main())
488
+ import sys
489
+
490
+ if len(sys.argv) > 1:
491
+ if sys.argv[1] == "--async":
492
+ asyncio.run(async_requests_demo())
493
+ elif sys.argv[1] == "--load-balance":
494
+ asyncio.run(load_balancing_demo())
495
+ else:
496
+ print("Usage:")
497
+ print(" python customagent_distributed_example.py # Main workflow demo")
498
+ print(" python customagent_distributed_example.py --async # Async requests demo")
499
+ print(" python customagent_distributed_example.py --load-balance # Load balancing demo")
500
+ else:
501
+ asyncio.run(main())