kubiya-control-plane-api 0.9.15__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 (479) hide show
  1. control_plane_api/LICENSE +676 -0
  2. control_plane_api/README.md +350 -0
  3. control_plane_api/__init__.py +4 -0
  4. control_plane_api/__version__.py +8 -0
  5. control_plane_api/alembic/README +1 -0
  6. control_plane_api/alembic/env.py +121 -0
  7. control_plane_api/alembic/script.py.mako +28 -0
  8. control_plane_api/alembic/versions/2613c65c3dbe_initial_database_setup.py +32 -0
  9. control_plane_api/alembic/versions/2df520d4927d_merge_heads.py +28 -0
  10. control_plane_api/alembic/versions/43abf98d6a01_add_paused_status_to_executions.py +73 -0
  11. control_plane_api/alembic/versions/6289854264cb_merge_multiple_heads.py +28 -0
  12. control_plane_api/alembic/versions/6a4d4dc3d8dc_generate_execution_transitions.py +50 -0
  13. control_plane_api/alembic/versions/87d11cf0a783_add_disconnected_status_to_worker_.py +44 -0
  14. control_plane_api/alembic/versions/add_ephemeral_queue_support.py +85 -0
  15. control_plane_api/alembic/versions/add_model_type_to_llm_models.py +31 -0
  16. control_plane_api/alembic/versions/add_plan_executions_table.py +114 -0
  17. control_plane_api/alembic/versions/add_trace_span_tables.py +154 -0
  18. control_plane_api/alembic/versions/add_user_info_to_traces.py +36 -0
  19. control_plane_api/alembic/versions/adjusting_foreign_keys.py +32 -0
  20. control_plane_api/alembic/versions/b4983d976db2_initial_tables.py +1128 -0
  21. control_plane_api/alembic/versions/d181a3b40e71_rename_custom_metadata_to_metadata_in_.py +50 -0
  22. control_plane_api/alembic/versions/df9117888e82_add_missing_columns.py +82 -0
  23. control_plane_api/alembic/versions/f25de6ad895a_missing_migrations.py +34 -0
  24. control_plane_api/alembic/versions/f71305fb69b9_fix_ephemeral_queue_deletion_foreign_key.py +54 -0
  25. control_plane_api/alembic/versions/mark_local_exec_queues_as_ephemeral.py +68 -0
  26. control_plane_api/alembic.ini +148 -0
  27. control_plane_api/api/index.py +12 -0
  28. control_plane_api/app/__init__.py +11 -0
  29. control_plane_api/app/activities/__init__.py +20 -0
  30. control_plane_api/app/activities/agent_activities.py +384 -0
  31. control_plane_api/app/activities/plan_generation_activities.py +499 -0
  32. control_plane_api/app/activities/team_activities.py +424 -0
  33. control_plane_api/app/activities/temporal_cloud_activities.py +588 -0
  34. control_plane_api/app/config/__init__.py +35 -0
  35. control_plane_api/app/config/api_config.py +469 -0
  36. control_plane_api/app/config/config_loader.py +224 -0
  37. control_plane_api/app/config/model_pricing.py +323 -0
  38. control_plane_api/app/config/storage_config.py +159 -0
  39. control_plane_api/app/config.py +115 -0
  40. control_plane_api/app/controllers/__init__.py +0 -0
  41. control_plane_api/app/controllers/execution_environment_controller.py +1315 -0
  42. control_plane_api/app/database.py +135 -0
  43. control_plane_api/app/exceptions.py +408 -0
  44. control_plane_api/app/lib/__init__.py +11 -0
  45. control_plane_api/app/lib/environment.py +65 -0
  46. control_plane_api/app/lib/event_bus/__init__.py +17 -0
  47. control_plane_api/app/lib/event_bus/base.py +136 -0
  48. control_plane_api/app/lib/event_bus/manager.py +335 -0
  49. control_plane_api/app/lib/event_bus/providers/__init__.py +6 -0
  50. control_plane_api/app/lib/event_bus/providers/http_provider.py +166 -0
  51. control_plane_api/app/lib/event_bus/providers/nats_provider.py +324 -0
  52. control_plane_api/app/lib/event_bus/providers/redis_provider.py +233 -0
  53. control_plane_api/app/lib/event_bus/providers/websocket_provider.py +497 -0
  54. control_plane_api/app/lib/job_executor.py +330 -0
  55. control_plane_api/app/lib/kubiya_client.py +293 -0
  56. control_plane_api/app/lib/litellm_pricing.py +166 -0
  57. control_plane_api/app/lib/mcp_validation.py +163 -0
  58. control_plane_api/app/lib/nats/__init__.py +13 -0
  59. control_plane_api/app/lib/nats/credentials_manager.py +288 -0
  60. control_plane_api/app/lib/nats/listener.py +374 -0
  61. control_plane_api/app/lib/planning_prompt_builder.py +153 -0
  62. control_plane_api/app/lib/planning_tools/__init__.py +41 -0
  63. control_plane_api/app/lib/planning_tools/agents.py +409 -0
  64. control_plane_api/app/lib/planning_tools/agno_toolkit.py +836 -0
  65. control_plane_api/app/lib/planning_tools/base.py +119 -0
  66. control_plane_api/app/lib/planning_tools/cognitive_memory_tools.py +403 -0
  67. control_plane_api/app/lib/planning_tools/context_graph_tools.py +545 -0
  68. control_plane_api/app/lib/planning_tools/environments.py +218 -0
  69. control_plane_api/app/lib/planning_tools/knowledge.py +204 -0
  70. control_plane_api/app/lib/planning_tools/models.py +93 -0
  71. control_plane_api/app/lib/planning_tools/planning_service.py +646 -0
  72. control_plane_api/app/lib/planning_tools/resources.py +242 -0
  73. control_plane_api/app/lib/planning_tools/teams.py +334 -0
  74. control_plane_api/app/lib/policy_enforcer_client.py +1016 -0
  75. control_plane_api/app/lib/redis_client.py +803 -0
  76. control_plane_api/app/lib/sqlalchemy_utils.py +486 -0
  77. control_plane_api/app/lib/state_transition_tools/__init__.py +7 -0
  78. control_plane_api/app/lib/state_transition_tools/execution_context.py +388 -0
  79. control_plane_api/app/lib/storage/__init__.py +20 -0
  80. control_plane_api/app/lib/storage/base_provider.py +274 -0
  81. control_plane_api/app/lib/storage/provider_factory.py +157 -0
  82. control_plane_api/app/lib/storage/vercel_blob_provider.py +468 -0
  83. control_plane_api/app/lib/supabase.py +71 -0
  84. control_plane_api/app/lib/supabase_utils.py +138 -0
  85. control_plane_api/app/lib/task_planning/__init__.py +138 -0
  86. control_plane_api/app/lib/task_planning/agent_factory.py +308 -0
  87. control_plane_api/app/lib/task_planning/agents.py +389 -0
  88. control_plane_api/app/lib/task_planning/cache.py +218 -0
  89. control_plane_api/app/lib/task_planning/entity_resolver.py +273 -0
  90. control_plane_api/app/lib/task_planning/helpers.py +293 -0
  91. control_plane_api/app/lib/task_planning/hooks.py +474 -0
  92. control_plane_api/app/lib/task_planning/models.py +503 -0
  93. control_plane_api/app/lib/task_planning/plan_validator.py +166 -0
  94. control_plane_api/app/lib/task_planning/planning_workflow.py +2911 -0
  95. control_plane_api/app/lib/task_planning/runner.py +656 -0
  96. control_plane_api/app/lib/task_planning/streaming_hook.py +213 -0
  97. control_plane_api/app/lib/task_planning/workflow.py +424 -0
  98. control_plane_api/app/lib/templating/__init__.py +88 -0
  99. control_plane_api/app/lib/templating/compiler.py +278 -0
  100. control_plane_api/app/lib/templating/engine.py +178 -0
  101. control_plane_api/app/lib/templating/parsers/__init__.py +29 -0
  102. control_plane_api/app/lib/templating/parsers/base.py +96 -0
  103. control_plane_api/app/lib/templating/parsers/env.py +85 -0
  104. control_plane_api/app/lib/templating/parsers/graph.py +112 -0
  105. control_plane_api/app/lib/templating/parsers/secret.py +87 -0
  106. control_plane_api/app/lib/templating/parsers/simple.py +81 -0
  107. control_plane_api/app/lib/templating/resolver.py +366 -0
  108. control_plane_api/app/lib/templating/types.py +214 -0
  109. control_plane_api/app/lib/templating/validator.py +201 -0
  110. control_plane_api/app/lib/temporal_client.py +232 -0
  111. control_plane_api/app/lib/temporal_credentials_cache.py +178 -0
  112. control_plane_api/app/lib/temporal_credentials_service.py +203 -0
  113. control_plane_api/app/lib/validation/__init__.py +24 -0
  114. control_plane_api/app/lib/validation/runtime_validation.py +388 -0
  115. control_plane_api/app/main.py +531 -0
  116. control_plane_api/app/middleware/__init__.py +10 -0
  117. control_plane_api/app/middleware/auth.py +645 -0
  118. control_plane_api/app/middleware/exception_handler.py +267 -0
  119. control_plane_api/app/middleware/prometheus_middleware.py +173 -0
  120. control_plane_api/app/middleware/rate_limiting.py +384 -0
  121. control_plane_api/app/middleware/request_id.py +202 -0
  122. control_plane_api/app/models/__init__.py +40 -0
  123. control_plane_api/app/models/agent.py +90 -0
  124. control_plane_api/app/models/analytics.py +206 -0
  125. control_plane_api/app/models/associations.py +107 -0
  126. control_plane_api/app/models/auth_user.py +73 -0
  127. control_plane_api/app/models/context.py +161 -0
  128. control_plane_api/app/models/custom_integration.py +99 -0
  129. control_plane_api/app/models/environment.py +64 -0
  130. control_plane_api/app/models/execution.py +125 -0
  131. control_plane_api/app/models/execution_transition.py +50 -0
  132. control_plane_api/app/models/job.py +159 -0
  133. control_plane_api/app/models/llm_model.py +78 -0
  134. control_plane_api/app/models/orchestration.py +66 -0
  135. control_plane_api/app/models/plan_execution.py +102 -0
  136. control_plane_api/app/models/presence.py +49 -0
  137. control_plane_api/app/models/project.py +61 -0
  138. control_plane_api/app/models/project_management.py +85 -0
  139. control_plane_api/app/models/session.py +29 -0
  140. control_plane_api/app/models/skill.py +155 -0
  141. control_plane_api/app/models/system_tables.py +43 -0
  142. control_plane_api/app/models/task_planning.py +372 -0
  143. control_plane_api/app/models/team.py +86 -0
  144. control_plane_api/app/models/trace.py +257 -0
  145. control_plane_api/app/models/user_profile.py +54 -0
  146. control_plane_api/app/models/worker.py +221 -0
  147. control_plane_api/app/models/workflow.py +161 -0
  148. control_plane_api/app/models/workspace.py +50 -0
  149. control_plane_api/app/observability/__init__.py +177 -0
  150. control_plane_api/app/observability/context_logging.py +475 -0
  151. control_plane_api/app/observability/decorators.py +337 -0
  152. control_plane_api/app/observability/local_span_processor.py +702 -0
  153. control_plane_api/app/observability/metrics.py +303 -0
  154. control_plane_api/app/observability/middleware.py +246 -0
  155. control_plane_api/app/observability/optional.py +115 -0
  156. control_plane_api/app/observability/tracing.py +382 -0
  157. control_plane_api/app/policies/README.md +149 -0
  158. control_plane_api/app/policies/approved_users.rego +62 -0
  159. control_plane_api/app/policies/business_hours.rego +51 -0
  160. control_plane_api/app/policies/rate_limiting.rego +100 -0
  161. control_plane_api/app/policies/tool_enforcement/README.md +336 -0
  162. control_plane_api/app/policies/tool_enforcement/bash_command_validation.rego +71 -0
  163. control_plane_api/app/policies/tool_enforcement/business_hours_enforcement.rego +82 -0
  164. control_plane_api/app/policies/tool_enforcement/mcp_tool_allowlist.rego +58 -0
  165. control_plane_api/app/policies/tool_enforcement/production_safeguards.rego +80 -0
  166. control_plane_api/app/policies/tool_enforcement/role_based_tool_access.rego +44 -0
  167. control_plane_api/app/policies/tool_restrictions.rego +86 -0
  168. control_plane_api/app/routers/__init__.py +4 -0
  169. control_plane_api/app/routers/agents.py +382 -0
  170. control_plane_api/app/routers/agents_v2.py +1598 -0
  171. control_plane_api/app/routers/analytics.py +1310 -0
  172. control_plane_api/app/routers/auth.py +59 -0
  173. control_plane_api/app/routers/client_config.py +57 -0
  174. control_plane_api/app/routers/context_graph.py +561 -0
  175. control_plane_api/app/routers/context_manager.py +577 -0
  176. control_plane_api/app/routers/custom_integrations.py +490 -0
  177. control_plane_api/app/routers/enforcer.py +132 -0
  178. control_plane_api/app/routers/environment_context.py +252 -0
  179. control_plane_api/app/routers/environments.py +761 -0
  180. control_plane_api/app/routers/execution_environment.py +847 -0
  181. control_plane_api/app/routers/executions/__init__.py +28 -0
  182. control_plane_api/app/routers/executions/router.py +286 -0
  183. control_plane_api/app/routers/executions/services/__init__.py +22 -0
  184. control_plane_api/app/routers/executions/services/demo_worker_health.py +156 -0
  185. control_plane_api/app/routers/executions/services/status_service.py +420 -0
  186. control_plane_api/app/routers/executions/services/test_worker_health.py +480 -0
  187. control_plane_api/app/routers/executions/services/worker_health.py +514 -0
  188. control_plane_api/app/routers/executions/streaming/__init__.py +22 -0
  189. control_plane_api/app/routers/executions/streaming/deduplication.py +352 -0
  190. control_plane_api/app/routers/executions/streaming/event_buffer.py +353 -0
  191. control_plane_api/app/routers/executions/streaming/event_formatter.py +964 -0
  192. control_plane_api/app/routers/executions/streaming/history_loader.py +588 -0
  193. control_plane_api/app/routers/executions/streaming/live_source.py +693 -0
  194. control_plane_api/app/routers/executions/streaming/streamer.py +849 -0
  195. control_plane_api/app/routers/executions.py +4888 -0
  196. control_plane_api/app/routers/health.py +165 -0
  197. control_plane_api/app/routers/health_v2.py +394 -0
  198. control_plane_api/app/routers/integration_templates.py +496 -0
  199. control_plane_api/app/routers/integrations.py +287 -0
  200. control_plane_api/app/routers/jobs.py +1809 -0
  201. control_plane_api/app/routers/metrics.py +517 -0
  202. control_plane_api/app/routers/models.py +82 -0
  203. control_plane_api/app/routers/models_v2.py +628 -0
  204. control_plane_api/app/routers/plan_executions.py +1481 -0
  205. control_plane_api/app/routers/plan_generation_async.py +304 -0
  206. control_plane_api/app/routers/policies.py +669 -0
  207. control_plane_api/app/routers/presence.py +234 -0
  208. control_plane_api/app/routers/projects.py +987 -0
  209. control_plane_api/app/routers/runners.py +379 -0
  210. control_plane_api/app/routers/runtimes.py +172 -0
  211. control_plane_api/app/routers/secrets.py +171 -0
  212. control_plane_api/app/routers/skills.py +1010 -0
  213. control_plane_api/app/routers/skills_definitions.py +140 -0
  214. control_plane_api/app/routers/storage.py +456 -0
  215. control_plane_api/app/routers/task_planning.py +611 -0
  216. control_plane_api/app/routers/task_queues.py +650 -0
  217. control_plane_api/app/routers/team_context.py +274 -0
  218. control_plane_api/app/routers/teams.py +1747 -0
  219. control_plane_api/app/routers/templates.py +248 -0
  220. control_plane_api/app/routers/traces.py +571 -0
  221. control_plane_api/app/routers/websocket_client.py +479 -0
  222. control_plane_api/app/routers/websocket_executions_status.py +437 -0
  223. control_plane_api/app/routers/websocket_gateway.py +323 -0
  224. control_plane_api/app/routers/websocket_traces.py +576 -0
  225. control_plane_api/app/routers/worker_queues.py +2555 -0
  226. control_plane_api/app/routers/worker_websocket.py +419 -0
  227. control_plane_api/app/routers/workers.py +1004 -0
  228. control_plane_api/app/routers/workflows.py +204 -0
  229. control_plane_api/app/runtimes/__init__.py +6 -0
  230. control_plane_api/app/runtimes/validation.py +344 -0
  231. control_plane_api/app/schemas/__init__.py +1 -0
  232. control_plane_api/app/schemas/job_schemas.py +302 -0
  233. control_plane_api/app/schemas/mcp_schemas.py +311 -0
  234. control_plane_api/app/schemas/template_schemas.py +133 -0
  235. control_plane_api/app/schemas/trace_schemas.py +168 -0
  236. control_plane_api/app/schemas/worker_queue_observability_schemas.py +165 -0
  237. control_plane_api/app/services/__init__.py +1 -0
  238. control_plane_api/app/services/agno_planning_strategy.py +233 -0
  239. control_plane_api/app/services/agno_service.py +838 -0
  240. control_plane_api/app/services/claude_code_planning_service.py +203 -0
  241. control_plane_api/app/services/context_graph_client.py +224 -0
  242. control_plane_api/app/services/custom_integration_service.py +415 -0
  243. control_plane_api/app/services/integration_resolution_service.py +345 -0
  244. control_plane_api/app/services/litellm_service.py +394 -0
  245. control_plane_api/app/services/plan_generator.py +79 -0
  246. control_plane_api/app/services/planning_strategy.py +66 -0
  247. control_plane_api/app/services/planning_strategy_factory.py +118 -0
  248. control_plane_api/app/services/policy_service.py +615 -0
  249. control_plane_api/app/services/state_transition_service.py +755 -0
  250. control_plane_api/app/services/storage_service.py +593 -0
  251. control_plane_api/app/services/temporal_cloud_provisioning.py +150 -0
  252. control_plane_api/app/services/toolsets/context_graph_skill.py +432 -0
  253. control_plane_api/app/services/trace_retention.py +354 -0
  254. control_plane_api/app/services/worker_queue_metrics_service.py +190 -0
  255. control_plane_api/app/services/workflow_cancellation_manager.py +135 -0
  256. control_plane_api/app/services/workflow_operations_service.py +611 -0
  257. control_plane_api/app/skills/__init__.py +100 -0
  258. control_plane_api/app/skills/base.py +239 -0
  259. control_plane_api/app/skills/builtin/__init__.py +37 -0
  260. control_plane_api/app/skills/builtin/agent_communication/__init__.py +8 -0
  261. control_plane_api/app/skills/builtin/agent_communication/skill.py +246 -0
  262. control_plane_api/app/skills/builtin/code_ingestion/__init__.py +4 -0
  263. control_plane_api/app/skills/builtin/code_ingestion/skill.py +267 -0
  264. control_plane_api/app/skills/builtin/cognitive_memory/__init__.py +4 -0
  265. control_plane_api/app/skills/builtin/cognitive_memory/skill.py +174 -0
  266. control_plane_api/app/skills/builtin/contextual_awareness/__init__.py +4 -0
  267. control_plane_api/app/skills/builtin/contextual_awareness/skill.py +387 -0
  268. control_plane_api/app/skills/builtin/data_visualization/__init__.py +4 -0
  269. control_plane_api/app/skills/builtin/data_visualization/skill.py +154 -0
  270. control_plane_api/app/skills/builtin/docker/__init__.py +4 -0
  271. control_plane_api/app/skills/builtin/docker/skill.py +104 -0
  272. control_plane_api/app/skills/builtin/file_generation/__init__.py +4 -0
  273. control_plane_api/app/skills/builtin/file_generation/skill.py +94 -0
  274. control_plane_api/app/skills/builtin/file_system/__init__.py +4 -0
  275. control_plane_api/app/skills/builtin/file_system/skill.py +110 -0
  276. control_plane_api/app/skills/builtin/knowledge_api/__init__.py +5 -0
  277. control_plane_api/app/skills/builtin/knowledge_api/skill.py +124 -0
  278. control_plane_api/app/skills/builtin/python/__init__.py +4 -0
  279. control_plane_api/app/skills/builtin/python/skill.py +92 -0
  280. control_plane_api/app/skills/builtin/remote_filesystem/__init__.py +5 -0
  281. control_plane_api/app/skills/builtin/remote_filesystem/skill.py +170 -0
  282. control_plane_api/app/skills/builtin/shell/__init__.py +4 -0
  283. control_plane_api/app/skills/builtin/shell/skill.py +161 -0
  284. control_plane_api/app/skills/builtin/slack/__init__.py +3 -0
  285. control_plane_api/app/skills/builtin/slack/skill.py +302 -0
  286. control_plane_api/app/skills/builtin/workflow_executor/__init__.py +4 -0
  287. control_plane_api/app/skills/builtin/workflow_executor/skill.py +469 -0
  288. control_plane_api/app/skills/business_intelligence.py +189 -0
  289. control_plane_api/app/skills/config.py +63 -0
  290. control_plane_api/app/skills/loaders/__init__.py +14 -0
  291. control_plane_api/app/skills/loaders/base.py +73 -0
  292. control_plane_api/app/skills/loaders/filesystem_loader.py +199 -0
  293. control_plane_api/app/skills/registry.py +125 -0
  294. control_plane_api/app/utils/helpers.py +12 -0
  295. control_plane_api/app/utils/workflow_executor.py +354 -0
  296. control_plane_api/app/workflows/__init__.py +11 -0
  297. control_plane_api/app/workflows/agent_execution.py +520 -0
  298. control_plane_api/app/workflows/agent_execution_with_skills.py +223 -0
  299. control_plane_api/app/workflows/namespace_provisioning.py +326 -0
  300. control_plane_api/app/workflows/plan_generation.py +254 -0
  301. control_plane_api/app/workflows/team_execution.py +442 -0
  302. control_plane_api/scripts/seed_models.py +240 -0
  303. control_plane_api/scripts/validate_existing_tool_names.py +492 -0
  304. control_plane_api/shared/__init__.py +8 -0
  305. control_plane_api/shared/version.py +17 -0
  306. control_plane_api/test_deduplication.py +274 -0
  307. control_plane_api/test_executor_deduplication_e2e.py +309 -0
  308. control_plane_api/test_job_execution_e2e.py +283 -0
  309. control_plane_api/test_real_integration.py +193 -0
  310. control_plane_api/version.py +38 -0
  311. control_plane_api/worker/__init__.py +0 -0
  312. control_plane_api/worker/activities/__init__.py +0 -0
  313. control_plane_api/worker/activities/agent_activities.py +1585 -0
  314. control_plane_api/worker/activities/approval_activities.py +234 -0
  315. control_plane_api/worker/activities/job_activities.py +199 -0
  316. control_plane_api/worker/activities/runtime_activities.py +1167 -0
  317. control_plane_api/worker/activities/skill_activities.py +282 -0
  318. control_plane_api/worker/activities/team_activities.py +479 -0
  319. control_plane_api/worker/agent_runtime_server.py +370 -0
  320. control_plane_api/worker/binary_manager.py +333 -0
  321. control_plane_api/worker/config/__init__.py +31 -0
  322. control_plane_api/worker/config/worker_config.py +273 -0
  323. control_plane_api/worker/control_plane_client.py +1491 -0
  324. control_plane_api/worker/examples/analytics_integration_example.py +362 -0
  325. control_plane_api/worker/health_monitor.py +159 -0
  326. control_plane_api/worker/metrics.py +237 -0
  327. control_plane_api/worker/models/__init__.py +1 -0
  328. control_plane_api/worker/models/error_events.py +105 -0
  329. control_plane_api/worker/models/inputs.py +89 -0
  330. control_plane_api/worker/runtimes/__init__.py +35 -0
  331. control_plane_api/worker/runtimes/agent_runtime/runtime.py +485 -0
  332. control_plane_api/worker/runtimes/agno/__init__.py +34 -0
  333. control_plane_api/worker/runtimes/agno/config.py +248 -0
  334. control_plane_api/worker/runtimes/agno/hooks.py +385 -0
  335. control_plane_api/worker/runtimes/agno/mcp_builder.py +195 -0
  336. control_plane_api/worker/runtimes/agno/runtime.py +1063 -0
  337. control_plane_api/worker/runtimes/agno/utils.py +163 -0
  338. control_plane_api/worker/runtimes/base.py +979 -0
  339. control_plane_api/worker/runtimes/claude_code/__init__.py +38 -0
  340. control_plane_api/worker/runtimes/claude_code/cleanup.py +184 -0
  341. control_plane_api/worker/runtimes/claude_code/client_pool.py +529 -0
  342. control_plane_api/worker/runtimes/claude_code/config.py +829 -0
  343. control_plane_api/worker/runtimes/claude_code/hooks.py +482 -0
  344. control_plane_api/worker/runtimes/claude_code/litellm_proxy.py +1702 -0
  345. control_plane_api/worker/runtimes/claude_code/mcp_builder.py +467 -0
  346. control_plane_api/worker/runtimes/claude_code/mcp_discovery.py +558 -0
  347. control_plane_api/worker/runtimes/claude_code/runtime.py +1546 -0
  348. control_plane_api/worker/runtimes/claude_code/tool_mapper.py +403 -0
  349. control_plane_api/worker/runtimes/claude_code/utils.py +149 -0
  350. control_plane_api/worker/runtimes/factory.py +173 -0
  351. control_plane_api/worker/runtimes/model_utils.py +107 -0
  352. control_plane_api/worker/runtimes/validation.py +93 -0
  353. control_plane_api/worker/services/__init__.py +1 -0
  354. control_plane_api/worker/services/agent_communication_tools.py +908 -0
  355. control_plane_api/worker/services/agent_executor.py +485 -0
  356. control_plane_api/worker/services/agent_executor_v2.py +793 -0
  357. control_plane_api/worker/services/analytics_collector.py +457 -0
  358. control_plane_api/worker/services/analytics_service.py +464 -0
  359. control_plane_api/worker/services/approval_tools.py +310 -0
  360. control_plane_api/worker/services/approval_tools_agno.py +207 -0
  361. control_plane_api/worker/services/cancellation_manager.py +177 -0
  362. control_plane_api/worker/services/code_ingestion_tools.py +465 -0
  363. control_plane_api/worker/services/contextual_awareness_tools.py +405 -0
  364. control_plane_api/worker/services/data_visualization.py +834 -0
  365. control_plane_api/worker/services/event_publisher.py +531 -0
  366. control_plane_api/worker/services/jira_tools.py +257 -0
  367. control_plane_api/worker/services/remote_filesystem_tools.py +498 -0
  368. control_plane_api/worker/services/runtime_analytics.py +328 -0
  369. control_plane_api/worker/services/session_service.py +365 -0
  370. control_plane_api/worker/services/skill_context_enhancement.py +181 -0
  371. control_plane_api/worker/services/skill_factory.py +471 -0
  372. control_plane_api/worker/services/system_prompt_enhancement.py +410 -0
  373. control_plane_api/worker/services/team_executor.py +715 -0
  374. control_plane_api/worker/services/team_executor_v2.py +1866 -0
  375. control_plane_api/worker/services/tool_enforcement.py +254 -0
  376. control_plane_api/worker/services/workflow_executor/__init__.py +52 -0
  377. control_plane_api/worker/services/workflow_executor/event_processor.py +287 -0
  378. control_plane_api/worker/services/workflow_executor/event_publisher.py +210 -0
  379. control_plane_api/worker/services/workflow_executor/executors/__init__.py +15 -0
  380. control_plane_api/worker/services/workflow_executor/executors/base.py +270 -0
  381. control_plane_api/worker/services/workflow_executor/executors/json_executor.py +50 -0
  382. control_plane_api/worker/services/workflow_executor/executors/python_executor.py +50 -0
  383. control_plane_api/worker/services/workflow_executor/models.py +142 -0
  384. control_plane_api/worker/services/workflow_executor_tools.py +1748 -0
  385. control_plane_api/worker/skills/__init__.py +12 -0
  386. control_plane_api/worker/skills/builtin/context_graph_search/README.md +213 -0
  387. control_plane_api/worker/skills/builtin/context_graph_search/__init__.py +5 -0
  388. control_plane_api/worker/skills/builtin/context_graph_search/agno_impl.py +808 -0
  389. control_plane_api/worker/skills/builtin/context_graph_search/skill.yaml +67 -0
  390. control_plane_api/worker/skills/builtin/contextual_awareness/__init__.py +4 -0
  391. control_plane_api/worker/skills/builtin/contextual_awareness/agno_impl.py +62 -0
  392. control_plane_api/worker/skills/builtin/data_visualization/agno_impl.py +18 -0
  393. control_plane_api/worker/skills/builtin/data_visualization/skill.yaml +84 -0
  394. control_plane_api/worker/skills/builtin/docker/agno_impl.py +65 -0
  395. control_plane_api/worker/skills/builtin/docker/skill.yaml +60 -0
  396. control_plane_api/worker/skills/builtin/file_generation/agno_impl.py +47 -0
  397. control_plane_api/worker/skills/builtin/file_generation/skill.yaml +64 -0
  398. control_plane_api/worker/skills/builtin/file_system/agno_impl.py +32 -0
  399. control_plane_api/worker/skills/builtin/file_system/skill.yaml +54 -0
  400. control_plane_api/worker/skills/builtin/knowledge_api/__init__.py +4 -0
  401. control_plane_api/worker/skills/builtin/knowledge_api/agno_impl.py +50 -0
  402. control_plane_api/worker/skills/builtin/knowledge_api/skill.yaml +66 -0
  403. control_plane_api/worker/skills/builtin/python/agno_impl.py +25 -0
  404. control_plane_api/worker/skills/builtin/python/skill.yaml +60 -0
  405. control_plane_api/worker/skills/builtin/schema_fix_mixin.py +260 -0
  406. control_plane_api/worker/skills/builtin/shell/agno_impl.py +31 -0
  407. control_plane_api/worker/skills/builtin/shell/skill.yaml +60 -0
  408. control_plane_api/worker/skills/builtin/slack/__init__.py +3 -0
  409. control_plane_api/worker/skills/builtin/slack/agno_impl.py +1282 -0
  410. control_plane_api/worker/skills/builtin/slack/skill.yaml +276 -0
  411. control_plane_api/worker/skills/builtin/workflow_executor/agno_impl.py +62 -0
  412. control_plane_api/worker/skills/builtin/workflow_executor/skill.yaml +79 -0
  413. control_plane_api/worker/skills/loaders/__init__.py +5 -0
  414. control_plane_api/worker/skills/loaders/base.py +23 -0
  415. control_plane_api/worker/skills/loaders/filesystem_loader.py +357 -0
  416. control_plane_api/worker/skills/registry.py +208 -0
  417. control_plane_api/worker/tests/__init__.py +1 -0
  418. control_plane_api/worker/tests/conftest.py +12 -0
  419. control_plane_api/worker/tests/e2e/__init__.py +0 -0
  420. control_plane_api/worker/tests/e2e/test_context_graph_real_api.py +338 -0
  421. control_plane_api/worker/tests/e2e/test_context_graph_templates_e2e.py +523 -0
  422. control_plane_api/worker/tests/e2e/test_enforcement_e2e.py +344 -0
  423. control_plane_api/worker/tests/e2e/test_execution_flow.py +571 -0
  424. control_plane_api/worker/tests/e2e/test_single_execution_mode.py +656 -0
  425. control_plane_api/worker/tests/integration/__init__.py +0 -0
  426. control_plane_api/worker/tests/integration/test_builtin_skills_fixes.py +245 -0
  427. control_plane_api/worker/tests/integration/test_context_graph_search_integration.py +365 -0
  428. control_plane_api/worker/tests/integration/test_control_plane_integration.py +308 -0
  429. control_plane_api/worker/tests/integration/test_hook_enforcement_integration.py +579 -0
  430. control_plane_api/worker/tests/integration/test_scheduled_job_workflow.py +237 -0
  431. control_plane_api/worker/tests/integration/test_system_prompt_enhancement_integration.py +343 -0
  432. control_plane_api/worker/tests/unit/__init__.py +0 -0
  433. control_plane_api/worker/tests/unit/test_builtin_skill_autoload.py +396 -0
  434. control_plane_api/worker/tests/unit/test_context_graph_search.py +450 -0
  435. control_plane_api/worker/tests/unit/test_context_graph_templates.py +403 -0
  436. control_plane_api/worker/tests/unit/test_control_plane_client.py +401 -0
  437. control_plane_api/worker/tests/unit/test_control_plane_client_jobs.py +345 -0
  438. control_plane_api/worker/tests/unit/test_job_activities.py +353 -0
  439. control_plane_api/worker/tests/unit/test_skill_context_enhancement.py +321 -0
  440. control_plane_api/worker/tests/unit/test_system_prompt_enhancement.py +415 -0
  441. control_plane_api/worker/tests/unit/test_tool_enforcement.py +324 -0
  442. control_plane_api/worker/utils/__init__.py +1 -0
  443. control_plane_api/worker/utils/chunk_batcher.py +330 -0
  444. control_plane_api/worker/utils/environment.py +65 -0
  445. control_plane_api/worker/utils/error_publisher.py +260 -0
  446. control_plane_api/worker/utils/event_batcher.py +256 -0
  447. control_plane_api/worker/utils/logging_config.py +335 -0
  448. control_plane_api/worker/utils/logging_helper.py +326 -0
  449. control_plane_api/worker/utils/parameter_validator.py +120 -0
  450. control_plane_api/worker/utils/retry_utils.py +60 -0
  451. control_plane_api/worker/utils/streaming_utils.py +665 -0
  452. control_plane_api/worker/utils/tool_validation.py +332 -0
  453. control_plane_api/worker/utils/workspace_manager.py +163 -0
  454. control_plane_api/worker/websocket_client.py +393 -0
  455. control_plane_api/worker/worker.py +1297 -0
  456. control_plane_api/worker/workflows/__init__.py +0 -0
  457. control_plane_api/worker/workflows/agent_execution.py +909 -0
  458. control_plane_api/worker/workflows/scheduled_job_wrapper.py +332 -0
  459. control_plane_api/worker/workflows/team_execution.py +611 -0
  460. kubiya_control_plane_api-0.9.15.dist-info/METADATA +354 -0
  461. kubiya_control_plane_api-0.9.15.dist-info/RECORD +479 -0
  462. kubiya_control_plane_api-0.9.15.dist-info/WHEEL +5 -0
  463. kubiya_control_plane_api-0.9.15.dist-info/entry_points.txt +5 -0
  464. kubiya_control_plane_api-0.9.15.dist-info/licenses/LICENSE +676 -0
  465. kubiya_control_plane_api-0.9.15.dist-info/top_level.txt +3 -0
  466. scripts/__init__.py +1 -0
  467. scripts/migrations.py +39 -0
  468. scripts/seed_worker_queues.py +128 -0
  469. scripts/setup_agent_runtime.py +142 -0
  470. worker_internal/__init__.py +1 -0
  471. worker_internal/planner/__init__.py +1 -0
  472. worker_internal/planner/activities.py +1499 -0
  473. worker_internal/planner/agent_tools.py +197 -0
  474. worker_internal/planner/event_models.py +148 -0
  475. worker_internal/planner/event_publisher.py +67 -0
  476. worker_internal/planner/models.py +199 -0
  477. worker_internal/planner/retry_logic.py +134 -0
  478. worker_internal/planner/worker.py +300 -0
  479. worker_internal/planner/workflows.py +970 -0
