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.

Files changed (185) hide show
  1. control_plane_api/README.md +266 -0
  2. control_plane_api/__init__.py +0 -0
  3. control_plane_api/__version__.py +1 -0
  4. control_plane_api/alembic/README +1 -0
  5. control_plane_api/alembic/env.py +98 -0
  6. control_plane_api/alembic/script.py.mako +28 -0
  7. control_plane_api/alembic/versions/1382bec74309_initial_migration_with_all_models.py +251 -0
  8. control_plane_api/alembic/versions/1f54bc2a37e3_add_analytics_tables.py +162 -0
  9. control_plane_api/alembic/versions/2e4cb136dc10_rename_toolset_ids_to_skill_ids_in_teams.py +30 -0
  10. control_plane_api/alembic/versions/31cd69a644ce_add_skill_templates_table.py +28 -0
  11. control_plane_api/alembic/versions/89e127caa47d_add_jobs_and_job_executions_tables.py +161 -0
  12. control_plane_api/alembic/versions/add_llm_models_table.py +51 -0
  13. control_plane_api/alembic/versions/b0e10697f212_add_runtime_column_to_teams_simple.py +42 -0
  14. control_plane_api/alembic/versions/ce43b24b63bf_add_execution_trigger_source_and_fix_.py +155 -0
  15. control_plane_api/alembic/versions/d4eaf16e3f8d_rename_toolsets_to_skills.py +84 -0
  16. control_plane_api/alembic/versions/efa2dc427da1_rename_metadata_to_custom_metadata.py +32 -0
  17. control_plane_api/alembic/versions/f973b431d1ce_add_workflow_executor_to_skill_types.py +44 -0
  18. control_plane_api/alembic.ini +148 -0
  19. control_plane_api/api/index.py +12 -0
  20. control_plane_api/app/__init__.py +11 -0
  21. control_plane_api/app/activities/__init__.py +20 -0
  22. control_plane_api/app/activities/agent_activities.py +379 -0
  23. control_plane_api/app/activities/team_activities.py +410 -0
  24. control_plane_api/app/activities/temporal_cloud_activities.py +577 -0
  25. control_plane_api/app/config/__init__.py +35 -0
  26. control_plane_api/app/config/api_config.py +354 -0
  27. control_plane_api/app/config/model_pricing.py +318 -0
  28. control_plane_api/app/config.py +95 -0
  29. control_plane_api/app/database.py +135 -0
  30. control_plane_api/app/exceptions.py +408 -0
  31. control_plane_api/app/lib/__init__.py +11 -0
  32. control_plane_api/app/lib/job_executor.py +312 -0
  33. control_plane_api/app/lib/kubiya_client.py +235 -0
  34. control_plane_api/app/lib/litellm_pricing.py +166 -0
  35. control_plane_api/app/lib/planning_tools/__init__.py +22 -0
  36. control_plane_api/app/lib/planning_tools/agents.py +155 -0
  37. control_plane_api/app/lib/planning_tools/base.py +189 -0
  38. control_plane_api/app/lib/planning_tools/environments.py +214 -0
  39. control_plane_api/app/lib/planning_tools/resources.py +240 -0
  40. control_plane_api/app/lib/planning_tools/teams.py +198 -0
  41. control_plane_api/app/lib/policy_enforcer_client.py +939 -0
  42. control_plane_api/app/lib/redis_client.py +436 -0
  43. control_plane_api/app/lib/supabase.py +71 -0
  44. control_plane_api/app/lib/temporal_client.py +138 -0
  45. control_plane_api/app/lib/validation/__init__.py +20 -0
  46. control_plane_api/app/lib/validation/runtime_validation.py +287 -0
  47. control_plane_api/app/main.py +128 -0
  48. control_plane_api/app/middleware/__init__.py +8 -0
  49. control_plane_api/app/middleware/auth.py +513 -0
  50. control_plane_api/app/middleware/exception_handler.py +267 -0
  51. control_plane_api/app/middleware/rate_limiting.py +384 -0
  52. control_plane_api/app/middleware/request_id.py +202 -0
  53. control_plane_api/app/models/__init__.py +27 -0
  54. control_plane_api/app/models/agent.py +79 -0
  55. control_plane_api/app/models/analytics.py +206 -0
  56. control_plane_api/app/models/associations.py +81 -0
  57. control_plane_api/app/models/environment.py +63 -0
  58. control_plane_api/app/models/execution.py +93 -0
  59. control_plane_api/app/models/job.py +179 -0
  60. control_plane_api/app/models/llm_model.py +75 -0
  61. control_plane_api/app/models/presence.py +49 -0
  62. control_plane_api/app/models/project.py +47 -0
  63. control_plane_api/app/models/session.py +38 -0
  64. control_plane_api/app/models/team.py +66 -0
  65. control_plane_api/app/models/workflow.py +55 -0
  66. control_plane_api/app/policies/README.md +121 -0
  67. control_plane_api/app/policies/approved_users.rego +62 -0
  68. control_plane_api/app/policies/business_hours.rego +51 -0
  69. control_plane_api/app/policies/rate_limiting.rego +100 -0
  70. control_plane_api/app/policies/tool_restrictions.rego +86 -0
  71. control_plane_api/app/routers/__init__.py +4 -0
  72. control_plane_api/app/routers/agents.py +364 -0
  73. control_plane_api/app/routers/agents_v2.py +1260 -0
  74. control_plane_api/app/routers/analytics.py +1014 -0
  75. control_plane_api/app/routers/context_manager.py +562 -0
  76. control_plane_api/app/routers/environment_context.py +270 -0
  77. control_plane_api/app/routers/environments.py +715 -0
  78. control_plane_api/app/routers/execution_environment.py +517 -0
  79. control_plane_api/app/routers/executions.py +1911 -0
  80. control_plane_api/app/routers/health.py +92 -0
  81. control_plane_api/app/routers/health_v2.py +326 -0
  82. control_plane_api/app/routers/integrations.py +274 -0
  83. control_plane_api/app/routers/jobs.py +1344 -0
  84. control_plane_api/app/routers/models.py +82 -0
  85. control_plane_api/app/routers/models_v2.py +361 -0
  86. control_plane_api/app/routers/policies.py +639 -0
  87. control_plane_api/app/routers/presence.py +234 -0
  88. control_plane_api/app/routers/projects.py +902 -0
  89. control_plane_api/app/routers/runners.py +379 -0
  90. control_plane_api/app/routers/runtimes.py +172 -0
  91. control_plane_api/app/routers/secrets.py +155 -0
  92. control_plane_api/app/routers/skills.py +1001 -0
  93. control_plane_api/app/routers/skills_definitions.py +140 -0
  94. control_plane_api/app/routers/task_planning.py +1256 -0
  95. control_plane_api/app/routers/task_queues.py +654 -0
  96. control_plane_api/app/routers/team_context.py +270 -0
  97. control_plane_api/app/routers/teams.py +1400 -0
  98. control_plane_api/app/routers/worker_queues.py +1545 -0
  99. control_plane_api/app/routers/workers.py +935 -0
  100. control_plane_api/app/routers/workflows.py +204 -0
  101. control_plane_api/app/runtimes/__init__.py +6 -0
  102. control_plane_api/app/runtimes/validation.py +344 -0
  103. control_plane_api/app/schemas/job_schemas.py +295 -0
  104. control_plane_api/app/services/__init__.py +1 -0
  105. control_plane_api/app/services/agno_service.py +619 -0
  106. control_plane_api/app/services/litellm_service.py +190 -0
  107. control_plane_api/app/services/policy_service.py +525 -0
  108. control_plane_api/app/services/temporal_cloud_provisioning.py +150 -0
  109. control_plane_api/app/skills/__init__.py +44 -0
  110. control_plane_api/app/skills/base.py +229 -0
  111. control_plane_api/app/skills/business_intelligence.py +189 -0
  112. control_plane_api/app/skills/data_visualization.py +154 -0
  113. control_plane_api/app/skills/docker.py +104 -0
  114. control_plane_api/app/skills/file_generation.py +94 -0
  115. control_plane_api/app/skills/file_system.py +110 -0
  116. control_plane_api/app/skills/python.py +92 -0
  117. control_plane_api/app/skills/registry.py +65 -0
  118. control_plane_api/app/skills/shell.py +102 -0
  119. control_plane_api/app/skills/workflow_executor.py +469 -0
  120. control_plane_api/app/utils/workflow_executor.py +354 -0
  121. control_plane_api/app/workflows/__init__.py +11 -0
  122. control_plane_api/app/workflows/agent_execution.py +507 -0
  123. control_plane_api/app/workflows/agent_execution_with_skills.py +222 -0
  124. control_plane_api/app/workflows/namespace_provisioning.py +326 -0
  125. control_plane_api/app/workflows/team_execution.py +399 -0
  126. control_plane_api/scripts/seed_models.py +239 -0
  127. control_plane_api/worker/__init__.py +0 -0
  128. control_plane_api/worker/activities/__init__.py +0 -0
  129. control_plane_api/worker/activities/agent_activities.py +1241 -0
  130. control_plane_api/worker/activities/approval_activities.py +234 -0
  131. control_plane_api/worker/activities/runtime_activities.py +388 -0
  132. control_plane_api/worker/activities/skill_activities.py +267 -0
  133. control_plane_api/worker/activities/team_activities.py +1217 -0
  134. control_plane_api/worker/config/__init__.py +31 -0
  135. control_plane_api/worker/config/worker_config.py +275 -0
  136. control_plane_api/worker/control_plane_client.py +529 -0
  137. control_plane_api/worker/examples/analytics_integration_example.py +362 -0
  138. control_plane_api/worker/models/__init__.py +1 -0
  139. control_plane_api/worker/models/inputs.py +89 -0
  140. control_plane_api/worker/runtimes/__init__.py +31 -0
  141. control_plane_api/worker/runtimes/base.py +789 -0
  142. control_plane_api/worker/runtimes/claude_code_runtime.py +1443 -0
  143. control_plane_api/worker/runtimes/default_runtime.py +617 -0
  144. control_plane_api/worker/runtimes/factory.py +173 -0
  145. control_plane_api/worker/runtimes/validation.py +93 -0
  146. control_plane_api/worker/services/__init__.py +1 -0
  147. control_plane_api/worker/services/agent_executor.py +422 -0
  148. control_plane_api/worker/services/agent_executor_v2.py +383 -0
  149. control_plane_api/worker/services/analytics_collector.py +457 -0
  150. control_plane_api/worker/services/analytics_service.py +464 -0
  151. control_plane_api/worker/services/approval_tools.py +310 -0
  152. control_plane_api/worker/services/approval_tools_agno.py +207 -0
  153. control_plane_api/worker/services/cancellation_manager.py +177 -0
  154. control_plane_api/worker/services/data_visualization.py +827 -0
  155. control_plane_api/worker/services/jira_tools.py +257 -0
  156. control_plane_api/worker/services/runtime_analytics.py +328 -0
  157. control_plane_api/worker/services/session_service.py +194 -0
  158. control_plane_api/worker/services/skill_factory.py +175 -0
  159. control_plane_api/worker/services/team_executor.py +574 -0
  160. control_plane_api/worker/services/team_executor_v2.py +465 -0
  161. control_plane_api/worker/services/workflow_executor_tools.py +1418 -0
  162. control_plane_api/worker/tests/__init__.py +1 -0
  163. control_plane_api/worker/tests/e2e/__init__.py +0 -0
  164. control_plane_api/worker/tests/e2e/test_execution_flow.py +571 -0
  165. control_plane_api/worker/tests/integration/__init__.py +0 -0
  166. control_plane_api/worker/tests/integration/test_control_plane_integration.py +308 -0
  167. control_plane_api/worker/tests/unit/__init__.py +0 -0
  168. control_plane_api/worker/tests/unit/test_control_plane_client.py +401 -0
  169. control_plane_api/worker/utils/__init__.py +1 -0
  170. control_plane_api/worker/utils/chunk_batcher.py +305 -0
  171. control_plane_api/worker/utils/retry_utils.py +60 -0
  172. control_plane_api/worker/utils/streaming_utils.py +373 -0
  173. control_plane_api/worker/worker.py +753 -0
  174. control_plane_api/worker/workflows/__init__.py +0 -0
  175. control_plane_api/worker/workflows/agent_execution.py +589 -0
  176. control_plane_api/worker/workflows/team_execution.py +429 -0
  177. kubiya_control_plane_api-0.3.4.dist-info/METADATA +229 -0
  178. kubiya_control_plane_api-0.3.4.dist-info/RECORD +182 -0
  179. kubiya_control_plane_api-0.3.4.dist-info/entry_points.txt +2 -0
  180. kubiya_control_plane_api-0.3.4.dist-info/top_level.txt +1 -0
  181. kubiya_control_plane_api-0.1.0.dist-info/METADATA +0 -66
  182. kubiya_control_plane_api-0.1.0.dist-info/RECORD +0 -5
  183. kubiya_control_plane_api-0.1.0.dist-info/top_level.txt +0 -1
  184. {kubiya_control_plane_api-0.1.0.dist-info/licenses → control_plane_api}/LICENSE +0 -0
  185. {kubiya_control_plane_api-0.1.0.dist-info → kubiya_control_plane_api-0.3.4.dist-info}/WHEEL +0 -0
