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,287 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Runtime validation logic shared between API and worker.
|
|
3
|
+
|
|
4
|
+
This module provides validation without depending on worker-specific types,
|
|
5
|
+
making it safe to import from both the API layer and worker layer.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import List, Optional, Dict, Any, Set
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
import re
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class ModelRequirement:
|
|
15
|
+
"""Model requirement specification for a runtime."""
|
|
16
|
+
|
|
17
|
+
# Patterns that model IDs must match (any match is valid)
|
|
18
|
+
model_id_patterns: List[str]
|
|
19
|
+
|
|
20
|
+
# Model providers that are supported (e.g., "anthropic", "openai")
|
|
21
|
+
supported_providers: Set[str]
|
|
22
|
+
|
|
23
|
+
# Specific model families supported (e.g., "claude", "gpt")
|
|
24
|
+
supported_families: Set[str]
|
|
25
|
+
|
|
26
|
+
# Human-readable description
|
|
27
|
+
description: str = ""
|
|
28
|
+
|
|
29
|
+
# Examples of valid model IDs
|
|
30
|
+
examples: List[str] = None
|
|
31
|
+
|
|
32
|
+
def __post_init__(self):
|
|
33
|
+
if self.examples is None:
|
|
34
|
+
self.examples = []
|
|
35
|
+
|
|
36
|
+
def validate(self, model_id: Optional[str]) -> tuple[bool, Optional[str]]:
|
|
37
|
+
"""
|
|
38
|
+
Validate a model ID against this requirement.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
model_id: Model ID to validate
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
Tuple of (is_valid, error_message)
|
|
45
|
+
"""
|
|
46
|
+
if not model_id:
|
|
47
|
+
return False, "Model ID is required for this runtime"
|
|
48
|
+
|
|
49
|
+
# Check pattern matching
|
|
50
|
+
for pattern in self.model_id_patterns:
|
|
51
|
+
if re.search(pattern, model_id, re.IGNORECASE):
|
|
52
|
+
return True, None
|
|
53
|
+
|
|
54
|
+
# Check provider/family
|
|
55
|
+
model_lower = model_id.lower()
|
|
56
|
+
|
|
57
|
+
# Check if any supported family is in the model ID
|
|
58
|
+
for family in self.supported_families:
|
|
59
|
+
if family.lower() in model_lower:
|
|
60
|
+
return True, None
|
|
61
|
+
|
|
62
|
+
# Provide helpful error message
|
|
63
|
+
examples_str = ", ".join(self.examples) if self.examples else "N/A"
|
|
64
|
+
return False, (
|
|
65
|
+
f"Model '{model_id}' is not compatible with this runtime. "
|
|
66
|
+
f"Expected models matching: {', '.join(self.model_id_patterns)}. "
|
|
67
|
+
f"Supported families: {', '.join(self.supported_families)}. "
|
|
68
|
+
f"Examples: {examples_str}"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@dataclass
|
|
73
|
+
class RuntimeRequirements:
|
|
74
|
+
"""Requirements specification for a runtime."""
|
|
75
|
+
|
|
76
|
+
runtime_type: str
|
|
77
|
+
|
|
78
|
+
# Model requirements
|
|
79
|
+
model_requirement: ModelRequirement
|
|
80
|
+
|
|
81
|
+
# Required fields in agent/team config
|
|
82
|
+
required_config_fields: List[str] = None
|
|
83
|
+
|
|
84
|
+
# Optional but recommended fields
|
|
85
|
+
recommended_config_fields: List[str] = None
|
|
86
|
+
|
|
87
|
+
# Maximum conversation history length
|
|
88
|
+
max_history_length: Optional[int] = None
|
|
89
|
+
|
|
90
|
+
# Whether system prompt is required
|
|
91
|
+
requires_system_prompt: bool = False
|
|
92
|
+
|
|
93
|
+
# Whether tools/skills are required
|
|
94
|
+
requires_tools: bool = False
|
|
95
|
+
|
|
96
|
+
def __post_init__(self):
|
|
97
|
+
if self.required_config_fields is None:
|
|
98
|
+
self.required_config_fields = []
|
|
99
|
+
if self.recommended_config_fields is None:
|
|
100
|
+
self.recommended_config_fields = []
|
|
101
|
+
|
|
102
|
+
def validate_model(self, model_id: Optional[str]) -> tuple[bool, Optional[str]]:
|
|
103
|
+
"""Validate model compatibility."""
|
|
104
|
+
return self.model_requirement.validate(model_id)
|
|
105
|
+
|
|
106
|
+
def validate_config(self, config: Optional[Dict[str, Any]]) -> List[str]:
|
|
107
|
+
"""
|
|
108
|
+
Validate agent/team configuration.
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
List of validation errors (empty if valid)
|
|
112
|
+
"""
|
|
113
|
+
errors = []
|
|
114
|
+
|
|
115
|
+
if not config:
|
|
116
|
+
if self.required_config_fields:
|
|
117
|
+
errors.append(
|
|
118
|
+
f"Configuration is required for this runtime. "
|
|
119
|
+
f"Required fields: {', '.join(self.required_config_fields)}"
|
|
120
|
+
)
|
|
121
|
+
return errors
|
|
122
|
+
|
|
123
|
+
# Check required fields
|
|
124
|
+
for field in self.required_config_fields:
|
|
125
|
+
if field not in config or config[field] is None:
|
|
126
|
+
errors.append(f"Required field '{field}' is missing in configuration")
|
|
127
|
+
|
|
128
|
+
return errors
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# ==================== Runtime Requirements Definitions ====================
|
|
132
|
+
|
|
133
|
+
# Agno/Default Runtime - Flexible, supports most models
|
|
134
|
+
DEFAULT_RUNTIME_REQUIREMENTS = RuntimeRequirements(
|
|
135
|
+
runtime_type="default",
|
|
136
|
+
model_requirement=ModelRequirement(
|
|
137
|
+
model_id_patterns=[
|
|
138
|
+
r".*", # Accept all models
|
|
139
|
+
],
|
|
140
|
+
supported_providers={"openai", "anthropic", "azure", "google", "mistral", "cohere"},
|
|
141
|
+
supported_families={"gpt", "claude", "gemini", "mistral", "command"},
|
|
142
|
+
description="Default runtime supports most LiteLLM-compatible models",
|
|
143
|
+
examples=[
|
|
144
|
+
"gpt-4",
|
|
145
|
+
"gpt-4-turbo",
|
|
146
|
+
"gpt-3.5-turbo",
|
|
147
|
+
"claude-3-opus",
|
|
148
|
+
"claude-3-sonnet",
|
|
149
|
+
"claude-sonnet-4",
|
|
150
|
+
"gemini-pro",
|
|
151
|
+
"mistral-large",
|
|
152
|
+
],
|
|
153
|
+
),
|
|
154
|
+
max_history_length=100, # Reasonable default
|
|
155
|
+
requires_system_prompt=False,
|
|
156
|
+
requires_tools=False,
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
# Claude Code Runtime - Requires Claude models
|
|
160
|
+
CLAUDE_CODE_RUNTIME_REQUIREMENTS = RuntimeRequirements(
|
|
161
|
+
runtime_type="claude_code",
|
|
162
|
+
model_requirement=ModelRequirement(
|
|
163
|
+
model_id_patterns=[
|
|
164
|
+
r"claude", # Must contain "claude"
|
|
165
|
+
r"kubiya/claude", # LiteLLM proxy format
|
|
166
|
+
r"anthropic\.claude", # Alternative format
|
|
167
|
+
],
|
|
168
|
+
supported_providers={"anthropic"},
|
|
169
|
+
supported_families={"claude"},
|
|
170
|
+
description=(
|
|
171
|
+
"Claude Code runtime requires Anthropic Claude models. "
|
|
172
|
+
"This runtime leverages Claude's advanced capabilities including "
|
|
173
|
+
"extended context, tool use, and code understanding."
|
|
174
|
+
),
|
|
175
|
+
examples=[
|
|
176
|
+
"claude-3-opus-20240229",
|
|
177
|
+
"claude-3-sonnet-20240229",
|
|
178
|
+
"claude-3-5-sonnet-20241022",
|
|
179
|
+
"claude-3-haiku-20240307",
|
|
180
|
+
"claude-sonnet-4",
|
|
181
|
+
"claude-opus-4",
|
|
182
|
+
"kubiya/claude-sonnet-4",
|
|
183
|
+
"kubiya/claude-opus-4",
|
|
184
|
+
],
|
|
185
|
+
),
|
|
186
|
+
max_history_length=200, # Claude handles longer contexts well
|
|
187
|
+
requires_system_prompt=False, # Optional but recommended
|
|
188
|
+
requires_tools=False, # Claude Code adds tools automatically
|
|
189
|
+
recommended_config_fields=["timeout", "max_tokens"],
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
# Registry of runtime requirements
|
|
194
|
+
RUNTIME_REQUIREMENTS: Dict[str, RuntimeRequirements] = {
|
|
195
|
+
"default": DEFAULT_RUNTIME_REQUIREMENTS,
|
|
196
|
+
"claude_code": CLAUDE_CODE_RUNTIME_REQUIREMENTS,
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
# ==================== Validation Functions ====================
|
|
201
|
+
|
|
202
|
+
def validate_agent_for_runtime(
|
|
203
|
+
runtime_type: str,
|
|
204
|
+
model_id: Optional[str],
|
|
205
|
+
agent_config: Optional[Dict[str, Any]] = None,
|
|
206
|
+
system_prompt: Optional[str] = None,
|
|
207
|
+
) -> tuple[bool, List[str]]:
|
|
208
|
+
"""
|
|
209
|
+
Validate agent configuration for a runtime.
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
runtime_type: Runtime type string (e.g., "default", "claude_code")
|
|
213
|
+
model_id: Model ID to validate
|
|
214
|
+
agent_config: Agent configuration dict
|
|
215
|
+
system_prompt: System prompt
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
Tuple of (is_valid, error_messages)
|
|
219
|
+
"""
|
|
220
|
+
requirements = RUNTIME_REQUIREMENTS.get(runtime_type)
|
|
221
|
+
if not requirements:
|
|
222
|
+
# No requirements registered - allow by default
|
|
223
|
+
return True, []
|
|
224
|
+
|
|
225
|
+
errors = []
|
|
226
|
+
|
|
227
|
+
# Validate model
|
|
228
|
+
is_valid, error = requirements.validate_model(model_id)
|
|
229
|
+
if not is_valid:
|
|
230
|
+
errors.append(error)
|
|
231
|
+
|
|
232
|
+
# Validate config
|
|
233
|
+
config_errors = requirements.validate_config(agent_config)
|
|
234
|
+
errors.extend(config_errors)
|
|
235
|
+
|
|
236
|
+
# Validate system prompt if required
|
|
237
|
+
if requirements.requires_system_prompt and not system_prompt:
|
|
238
|
+
errors.append("System prompt is required for this runtime")
|
|
239
|
+
|
|
240
|
+
return len(errors) == 0, errors
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def get_runtime_requirements_info(runtime_type: str) -> Dict[str, Any]:
|
|
244
|
+
"""
|
|
245
|
+
Get human-readable requirements info for a runtime.
|
|
246
|
+
|
|
247
|
+
Args:
|
|
248
|
+
runtime_type: Runtime type string
|
|
249
|
+
|
|
250
|
+
Returns:
|
|
251
|
+
Dict with requirements information
|
|
252
|
+
"""
|
|
253
|
+
requirements = RUNTIME_REQUIREMENTS.get(runtime_type)
|
|
254
|
+
if not requirements:
|
|
255
|
+
return {
|
|
256
|
+
"runtime_type": runtime_type,
|
|
257
|
+
"model_requirement": "No specific requirements",
|
|
258
|
+
"flexible": True,
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return {
|
|
262
|
+
"runtime_type": runtime_type,
|
|
263
|
+
"model_requirement": {
|
|
264
|
+
"description": requirements.model_requirement.description,
|
|
265
|
+
"supported_providers": list(requirements.model_requirement.supported_providers),
|
|
266
|
+
"supported_families": list(requirements.model_requirement.supported_families),
|
|
267
|
+
"examples": requirements.model_requirement.examples,
|
|
268
|
+
},
|
|
269
|
+
"required_config_fields": requirements.required_config_fields,
|
|
270
|
+
"recommended_config_fields": requirements.recommended_config_fields,
|
|
271
|
+
"max_history_length": requirements.max_history_length,
|
|
272
|
+
"requires_system_prompt": requirements.requires_system_prompt,
|
|
273
|
+
"requires_tools": requirements.requires_tools,
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def list_all_runtime_requirements() -> Dict[str, Dict[str, Any]]:
|
|
278
|
+
"""
|
|
279
|
+
Get requirements for all registered runtimes.
|
|
280
|
+
|
|
281
|
+
Returns:
|
|
282
|
+
Dict mapping runtime type to requirements info
|
|
283
|
+
"""
|
|
284
|
+
return {
|
|
285
|
+
runtime_type: get_runtime_requirements_info(runtime_type)
|
|
286
|
+
for runtime_type in RUNTIME_REQUIREMENTS.keys()
|
|
287
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
from fastapi import FastAPI
|
|
2
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
3
|
+
from contextlib import asynccontextmanager
|
|
4
|
+
import structlog
|
|
5
|
+
|
|
6
|
+
from control_plane_api.app.config import settings
|
|
7
|
+
from control_plane_api.app.routers import agents, teams, workflows, health, executions, presence, runners, workers, projects, models, models_v2, task_queues, worker_queues, environment_context, team_context, context_manager, skills, skills_definitions, environments, runtimes, secrets, integrations, execution_environment, policies, task_planning, jobs, analytics
|
|
8
|
+
from control_plane_api.app.routers import agents_v2 # New multi-tenant agent router
|
|
9
|
+
|
|
10
|
+
# Configure structured logging
|
|
11
|
+
import logging
|
|
12
|
+
|
|
13
|
+
structlog.configure(
|
|
14
|
+
processors=[
|
|
15
|
+
structlog.contextvars.merge_contextvars,
|
|
16
|
+
structlog.processors.add_log_level,
|
|
17
|
+
structlog.processors.TimeStamper(fmt="iso"),
|
|
18
|
+
structlog.processors.JSONRenderer(),
|
|
19
|
+
],
|
|
20
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
|
21
|
+
getattr(logging, settings.log_level.upper(), logging.INFO)
|
|
22
|
+
),
|
|
23
|
+
logger_factory=structlog.PrintLoggerFactory(),
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
logger = structlog.get_logger()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@asynccontextmanager
|
|
30
|
+
async def lifespan(app: FastAPI):
|
|
31
|
+
"""Application lifespan manager for serverless"""
|
|
32
|
+
logger.info(
|
|
33
|
+
"agent_control_plane_starting",
|
|
34
|
+
version=settings.api_version,
|
|
35
|
+
environment=settings.environment
|
|
36
|
+
)
|
|
37
|
+
# No database initialization needed for serverless
|
|
38
|
+
# Supabase client is initialized on-demand
|
|
39
|
+
yield
|
|
40
|
+
logger.info("agent_control_plane_shutting_down")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# Create FastAPI application
|
|
44
|
+
app = FastAPI(
|
|
45
|
+
title=settings.api_title,
|
|
46
|
+
version=settings.api_version,
|
|
47
|
+
description=settings.api_description,
|
|
48
|
+
lifespan=lifespan,
|
|
49
|
+
# Disable lifespan for Vercel (will be "off" via Mangum)
|
|
50
|
+
openapi_url="/api/openapi.json" if settings.environment != "production" else None,
|
|
51
|
+
docs_url="/api/docs" if settings.environment != "production" else None,
|
|
52
|
+
redoc_url="/api/redoc" if settings.environment != "production" else None,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Add CORS middleware
|
|
56
|
+
app.add_middleware(
|
|
57
|
+
CORSMiddleware,
|
|
58
|
+
allow_origins=settings.cors_origins,
|
|
59
|
+
allow_credentials=True,
|
|
60
|
+
allow_methods=["*"],
|
|
61
|
+
allow_headers=["*"],
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Include routers (all routes under /api/v1)
|
|
65
|
+
app.include_router(health.router, prefix="/api", tags=["Health"])
|
|
66
|
+
app.include_router(models_v2.router, prefix="/api/v1/models", tags=["Models"]) # LLM models CRUD (database-backed)
|
|
67
|
+
app.include_router(runtimes.router, prefix="/api/v1", tags=["Runtimes"]) # Agent runtime types
|
|
68
|
+
app.include_router(secrets.router, prefix="/api/v1", tags=["Secrets"]) # Kubiya secrets proxy
|
|
69
|
+
app.include_router(integrations.router, prefix="/api/v1", tags=["Integrations"]) # Kubiya integrations proxy
|
|
70
|
+
app.include_router(execution_environment.router, prefix="/api/v1", tags=["Execution Environment"]) # Resolved execution environment for workers
|
|
71
|
+
app.include_router(projects.router, prefix="/api/v1/projects", tags=["Projects"]) # Multi-project management
|
|
72
|
+
app.include_router(environments.router, prefix="/api/v1/environments", tags=["Environments"]) # Environment management
|
|
73
|
+
app.include_router(task_queues.router, prefix="/api/v1/task-queues", tags=["Task Queues"]) # Legacy endpoint (use /environments)
|
|
74
|
+
app.include_router(worker_queues.router, prefix="/api/v1", tags=["Worker Queues"]) # Worker queue management per environment
|
|
75
|
+
app.include_router(environment_context.router, prefix="/api/v1", tags=["Environment Context"]) # Environment context management
|
|
76
|
+
app.include_router(team_context.router, prefix="/api/v1", tags=["Team Context"]) # Team context management
|
|
77
|
+
app.include_router(context_manager.router, prefix="/api/v1", tags=["Context Manager"]) # Unified context management
|
|
78
|
+
app.include_router(skills_definitions.router, prefix="/api/v1/skills", tags=["Tool Sets"]) # Skill definitions and templates (must be before skills.router)
|
|
79
|
+
app.include_router(skills.router, prefix="/api/v1/skills", tags=["Tool Sets"]) # Tool sets management
|
|
80
|
+
app.include_router(policies.router, prefix="/api/v1/policies", tags=["Policies"]) # Policy management and enforcement
|
|
81
|
+
app.include_router(task_planning.router, prefix="/api/v1", tags=["Task Planning"]) # AI-powered task planning
|
|
82
|
+
app.include_router(agents_v2.router, prefix="/api/v1/agents", tags=["Agents"]) # Use new multi-tenant router
|
|
83
|
+
app.include_router(runners.router, prefix="/api/v1/runners", tags=["Runners"]) # Proxy to Kubiya API
|
|
84
|
+
app.include_router(workers.router, prefix="/api/v1/workers", tags=["Workers"]) # Worker registration and heartbeats
|
|
85
|
+
app.include_router(teams.router, prefix="/api/v1/teams", tags=["Teams"])
|
|
86
|
+
app.include_router(workflows.router, prefix="/api/v1/workflows", tags=["Workflows"])
|
|
87
|
+
app.include_router(executions.router, prefix="/api/v1/executions", tags=["Executions"])
|
|
88
|
+
app.include_router(presence.router, prefix="/api/v1/presence", tags=["Presence"])
|
|
89
|
+
app.include_router(jobs.router, prefix="/api/v1/jobs", tags=["Jobs"]) # Scheduled and webhook-triggered jobs
|
|
90
|
+
app.include_router(analytics.router, prefix="/api/v1/analytics", tags=["Analytics"]) # Execution metrics and reporting
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@app.get("/")
|
|
94
|
+
async def root():
|
|
95
|
+
"""Root endpoint"""
|
|
96
|
+
return {
|
|
97
|
+
"message": "Welcome to Agent Control Plane",
|
|
98
|
+
"version": settings.api_version,
|
|
99
|
+
"environment": settings.environment,
|
|
100
|
+
"docs": "/api/docs" if settings.environment != "production" else None,
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@app.get("/api")
|
|
105
|
+
async def api_root():
|
|
106
|
+
"""API root endpoint"""
|
|
107
|
+
return {
|
|
108
|
+
"message": "Agent Control Plane API",
|
|
109
|
+
"version": settings.api_version,
|
|
110
|
+
"endpoints": {
|
|
111
|
+
"projects": "/api/v1/projects",
|
|
112
|
+
"task_queues": "/api/v1/task-queues",
|
|
113
|
+
"agents": "/api/v1/agents",
|
|
114
|
+
"teams": "/api/v1/teams",
|
|
115
|
+
"skills": "/api/v1/skills",
|
|
116
|
+
"policies": "/api/v1/policies",
|
|
117
|
+
"workflows": "/api/v1/workflows",
|
|
118
|
+
"executions": "/api/v1/executions",
|
|
119
|
+
"presence": "/api/v1/presence",
|
|
120
|
+
"runners": "/api/v1/runners",
|
|
121
|
+
"workers": "/api/v1/workers",
|
|
122
|
+
"models": "/api/v1/models",
|
|
123
|
+
"runtimes": "/api/v1/runtimes",
|
|
124
|
+
"secrets": "/api/v1/secrets",
|
|
125
|
+
"integrations": "/api/v1/integrations",
|
|
126
|
+
"health": "/api/health",
|
|
127
|
+
}
|
|
128
|
+
}
|