jarviscore-framework 0.2.0__py3-none-any.whl → 0.3.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 (36) hide show
  1. examples/cloud_deployment_example.py +162 -0
  2. examples/customagent_p2p_example.py +566 -183
  3. examples/fastapi_integration_example.py +570 -0
  4. examples/listeneragent_cognitive_discovery_example.py +343 -0
  5. jarviscore/__init__.py +22 -5
  6. jarviscore/cli/smoketest.py +8 -4
  7. jarviscore/core/agent.py +227 -0
  8. jarviscore/data/examples/cloud_deployment_example.py +162 -0
  9. jarviscore/data/examples/customagent_p2p_example.py +566 -183
  10. jarviscore/data/examples/fastapi_integration_example.py +570 -0
  11. jarviscore/data/examples/listeneragent_cognitive_discovery_example.py +343 -0
  12. jarviscore/docs/API_REFERENCE.md +296 -3
  13. jarviscore/docs/CHANGELOG.md +97 -0
  14. jarviscore/docs/CONFIGURATION.md +2 -2
  15. jarviscore/docs/CUSTOMAGENT_GUIDE.md +2021 -255
  16. jarviscore/docs/GETTING_STARTED.md +112 -8
  17. jarviscore/docs/TROUBLESHOOTING.md +3 -3
  18. jarviscore/docs/USER_GUIDE.md +152 -6
  19. jarviscore/integrations/__init__.py +16 -0
  20. jarviscore/integrations/fastapi.py +247 -0
  21. jarviscore/p2p/broadcaster.py +10 -3
  22. jarviscore/p2p/coordinator.py +310 -14
  23. jarviscore/p2p/keepalive.py +45 -23
  24. jarviscore/p2p/peer_client.py +282 -10
  25. jarviscore/p2p/swim_manager.py +9 -4
  26. jarviscore/profiles/__init__.py +10 -2
  27. jarviscore/profiles/listeneragent.py +292 -0
  28. {jarviscore_framework-0.2.0.dist-info → jarviscore_framework-0.3.0.dist-info}/METADATA +42 -8
  29. {jarviscore_framework-0.2.0.dist-info → jarviscore_framework-0.3.0.dist-info}/RECORD +36 -22
  30. {jarviscore_framework-0.2.0.dist-info → jarviscore_framework-0.3.0.dist-info}/WHEEL +1 -1
  31. tests/test_13_dx_improvements.py +554 -0
  32. tests/test_14_cloud_deployment.py +403 -0
  33. tests/test_15_llm_cognitive_discovery.py +684 -0
  34. tests/test_16_unified_dx_flow.py +947 -0
  35. {jarviscore_framework-0.2.0.dist-info → jarviscore_framework-0.3.0.dist-info}/licenses/LICENSE +0 -0
  36. {jarviscore_framework-0.2.0.dist-info → jarviscore_framework-0.3.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,162 @@
1
+ """
2
+ Cloud Deployment Example (v0.3.0)
3
+
4
+ Demonstrates agent self-registration with join_mesh() and leave_mesh().
5
+ Agents join an existing mesh independently - no central orchestrator needed.
6
+
7
+ This is the pattern for:
8
+ - Docker containers where each container runs one agent
9
+ - Kubernetes pods with auto-scaling
10
+ - Cloud Functions / Lambda
11
+ - Any distributed deployment where agents start independently
12
+
13
+ Usage:
14
+ # Terminal 1: Start a mesh (or use an existing one)
15
+ python examples/customagent_p2p_example.py
16
+
17
+ # Terminal 2: Run standalone agent that joins the mesh
18
+ JARVISCORE_SEED_NODES=127.0.0.1:7946 python examples/cloud_deployment_example.py
19
+
20
+ Environment Variables:
21
+ JARVISCORE_SEED_NODES: Comma-separated seed nodes (e.g., "host1:7946,host2:7946")
22
+ JARVISCORE_MESH_ENDPOINT: Single mesh endpoint (alternative to seed_nodes)
23
+ """
24
+ import asyncio
25
+ import os
26
+ import signal
27
+ import sys
28
+
29
+ sys.path.insert(0, '.')
30
+
31
+ from jarviscore.profiles import ListenerAgent
32
+
33
+
34
+ class StandaloneProcessor(ListenerAgent):
35
+ """
36
+ Example standalone agent that joins mesh independently.
37
+
38
+ This agent:
39
+ - Self-registers with the mesh on startup
40
+ - Listens for peer requests
41
+ - Shows its view of the mesh (cognitive context)
42
+ - Gracefully leaves mesh on shutdown
43
+ """
44
+
45
+ role = "standalone_processor"
46
+ capabilities = ["standalone", "processing", "example"]
47
+ description = "Processes requests from other mesh agents (standalone deployment)"
48
+
49
+ async def on_peer_request(self, msg):
50
+ """Handle incoming requests from other agents."""
51
+ print(f"\n[{self.role}] Received request from {msg.sender}:")
52
+ print(f" Data: {msg.data}")
53
+
54
+ # Process the request
55
+ task = msg.data.get("task", "")
56
+ result = {
57
+ "status": "success",
58
+ "output": f"Processed: {task}",
59
+ "agent_id": self.agent_id,
60
+ "processed_by": self.role
61
+ }
62
+
63
+ print(f"[{self.role}] Sending response: {result}")
64
+ return result
65
+
66
+ async def on_peer_notify(self, msg):
67
+ """Handle incoming notifications from other agents."""
68
+ print(f"\n[{self.role}] Received notification from {msg.sender}:")
69
+ print(f" Event: {msg.data.get('event', 'unknown')}")
70
+ print(f" Data: {msg.data}")
71
+
72
+
73
+ async def main():
74
+ print("=" * 60)
75
+ print("Standalone Agent Example - Cloud Deployment Pattern")
76
+ print("=" * 60)
77
+
78
+ # Check for mesh connection info
79
+ endpoint = os.environ.get("JARVISCORE_MESH_ENDPOINT")
80
+ seed_nodes = os.environ.get("JARVISCORE_SEED_NODES")
81
+
82
+ if not endpoint and not seed_nodes:
83
+ print("\nNo mesh endpoint configured!")
84
+ print("\nSet one of:")
85
+ print(" - JARVISCORE_MESH_ENDPOINT (single endpoint)")
86
+ print(" - JARVISCORE_SEED_NODES (comma-separated list)")
87
+ print("\nExample:")
88
+ print(" JARVISCORE_SEED_NODES=127.0.0.1:7946 python cloud_deployment_example.py")
89
+ print("\nTo start a mesh first, run:")
90
+ print(" python examples/customagent_p2p_example.py")
91
+ return
92
+
93
+ print(f"\nConnecting to mesh via: {endpoint or seed_nodes}")
94
+
95
+ # Create agent
96
+ agent = StandaloneProcessor()
97
+
98
+ # Join the mesh
99
+ print(f"\nJoining mesh...")
100
+ try:
101
+ await agent.join_mesh()
102
+ except Exception as e:
103
+ print(f"Failed to join mesh: {e}")
104
+ return
105
+
106
+ print(f"\nSuccessfully joined mesh!")
107
+ print(f" Agent ID: {agent.agent_id}")
108
+ print(f" Role: {agent.role}")
109
+ print(f" Capabilities: {agent.capabilities}")
110
+
111
+ # Show discovered peers
112
+ print(f"\n--- Discovered Peers ---")
113
+ peers = agent.peers.list_peers()
114
+ if peers:
115
+ for p in peers:
116
+ location = f" ({p.get('location', 'unknown')})" if 'location' in p else ""
117
+ print(f" - {p['role']}: {p['capabilities']}{location}")
118
+ else:
119
+ print(" No other peers discovered yet")
120
+
121
+ # Show cognitive context (what an LLM would see)
122
+ print(f"\n--- Cognitive Context for LLM ---")
123
+ print(agent.peers.get_cognitive_context())
124
+
125
+ # Setup graceful shutdown
126
+ shutdown_event = asyncio.Event()
127
+
128
+ def signal_handler():
129
+ print("\n\nShutdown requested (Ctrl+C)...")
130
+ agent.request_shutdown()
131
+ shutdown_event.set()
132
+
133
+ # Register signal handlers
134
+ loop = asyncio.get_event_loop()
135
+ for sig in (signal.SIGINT, signal.SIGTERM):
136
+ try:
137
+ loop.add_signal_handler(sig, signal_handler)
138
+ except NotImplementedError:
139
+ # Windows doesn't support add_signal_handler
140
+ pass
141
+
142
+ print(f"\n--- Agent Running ---")
143
+ print("Listening for peer requests...")
144
+ print("Press Ctrl+C to stop.\n")
145
+
146
+ # Run agent (ListenerAgent's run() handles the message loop)
147
+ try:
148
+ await agent.run()
149
+ except asyncio.CancelledError:
150
+ pass
151
+
152
+ # Leave mesh gracefully
153
+ print("\nLeaving mesh...")
154
+ await agent.leave_mesh()
155
+ print("Goodbye!")
156
+
157
+
158
+ if __name__ == "__main__":
159
+ try:
160
+ asyncio.run(main())
161
+ except KeyboardInterrupt:
162
+ print("\nInterrupted.")