@@ -0,0 +1,469 @@
1
+ """Workflow Executor Skill - Execute workflows defined via JSON or Python DSL."""
2
+ import json
3
+ import sys
4
+ import traceback
5
+ from io import StringIO
6
+ from typing import Any, Dict, List, Optional
7
+
8
+ from pydantic import BaseModel, Field, validator
9
+
10
+ from control_plane_api.app.skills.base import SkillDefinition, SkillType, SkillCategory, SkillVariant, SkillRequirements
11
+
12
+
13
+ class WorkflowStepConfig(BaseModel):
14
+ """Configuration for a workflow step."""
15
+ name: str = Field(..., description="Step name")
16
+ description: Optional[str] = Field(None, description="Step description")
17
+ executor: Dict[str, Any] = Field(..., description="Executor configuration (type, config)")
18
+ depends_on: Optional[List[str]] = Field(None, description="Step dependencies")
19
+
20
+
21
+ class WorkflowTriggerConfig(BaseModel):
22
+ """Configuration for a workflow trigger."""
23
+ type: str = Field(..., description="Trigger type (manual, cron, webhook)")
24
+ config: Dict[str, Any] = Field(default_factory=dict, description="Trigger configuration")
25
+ runner: Optional[str] = Field(None, description="Runner/environment name")
26
+
27
+
28
+ class WorkflowDefinitionConfig(BaseModel):
29
+ """Workflow definition in JSON format."""
30
+ name: str = Field(..., description="Workflow name")
31
+ description: Optional[str] = Field(None, description="Workflow description")
32
+ steps: List[Dict[str, Any]] = Field(..., min_items=1, description="Workflow steps")
33
+ triggers: Optional[List[Dict[str, Any]]] = Field(None, description="Workflow triggers")
34
+ runner: Optional[str] = Field(None, description="Default runner/environment")
35
+ parameters: Optional[Dict[str, Any]] = Field(
36
+ None,
37
+ description="Parameter schema - defines available parameters (name, type, description). Agent fills values dynamically at runtime."
38
+ )
39
+
40
+ @validator('steps')
41
+ def validate_steps(cls, steps):
42
+ """Validate that steps have required fields."""
43
+ if not steps:
44
+ raise ValueError("Workflow must have at least one step")
45
+
46
+ step_names = set()
47
+ for step in steps:
48
+ if 'name' not in step:
49
+ raise ValueError("Each step must have a 'name' field")
50
+ if step['name'] in step_names:
51
+ raise ValueError(f"Duplicate step name: {step['name']}")
52
+ step_names.add(step['name'])
53
+
54
+ if 'executor' not in step:
55
+ raise ValueError(f"Step '{step['name']}' must have an 'executor' field")
56
+
57
+ executor = step['executor']
58
+ if not isinstance(executor, dict) or 'type' not in executor:
59
+ raise ValueError(f"Step '{step['name']}' executor must be a dict with 'type' field")
60
+
61
+ return steps
62
+
63
+
64
+ class WorkflowExecutorConfiguration(BaseModel):
65
+ """Configuration for the Workflow Executor skill."""
66
+
67
+ workflows: List[Dict[str, Any]] = Field(
68
+ default_factory=list,
69
+ description="Collection of workflow definitions. Each workflow becomes a separate tool."
70
+ )
71
+
72
+ validation_enabled: bool = Field(
73
+ True,
74
+ description="Enable workflow validation before saving"
75
+ )
76
+
77
+ default_runner: Optional[str] = Field(
78
+ None,
79
+ description="Default runner/environment for workflow execution"
80
+ )
81
+
82
+ timeout: int = Field(
83
+ 3600,
84
+ ge=30,
85
+ le=7200,
86
+ description="Maximum workflow execution timeout in seconds (30s - 2h)"
87
+ )
88
+
89
+ default_parameters: Optional[Dict[str, Any]] = Field(
90
+ None,
91
+ description="Default parameter values (optional). Used only if agent doesn't provide values at runtime."
92
+ )
93
+
94
+ # Legacy fields for backwards compatibility
95
+ workflow_type: Optional[str] = Field(
96
+ None,
97
+ description="LEGACY: Type of workflow definition: 'json' or 'python_dsl'"
98
+ )
99
+
100
+ workflow_definition: Optional[str] = Field(
101
+ None,
102
+ description="LEGACY: JSON workflow definition as a string"
103
+ )
104
+
105
+ python_dsl_code: Optional[str] = Field(
106
+ None,
107
+ description="LEGACY: Python DSL code for workflow definition"
108
+ )
109
+
110
+ @validator('workflows')
111
+ def validate_workflows(cls, v, values):
112
+ """Validate workflows collection."""
113
+ if not v:
114
+ # Check if using legacy fields
115
+ if values.get('workflow_definition') or values.get('python_dsl_code'):
116
+ return v # Allow empty if using legacy mode
117
+ raise ValueError("At least one workflow must be defined in 'workflows' array")
118
+
119
+ validation_enabled = values.get('validation_enabled', True)
120
+
121
+ workflow_names = set()
122
+ for idx, workflow in enumerate(v):
123
+ # Each workflow must have required fields
124
+ if 'name' not in workflow:
125
+ raise ValueError(f"Workflow at index {idx} missing 'name' field")
126
+
127
+ if 'type' not in workflow:
128
+ raise ValueError(f"Workflow '{workflow['name']}' missing 'type' field (json or python_dsl)")
129
+
130
+ # Check for duplicate names
131
+ name = workflow['name']
132
+ if name in workflow_names:
133
+ raise ValueError(f"Duplicate workflow name: {name}")
134
+ workflow_names.add(name)
135
+
136
+ # Validate based on type
137
+ wf_type = workflow['type']
138
+ if wf_type not in ['json', 'python_dsl']:
139
+ raise ValueError(f"Workflow '{name}' has invalid type: {wf_type}")
140
+
141
+ if wf_type == 'json':
142
+ if 'definition' not in workflow:
143
+ raise ValueError(f"JSON workflow '{name}' missing 'definition' field")
144
+
145
+ if validation_enabled:
146
+ try:
147
+ # Validate JSON structure
148
+ if isinstance(workflow['definition'], str):
149
+ workflow_data = json.loads(workflow['definition'])
150
+ else:
151
+ workflow_data = workflow['definition']
152
+
153
+ # Validate using WorkflowDefinitionConfig
154
+ WorkflowDefinitionConfig(**workflow_data)
155
+ except json.JSONDecodeError as e:
156
+ raise ValueError(f"Workflow '{name}' has invalid JSON: {str(e)}")
157
+ except Exception as e:
158
+ raise ValueError(f"Workflow '{name}' validation failed: {str(e)}")
159
+
160
+ elif wf_type == 'python_dsl':
161
+ if 'code' not in workflow:
162
+ raise ValueError(f"Python DSL workflow '{name}' missing 'code' field")
163
+
164
+ if validation_enabled:
165
+ try:
166
+ compile(workflow['code'], f'<workflow:{name}>', 'exec')
167
+ except SyntaxError as e:
168
+ raise ValueError(f"Workflow '{name}' has invalid Python syntax: {str(e)}")
169
+
170
+ return v
171
+
172
+ @validator('workflow_type')
173
+ def validate_workflow_type(cls, v):
174
+ """Validate workflow type (legacy)."""
175
+ if v and v not in ['json', 'python_dsl']:
176
+ raise ValueError("workflow_type must be 'json' or 'python_dsl'")
177
+ return v
178
+
179
+ @validator('workflow_definition')
180
+ def validate_workflow_definition(cls, v, values):
181
+ """Validate JSON workflow definition (legacy)."""
182
+ if v and values.get('validation_enabled', True):
183
+ try:
184
+ workflow_data = json.loads(v)
185
+ # Validate using WorkflowDefinitionConfig
186
+ WorkflowDefinitionConfig(**workflow_data)
187
+ except json.JSONDecodeError as e:
188
+ raise ValueError(f"Invalid JSON in workflow_definition: {str(e)}")
189
+ except Exception as e:
190
+ raise ValueError(f"Invalid workflow definition: {str(e)}")
191
+ return v
192
+
193
+ @validator('python_dsl_code')
194
+ def validate_python_dsl_code(cls, v, values):
195
+ """Validate Python DSL code (legacy)."""
196
+ if v and values.get('validation_enabled', True):
197
+ try:
198
+ compile(v, '<workflow>', 'exec')
199
+ except SyntaxError as e:
200
+ raise ValueError(f"Invalid Python syntax in DSL code: {str(e)}")
201
+ return v
202
+
203
+
204
+ class WorkflowExecutorSkill(SkillDefinition):
205
+ """Workflow Executor Skill - Execute workflows defined via JSON or Python DSL.
206
+
207
+ This skill allows defining and executing workflows using either:
208
+ 1. JSON workflow definitions with steps and executors
209
+ 2. Python DSL using the kubiya-sdk
210
+
211
+ Workflows are validated before saving and can be executed via the control plane.
212
+ """
213
+
214
+ @property
215
+ def type(self) -> SkillType:
216
+ """Return the skill type."""
217
+ return SkillType.WORKFLOW_EXECUTOR
218
+
219
+ @property
220
+ def name(self) -> str:
221
+ """Return the skill name."""
222
+ return "Workflow Executor"
223
+
224
+ @property
225
+ def description(self) -> str:
226
+ """Return the skill description."""
227
+ return (
228
+ "Execute workflows defined via JSON or Python DSL. "
229
+ "Supports complex multi-step workflows with dependencies, "
230
+ "conditional execution, and various executor types."
231
+ )
232
+
233
+ @property
234
+ def icon(self) -> str:
235
+ """Return the skill icon."""
236
+ return "Workflow"
237
+
238
+ @property
239
+ def icon_type(self) -> str:
240
+ """Return the icon type."""
241
+ return "lucide"
242
+
243
+ def get_variants(self) -> List[SkillVariant]:
244
+ """Return single workflow executor variant with empty configuration for user to fill."""
245
+ return [
246
+ SkillVariant(
247
+ id="workflow_executor",
248
+ name="Workflow Executor",
249
+ description="Execute workflows with dynamic parameters. Agent fills parameter values at runtime based on user requests.",
250
+ category=SkillCategory.ADVANCED,
251
+ configuration={
252
+ "workflows": [
253
+ {
254
+ "name": "deploy-app",
255
+ "type": "json",
256
+ "definition": {
257
+ "name": "deploy-app",
258
+ "description": "Deploy application to specified environment",
259
+ "runner": "kubiya-prod",
260
+ "parameters": {
261
+ "app_name": {
262
+ "type": "string",
263
+ "description": "Application name to deploy"
264
+ },
265
+ "environment": {
266
+ "type": "string",
267
+ "description": "Target environment (dev, staging, prod)"
268
+ },
269
+ "version": {
270
+ "type": "string",
271
+ "description": "Version to deploy"
272
+ }
273
+ },
274
+ "steps": [
275
+ {
276
+ "name": "deploy",
277
+ "description": "Deploy application",
278
+ "executor": {
279
+ "type": "shell",
280
+ "config": {
281
+ "command": "kubectl apply -f deploy.yaml --namespace={{environment}} && kubectl set image deployment/{{app_name}} app={{app_name}}:{{version}}"
282
+ }
283
+ }
284
+ }
285
+ ]
286
+ }
287
+ }
288
+ ],
289
+ "validation_enabled": True,
290
+ "default_runner": "kubiya-prod",
291
+ "timeout": 3600,
292
+ "default_parameters": {
293
+ "environment": "staging"
294
+ }
295
+ },
296
+ icon="Workflow",
297
+ is_default=True
298
+ )
299
+ ]
300
+
301
+ def validate_configuration(self, config: Dict[str, Any]) -> Dict[str, Any]:
302
+ """Validate the workflow executor configuration.
303
+
304
+ Args:
305
+ config: Configuration dictionary to validate
306
+
307
+ Returns:
308
+ Validated and normalized configuration
309
+
310
+ Raises:
311
+ ValueError: If configuration is invalid
312
+ """
313
+ try:
314
+ # Use Pydantic model for validation
315
+ validated = WorkflowExecutorConfiguration(**config)
316
+
317
+ # Additional validation for workflow execution
318
+ if validated.workflow_type == 'json' and validated.workflow_definition:
319
+ workflow_data = json.loads(validated.workflow_definition)
320
+ # Ensure step dependencies are valid
321
+ step_names = {step['name'] for step in workflow_data.get('steps', [])}
322
+ for step in workflow_data.get('steps', []):
323
+ depends_on = step.get('depends_on', [])
324
+ if depends_on:
325
+ for dep in depends_on:
326
+ if dep not in step_names:
327
+ raise ValueError(
328
+ f"Step '{step['name']}' depends on non-existent step: {dep}"
329
+ )
330
+
331
+ elif validated.workflow_type == 'python_dsl' and validated.python_dsl_code:
332
+ # Try to execute the DSL code to validate it can create a workflow
333
+ if validated.validation_enabled:
334
+ self._validate_python_dsl(validated.python_dsl_code)
335
+
336
+ return validated.dict()
337
+
338
+ except Exception as e:
339
+ raise ValueError(f"Workflow executor configuration validation failed: {str(e)}")
340
+
341
+ def _validate_python_dsl(self, dsl_code: str) -> None:
342
+ """Validate Python DSL code by attempting to compile and check imports.
343
+
344
+ Args:
345
+ dsl_code: Python DSL code to validate
346
+
347
+ Raises:
348
+ ValueError: If DSL code is invalid
349
+ """
350
+ try:
351
+ # First check if kubiya_sdk is available
352
+ try:
353
+ import kubiya_sdk
354
+ except ImportError:
355
+ raise ValueError(
356
+ "kubiya-sdk is not installed. Please install it to use Python DSL workflows."
357
+ )
358
+
359
+ # Compile the code to check for syntax errors
360
+ try:
361
+ compile(dsl_code, '<workflow>', 'exec')
362
+ except SyntaxError as e:
363
+ raise ValueError(f"Python syntax error in DSL code: {str(e)}")
364
+
365
+ # Create a restricted execution environment
366
+ namespace = {
367
+ '__builtins__': __builtins__,
368
+ }
369
+
370
+ # Import kubiya_sdk modules for validation
371
+ try:
372
+ from kubiya_sdk import StatefulWorkflow, Tool
373
+ from kubiya_sdk.workflows import step, tool_step
374
+ namespace.update({
375
+ 'StatefulWorkflow': StatefulWorkflow,
376
+ 'Tool': Tool,
377
+ 'step': step,
378
+ 'tool_step': tool_step,
379
+ })
380
+ except ImportError as e:
381
+ raise ValueError(f"Failed to import kubiya_sdk modules: {str(e)}")
382
+
383
+ # Capture stdout/stderr during validation
384
+ old_stdout = sys.stdout
385
+ old_stderr = sys.stderr
386
+ stdout_capture = StringIO()
387
+ stderr_capture = StringIO()
388
+
389
+ try:
390
+ sys.stdout = stdout_capture
391
+ sys.stderr = stderr_capture
392
+
393
+ # Execute the DSL code
394
+ exec(dsl_code, namespace)
395
+
396
+ # Check if a workflow was created
397
+ workflow_found = False
398
+ for name, obj in namespace.items():
399
+ if name.startswith('_'):
400
+ continue
401
+ # Check for StatefulWorkflow instance
402
+ if hasattr(obj, '__class__'):
403
+ class_name = obj.__class__.__name__
404
+ if 'StatefulWorkflow' in class_name or 'Workflow' in class_name:
405
+ workflow_found = True
406
+ break
407
+
408
+ if not workflow_found:
409
+ raise ValueError(
410
+ "Python DSL code must create a StatefulWorkflow instance. "
411
+ "Example: workflow = StatefulWorkflow(name='my-workflow', description='...')"
412
+ )
413
+
414
+ finally:
415
+ sys.stdout = old_stdout
416
+ sys.stderr = old_stderr
417
+
418
+ # Check for any errors in stderr
419
+ stderr_output = stderr_capture.getvalue()
420
+ if stderr_output and 'error' in stderr_output.lower():
421
+ raise ValueError(f"Python DSL execution produced errors: {stderr_output}")
422
+
423
+ except ValueError:
424
+ raise
425
+ except Exception as e:
426
+ raise ValueError(f"Python DSL validation failed: {str(e)}\n{traceback.format_exc()}")
427
+
428
+ def get_default_configuration(self) -> Dict[str, Any]:
429
+ """Return the default configuration."""
430
+ return {
431
+ "workflow_type": "json",
432
+ "validation_enabled": True,
433
+ "timeout": 3600,
434
+ "workflow_definition": json.dumps({
435
+ "name": "new-workflow",
436
+ "description": "New workflow",
437
+ "steps": [
438
+ {
439
+ "name": "step-1",
440
+ "description": "First step",
441
+ "executor": {
442
+ "type": "shell",
443
+ "config": {
444
+ "command": "echo 'Hello World'"
445
+ }
446
+ }
447
+ }
448
+ ]
449
+ }, indent=2)
450
+ }
451
+
452
+ def get_framework_class_name(self) -> str:
453
+ """Return the framework class name for this skill."""
454
+ return "WorkflowExecutorTool"
455
+
456
+ def get_requirements(self) -> SkillRequirements:
457
+ """Return the skill requirements."""
458
+ return SkillRequirements(
459
+ supported_os=["linux", "darwin", "win32"],
460
+ min_python_version="3.10",
461
+ python_packages=["kubiya-sdk"],
462
+ required_env_vars=[],
463
+ notes="Optional env vars: KUBIYA_API_KEY, KUBIYA_API_URL for workflow execution"
464
+ )
465
+
466
+
467
+ # Auto-register this skill
468
+ from control_plane_api.app.skills.registry import register_skill
469
+ register_skill(WorkflowExecutorSkill())
@@ -0,0 +1,189 @@
1
+ """
2
+ Business Intelligence Skill
3
+
4
+ Provides comprehensive BI capabilities including database querying, analytics,
5
+ visualization generation, and multi-agent analysis. Supports PostgreSQL, MySQL,
6
+ MongoDB, and file-based data sources (CSV, JSON, Parquet, Excel).
7
+ """
8
+ from typing import Dict, Any, List
9
+ from .base import SkillDefinition, SkillType, SkillCategory, SkillVariant
10
+ from .registry import register_skill
11
+
12
+
13
+ class BusinessIntelligenceSkill(SkillDefinition):
14
+ """Business Intelligence and Analytics skill"""
15
+
16
+ @property
17
+ def type(self) -> SkillType:
18
+ return SkillType.BUSINESS_INTELLIGENCE
19
+
20
+ @property
21
+ def name(self) -> str:
22
+ return "Business Intelligence"
23
+
24
+ @property
25
+ def description(self) -> str:
26
+ return "Advanced BI and analytics with multi-agent analysis, database querying, and interactive visualizations"
27
+
28
+ @property
29
+ def icon(self) -> str:
30
+ return "BarChart"
31
+
32
+ def get_variants(self) -> List[SkillVariant]:
33
+ return [
34
+ SkillVariant(
35
+ id="bi_full",
36
+ name="Full BI Suite",
37
+ description="Complete BI capabilities with all data sources and analytics features",
38
+ category=SkillCategory.ADVANCED,
39
+ badge="Recommended",
40
+ icon="BarChart",
41
+ configuration={
42
+ "data_sources": [
43
+ {
44
+ "id": "default_postgres",
45
+ "name": "PostgreSQL Database",
46
+ "type": "postgresql",
47
+ "connection": {
48
+ "host": "${POSTGRES_HOST}",
49
+ "port": "${POSTGRES_PORT:5432}",
50
+ "database": "${POSTGRES_DB}",
51
+ "username": "${POSTGRES_USER}",
52
+ "password": "${POSTGRES_PASSWORD}",
53
+ "ssl": True,
54
+ "pool_size": 5
55
+ },
56
+ "query_limits": {
57
+ "max_rows": 10000,
58
+ "timeout_seconds": 30
59
+ }
60
+ }
61
+ ],
62
+ "security": {
63
+ "allowed_sql_commands": ["SELECT"],
64
+ "deny_patterns": ["DROP", "DELETE", "TRUNCATE", "ALTER", "INSERT", "UPDATE"]
65
+ },
66
+ "features": {
67
+ "enable_multi_agent": True,
68
+ "enable_visualizations": True,
69
+ "enable_schema_introspection": True,
70
+ "enable_query_validation": True
71
+ }
72
+ },
73
+ is_default=True,
74
+ ),
75
+ SkillVariant(
76
+ id="bi_read_only",
77
+ name="Read-Only BI",
78
+ description="Safe, read-only analytics with SELECT-only permissions",
79
+ category=SkillCategory.COMMON,
80
+ badge="Safe",
81
+ icon="Eye",
82
+ configuration={
83
+ "data_sources": [], # Configured per agent
84
+ "security": {
85
+ "allowed_sql_commands": ["SELECT"],
86
+ "deny_patterns": ["DROP", "DELETE", "TRUNCATE", "ALTER", "INSERT", "UPDATE", "CREATE"]
87
+ },
88
+ "features": {
89
+ "enable_multi_agent": True,
90
+ "enable_visualizations": True,
91
+ "enable_schema_introspection": True,
92
+ "enable_query_validation": True
93
+ }
94
+ },
95
+ is_default=False,
96
+ ),
97
+ SkillVariant(
98
+ id="bi_file_analysis",
99
+ name="File Analysis",
100
+ description="Analyze CSV, JSON, Parquet, and Excel files without database access",
101
+ category=SkillCategory.COMMON,
102
+ badge="Simple",
103
+ icon="FileSpreadsheet",
104
+ configuration={
105
+ "data_sources": [],
106
+ "security": {
107
+ "allowed_sql_commands": ["SELECT"],
108
+ "deny_patterns": []
109
+ },
110
+ "features": {
111
+ "enable_multi_agent": True,
112
+ "enable_visualizations": True,
113
+ "enable_schema_introspection": True,
114
+ "enable_query_validation": False,
115
+ "supported_formats": ["csv", "json", "parquet", "excel"]
116
+ }
117
+ },
118
+ is_default=False,
119
+ ),
120
+ SkillVariant(
121
+ id="bi_custom",
122
+ name="Custom BI Configuration",
123
+ description="Fully customizable BI setup with user-defined data sources and security policies",
124
+ category=SkillCategory.ADVANCED,
125
+ badge="Flexible",
126
+ icon="Settings",
127
+ configuration={
128
+ "data_sources": [],
129
+ "security": {
130
+ "allowed_sql_commands": ["SELECT"],
131
+ "deny_patterns": []
132
+ },
133
+ "features": {
134
+ "enable_multi_agent": True,
135
+ "enable_visualizations": True,
136
+ "enable_schema_introspection": True,
137
+ "enable_query_validation": True
138
+ }
139
+ },
140
+ is_default=False,
141
+ ),
142
+ ]
143
+
144
+ def validate_configuration(self, config: Dict[str, Any]) -> bool:
145
+ """Validate BI skill configuration"""
146
+ required_keys = ["data_sources", "security", "features"]
147
+
148
+ # Check required top-level keys
149
+ for key in required_keys:
150
+ if key not in config:
151
+ return False
152
+
153
+ # Validate security config
154
+ if "security" in config:
155
+ security = config["security"]
156
+ if "allowed_sql_commands" not in security:
157
+ return False
158
+ if not isinstance(security["allowed_sql_commands"], list):
159
+ return False
160
+
161
+ # Validate data sources
162
+ if "data_sources" in config:
163
+ for ds in config["data_sources"]:
164
+ if "id" not in ds or "type" not in ds:
165
+ return False
166
+ if "connection" not in ds:
167
+ return False
168
+
169
+ return True
170
+
171
+ def get_default_configuration(self) -> Dict[str, Any]:
172
+ """Get default configuration for BI skill"""
173
+ return {
174
+ "data_sources": [],
175
+ "security": {
176
+ "allowed_sql_commands": ["SELECT"],
177
+ "deny_patterns": ["DROP", "DELETE", "TRUNCATE", "ALTER", "INSERT", "UPDATE"]
178
+ },
179
+ "features": {
180
+ "enable_multi_agent": True,
181
+ "enable_visualizations": True,
182
+ "enable_schema_introspection": True,
183
+ "enable_query_validation": True
184
+ }
185
+ }
186
+
187
+
188
+ # Register the skill
189
+ register_skill(BusinessIntelligenceToolSet())