@@ -0,0 +1,267 @@
1
+ """
2
+ Skill Activities for Agent Control Plane Worker.
3
+
4
+ These activities handle skill resolution and instantiation for agent execution.
5
+ """
6
+
7
+ import structlog
8
+ from dataclasses import dataclass
9
+ from typing import Any, Optional
10
+ from temporalio import activity
11
+ import httpx
12
+
13
+ logger = structlog.get_logger()
14
+
15
+
16
+ @dataclass
17
+ class SkillDefinition:
18
+ """Resolved skill definition with merged configuration"""
19
+ id: str
20
+ name: str
21
+ type: str
22
+ description: str
23
+ enabled: bool
24
+ configuration: dict
25
+ source: str # 'environment', 'team', 'agent'
26
+
27
+
28
+ @activity.defn
29
+ async def resolve_agent_skills(
30
+ agent_id: str,
31
+ control_plane_url: str,
32
+ api_key: str
33
+ ) -> list[dict]:
34
+ """
35
+ Resolve skills for an agent by calling Control Plane API.
36
+
37
+ The Control Plane handles all inheritance logic (Environment → Team → Agent)
38
+ and returns the merged, resolved skill list.
39
+
40
+ Args:
41
+ agent_id: Agent ID
42
+ control_plane_url: Control Plane API URL (e.g., https://control-plane.kubiya.ai)
43
+ api_key: API key for authentication
44
+
45
+ Returns:
46
+ List of resolved skill definitions with merged configurations
47
+ """
48
+ logger.info(
49
+ "resolving_agent_skills_from_control_plane",
50
+ agent_id=agent_id,
51
+ control_plane_url=control_plane_url
52
+ )
53
+
54
+ try:
55
+ async with httpx.AsyncClient(timeout=30.0) as client:
56
+ # Call Control Plane API to resolve skills with inheritance
57
+ response = await client.get(
58
+ f"{control_plane_url}/api/v1/skills/associations/agents/{agent_id}/skills/resolved",
59
+ headers={"Authorization": f"Bearer {api_key}"}
60
+ )
61
+
62
+ if response.status_code != 200:
63
+ logger.error(
64
+ "skill_resolution_failed",
65
+ status_code=response.status_code,
66
+ response=response.text[:500],
67
+ agent_id=agent_id
68
+ )
69
+ # Return empty list on failure - agent can still run without tools
70
+ return []
71
+
72
+ # Response is list of resolved skills
73
+ skills = response.json()
74
+
75
+ logger.info(
76
+ "skills_resolved_from_control_plane",
77
+ agent_id=agent_id,
78
+ skill_count=len(skills),
79
+ skill_types=[t.get("type") for t in skills],
80
+ skill_sources=[t.get("source") for t in skills]
81
+ )
82
+
83
+ return skills
84
+
85
+ except Exception as e:
86
+ logger.error(
87
+ "skill_resolution_error",
88
+ error=str(e),
89
+ agent_id=agent_id
90
+ )
91
+ return []
92
+
93
+
94
+ @activity.defn
95
+ async def instantiate_agent_skills(
96
+ skill_definitions: list[dict]
97
+ ) -> list[Any]:
98
+ """
99
+ Instantiate agno tool instances from skill definitions.
100
+
101
+ Args:
102
+ skill_definitions: List of resolved skill definitions
103
+
104
+ Returns:
105
+ List of instantiated agno tool objects
106
+ """
107
+ # Import agno tools
108
+ try:
109
+ from agno.tools.file import FileTools
110
+ from agno.tools.shell import ShellTools
111
+ from agno.tools.docker import DockerTools
112
+ from agno.tools.sleep import SleepTools
113
+ from agno.tools.file_generation import FileGenerationTools
114
+ except ImportError as e:
115
+ logger.error("agno_tools_import_failed", error=str(e))
116
+ return []
117
+
118
+ # Tool registry
119
+ SKILL_REGISTRY = {
120
+ "file_system": FileTools,
121
+ "shell": ShellTools,
122
+ "docker": DockerTools,
123
+ "sleep": SleepTools,
124
+ "file_generation": FileGenerationTools,
125
+ }
126
+
127
+ tools = []
128
+
129
+ for skill_def in skill_definitions:
130
+ if not skill_def.get("enabled", True):
131
+ logger.debug(
132
+ "skipping_disabled_skill",
133
+ skill_name=skill_def.get("name")
134
+ )
135
+ continue
136
+
137
+ skill_type = skill_def.get("type")
138
+ tool_class = SKILL_REGISTRY.get(skill_type)
139
+
140
+ if not tool_class:
141
+ logger.warning(
142
+ "unknown_skill_type",
143
+ skill_type=skill_type,
144
+ skill_name=skill_def.get("name")
145
+ )
146
+ continue
147
+
148
+ # Get configuration
149
+ config = skill_def.get("configuration", {})
150
+
151
+ # Instantiate tool with configuration
152
+ try:
153
+ tool_instance = tool_class(**config)
154
+ tools.append(tool_instance)
155
+
156
+ logger.info(
157
+ "skill_instantiated",
158
+ skill_name=skill_def.get("name"),
159
+ skill_type=skill_type,
160
+ configuration=config
161
+ )
162
+ except Exception as e:
163
+ logger.error(
164
+ "skill_instantiation_failed",
165
+ skill_name=skill_def.get("name"),
166
+ skill_type=skill_type,
167
+ error=str(e)
168
+ )
169
+ # Continue with other tools even if one fails
170
+
171
+ logger.info(
172
+ "agent_tools_instantiated",
173
+ tool_count=len(tools),
174
+ tool_types=[type(t).__name__ for t in tools]
175
+ )
176
+
177
+ return tools
178
+
179
+
180
+ @activity.defn
181
+ async def instantiate_custom_skill(
182
+ skill_definition: dict,
183
+ organization_id: str,
184
+ control_plane_url: str,
185
+ api_key: str
186
+ ) -> Optional[Any]:
187
+ """
188
+ Instantiate a custom skill by loading user-provided Python code.
189
+
190
+ Args:
191
+ skill_definition: Skill definition with custom_class path
192
+ organization_id: Organization ID
193
+ control_plane_url: Control Plane API URL
194
+ api_key: API key for authentication
195
+
196
+ Returns:
197
+ Instantiated tool instance or None if failed
198
+ """
199
+ logger.info(
200
+ "instantiating_custom_skill",
201
+ skill_name=skill_definition.get("name"),
202
+ organization_id=organization_id
203
+ )
204
+
205
+ try:
206
+ # Get custom class path from configuration
207
+ custom_class = skill_definition.get("configuration", {}).get("custom_class")
208
+ if not custom_class:
209
+ logger.error("custom_skill_missing_class", skill_definition=skill_definition)
210
+ return None
211
+
212
+ # Fetch custom skill code from Control Plane
213
+ async with httpx.AsyncClient(timeout=30.0) as client:
214
+ response = await client.get(
215
+ f"{control_plane_url}/api/v1/skills/{skill_definition['id']}/code",
216
+ headers={"Authorization": f"Bearer {api_key}"},
217
+ params={"organization_id": organization_id}
218
+ )
219
+
220
+ if response.status_code != 200:
221
+ logger.error(
222
+ "custom_skill_code_fetch_failed",
223
+ status_code=response.status_code
224
+ )
225
+ return None
226
+
227
+ code_data = response.json()
228
+ python_code = code_data.get("code")
229
+
230
+ if not python_code:
231
+ logger.error("custom_skill_no_code")
232
+ return None
233
+
234
+ # Execute code in isolated namespace
235
+ namespace = {}
236
+ exec(python_code, namespace)
237
+
238
+ # Extract class from namespace
239
+ class_parts = custom_class.split(".")
240
+ tool_class = namespace.get(class_parts[-1])
241
+
242
+ if not tool_class:
243
+ logger.error(
244
+ "custom_skill_class_not_found",
245
+ custom_class=custom_class
246
+ )
247
+ return None
248
+
249
+ # Instantiate with configuration
250
+ config = skill_definition.get("configuration", {}).get("custom_config", {})
251
+ tool_instance = tool_class(**config)
252
+
253
+ logger.info(
254
+ "custom_skill_instantiated",
255
+ skill_name=skill_definition.get("name"),
256
+ custom_class=custom_class
257
+ )
258
+
259
+ return tool_instance
260
+
261
+ except Exception as e:
262
+ logger.error(
263
+ "custom_skill_instantiation_error",
264
+ skill_name=skill_definition.get("name"),
265
+ error=str(e)
266
+ )
267
+ return None