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,248 @@
1
+ """
2
+ Tests for CustomAgent profile.
3
+ """
4
+ import pytest
5
+ from jarviscore.profiles.customagent import CustomAgent
6
+
7
+
8
+ class ValidCustomAgent(CustomAgent):
9
+ """Valid CustomAgent with execute_task implementation."""
10
+ role = "test_custom"
11
+ capabilities = ["custom_testing"]
12
+
13
+ async def execute_task(self, task):
14
+ return {
15
+ "status": "success",
16
+ "output": f"Custom result for: {task.get('task', '')}",
17
+ "custom_field": "user_data"
18
+ }
19
+
20
+
21
+ class NoExecuteCustomAgent(CustomAgent):
22
+ """CustomAgent without execute_task (should raise NotImplementedError)."""
23
+ role = "no_execute"
24
+ capabilities = ["testing"]
25
+
26
+
27
+ class TestCustomAgentInitialization:
28
+ """Test CustomAgent initialization."""
29
+
30
+ def test_valid_customagent_creation(self):
31
+ """Test creating a valid CustomAgent."""
32
+ agent = ValidCustomAgent()
33
+
34
+ assert agent.role == "test_custom"
35
+ assert agent.capabilities == ["custom_testing"]
36
+
37
+ def test_customagent_with_custom_attributes(self):
38
+ """Test CustomAgent with user-defined attributes."""
39
+ class APICustomAgent(CustomAgent):
40
+ role = "api_agent"
41
+ capabilities = ["api_calls"]
42
+ api_endpoint = "https://api.example.com"
43
+ api_key = "test-key-123"
44
+
45
+ async def execute_task(self, task):
46
+ return {"status": "success"}
47
+
48
+ agent = APICustomAgent()
49
+
50
+ assert agent.api_endpoint == "https://api.example.com"
51
+ assert agent.api_key == "test-key-123"
52
+
53
+
54
+ class TestCustomAgentSetup:
55
+ """Test CustomAgent setup."""
56
+
57
+ @pytest.mark.asyncio
58
+ async def test_customagent_setup(self):
59
+ """Test CustomAgent setup hook."""
60
+ agent = ValidCustomAgent()
61
+ await agent.setup()
62
+
63
+ # Should run without error
64
+
65
+ @pytest.mark.asyncio
66
+ async def test_customagent_setup_with_framework_initialization(self):
67
+ """Test CustomAgent setup with framework initialization."""
68
+ setup_called = []
69
+
70
+ class FrameworkCustomAgent(CustomAgent):
71
+ role = "framework_agent"
72
+ capabilities = ["framework"]
73
+
74
+ async def setup(self):
75
+ await super().setup()
76
+ # Simulate initializing a framework (e.g., LangChain, MCP)
77
+ setup_called.append("framework_initialized")
78
+
79
+ async def execute_task(self, task):
80
+ return {"status": "success"}
81
+
82
+ agent = FrameworkCustomAgent()
83
+ await agent.setup()
84
+
85
+ assert "framework_initialized" in setup_called
86
+
87
+
88
+ class TestCustomAgentExecution:
89
+ """Test CustomAgent task execution."""
90
+
91
+ @pytest.mark.asyncio
92
+ async def test_execute_task_implementation(self):
93
+ """Test CustomAgent execute_task with user implementation."""
94
+ agent = ValidCustomAgent()
95
+
96
+ task = {"task": "Process data"}
97
+ result = await agent.execute_task(task)
98
+
99
+ assert result["status"] == "success"
100
+ assert "Process data" in result["output"]
101
+ assert result["custom_field"] == "user_data"
102
+
103
+ @pytest.mark.asyncio
104
+ async def test_execute_task_not_implemented_raises_error(self):
105
+ """Test that CustomAgent without execute_task raises NotImplementedError."""
106
+ agent = NoExecuteCustomAgent()
107
+
108
+ task = {"task": "Should fail"}
109
+
110
+ with pytest.raises(NotImplementedError) as exc_info:
111
+ await agent.execute_task(task)
112
+
113
+ assert "must implement execute_task" in str(exc_info.value)
114
+
115
+ @pytest.mark.asyncio
116
+ async def test_execute_task_with_optional_cost_tracking(self):
117
+ """Test CustomAgent returning optional cost tracking fields."""
118
+ class CostTrackingAgent(CustomAgent):
119
+ role = "cost_tracker"
120
+ capabilities = ["tracking"]
121
+
122
+ async def execute_task(self, task):
123
+ return {
124
+ "status": "success",
125
+ "output": "result",
126
+ "tokens_used": 1500,
127
+ "cost_usd": 0.003
128
+ }
129
+
130
+ agent = CostTrackingAgent()
131
+ result = await agent.execute_task({"task": "Track costs"})
132
+
133
+ assert result["tokens_used"] == 1500
134
+ assert result["cost_usd"] == 0.003
135
+
136
+
137
+ class TestCustomAgentFrameworkIntegration:
138
+ """Test CustomAgent with various framework integrations."""
139
+
140
+ @pytest.mark.asyncio
141
+ async def test_langchain_integration_example(self):
142
+ """Test CustomAgent simulating LangChain integration."""
143
+ class LangChainAgent(CustomAgent):
144
+ role = "langchain_agent"
145
+ capabilities = ["langchain"]
146
+
147
+ async def setup(self):
148
+ await super().setup()
149
+ # Simulate LangChain initialization
150
+ self.lc_agent = "mock_langchain_agent"
151
+
152
+ async def execute_task(self, task):
153
+ # Simulate LangChain execution
154
+ return {
155
+ "status": "success",
156
+ "output": f"LangChain result: {task['task']}"
157
+ }
158
+
159
+ agent = LangChainAgent()
160
+ await agent.setup()
161
+
162
+ result = await agent.execute_task({"task": "Query database"})
163
+
164
+ assert result["status"] == "success"
165
+ assert "LangChain result" in result["output"]
166
+
167
+ @pytest.mark.asyncio
168
+ async def test_mcp_integration_example(self):
169
+ """Test CustomAgent simulating MCP integration."""
170
+ class MCPAgent(CustomAgent):
171
+ role = "mcp_agent"
172
+ capabilities = ["mcp_tools"]
173
+ mcp_server_url = "stdio://./server.py"
174
+
175
+ async def setup(self):
176
+ await super().setup()
177
+ # Simulate MCP connection
178
+ self.mcp_client = "mock_mcp_client"
179
+
180
+ async def execute_task(self, task):
181
+ # Simulate MCP tool call
182
+ return {
183
+ "status": "success",
184
+ "data": {"tool": "executed", "params": task.get("params")}
185
+ }
186
+
187
+ agent = MCPAgent()
188
+ await agent.setup()
189
+
190
+ result = await agent.execute_task({
191
+ "task": "Call MCP tool",
192
+ "params": {"arg1": "value1"}
193
+ })
194
+
195
+ assert result["status"] == "success"
196
+ assert result["data"]["tool"] == "executed"
197
+
198
+ @pytest.mark.asyncio
199
+ async def test_raw_python_integration_example(self):
200
+ """Test CustomAgent with raw Python logic."""
201
+ class DataProcessor(CustomAgent):
202
+ role = "processor"
203
+ capabilities = ["data_processing"]
204
+
205
+ async def execute_task(self, task):
206
+ # Pure Python logic
207
+ data = task.get("params", {}).get("data", [])
208
+ processed = [x * 2 for x in data]
209
+ return {
210
+ "status": "success",
211
+ "output": processed
212
+ }
213
+
214
+ agent = DataProcessor()
215
+ result = await agent.execute_task({
216
+ "task": "Double values",
217
+ "params": {"data": [1, 2, 3, 4, 5]}
218
+ })
219
+
220
+ assert result["status"] == "success"
221
+ assert result["output"] == [2, 4, 6, 8, 10]
222
+
223
+
224
+ class TestCustomAgentInheritance:
225
+ """Test CustomAgent inheritance from Profile and Agent."""
226
+
227
+ def test_customagent_inherits_agent_methods(self):
228
+ """Test that CustomAgent inherits Agent methods."""
229
+ agent = ValidCustomAgent()
230
+
231
+ # Should have Agent methods
232
+ assert hasattr(agent, "can_handle")
233
+ assert hasattr(agent, "execute_task")
234
+ assert hasattr(agent, "setup")
235
+ assert hasattr(agent, "teardown")
236
+
237
+ def test_customagent_can_handle_tasks(self):
238
+ """Test that CustomAgent can check task compatibility."""
239
+ agent = ValidCustomAgent()
240
+
241
+ task1 = {"role": "test_custom", "task": "Do something"}
242
+ assert agent.can_handle(task1) is True
243
+
244
+ task2 = {"capability": "custom_testing", "task": "Run tests"}
245
+ assert agent.can_handle(task2) is True
246
+
247
+ task3 = {"role": "different", "task": "Won't handle"}
248
+ assert agent.can_handle(task3) is False
@@ -0,0 +1,293 @@
1
+ """
2
+ Integration tests demonstrating full framework usage.
3
+ """
4
+ import pytest
5
+ from jarviscore import Mesh, AutoAgent, CustomAgent
6
+
7
+
8
+ # Example agents for integration testing
9
+ class ScraperAgent(CustomAgent):
10
+ """Web scraper agent using CustomAgent profile (mocked for testing)."""
11
+ role = "scraper"
12
+ capabilities = ["web_scraping", "data_extraction"]
13
+
14
+ async def execute_task(self, task):
15
+ # Mock scraper for integration testing
16
+ return {
17
+ "status": "success",
18
+ "output": {
19
+ "url": "example.com",
20
+ "products": ["Product A", "Product B", "Product C"]
21
+ },
22
+ "tokens_used": 0,
23
+ "cost_usd": 0.0
24
+ }
25
+
26
+
27
+ class ProcessorAgent(CustomAgent):
28
+ """Data processor using CustomAgent profile."""
29
+ role = "processor"
30
+ capabilities = ["data_processing", "transformation"]
31
+
32
+ async def execute_task(self, task):
33
+ # Simulate data processing
34
+ data = task.get("params", {}).get("data", [])
35
+ processed = [x.upper() if isinstance(x, str) else x * 2 for x in data]
36
+
37
+ return {
38
+ "status": "success",
39
+ "output": processed,
40
+ "tokens_used": 0, # No LLM usage
41
+ "cost_usd": 0.0
42
+ }
43
+
44
+
45
+ class StorageAgent(CustomAgent):
46
+ """Storage agent for saving results."""
47
+ role = "storage"
48
+ capabilities = ["database", "file_storage"]
49
+
50
+ def __init__(self, *args, **kwargs):
51
+ super().__init__(*args, **kwargs)
52
+ self.stored_data = [] # Mock storage
53
+
54
+ async def execute_task(self, task):
55
+ data = task.get("params", {}).get("data")
56
+ self.stored_data.append(data)
57
+
58
+ return {
59
+ "status": "success",
60
+ "output": f"Stored {len(self.stored_data)} record(s)",
61
+ "records_stored": len(self.stored_data)
62
+ }
63
+
64
+
65
+ class TestBasicIntegration:
66
+ """Test basic framework integration."""
67
+
68
+ @pytest.mark.asyncio
69
+ async def test_single_agent_workflow(self):
70
+ """Test workflow with single agent."""
71
+ mesh = Mesh(mode="autonomous")
72
+ mesh.add(ScraperAgent)
73
+
74
+ await mesh.start()
75
+
76
+ results = await mesh.workflow("simple-scrape", [
77
+ {
78
+ "agent": "scraper",
79
+ "task": "Scrape example.com for product data"
80
+ }
81
+ ])
82
+
83
+ assert len(results) == 1
84
+ assert results[0]["status"] == "success"
85
+
86
+ await mesh.stop()
87
+
88
+ @pytest.mark.asyncio
89
+ async def test_multi_agent_workflow(self):
90
+ """Test workflow with multiple agents."""
91
+ mesh = Mesh(mode="autonomous")
92
+ mesh.add(ScraperAgent)
93
+ mesh.add(ProcessorAgent)
94
+ mesh.add(StorageAgent)
95
+
96
+ await mesh.start()
97
+
98
+ results = await mesh.workflow("scrape-process-store", [
99
+ {
100
+ "agent": "scraper",
101
+ "task": "Scrape example.com"
102
+ },
103
+ {
104
+ "agent": "processor",
105
+ "task": "Process scraped data",
106
+ "params": {"data": ["hello", "world"]}
107
+ },
108
+ {
109
+ "agent": "storage",
110
+ "task": "Save processed data",
111
+ "params": {"data": ["HELLO", "WORLD"]}
112
+ }
113
+ ])
114
+
115
+ assert len(results) == 3
116
+ assert all(r["status"] == "success" for r in results)
117
+
118
+ await mesh.stop()
119
+
120
+
121
+ class TestMixedProfileIntegration:
122
+ """Test integration of AutoAgent and CustomAgent profiles."""
123
+
124
+ @pytest.mark.asyncio
125
+ async def test_auto_and_custom_agents_together(self):
126
+ """Test that AutoAgent and CustomAgent work together."""
127
+ mesh = Mesh(mode="autonomous")
128
+
129
+ # Add AutoAgent
130
+ scraper = mesh.add(ScraperAgent)
131
+
132
+ # Add CustomAgent
133
+ processor = mesh.add(ProcessorAgent)
134
+
135
+ await mesh.start()
136
+
137
+ # Verify both agents are registered
138
+ assert mesh.get_agent("scraper") == scraper
139
+ assert mesh.get_agent("processor") == processor
140
+
141
+ # Execute workflow using both
142
+ results = await mesh.workflow("mixed-workflow", [
143
+ {"agent": "scraper", "task": "Scrape data"},
144
+ {"agent": "processor", "task": "Process", "params": {"data": [1, 2, 3]}}
145
+ ])
146
+
147
+ assert len(results) == 2
148
+ assert results[0]["status"] == "success"
149
+ assert results[1]["status"] == "success"
150
+
151
+ await mesh.stop()
152
+
153
+
154
+ class TestCapabilityRouting:
155
+ """Test task routing by capabilities."""
156
+
157
+ @pytest.mark.asyncio
158
+ async def test_route_by_capability(self):
159
+ """Test that tasks are routed by capability."""
160
+ mesh = Mesh(mode="autonomous")
161
+ mesh.add(ProcessorAgent)
162
+
163
+ await mesh.start()
164
+
165
+ # Route by capability instead of role
166
+ results = await mesh.workflow("capability-routing", [
167
+ {
168
+ "agent": "data_processing", # Capability, not role
169
+ "task": "Process this data",
170
+ "params": {"data": [10, 20, 30]}
171
+ }
172
+ ])
173
+
174
+ assert len(results) == 1
175
+ assert results[0]["status"] == "success"
176
+ assert results[0]["output"] == [20, 40, 60] # Doubled
177
+
178
+ await mesh.stop()
179
+
180
+
181
+ class TestAgentStateAndCustomization:
182
+ """Test agent state management and customization."""
183
+
184
+ @pytest.mark.asyncio
185
+ async def test_agent_maintains_state_across_tasks(self):
186
+ """Test that CustomAgent can maintain state across multiple tasks."""
187
+ mesh = Mesh(mode="autonomous")
188
+ storage = mesh.add(StorageAgent)
189
+
190
+ await mesh.start()
191
+
192
+ # Execute multiple storage tasks
193
+ await mesh.workflow("multi-store", [
194
+ {"agent": "storage", "task": "Store item 1", "params": {"data": "item1"}},
195
+ {"agent": "storage", "task": "Store item 2", "params": {"data": "item2"}},
196
+ {"agent": "storage", "task": "Store item 3", "params": {"data": "item3"}},
197
+ ])
198
+
199
+ # Verify storage agent maintained state
200
+ assert len(storage.stored_data) == 3
201
+ assert storage.stored_data == ["item1", "item2", "item3"]
202
+
203
+ await mesh.stop()
204
+
205
+
206
+ class TestErrorHandling:
207
+ """Test error handling in workflows."""
208
+
209
+ @pytest.mark.asyncio
210
+ async def test_missing_agent_error(self):
211
+ """Test workflow with missing agent."""
212
+ mesh = Mesh(mode="autonomous")
213
+ mesh.add(ProcessorAgent)
214
+
215
+ await mesh.start()
216
+
217
+ results = await mesh.workflow("missing-agent", [
218
+ {
219
+ "agent": "nonexistent_agent",
220
+ "task": "Should fail"
221
+ }
222
+ ])
223
+
224
+ assert len(results) == 1
225
+ assert results[0]["status"] == "failure"
226
+ assert "No agent found" in results[0]["error"]
227
+
228
+ await mesh.stop()
229
+
230
+
231
+ class TestRealWorldScenario:
232
+ """Test real-world usage scenarios."""
233
+
234
+ @pytest.mark.asyncio
235
+ async def test_data_pipeline_scenario(self):
236
+ """Test complete data pipeline: scrape → process → store."""
237
+ mesh = Mesh(mode="autonomous")
238
+ mesh.add(ScraperAgent)
239
+ mesh.add(ProcessorAgent)
240
+ storage = mesh.add(StorageAgent)
241
+
242
+ await mesh.start()
243
+
244
+ # Simulate data pipeline
245
+ results = await mesh.workflow("data-pipeline", [
246
+ {
247
+ "agent": "scraper",
248
+ "task": "Scrape example.com for products"
249
+ },
250
+ {
251
+ "agent": "processor",
252
+ "task": "Clean and normalize product data",
253
+ "params": {"data": ["product-a", "product-b", "product-c"]},
254
+ "depends_on": [0]
255
+ },
256
+ {
257
+ "agent": "storage",
258
+ "task": "Save to database",
259
+ "params": {"data": ["PRODUCT-A", "PRODUCT-B", "PRODUCT-C"]},
260
+ "depends_on": [1]
261
+ }
262
+ ])
263
+
264
+ # Verify all steps succeeded
265
+ assert len(results) == 3
266
+ assert all(r["status"] == "success" for r in results)
267
+
268
+ # Verify data was stored
269
+ assert len(storage.stored_data) == 1
270
+ assert storage.stored_data[0] == ["PRODUCT-A", "PRODUCT-B", "PRODUCT-C"]
271
+
272
+ await mesh.stop()
273
+
274
+ @pytest.mark.asyncio
275
+ async def test_agent_discovery_by_capability(self):
276
+ """Test that mesh can discover agents by capability."""
277
+ mesh = Mesh(mode="autonomous")
278
+ mesh.add(ScraperAgent)
279
+ mesh.add(ProcessorAgent)
280
+ mesh.add(StorageAgent)
281
+
282
+ # Test capability indexing
283
+ scrapers = mesh.get_agents_by_capability("web_scraping")
284
+ assert len(scrapers) == 1
285
+ assert scrapers[0].role == "scraper"
286
+
287
+ processors = mesh.get_agents_by_capability("data_processing")
288
+ assert len(processors) == 1
289
+ assert processors[0].role == "processor"
290
+
291
+ storage_agents = mesh.get_agents_by_capability("database")
292
+ assert len(storage_agents) == 1
293
+ assert storage_agents[0].role == "storage"