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,302 @@
1
+ """
2
+ Pydantic schemas for Jobs API.
3
+
4
+ This module defines request/response schemas for the Jobs CRUD API.
5
+ """
6
+
7
+ from pydantic import BaseModel, Field, field_validator, model_validator
8
+ from typing import Optional, Dict, List, Any
9
+ from datetime import datetime
10
+ from croniter import croniter
11
+
12
+
13
+ class ExecutionEnvironment(BaseModel):
14
+ """Execution environment configuration for jobs"""
15
+ env_vars: Dict[str, str] = Field(default_factory=dict, description="Environment variables (key-value pairs)")
16
+ secrets: List[str] = Field(default_factory=list, description="Secret names from Kubiya vault")
17
+ integration_ids: List[str] = Field(default_factory=list, description="Integration UUIDs for delegated credentials")
18
+ mcp_servers: Dict[str, Dict] = Field(
19
+ default_factory=dict,
20
+ description="MCP (Model Context Protocol) server configurations. Supports stdio, HTTP, and SSE transports."
21
+ )
22
+
23
+
24
+ class JobCreate(BaseModel):
25
+ """Schema for creating a new job"""
26
+ name: str = Field(..., description="Job name", min_length=1, max_length=255)
27
+ description: Optional[str] = Field(None, description="Job description")
28
+ enabled: bool = Field(True, description="Whether the job is enabled")
29
+
30
+ # Trigger configuration
31
+ trigger_type: str = Field(..., description="Trigger type: 'cron', 'webhook', or 'manual'")
32
+
33
+ # Cron configuration (required if trigger_type is 'cron')
34
+ cron_schedule: Optional[str] = Field(None, description="Cron expression (e.g., '0 17 * * *' for daily at 5pm)")
35
+ cron_timezone: Optional[str] = Field("UTC", description="Timezone for cron schedule (e.g., 'America/New_York')")
36
+
37
+ # Planning and execution configuration
38
+ planning_mode: str = Field(
39
+ default="predefined_agent",
40
+ description="Planning mode: 'on_the_fly', 'predefined_agent', 'predefined_team', or 'predefined_workflow'"
41
+ )
42
+
43
+ # Entity to execute (required for predefined modes)
44
+ entity_type: Optional[str] = Field(None, description="Entity type: 'agent', 'team', or 'workflow'")
45
+ entity_id: Optional[str] = Field(None, description="Entity ID (agent_id, team_id, or workflow_id)")
46
+
47
+ # Prompt configuration
48
+ prompt_template: str = Field(..., description="Prompt template (can include {{variables}} for dynamic params)")
49
+ system_prompt: Optional[str] = Field(None, description="Optional system prompt")
50
+
51
+ # Executor routing configuration
52
+ executor_type: str = Field(
53
+ default="auto",
54
+ description="Executor routing: 'auto', 'specific_queue', or 'environment'"
55
+ )
56
+ worker_queue_name: Optional[str] = Field(None, description="Worker queue name for 'specific_queue' executor type")
57
+ environment_name: Optional[str] = Field(None, description="Environment name for 'environment' executor type")
58
+
59
+ # Execution configuration
60
+ config: Dict[str, Any] = Field(default_factory=dict, description="Additional execution config (timeout, retry, etc.)")
61
+ execution_environment: Optional[ExecutionEnvironment] = Field(
62
+ None,
63
+ description="Execution environment: env vars, secrets, integrations"
64
+ )
65
+
66
+ @field_validator("trigger_type")
67
+ @classmethod
68
+ def validate_trigger_type(cls, v):
69
+ valid_types = ["cron", "webhook", "manual"]
70
+ if v not in valid_types:
71
+ raise ValueError(f"trigger_type must be one of {valid_types}")
72
+ return v
73
+
74
+ @field_validator("planning_mode")
75
+ @classmethod
76
+ def validate_planning_mode(cls, v):
77
+ valid_modes = ["on_the_fly", "predefined_agent", "predefined_team", "predefined_workflow"]
78
+ if v not in valid_modes:
79
+ raise ValueError(f"planning_mode must be one of {valid_modes}")
80
+ return v
81
+
82
+ @field_validator("executor_type")
83
+ @classmethod
84
+ def validate_executor_type(cls, v):
85
+ valid_types = ["auto", "specific_queue", "environment"]
86
+ if v not in valid_types:
87
+ raise ValueError(f"executor_type must be one of {valid_types}")
88
+ return v
89
+
90
+ @field_validator("cron_schedule")
91
+ @classmethod
92
+ def validate_cron_schedule(cls, v):
93
+ if v is not None:
94
+ # Validate cron expression
95
+ try:
96
+ croniter(v)
97
+ except Exception as e:
98
+ raise ValueError(f"Invalid cron expression: {str(e)}")
99
+ return v
100
+
101
+ @model_validator(mode='after')
102
+ def validate_cross_field_dependencies(self):
103
+ # Validate cron_schedule required for cron trigger
104
+ if self.trigger_type == "cron" and not self.cron_schedule:
105
+ raise ValueError("cron_schedule is required when trigger_type is 'cron'")
106
+
107
+ # Validate entity_id required for predefined modes
108
+ if self.planning_mode in ["predefined_agent", "predefined_team", "predefined_workflow"] and not self.entity_id:
109
+ raise ValueError(f"entity_id is required when planning_mode is '{self.planning_mode}'")
110
+
111
+ # Validate worker_queue_name for specific_queue executor
112
+ if self.executor_type == "specific_queue" and not self.worker_queue_name:
113
+ raise ValueError("worker_queue_name is required when executor_type is 'specific_queue'")
114
+
115
+ # Validate environment_name for environment executor
116
+ if self.executor_type == "environment" and not self.environment_name:
117
+ raise ValueError("environment_name is required when executor_type is 'environment'")
118
+
119
+ return self
120
+
121
+
122
+ class JobUpdate(BaseModel):
123
+ """Schema for updating an existing job"""
124
+ name: Optional[str] = Field(None, min_length=1, max_length=255)
125
+ description: Optional[str] = None
126
+ enabled: Optional[bool] = None
127
+
128
+ # Trigger configuration
129
+ trigger_type: Optional[str] = None
130
+ cron_schedule: Optional[str] = None
131
+ cron_timezone: Optional[str] = None
132
+
133
+ # Planning and execution configuration
134
+ planning_mode: Optional[str] = None
135
+ entity_type: Optional[str] = None
136
+ entity_id: Optional[str] = None
137
+
138
+ # Prompt configuration
139
+ prompt_template: Optional[str] = None
140
+ system_prompt: Optional[str] = None
141
+
142
+ # Executor routing configuration
143
+ executor_type: Optional[str] = None
144
+ worker_queue_name: Optional[str] = None
145
+ environment_name: Optional[str] = None
146
+
147
+ # Execution configuration
148
+ config: Optional[Dict[str, Any]] = None
149
+ execution_environment: Optional[ExecutionEnvironment] = None
150
+
151
+ @field_validator("trigger_type")
152
+ @classmethod
153
+ def validate_trigger_type(cls, v):
154
+ if v is not None:
155
+ valid_types = ["cron", "webhook", "manual"]
156
+ if v not in valid_types:
157
+ raise ValueError(f"trigger_type must be one of {valid_types}")
158
+ return v
159
+
160
+ @field_validator("planning_mode")
161
+ @classmethod
162
+ def validate_planning_mode(cls, v):
163
+ if v is not None:
164
+ valid_modes = ["on_the_fly", "predefined_agent", "predefined_team", "predefined_workflow"]
165
+ if v not in valid_modes:
166
+ raise ValueError(f"planning_mode must be one of {valid_modes}")
167
+ return v
168
+
169
+ @field_validator("executor_type")
170
+ @classmethod
171
+ def validate_executor_type(cls, v):
172
+ if v is not None:
173
+ valid_types = ["auto", "specific_queue", "environment"]
174
+ if v not in valid_types:
175
+ raise ValueError(f"executor_type must be one of {valid_types}")
176
+ return v
177
+
178
+ @field_validator("cron_schedule")
179
+ @classmethod
180
+ def validate_cron_schedule(cls, v):
181
+ if v is not None:
182
+ try:
183
+ croniter(v)
184
+ except Exception as e:
185
+ raise ValueError(f"Invalid cron expression: {str(e)}")
186
+ return v
187
+
188
+
189
+ class JobResponse(BaseModel):
190
+ """Schema for job response"""
191
+ id: str
192
+ organization_id: str
193
+ name: str
194
+ description: Optional[str]
195
+ enabled: bool
196
+ status: str
197
+
198
+ # Trigger configuration
199
+ trigger_type: str
200
+ cron_schedule: Optional[str]
201
+ cron_timezone: Optional[str]
202
+ webhook_url: Optional[str] = Field(None, description="Full webhook URL (generated from webhook_url_path)")
203
+ webhook_secret: Optional[str] = Field(None, description="Webhook HMAC secret for signature verification")
204
+ temporal_schedule_id: Optional[str]
205
+
206
+ # Planning and execution configuration
207
+ planning_mode: str
208
+ entity_type: Optional[str]
209
+ entity_id: Optional[str]
210
+ entity_name: Optional[str]
211
+
212
+ # Prompt configuration
213
+ prompt_template: str
214
+ system_prompt: Optional[str]
215
+
216
+ # Executor routing configuration
217
+ executor_type: str
218
+ worker_queue_name: Optional[str]
219
+ environment_name: Optional[str]
220
+
221
+ # Execution configuration
222
+ config: Dict[str, Any]
223
+ execution_environment: Optional[ExecutionEnvironment]
224
+
225
+ # Execution tracking
226
+ last_execution_id: Optional[str]
227
+ last_execution_at: Optional[datetime]
228
+ next_execution_at: Optional[datetime]
229
+ total_executions: int
230
+ successful_executions: int
231
+ failed_executions: int
232
+ execution_history: List[Dict[str, Any]]
233
+
234
+ # Audit fields
235
+ created_by: Optional[str]
236
+ updated_by: Optional[str]
237
+ created_by_email: Optional[str] = Field(None, description="Email of the user who created the job (enriched)")
238
+ updated_by_email: Optional[str] = Field(None, description="Email of the user who last updated the job (enriched)")
239
+
240
+ # Timestamps
241
+ created_at: datetime
242
+ updated_at: datetime
243
+ last_triggered_at: Optional[datetime]
244
+
245
+ class Config:
246
+ from_attributes = True
247
+
248
+
249
+ class JobTriggerRequest(BaseModel):
250
+ """Schema for manually triggering a job"""
251
+ parameters: Dict[str, Any] = Field(
252
+ default_factory=dict,
253
+ description="Parameters to substitute in prompt template (e.g., {{param_name}})"
254
+ )
255
+ config_override: Optional[Dict[str, Any]] = Field(
256
+ None,
257
+ description="Optional config overrides for this execution"
258
+ )
259
+
260
+
261
+ class JobTriggerResponse(BaseModel):
262
+ """Schema for job trigger response"""
263
+ job_id: str
264
+ execution_id: str
265
+ workflow_id: str
266
+ status: str
267
+ message: str
268
+
269
+
270
+ class JobExecutionHistoryItem(BaseModel):
271
+ """Schema for a single job execution history item"""
272
+ execution_id: str
273
+ trigger_type: str
274
+ status: str
275
+ started_at: Optional[datetime]
276
+ completed_at: Optional[datetime]
277
+ duration_ms: Optional[int]
278
+ error_message: Optional[str]
279
+ trigger_metadata: Optional[Dict[str, Any]] = None
280
+
281
+
282
+ class JobExecutionHistoryResponse(BaseModel):
283
+ """Schema for job execution history response"""
284
+ job_id: str
285
+ total_count: int
286
+ executions: List[JobExecutionHistoryItem]
287
+
288
+
289
+ class WebhookPayload(BaseModel):
290
+ """Schema for webhook trigger payload"""
291
+ parameters: Dict[str, Any] = Field(
292
+ default_factory=dict,
293
+ description="Parameters to substitute in prompt template"
294
+ )
295
+ config_override: Optional[Dict[str, Any]] = Field(
296
+ None,
297
+ description="Optional config overrides for this execution"
298
+ )
299
+ metadata: Optional[Dict[str, Any]] = Field(
300
+ None,
301
+ description="Additional metadata for this webhook trigger"
302
+ )
@@ -0,0 +1,311 @@
1
+ """
2
+ Pydantic schemas for MCP (Model Context Protocol) server configurations.
3
+
4
+ Supports multiple transport types:
5
+ - stdio: External process communication via stdin/stdout
6
+ - http: HTTP-based communication
7
+ - sse: Server-Sent Events communication
8
+
9
+ All string fields support template syntax for dynamic value resolution.
10
+ """
11
+
12
+ from pydantic import BaseModel, Field, field_validator, model_validator, ConfigDict
13
+ from typing import Dict, List, Literal, Optional, Union, Any
14
+ from enum import Enum
15
+
16
+
17
+ class MCPTransportType(str, Enum):
18
+ """MCP server transport types."""
19
+ STDIO = "stdio"
20
+ HTTP = "http"
21
+ SSE = "sse"
22
+
23
+
24
+ class MCPServerStdioConfig(BaseModel):
25
+ """
26
+ Configuration for stdio-based MCP servers.
27
+
28
+ Stdio servers run as external processes and communicate via stdin/stdout.
29
+ Commonly used for local tools and CLI-based MCP servers.
30
+
31
+ All string fields support template syntax:
32
+ - {{variable}} - Simple variables
33
+ - {{.secret.name}} - Secrets from vault
34
+ - {{.env.VAR}} - Environment variables
35
+
36
+ Example:
37
+ {
38
+ "command": "python",
39
+ "args": ["-m", "mcp_server_filesystem"],
40
+ "env": {
41
+ "ALLOWED_PATHS": "{{.env.PROJECT_ROOT}}",
42
+ "API_KEY": "{{.secret.filesystem_key}}"
43
+ }
44
+ }
45
+ """
46
+ command: str = Field(
47
+ ...,
48
+ description="Command to execute (supports templates)",
49
+ min_length=1,
50
+ examples=["python", "node", "npx", "/usr/local/bin/mcp-server"]
51
+ )
52
+ args: List[str] = Field(
53
+ default_factory=list,
54
+ description="Command arguments (each arg supports templates)",
55
+ examples=[
56
+ ["-m", "mcp_server_filesystem"],
57
+ ["@modelcontextprotocol/server-filesystem", "{{.env.ROOT_PATH}}"]
58
+ ]
59
+ )
60
+ env: Dict[str, str] = Field(
61
+ default_factory=dict,
62
+ description="Environment variables (values support templates)",
63
+ examples=[
64
+ {"ALLOWED_PATHS": "/home/user/projects", "DEBUG": "{{.env.DEBUG_MODE}}"}
65
+ ]
66
+ )
67
+
68
+ @field_validator('command')
69
+ @classmethod
70
+ def validate_command(cls, v: str) -> str:
71
+ """Validate command is not empty after stripping."""
72
+ if not v.strip():
73
+ raise ValueError("Command cannot be empty or whitespace only")
74
+ return v.strip()
75
+
76
+ @field_validator('args')
77
+ @classmethod
78
+ def validate_args(cls, v: List[str]) -> List[str]:
79
+ """Validate args list doesn't contain empty strings."""
80
+ if any(not arg.strip() for arg in v):
81
+ raise ValueError("Arguments cannot contain empty or whitespace-only strings")
82
+ return [arg.strip() for arg in v]
83
+
84
+ model_config = ConfigDict(
85
+ json_schema_extra={
86
+ "example": {
87
+ "command": "python",
88
+ "args": ["-m", "mcp_server_filesystem"],
89
+ "env": {
90
+ "ALLOWED_PATHS": "{{.env.PROJECT_ROOT}}",
91
+ "LOG_LEVEL": "info"
92
+ }
93
+ }
94
+ }
95
+ )
96
+
97
+
98
+ class MCPServerHTTPConfig(BaseModel):
99
+ """
100
+ Configuration for HTTP/SSE-based MCP servers.
101
+
102
+ HTTP servers communicate over network using HTTP protocol or Server-Sent Events.
103
+ Useful for remote MCP servers and cloud-hosted tools.
104
+
105
+ All string fields support template syntax:
106
+ - {{variable}} - Simple variables
107
+ - {{.secret.name}} - Secrets from vault
108
+ - {{.env.VAR}} - Environment variables
109
+
110
+ Example:
111
+ {
112
+ "type": "sse",
113
+ "url": "https://{{.env.API_HOST}}/mcp/sse",
114
+ "headers": {
115
+ "Authorization": "Bearer {{.secret.api_token}}",
116
+ "X-API-Key": "{{.secret.api_key}}"
117
+ }
118
+ }
119
+ """
120
+ type: Literal["http", "sse"] = Field(
121
+ ...,
122
+ description="Transport type: 'http' for HTTP or 'sse' for Server-Sent Events"
123
+ )
124
+ url: str = Field(
125
+ ...,
126
+ description="Server URL (supports templates)",
127
+ min_length=1,
128
+ examples=[
129
+ "https://api.example.com/mcp",
130
+ "https://{{.env.MCP_HOST}}/sse",
131
+ "http://localhost:{{.env.MCP_PORT}}/mcp"
132
+ ]
133
+ )
134
+ headers: Dict[str, str] = Field(
135
+ default_factory=dict,
136
+ description="HTTP headers (values support templates)",
137
+ examples=[
138
+ {
139
+ "Authorization": "Bearer {{.secret.mcp_token}}",
140
+ "X-API-Key": "{{.secret.api_key}}",
141
+ "Content-Type": "application/json"
142
+ }
143
+ ]
144
+ )
145
+
146
+ @field_validator('url')
147
+ @classmethod
148
+ def validate_url(cls, v: str) -> str:
149
+ """Validate URL format (basic check, templates make full validation impossible)."""
150
+ v = v.strip()
151
+ if not v:
152
+ raise ValueError("URL cannot be empty")
153
+
154
+ # Basic sanity check - should start with http:// or https:// or contain template
155
+ if not (v.startswith(('http://', 'https://')) or '{{' in v):
156
+ raise ValueError("URL must start with http:// or https://, or contain templates")
157
+
158
+ return v
159
+
160
+ @field_validator('headers')
161
+ @classmethod
162
+ def validate_headers(cls, v: Dict[str, str]) -> Dict[str, str]:
163
+ """Validate headers don't have empty keys or values."""
164
+ for key, value in v.items():
165
+ if not key.strip():
166
+ raise ValueError("Header keys cannot be empty")
167
+ if not value.strip():
168
+ raise ValueError(f"Header value for '{key}' cannot be empty")
169
+ return v
170
+
171
+ model_config = ConfigDict(
172
+ json_schema_extra={
173
+ "example": {
174
+ "type": "sse",
175
+ "url": "https://api.example.com/mcp/sse",
176
+ "headers": {
177
+ "Authorization": "Bearer {{.secret.mcp_token}}",
178
+ "X-Organization": "{{.env.ORG_ID}}"
179
+ }
180
+ }
181
+ }
182
+ )
183
+
184
+
185
+ class MCPServerConfig(BaseModel):
186
+ """
187
+ Unified MCP server configuration supporting multiple transport types.
188
+
189
+ This schema uses discriminated union based on the presence of 'command' or 'type' field:
190
+ - If 'command' is present: stdio transport
191
+ - If 'type' is present: HTTP/SSE transport
192
+
193
+ The configuration is validated to ensure only one transport type is specified.
194
+ """
195
+ # Fields from stdio config
196
+ command: Optional[str] = Field(
197
+ None,
198
+ description="Command for stdio transport (mutually exclusive with url/type)"
199
+ )
200
+ args: Optional[List[str]] = Field(
201
+ None,
202
+ description="Arguments for stdio transport"
203
+ )
204
+ env: Optional[Dict[str, str]] = Field(
205
+ None,
206
+ description="Environment variables (used by both stdio and HTTP transports)"
207
+ )
208
+
209
+ # Fields from HTTP/SSE config
210
+ type: Optional[Literal["http", "sse"]] = Field(
211
+ None,
212
+ description="Transport type for HTTP/SSE (mutually exclusive with command)",
213
+ alias="transport_type" # Support both 'type' and 'transport_type' for backward compatibility
214
+ )
215
+ url: Optional[str] = Field(
216
+ None,
217
+ description="URL for HTTP/SSE transport (mutually exclusive with command)"
218
+ )
219
+ headers: Optional[Dict[str, str]] = Field(
220
+ None,
221
+ description="HTTP headers for HTTP/SSE transport"
222
+ )
223
+
224
+ @model_validator(mode='after')
225
+ def validate_transport_type(self):
226
+ """Validate that exactly one transport type is configured."""
227
+ has_stdio = self.command is not None
228
+ has_http = self.type is not None or self.url is not None
229
+
230
+ if not has_stdio and not has_http:
231
+ raise ValueError(
232
+ "MCP server config must specify either 'command' (stdio) or 'type'/'url' (HTTP/SSE)"
233
+ )
234
+
235
+ if has_stdio and has_http:
236
+ raise ValueError(
237
+ "MCP server config cannot specify both stdio (command) and HTTP/SSE (type/url) transport"
238
+ )
239
+
240
+ # Validate stdio config
241
+ if has_stdio:
242
+ if not self.command.strip():
243
+ raise ValueError("Command cannot be empty for stdio transport")
244
+
245
+ # Validate HTTP/SSE config
246
+ if has_http:
247
+ if not self.type:
248
+ raise ValueError("'type' field is required for HTTP/SSE transport")
249
+ if not self.url:
250
+ raise ValueError("'url' field is required for HTTP/SSE transport")
251
+ if not self.url.strip():
252
+ raise ValueError("URL cannot be empty for HTTP/SSE transport")
253
+
254
+ return self
255
+
256
+ def get_transport_type(self) -> MCPTransportType:
257
+ """Get the transport type of this configuration."""
258
+ if self.command:
259
+ return MCPTransportType.STDIO
260
+ elif self.type == "sse":
261
+ return MCPTransportType.SSE
262
+ elif self.type == "http":
263
+ return MCPTransportType.HTTP
264
+ else:
265
+ raise ValueError("Invalid MCP server configuration")
266
+
267
+ def to_stdio_config(self) -> Optional[MCPServerStdioConfig]:
268
+ """Convert to stdio config if applicable."""
269
+ if self.command:
270
+ return MCPServerStdioConfig(
271
+ command=self.command,
272
+ args=self.args or [],
273
+ env=self.env or {}
274
+ )
275
+ return None
276
+
277
+ def to_http_config(self) -> Optional[MCPServerHTTPConfig]:
278
+ """Convert to HTTP/SSE config if applicable."""
279
+ if self.type and self.url:
280
+ return MCPServerHTTPConfig(
281
+ type=self.type,
282
+ url=self.url,
283
+ headers=self.headers or {}
284
+ )
285
+ return None
286
+
287
+ model_config = ConfigDict(
288
+ populate_by_name=True, # Allow populating by both field name and alias
289
+ json_schema_extra={
290
+ "examples": [
291
+ {
292
+ "command": "python",
293
+ "args": ["-m", "mcp_server_filesystem"],
294
+ "env": {"ALLOWED_PATHS": "{{.env.PROJECT_ROOT}}"}
295
+ },
296
+ {
297
+ "type": "sse",
298
+ "url": "https://api.example.com/mcp",
299
+ "headers": {"Authorization": "Bearer {{.secret.token}}"}
300
+ },
301
+ {
302
+ "transport_type": "sse", # Also supports 'transport_type'
303
+ "url": "https://api.example.com/mcp",
304
+ "headers": {"Authorization": "Bearer {{.secret.token}}"}
305
+ }
306
+ ]
307
+ }
308
+ )
309
+
310
+ # NOTE: MCPServersConfig was removed as it's not used anywhere and had Pydantic v2 compatibility issues.
311
+ # MCP servers are stored as Dict[str, Any] in execution_environment.mcp_servers