kubiya-control-plane-api 0.1.0__py3-none-any.whl → 0.3.4__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.
Potentially problematic release.
This version of kubiya-control-plane-api might be problematic. Click here for more details.
- control_plane_api/README.md +266 -0
- control_plane_api/__init__.py +0 -0
- control_plane_api/__version__.py +1 -0
- control_plane_api/alembic/README +1 -0
- control_plane_api/alembic/env.py +98 -0
- control_plane_api/alembic/script.py.mako +28 -0
- control_plane_api/alembic/versions/1382bec74309_initial_migration_with_all_models.py +251 -0
- control_plane_api/alembic/versions/1f54bc2a37e3_add_analytics_tables.py +162 -0
- control_plane_api/alembic/versions/2e4cb136dc10_rename_toolset_ids_to_skill_ids_in_teams.py +30 -0
- control_plane_api/alembic/versions/31cd69a644ce_add_skill_templates_table.py +28 -0
- control_plane_api/alembic/versions/89e127caa47d_add_jobs_and_job_executions_tables.py +161 -0
- control_plane_api/alembic/versions/add_llm_models_table.py +51 -0
- control_plane_api/alembic/versions/b0e10697f212_add_runtime_column_to_teams_simple.py +42 -0
- control_plane_api/alembic/versions/ce43b24b63bf_add_execution_trigger_source_and_fix_.py +155 -0
- control_plane_api/alembic/versions/d4eaf16e3f8d_rename_toolsets_to_skills.py +84 -0
- control_plane_api/alembic/versions/efa2dc427da1_rename_metadata_to_custom_metadata.py +32 -0
- control_plane_api/alembic/versions/f973b431d1ce_add_workflow_executor_to_skill_types.py +44 -0
- control_plane_api/alembic.ini +148 -0
- control_plane_api/api/index.py +12 -0
- control_plane_api/app/__init__.py +11 -0
- control_plane_api/app/activities/__init__.py +20 -0
- control_plane_api/app/activities/agent_activities.py +379 -0
- control_plane_api/app/activities/team_activities.py +410 -0
- control_plane_api/app/activities/temporal_cloud_activities.py +577 -0
- control_plane_api/app/config/__init__.py +35 -0
- control_plane_api/app/config/api_config.py +354 -0
- control_plane_api/app/config/model_pricing.py +318 -0
- control_plane_api/app/config.py +95 -0
- control_plane_api/app/database.py +135 -0
- control_plane_api/app/exceptions.py +408 -0
- control_plane_api/app/lib/__init__.py +11 -0
- control_plane_api/app/lib/job_executor.py +312 -0
- control_plane_api/app/lib/kubiya_client.py +235 -0
- control_plane_api/app/lib/litellm_pricing.py +166 -0
- control_plane_api/app/lib/planning_tools/__init__.py +22 -0
- control_plane_api/app/lib/planning_tools/agents.py +155 -0
- control_plane_api/app/lib/planning_tools/base.py +189 -0
- control_plane_api/app/lib/planning_tools/environments.py +214 -0
- control_plane_api/app/lib/planning_tools/resources.py +240 -0
- control_plane_api/app/lib/planning_tools/teams.py +198 -0
- control_plane_api/app/lib/policy_enforcer_client.py +939 -0
- control_plane_api/app/lib/redis_client.py +436 -0
- control_plane_api/app/lib/supabase.py +71 -0
- control_plane_api/app/lib/temporal_client.py +138 -0
- control_plane_api/app/lib/validation/__init__.py +20 -0
- control_plane_api/app/lib/validation/runtime_validation.py +287 -0
- control_plane_api/app/main.py +128 -0
- control_plane_api/app/middleware/__init__.py +8 -0
- control_plane_api/app/middleware/auth.py +513 -0
- control_plane_api/app/middleware/exception_handler.py +267 -0
- control_plane_api/app/middleware/rate_limiting.py +384 -0
- control_plane_api/app/middleware/request_id.py +202 -0
- control_plane_api/app/models/__init__.py +27 -0
- control_plane_api/app/models/agent.py +79 -0
- control_plane_api/app/models/analytics.py +206 -0
- control_plane_api/app/models/associations.py +81 -0
- control_plane_api/app/models/environment.py +63 -0
- control_plane_api/app/models/execution.py +93 -0
- control_plane_api/app/models/job.py +179 -0
- control_plane_api/app/models/llm_model.py +75 -0
- control_plane_api/app/models/presence.py +49 -0
- control_plane_api/app/models/project.py +47 -0
- control_plane_api/app/models/session.py +38 -0
- control_plane_api/app/models/team.py +66 -0
- control_plane_api/app/models/workflow.py +55 -0
- control_plane_api/app/policies/README.md +121 -0
- control_plane_api/app/policies/approved_users.rego +62 -0
- control_plane_api/app/policies/business_hours.rego +51 -0
- control_plane_api/app/policies/rate_limiting.rego +100 -0
- control_plane_api/app/policies/tool_restrictions.rego +86 -0
- control_plane_api/app/routers/__init__.py +4 -0
- control_plane_api/app/routers/agents.py +364 -0
- control_plane_api/app/routers/agents_v2.py +1260 -0
- control_plane_api/app/routers/analytics.py +1014 -0
- control_plane_api/app/routers/context_manager.py +562 -0
- control_plane_api/app/routers/environment_context.py +270 -0
- control_plane_api/app/routers/environments.py +715 -0
- control_plane_api/app/routers/execution_environment.py +517 -0
- control_plane_api/app/routers/executions.py +1911 -0
- control_plane_api/app/routers/health.py +92 -0
- control_plane_api/app/routers/health_v2.py +326 -0
- control_plane_api/app/routers/integrations.py +274 -0
- control_plane_api/app/routers/jobs.py +1344 -0
- control_plane_api/app/routers/models.py +82 -0
- control_plane_api/app/routers/models_v2.py +361 -0
- control_plane_api/app/routers/policies.py +639 -0
- control_plane_api/app/routers/presence.py +234 -0
- control_plane_api/app/routers/projects.py +902 -0
- control_plane_api/app/routers/runners.py +379 -0
- control_plane_api/app/routers/runtimes.py +172 -0
- control_plane_api/app/routers/secrets.py +155 -0
- control_plane_api/app/routers/skills.py +1001 -0
- control_plane_api/app/routers/skills_definitions.py +140 -0
- control_plane_api/app/routers/task_planning.py +1256 -0
- control_plane_api/app/routers/task_queues.py +654 -0
- control_plane_api/app/routers/team_context.py +270 -0
- control_plane_api/app/routers/teams.py +1400 -0
- control_plane_api/app/routers/worker_queues.py +1545 -0
- control_plane_api/app/routers/workers.py +935 -0
- control_plane_api/app/routers/workflows.py +204 -0
- control_plane_api/app/runtimes/__init__.py +6 -0
- control_plane_api/app/runtimes/validation.py +344 -0
- control_plane_api/app/schemas/job_schemas.py +295 -0
- control_plane_api/app/services/__init__.py +1 -0
- control_plane_api/app/services/agno_service.py +619 -0
- control_plane_api/app/services/litellm_service.py +190 -0
- control_plane_api/app/services/policy_service.py +525 -0
- control_plane_api/app/services/temporal_cloud_provisioning.py +150 -0
- control_plane_api/app/skills/__init__.py +44 -0
- control_plane_api/app/skills/base.py +229 -0
- control_plane_api/app/skills/business_intelligence.py +189 -0
- control_plane_api/app/skills/data_visualization.py +154 -0
- control_plane_api/app/skills/docker.py +104 -0
- control_plane_api/app/skills/file_generation.py +94 -0
- control_plane_api/app/skills/file_system.py +110 -0
- control_plane_api/app/skills/python.py +92 -0
- control_plane_api/app/skills/registry.py +65 -0
- control_plane_api/app/skills/shell.py +102 -0
- control_plane_api/app/skills/workflow_executor.py +469 -0
- control_plane_api/app/utils/workflow_executor.py +354 -0
- control_plane_api/app/workflows/__init__.py +11 -0
- control_plane_api/app/workflows/agent_execution.py +507 -0
- control_plane_api/app/workflows/agent_execution_with_skills.py +222 -0
- control_plane_api/app/workflows/namespace_provisioning.py +326 -0
- control_plane_api/app/workflows/team_execution.py +399 -0
- control_plane_api/scripts/seed_models.py +239 -0
- control_plane_api/worker/__init__.py +0 -0
- control_plane_api/worker/activities/__init__.py +0 -0
- control_plane_api/worker/activities/agent_activities.py +1241 -0
- control_plane_api/worker/activities/approval_activities.py +234 -0
- control_plane_api/worker/activities/runtime_activities.py +388 -0
- control_plane_api/worker/activities/skill_activities.py +267 -0
- control_plane_api/worker/activities/team_activities.py +1217 -0
- control_plane_api/worker/config/__init__.py +31 -0
- control_plane_api/worker/config/worker_config.py +275 -0
- control_plane_api/worker/control_plane_client.py +529 -0
- control_plane_api/worker/examples/analytics_integration_example.py +362 -0
- control_plane_api/worker/models/__init__.py +1 -0
- control_plane_api/worker/models/inputs.py +89 -0
- control_plane_api/worker/runtimes/__init__.py +31 -0
- control_plane_api/worker/runtimes/base.py +789 -0
- control_plane_api/worker/runtimes/claude_code_runtime.py +1443 -0
- control_plane_api/worker/runtimes/default_runtime.py +617 -0
- control_plane_api/worker/runtimes/factory.py +173 -0
- control_plane_api/worker/runtimes/validation.py +93 -0
- control_plane_api/worker/services/__init__.py +1 -0
- control_plane_api/worker/services/agent_executor.py +422 -0
- control_plane_api/worker/services/agent_executor_v2.py +383 -0
- control_plane_api/worker/services/analytics_collector.py +457 -0
- control_plane_api/worker/services/analytics_service.py +464 -0
- control_plane_api/worker/services/approval_tools.py +310 -0
- control_plane_api/worker/services/approval_tools_agno.py +207 -0
- control_plane_api/worker/services/cancellation_manager.py +177 -0
- control_plane_api/worker/services/data_visualization.py +827 -0
- control_plane_api/worker/services/jira_tools.py +257 -0
- control_plane_api/worker/services/runtime_analytics.py +328 -0
- control_plane_api/worker/services/session_service.py +194 -0
- control_plane_api/worker/services/skill_factory.py +175 -0
- control_plane_api/worker/services/team_executor.py +574 -0
- control_plane_api/worker/services/team_executor_v2.py +465 -0
- control_plane_api/worker/services/workflow_executor_tools.py +1418 -0
- control_plane_api/worker/tests/__init__.py +1 -0
- control_plane_api/worker/tests/e2e/__init__.py +0 -0
- control_plane_api/worker/tests/e2e/test_execution_flow.py +571 -0
- control_plane_api/worker/tests/integration/__init__.py +0 -0
- control_plane_api/worker/tests/integration/test_control_plane_integration.py +308 -0
- control_plane_api/worker/tests/unit/__init__.py +0 -0
- control_plane_api/worker/tests/unit/test_control_plane_client.py +401 -0
- control_plane_api/worker/utils/__init__.py +1 -0
- control_plane_api/worker/utils/chunk_batcher.py +305 -0
- control_plane_api/worker/utils/retry_utils.py +60 -0
- control_plane_api/worker/utils/streaming_utils.py +373 -0
- control_plane_api/worker/worker.py +753 -0
- control_plane_api/worker/workflows/__init__.py +0 -0
- control_plane_api/worker/workflows/agent_execution.py +589 -0
- control_plane_api/worker/workflows/team_execution.py +429 -0
- kubiya_control_plane_api-0.3.4.dist-info/METADATA +229 -0
- kubiya_control_plane_api-0.3.4.dist-info/RECORD +182 -0
- kubiya_control_plane_api-0.3.4.dist-info/entry_points.txt +2 -0
- kubiya_control_plane_api-0.3.4.dist-info/top_level.txt +1 -0
- kubiya_control_plane_api-0.1.0.dist-info/METADATA +0 -66
- kubiya_control_plane_api-0.1.0.dist-info/RECORD +0 -5
- kubiya_control_plane_api-0.1.0.dist-info/top_level.txt +0 -1
- {kubiya_control_plane_api-0.1.0.dist-info/licenses → control_plane_api}/LICENSE +0 -0
- {kubiya_control_plane_api-0.1.0.dist-info → kubiya_control_plane_api-0.3.4.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
"""Integration tests for Control Plane client integration with activities"""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
import os
|
|
5
|
+
from unittest.mock import Mock, patch, MagicMock
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
import sys
|
|
8
|
+
|
|
9
|
+
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
|
10
|
+
|
|
11
|
+
from control_plane_api.worker.control_plane_client import ControlPlaneClient, get_control_plane_client
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TestControlPlaneIntegration:
|
|
15
|
+
"""Test integration between Control Plane client and activity modules"""
|
|
16
|
+
|
|
17
|
+
@pytest.fixture
|
|
18
|
+
def mock_http_server(self):
|
|
19
|
+
"""Mock HTTP responses from Control Plane"""
|
|
20
|
+
with patch('control_plane_client.httpx.Client') as mock_client_class:
|
|
21
|
+
mock_client = MagicMock()
|
|
22
|
+
mock_client_class.return_value = mock_client
|
|
23
|
+
yield mock_client
|
|
24
|
+
|
|
25
|
+
def test_client_can_publish_events(self, mock_http_server):
|
|
26
|
+
"""Test that client can successfully publish events to Control Plane"""
|
|
27
|
+
client = ControlPlaneClient(
|
|
28
|
+
base_url="http://localhost:8000",
|
|
29
|
+
api_key="test_key"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# Mock successful response
|
|
33
|
+
mock_response = Mock()
|
|
34
|
+
mock_response.status_code = 200
|
|
35
|
+
mock_http_server.post = Mock(return_value=mock_response)
|
|
36
|
+
|
|
37
|
+
# Publish event
|
|
38
|
+
result = client.publish_event(
|
|
39
|
+
execution_id="exec_123",
|
|
40
|
+
event_type="message_chunk",
|
|
41
|
+
data={"content": "test"}
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
assert result is True
|
|
45
|
+
assert mock_http_server.post.called
|
|
46
|
+
|
|
47
|
+
def test_client_can_cache_metadata(self, mock_http_server):
|
|
48
|
+
"""Test that client can cache execution metadata"""
|
|
49
|
+
client = ControlPlaneClient(
|
|
50
|
+
base_url="http://localhost:8000",
|
|
51
|
+
api_key="test_key"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
# Mock successful response
|
|
55
|
+
mock_response = Mock()
|
|
56
|
+
mock_response.status_code = 202
|
|
57
|
+
mock_http_server.post = Mock(return_value=mock_response)
|
|
58
|
+
|
|
59
|
+
# Cache metadata
|
|
60
|
+
result = client.cache_metadata(
|
|
61
|
+
execution_id="exec_123",
|
|
62
|
+
execution_type="AGENT"
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
assert result is True
|
|
66
|
+
|
|
67
|
+
def test_client_can_persist_session(self, mock_http_server):
|
|
68
|
+
"""Test that client can persist session history"""
|
|
69
|
+
client = ControlPlaneClient(
|
|
70
|
+
base_url="http://localhost:8000",
|
|
71
|
+
api_key="test_key"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Mock successful response
|
|
75
|
+
mock_response = Mock()
|
|
76
|
+
mock_response.status_code = 201
|
|
77
|
+
mock_http_server.post = Mock(return_value=mock_response)
|
|
78
|
+
|
|
79
|
+
# Persist session
|
|
80
|
+
messages = [
|
|
81
|
+
{"role": "user", "content": "Hello"},
|
|
82
|
+
{"role": "assistant", "content": "Hi!"}
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
result = client.persist_session(
|
|
86
|
+
execution_id="exec_123",
|
|
87
|
+
session_id="session_456",
|
|
88
|
+
user_id="user_789",
|
|
89
|
+
messages=messages
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
assert result is True
|
|
93
|
+
|
|
94
|
+
def test_client_can_fetch_skills(self, mock_http_server):
|
|
95
|
+
"""Test that client can fetch skills from Control Plane"""
|
|
96
|
+
client = ControlPlaneClient(
|
|
97
|
+
base_url="http://localhost:8000",
|
|
98
|
+
api_key="test_key"
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Mock successful response with skills
|
|
102
|
+
mock_response = Mock()
|
|
103
|
+
mock_response.status_code = 200
|
|
104
|
+
mock_response.json = Mock(return_value=[
|
|
105
|
+
{"type": "file_system", "name": "File Tools", "enabled": True},
|
|
106
|
+
{"type": "shell", "name": "Shell Tools", "enabled": True}
|
|
107
|
+
])
|
|
108
|
+
mock_http_server.get = Mock(return_value=mock_response)
|
|
109
|
+
|
|
110
|
+
# Fetch skills
|
|
111
|
+
skills = client.get_skills(agent_id="agent_123")
|
|
112
|
+
|
|
113
|
+
assert len(skills) == 2
|
|
114
|
+
assert skills[0]["type"] == "file_system"
|
|
115
|
+
|
|
116
|
+
def test_client_handles_connection_errors_gracefully(self, mock_http_server):
|
|
117
|
+
"""Test that client handles connection errors without crashing"""
|
|
118
|
+
client = ControlPlaneClient(
|
|
119
|
+
base_url="http://localhost:8000",
|
|
120
|
+
api_key="test_key"
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# Mock connection error
|
|
124
|
+
import httpx
|
|
125
|
+
mock_http_server.post = Mock(side_effect=httpx.ConnectError("Connection failed"))
|
|
126
|
+
|
|
127
|
+
# Should not raise exception
|
|
128
|
+
result = client.publish_event(
|
|
129
|
+
execution_id="exec_123",
|
|
130
|
+
event_type="message_chunk",
|
|
131
|
+
data={"content": "test"}
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
assert result is False
|
|
135
|
+
|
|
136
|
+
def test_client_handles_timeout_errors_gracefully(self, mock_http_server):
|
|
137
|
+
"""Test that client handles timeout errors without crashing"""
|
|
138
|
+
client = ControlPlaneClient(
|
|
139
|
+
base_url="http://localhost:8000",
|
|
140
|
+
api_key="test_key"
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
# Mock timeout error
|
|
144
|
+
import httpx
|
|
145
|
+
mock_http_server.post = Mock(side_effect=httpx.TimeoutException("Timeout"))
|
|
146
|
+
|
|
147
|
+
# Should not raise exception
|
|
148
|
+
result = client.publish_event(
|
|
149
|
+
execution_id="exec_123",
|
|
150
|
+
event_type="message_chunk",
|
|
151
|
+
data={"content": "test"}
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
assert result is False
|
|
155
|
+
|
|
156
|
+
def test_singleton_integration_with_environment(self):
|
|
157
|
+
"""Test that singleton pattern works with environment variables"""
|
|
158
|
+
# Reset singleton
|
|
159
|
+
import control_plane_client
|
|
160
|
+
control_plane_client._control_plane_client = None
|
|
161
|
+
|
|
162
|
+
with patch.dict(os.environ, {
|
|
163
|
+
'CONTROL_PLANE_URL': 'http://test.example.com',
|
|
164
|
+
'KUBIYA_API_KEY': 'integration_test_key'
|
|
165
|
+
}):
|
|
166
|
+
client1 = get_control_plane_client()
|
|
167
|
+
client2 = get_control_plane_client()
|
|
168
|
+
|
|
169
|
+
# Should return same instance
|
|
170
|
+
assert client1 is client2
|
|
171
|
+
assert client1.base_url == "http://test.example.com"
|
|
172
|
+
assert client1.api_key == "integration_test_key"
|
|
173
|
+
|
|
174
|
+
# Reset for other tests
|
|
175
|
+
control_plane_client._control_plane_client = None
|
|
176
|
+
|
|
177
|
+
def test_multiple_events_can_be_published_sequentially(self, mock_http_server):
|
|
178
|
+
"""Test publishing multiple events in sequence"""
|
|
179
|
+
client = ControlPlaneClient(
|
|
180
|
+
base_url="http://localhost:8000",
|
|
181
|
+
api_key="test_key"
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# Mock successful responses
|
|
185
|
+
mock_response = Mock()
|
|
186
|
+
mock_response.status_code = 200
|
|
187
|
+
mock_http_server.post = Mock(return_value=mock_response)
|
|
188
|
+
|
|
189
|
+
# Publish multiple events
|
|
190
|
+
results = []
|
|
191
|
+
for i in range(5):
|
|
192
|
+
result = client.publish_event(
|
|
193
|
+
execution_id=f"exec_{i}",
|
|
194
|
+
event_type="message_chunk",
|
|
195
|
+
data={"content": f"chunk {i}"}
|
|
196
|
+
)
|
|
197
|
+
results.append(result)
|
|
198
|
+
|
|
199
|
+
# All should succeed
|
|
200
|
+
assert all(results)
|
|
201
|
+
assert mock_http_server.post.call_count == 5
|
|
202
|
+
|
|
203
|
+
def test_client_properly_formats_urls(self, mock_http_server):
|
|
204
|
+
"""Test that client formats URLs correctly"""
|
|
205
|
+
client = ControlPlaneClient(
|
|
206
|
+
base_url="http://localhost:8000",
|
|
207
|
+
api_key="test_key"
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
mock_response = Mock()
|
|
211
|
+
mock_response.status_code = 200
|
|
212
|
+
mock_http_server.post = Mock(return_value=mock_response)
|
|
213
|
+
|
|
214
|
+
# Publish event
|
|
215
|
+
client.publish_event(
|
|
216
|
+
execution_id="exec_123",
|
|
217
|
+
event_type="test",
|
|
218
|
+
data={}
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
# Check URL was properly formatted
|
|
222
|
+
call_args = mock_http_server.post.call_args
|
|
223
|
+
url = call_args[0][0]
|
|
224
|
+
assert url == "http://localhost:8000/api/v1/executions/exec_123/events"
|
|
225
|
+
|
|
226
|
+
def test_client_includes_proper_headers(self, mock_http_server):
|
|
227
|
+
"""Test that client includes proper authentication headers"""
|
|
228
|
+
client = ControlPlaneClient(
|
|
229
|
+
base_url="http://localhost:8000",
|
|
230
|
+
api_key="secret_key_123"
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
mock_response = Mock()
|
|
234
|
+
mock_response.status_code = 200
|
|
235
|
+
mock_http_server.post = Mock(return_value=mock_response)
|
|
236
|
+
|
|
237
|
+
# Publish event
|
|
238
|
+
client.publish_event(
|
|
239
|
+
execution_id="exec_123",
|
|
240
|
+
event_type="test",
|
|
241
|
+
data={}
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
# Check headers
|
|
245
|
+
call_args = mock_http_server.post.call_args
|
|
246
|
+
headers = call_args[1]["headers"]
|
|
247
|
+
assert headers["Authorization"] == "UserKey secret_key_123"
|
|
248
|
+
|
|
249
|
+
def test_session_persistence_includes_all_fields(self, mock_http_server):
|
|
250
|
+
"""Test that session persistence sends all required fields"""
|
|
251
|
+
client = ControlPlaneClient(
|
|
252
|
+
base_url="http://localhost:8000",
|
|
253
|
+
api_key="test_key"
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
mock_response = Mock()
|
|
257
|
+
mock_response.status_code = 201
|
|
258
|
+
mock_http_server.post = Mock(return_value=mock_response)
|
|
259
|
+
|
|
260
|
+
# Persist session with all fields
|
|
261
|
+
messages = [{"role": "user", "content": "test"}]
|
|
262
|
+
metadata = {"team_id": "team_123", "turn": 1}
|
|
263
|
+
|
|
264
|
+
client.persist_session(
|
|
265
|
+
execution_id="exec_123",
|
|
266
|
+
session_id="session_456",
|
|
267
|
+
user_id="user_789",
|
|
268
|
+
messages=messages,
|
|
269
|
+
metadata=metadata
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
# Check payload
|
|
273
|
+
call_args = mock_http_server.post.call_args
|
|
274
|
+
payload = call_args[1]["json"]
|
|
275
|
+
|
|
276
|
+
assert payload["session_id"] == "session_456"
|
|
277
|
+
assert payload["user_id"] == "user_789"
|
|
278
|
+
assert payload["messages"] == messages
|
|
279
|
+
assert payload["metadata"] == metadata
|
|
280
|
+
|
|
281
|
+
def test_skills_request_format(self, mock_http_server):
|
|
282
|
+
"""Test that skills request is properly formatted"""
|
|
283
|
+
client = ControlPlaneClient(
|
|
284
|
+
base_url="http://localhost:8000",
|
|
285
|
+
api_key="test_key"
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
mock_response = Mock()
|
|
289
|
+
mock_response.status_code = 200
|
|
290
|
+
mock_response.json = Mock(return_value=[])
|
|
291
|
+
mock_http_server.get = Mock(return_value=mock_response)
|
|
292
|
+
|
|
293
|
+
# Fetch skills
|
|
294
|
+
client.get_skills(agent_id="agent_abc123")
|
|
295
|
+
|
|
296
|
+
# Check URL
|
|
297
|
+
call_args = mock_http_server.get.call_args
|
|
298
|
+
url = call_args[0][0]
|
|
299
|
+
assert "agent_abc123" in url
|
|
300
|
+
assert "skills/resolved" in url
|
|
301
|
+
|
|
302
|
+
# Check headers
|
|
303
|
+
headers = call_args[1]["headers"]
|
|
304
|
+
assert "Authorization" in headers
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
if __name__ == "__main__":
|
|
308
|
+
pytest.main([__file__, "-v"])
|
|
File without changes
|