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,374 @@
1
+ """NATS event listener for control plane."""
2
+
3
+ import json
4
+ from typing import Dict, Any, Optional, Set
5
+ import asyncio
6
+ import structlog
7
+
8
+ logger = structlog.get_logger(__name__)
9
+
10
+
11
+ class NATSEventListener:
12
+ """
13
+ Control plane listener for NATS events from workers.
14
+
15
+ Subscribes to org-specific subjects and processes events by storing them
16
+ in Redis for UI consumption (same flow as HTTP/WebSocket events).
17
+ """
18
+
19
+ def __init__(
20
+ self,
21
+ nats_url: str,
22
+ credentials_file: str,
23
+ jetstream_enabled: bool = True,
24
+ stream_name: str = "EVENTS",
25
+ ):
26
+ """
27
+ Initialize NATS event listener.
28
+
29
+ Args:
30
+ nats_url: NATS server URL
31
+ credentials_file: Path to control plane NATS credentials file
32
+ jetstream_enabled: Enable JetStream for durable consumers
33
+ stream_name: JetStream stream name
34
+ """
35
+ self.nats_url = nats_url
36
+ self.credentials_file = credentials_file
37
+ self.jetstream_enabled = jetstream_enabled
38
+ self.stream_name = stream_name
39
+
40
+ self.nc = None # NATS connection
41
+ self.js = None # JetStream context
42
+ self.subscriptions: Dict[str, Any] = {} # org_id -> subscription
43
+ self._running = False
44
+
45
+ async def start(self) -> None:
46
+ """Start NATS listener and connect to server."""
47
+ if self._running:
48
+ logger.warning("nats_listener_already_running")
49
+ return
50
+
51
+ try:
52
+ # Import nats-py
53
+ try:
54
+ import nats
55
+ from nats.errors import TimeoutError, NoServersError
56
+ except ImportError:
57
+ raise ImportError(
58
+ "nats-py is required for NATS listener. "
59
+ "Install it with: pip install nats-py"
60
+ )
61
+
62
+ # Connect to NATS
63
+ self.nc = await nats.connect(
64
+ servers=[self.nats_url],
65
+ user_credentials=self.credentials_file,
66
+ max_reconnect_attempts=-1, # Infinite reconnects
67
+ reconnect_time_wait=2,
68
+ ping_interval=20,
69
+ max_outstanding_pings=3,
70
+ )
71
+
72
+ # Initialize JetStream if enabled
73
+ if self.jetstream_enabled:
74
+ self.js = self.nc.jetstream()
75
+
76
+ self._running = True
77
+
78
+ logger.info(
79
+ "nats_listener_started",
80
+ url=self.nats_url,
81
+ jetstream_enabled=self.jetstream_enabled,
82
+ credentials_file=self.credentials_file,
83
+ )
84
+
85
+ except ImportError as e:
86
+ logger.error(
87
+ "nats_listener_dependency_missing",
88
+ error=str(e),
89
+ )
90
+ raise
91
+
92
+ except Exception as e:
93
+ logger.error(
94
+ "nats_listener_start_failed",
95
+ error=str(e),
96
+ url=self.nats_url,
97
+ )
98
+ raise
99
+
100
+ async def subscribe_organization(self, organization_id: str) -> None:
101
+ """
102
+ Subscribe to all events for an organization.
103
+
104
+ Subject: events.{organization_id}.>
105
+
106
+ Args:
107
+ organization_id: Organization ID to subscribe to
108
+
109
+ Raises:
110
+ RuntimeError: If listener not started
111
+ Exception: If subscription fails
112
+ """
113
+ if not self._running or not self.nc:
114
+ raise RuntimeError("NATS listener not started")
115
+
116
+ if organization_id in self.subscriptions:
117
+ logger.warning(
118
+ "nats_org_already_subscribed",
119
+ organization_id=organization_id,
120
+ )
121
+ return
122
+
123
+ subject = f"events.{organization_id}.>"
124
+
125
+ try:
126
+ async def message_handler(msg):
127
+ """Handle incoming NATS message."""
128
+ try:
129
+ # Parse message
130
+ event_data = json.loads(msg.data.decode())
131
+
132
+ # Process event (store in Redis)
133
+ await self._process_event(event_data)
134
+
135
+ # Acknowledge message
136
+ if hasattr(msg, "ack"):
137
+ await msg.ack()
138
+
139
+ except json.JSONDecodeError as e:
140
+ logger.error(
141
+ "nats_message_invalid_json",
142
+ error=str(e),
143
+ subject=msg.subject,
144
+ )
145
+ # Negative acknowledgment for retry
146
+ if hasattr(msg, "nak"):
147
+ await msg.nak()
148
+
149
+ except Exception as e:
150
+ logger.error(
151
+ "nats_message_process_error",
152
+ error=str(e),
153
+ subject=msg.subject,
154
+ )
155
+ # Negative acknowledgment for retry
156
+ if hasattr(msg, "nak"):
157
+ await msg.nak()
158
+
159
+ if self.jetstream_enabled and self.js:
160
+ # Subscribe with JetStream (durable consumer)
161
+ consumer_name = f"control-plane-{organization_id}"
162
+
163
+ sub = await self.js.subscribe(
164
+ subject,
165
+ durable=consumer_name,
166
+ cb=message_handler,
167
+ manual_ack=True,
168
+ )
169
+
170
+ logger.info(
171
+ "nats_jetstream_org_subscribed",
172
+ organization_id=organization_id,
173
+ subject=subject,
174
+ consumer=consumer_name,
175
+ )
176
+ else:
177
+ # Subscribe without JetStream
178
+ sub = await self.nc.subscribe(subject, cb=message_handler)
179
+
180
+ logger.info(
181
+ "nats_org_subscribed",
182
+ organization_id=organization_id,
183
+ subject=subject,
184
+ )
185
+
186
+ self.subscriptions[organization_id] = sub
187
+
188
+ except Exception as e:
189
+ logger.error(
190
+ "nats_org_subscribe_failed",
191
+ error=str(e),
192
+ organization_id=organization_id,
193
+ subject=subject,
194
+ )
195
+ raise
196
+
197
+ async def unsubscribe_organization(self, organization_id: str) -> None:
198
+ """
199
+ Unsubscribe from organization events.
200
+
201
+ Args:
202
+ organization_id: Organization ID to unsubscribe from
203
+ """
204
+ if organization_id not in self.subscriptions:
205
+ logger.warning(
206
+ "nats_org_not_subscribed",
207
+ organization_id=organization_id,
208
+ )
209
+ return
210
+
211
+ try:
212
+ sub = self.subscriptions[organization_id]
213
+ await sub.unsubscribe()
214
+ del self.subscriptions[organization_id]
215
+
216
+ logger.info(
217
+ "nats_org_unsubscribed",
218
+ organization_id=organization_id,
219
+ )
220
+
221
+ except Exception as e:
222
+ logger.error(
223
+ "nats_org_unsubscribe_failed",
224
+ error=str(e),
225
+ organization_id=organization_id,
226
+ )
227
+
228
+ async def _process_event(self, event_data: Dict[str, Any]) -> None:
229
+ """
230
+ Process event received from NATS.
231
+
232
+ Stores event in Redis for UI consumption (same as HTTP/WebSocket flow).
233
+
234
+ Args:
235
+ event_data: Event data from NATS message
236
+ """
237
+ try:
238
+ # Extract event fields
239
+ execution_id = event_data.get("execution_id")
240
+ event_type = event_data.get("event_type")
241
+ data = event_data.get("data")
242
+ timestamp = event_data.get("timestamp")
243
+ worker_id = event_data.get("worker_id")
244
+ organization_id = event_data.get("organization_id")
245
+
246
+ if not all([execution_id, event_type, data]):
247
+ logger.warning(
248
+ "nats_event_missing_required_fields",
249
+ event_data=event_data,
250
+ )
251
+ return
252
+
253
+ # Get Redis client
254
+ from control_plane_api.app.lib.redis_client import get_redis_client
255
+
256
+ redis_client = get_redis_client()
257
+ if not redis_client:
258
+ logger.warning("nats_event_redis_not_available")
259
+ return
260
+
261
+ # Build message for Redis
262
+ message = {
263
+ "event_type": event_type,
264
+ "data": data,
265
+ "timestamp": timestamp,
266
+ }
267
+
268
+ message_json = json.dumps(message)
269
+
270
+ # Redis keys
271
+ list_key = f"execution:{execution_id}:events"
272
+ channel = f"execution:{execution_id}:stream"
273
+
274
+ # Store in Redis list for replay
275
+ await redis_client.lpush(list_key, message_json)
276
+ await redis_client.ltrim(list_key, 0, 999) # Keep last 1000
277
+ await redis_client.expire(list_key, 3600) # 1 hour TTL
278
+
279
+ # Publish to Redis pub/sub for real-time UI
280
+ await redis_client.publish(channel, message_json)
281
+
282
+ logger.debug(
283
+ "nats_event_processed",
284
+ execution_id=execution_id,
285
+ event_type=event_type,
286
+ worker_id=worker_id[:8] if worker_id else None,
287
+ organization_id=organization_id,
288
+ )
289
+
290
+ except Exception as e:
291
+ logger.error(
292
+ "nats_event_process_failed",
293
+ error=str(e),
294
+ event_data=event_data,
295
+ )
296
+ raise
297
+
298
+ async def stop(self) -> None:
299
+ """Stop NATS listener and cleanup resources."""
300
+ if not self._running:
301
+ return
302
+
303
+ self._running = False
304
+
305
+ logger.info("nats_listener_stopping")
306
+
307
+ # Unsubscribe from all organizations
308
+ for org_id in list(self.subscriptions.keys()):
309
+ try:
310
+ await self.unsubscribe_organization(org_id)
311
+ except Exception as e:
312
+ logger.warning(
313
+ "nats_org_unsubscribe_on_stop_failed",
314
+ error=str(e),
315
+ organization_id=org_id,
316
+ )
317
+
318
+ # Close NATS connection
319
+ if self.nc:
320
+ try:
321
+ await self.nc.drain()
322
+ await self.nc.close()
323
+ except Exception as e:
324
+ logger.warning("nats_connection_close_error", error=str(e))
325
+
326
+ logger.info("nats_listener_stopped")
327
+
328
+ def is_running(self) -> bool:
329
+ """Check if listener is running."""
330
+ return self._running and self.nc is not None and self.nc.is_connected
331
+
332
+ def get_subscribed_organizations(self) -> Set[str]:
333
+ """Get set of currently subscribed organization IDs."""
334
+ return set(self.subscriptions.keys())
335
+
336
+ async def health_check(self) -> Dict[str, Any]:
337
+ """
338
+ Check NATS listener health.
339
+
340
+ Returns:
341
+ Dict with health status
342
+ """
343
+ if not self.nc:
344
+ return {
345
+ "healthy": False,
346
+ "error": "nats_listener_not_initialized",
347
+ }
348
+
349
+ health = {
350
+ "healthy": self.nc.is_connected,
351
+ "running": self._running,
352
+ "nats_url": self.nats_url,
353
+ "jetstream_enabled": self.jetstream_enabled,
354
+ "subscribed_organizations": len(self.subscriptions),
355
+ "organizations": list(self.subscriptions.keys()),
356
+ }
357
+
358
+ if self.nc.is_connected:
359
+ health["connected_url"] = (
360
+ self.nc.connected_url.netloc
361
+ if self.nc.connected_url
362
+ else None
363
+ )
364
+
365
+ # Add stats if available
366
+ if hasattr(self.nc, "stats"):
367
+ stats = self.nc.stats
368
+ health["stats"] = {
369
+ "in_msgs": stats.get("in_msgs", 0),
370
+ "out_msgs": stats.get("out_msgs", 0),
371
+ "reconnects": stats.get("reconnects", 0),
372
+ }
373
+
374
+ return health
@@ -0,0 +1,153 @@
1
+ """
2
+ Shared Planning Prompt Builder
3
+
4
+ Builds the rich, detailed planning prompt used by ALL strategies (Agno, Claude Code SDK, etc.)
5
+ This ensures 100% identical prompts across all implementations.
6
+ """
7
+
8
+ import json
9
+ from typing import List
10
+ from control_plane_api.app.models.task_planning import TaskPlanRequest, AgentInfo, TeamInfo
11
+ from control_plane_api.app.lib.task_planning.helpers import REFINEMENT_INSTRUCTIONS
12
+
13
+
14
+ def build_planning_prompt(
15
+ request: TaskPlanRequest,
16
+ agents_to_use: List[dict],
17
+ teams_to_use: List[dict],
18
+ pricing_context: str,
19
+ ) -> str:
20
+ """
21
+ Build the complete planning prompt with full context.
22
+
23
+ This is the SAME prompt used by both Agno and Claude Code SDK to ensure
24
+ 100% identical results.
25
+
26
+ Args:
27
+ request: Task plan request
28
+ agents_to_use: Prepared agents data (JSON-serializable)
29
+ teams_to_use: Prepared teams data (JSON-serializable)
30
+ pricing_context: Model pricing information
31
+
32
+ Returns:
33
+ Complete planning prompt string
34
+ """
35
+ # Build environments context
36
+ environments_context = (
37
+ "\n".join(
38
+ [
39
+ f"- **{e.name}** (ID: `{e.id}`)\n"
40
+ f" - **Type**: {e.type}\n"
41
+ f" - **Status**: {e.status}"
42
+ for e in request.environments
43
+ ]
44
+ )
45
+ if request.environments
46
+ else "No execution environments specified"
47
+ )
48
+
49
+ # Build worker queues context
50
+ worker_queues_context = (
51
+ "\n".join(
52
+ [
53
+ f"- **{q.name}** (ID: `{q.id}`)\n"
54
+ f" - **Environment**: {q.environment_id or 'Not specified'}\n"
55
+ f" - **Active Workers**: {q.active_workers}\n"
56
+ f" - **Status**: {q.status}\n"
57
+ f" - **Capacity**: {'Available' if q.active_workers > 0 and q.status == 'active' else 'Limited or Inactive'}"
58
+ for q in request.worker_queues
59
+ ]
60
+ )
61
+ if request.worker_queues
62
+ else "No worker queues specified"
63
+ )
64
+
65
+ # System capabilities (condensed)
66
+ system_capabilities = "**System**: Code execution (Python/Bash/JS), Cloud (AWS/Azure/GCP), APIs, Kubernetes, Docker, Databases, Monitoring, Security, DevOps/IaC"
67
+
68
+ # Check conversation context
69
+ has_conversation_history = bool(request.conversation_context and request.conversation_context.strip())
70
+ should_be_decisive = request.iteration > 1 or has_conversation_history
71
+
72
+ # Build the complete prompt
73
+ planning_prompt = f"""
74
+ # Task Planning Request - Iteration #{request.iteration}
75
+
76
+ ## Task Description
77
+ {request.description}
78
+
79
+ ## Priority
80
+ {request.priority.upper()}
81
+
82
+ {"## Previous Conversation (USE THIS CONTEXT)" if has_conversation_history else ""}
83
+ {request.conversation_context if has_conversation_history else ""}
84
+
85
+ {"## User Feedback for Refinement" if request.refinement_feedback else ""}
86
+ {request.refinement_feedback if request.refinement_feedback else ""}
87
+
88
+ {"## Previous Plan (to be refined)" if request.previous_plan else ""}
89
+ {json.dumps(request.previous_plan, indent=2) if request.previous_plan else ""}
90
+
91
+ {REFINEMENT_INSTRUCTIONS.format(iteration=request.iteration) if request.previous_plan and request.refinement_feedback else ""}
92
+
93
+ ## Available Resources
94
+
95
+ **IMPORTANT**: Agent and team data below is provided as complete JSON with ALL details including:
96
+ - execution_environment (secrets, env_vars, integration_ids)
97
+ - skills (with full configuration)
98
+ - projects and environments
99
+ - capabilities and runtime info
100
+
101
+ Use this rich data to make informed decisions about agent/team selection and task planning.
102
+
103
+ ### Agents
104
+ {json.dumps(agents_to_use, indent=2) if agents_to_use else "No agents available"}
105
+
106
+ ### Teams
107
+ {json.dumps(teams_to_use, indent=2) if teams_to_use else "No teams available"}
108
+
109
+ ### Execution Environments
110
+ {environments_context}
111
+
112
+ ### Worker Queues
113
+ {worker_queues_context}
114
+
115
+ {system_capabilities}
116
+
117
+ {pricing_context}
118
+
119
+ ## Your Task
120
+
121
+ {'**BE DECISIVE**: You have conversation history showing the user has already provided context. DO NOT ask more questions. Use the information provided in the conversation history above to create a reasonable plan. Make sensible assumptions where needed and proceed with planning.' if should_be_decisive else '**FIRST ITERATION**: Review if you have enough context. ONLY ask questions if you are missing CRITICAL information that makes planning impossible (like completely unknown technology stack or domain). If the task is reasonably clear, proceed with planning and make reasonable assumptions.'}
122
+
123
+ {'**IMPORTANT**: DO NOT ask questions. The user wants a plan now. Use the conversation history above and create a comprehensive plan.' if should_be_decisive else 'If you need CRITICAL information to proceed, set has_questions=true and provide 1-2 critical questions in the questions array. Otherwise, proceed with planning.'}
124
+
125
+ Analyze this task and provide a comprehensive plan.
126
+
127
+ **Key Planning Guidelines:**
128
+
129
+ 1. **Agent/Team Selection**: Choose the most capable entity from the lists above based on:
130
+ - Task complexity and requirements → Agent/team capabilities
131
+ - Single agent sufficient? Use agent. Multi-domain? Use team.
132
+ - Match agent model (from model_id) to task complexity
133
+
134
+ 2. **Environment & Queue**: Select environment matching task needs (prod/staging/dev). Choose worker queue with capacity (active_workers > 0, status='active'). Match queue to environment when possible.
135
+
136
+ 3. **Cost Breakdown** (use pricing above):
137
+ - **Token estimates** by complexity: Simple (1-3 pts): 2-5K in/1-2K out. Medium (5-8): 5-10K in/2-5K out. Complex (13-21): 10-20K in/5-10K out
138
+ - **Model costs**: Calculate from token estimates × pricing (Sonnet 4: $0.003/1K in, $0.015/1K out)
139
+ - **Tool costs**: AWS APIs $0.0004-0.001/call, DB queries $0.0001/call, Free tools $0
140
+ - **Runtime**: Time estimate × $0.10/hr
141
+ - **agent_cost** per agent: model_cost + tool_costs
142
+ - **estimated_cost_usd**: Sum all costs
143
+
144
+ 4. **Realized Savings**:
145
+ - **Manual**: Use realistic hourly rates (Senior: $120-200/hr, Mid: $80-120/hr, Jr: $50-80/hr) × estimated manual time
146
+ - **AI**: Use calculated estimated_cost_usd and time
147
+ - **Savings**: money_saved, time_saved_hours, time_saved_percentage
148
+ - **Summary**: Compelling narrative showing concrete savings
149
+
150
+ 5. Use exact IDs from lists. Be specific and actionable. Output valid JSON only.
151
+ """
152
+
153
+ return planning_prompt
@@ -0,0 +1,41 @@
1
+ """
2
+ Planning Tools - Modular tools for the task planning agent
3
+
4
+ This package provides decoupled, maintainable tools organized by category:
5
+ - agents: Agent-related context and operations
6
+ - teams: Team-related context and operations
7
+ - environments: Environment and infrastructure context
8
+ - resources: General resource and capability queries
9
+ - models: Pydantic models for type-safe data structures
10
+ """
11
+
12
+ from control_plane_api.app.lib.planning_tools.agents import AgentsContextTools
13
+ from control_plane_api.app.lib.planning_tools.teams import TeamsContextTools
14
+ from control_plane_api.app.lib.planning_tools.environments import EnvironmentsContextTools
15
+ from control_plane_api.app.lib.planning_tools.resources import ResourcesContextTools
16
+ from control_plane_api.app.lib.planning_tools.knowledge import KnowledgeContextTools
17
+ from control_plane_api.app.lib.planning_tools.models import (
18
+ AgentModel,
19
+ TeamModel,
20
+ TeamMemberModel,
21
+ EnvironmentModel,
22
+ WorkerQueueModel,
23
+ ExecutionHistoryModel,
24
+ SkillModel,
25
+ )
26
+
27
+ __all__ = [
28
+ "AgentsContextTools",
29
+ "TeamsContextTools",
30
+ "EnvironmentsContextTools",
31
+ "ResourcesContextTools",
32
+ "KnowledgeContextTools",
33
+ # Models
34
+ "AgentModel",
35
+ "TeamModel",
36
+ "TeamMemberModel",
37
+ "EnvironmentModel",
38
+ "WorkerQueueModel",
39
+ "ExecutionHistoryModel",
40
+ "SkillModel",
41
+ ]