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,138 @@
1
+ """
2
+ Supabase utility functions with defensive error handling.
3
+
4
+ Provides wrappers around Supabase queries to handle common errors like:
5
+ - Code 556: JSON could not be generated (invalid JSONB data)
6
+ - Network timeouts
7
+ - Connection errors
8
+ """
9
+
10
+ import structlog
11
+ from typing import Any, Optional, Callable
12
+ from supabase import Client
13
+
14
+ logger = structlog.get_logger()
15
+
16
+
17
+ def safe_execute_query(
18
+ client: Client,
19
+ query_builder: Callable,
20
+ operation_name: str,
21
+ fallback_query_builder: Optional[Callable] = None,
22
+ **context
23
+ ) -> Any:
24
+ """
25
+ Execute a Supabase query with defensive error handling.
26
+
27
+ This wrapper handles common Supabase/PostgREST errors gracefully,
28
+ including code 556 (JSON could not be generated) which occurs when
29
+ JSONB columns contain invalid data.
30
+
31
+ Args:
32
+ client: Supabase client
33
+ query_builder: Function that returns the query to execute
34
+ operation_name: Name of the operation for logging
35
+ fallback_query_builder: Optional fallback query if primary fails
36
+ **context: Additional context for logging
37
+
38
+ Returns:
39
+ Query result or None if both queries fail
40
+
41
+ Example:
42
+ ```python
43
+ result = safe_execute_query(
44
+ client=get_supabase(),
45
+ query_builder=lambda: client.table("executions")
46
+ .select("*, execution_participants(*)")
47
+ .eq("organization_id", org_id),
48
+ fallback_query_builder=lambda: client.table("executions")
49
+ .select("*")
50
+ .eq("organization_id", org_id),
51
+ operation_name="list_executions",
52
+ org_id=org_id,
53
+ )
54
+ ```
55
+ """
56
+ try:
57
+ # Try primary query
58
+ query = query_builder()
59
+ result = query.execute()
60
+ return result
61
+
62
+ except Exception as primary_error:
63
+ error_str = str(primary_error)
64
+
65
+ # Check if it's a JSON serialization error (code 556)
66
+ is_json_error = (
67
+ "JSON could not be generated" in error_str or
68
+ "'code': 556" in error_str or
69
+ "code\": 556" in error_str
70
+ )
71
+
72
+ if is_json_error:
73
+ logger.warning(
74
+ f"{operation_name}_json_error_using_fallback",
75
+ error=error_str[:200], # Truncate long errors
76
+ **context
77
+ )
78
+
79
+ # Try fallback query if provided
80
+ if fallback_query_builder:
81
+ try:
82
+ fallback_query = fallback_query_builder()
83
+ result = fallback_query.execute()
84
+ logger.debug(
85
+ f"{operation_name}_fallback_succeeded",
86
+ **context
87
+ )
88
+ return result
89
+
90
+ except Exception as fallback_error:
91
+ logger.error(
92
+ f"{operation_name}_fallback_query_failed",
93
+ error=str(fallback_error),
94
+ **context
95
+ )
96
+ raise fallback_error
97
+ else:
98
+ # No fallback provided, re-raise original error
99
+ raise primary_error
100
+ else:
101
+ # Different error type - re-raise
102
+ logger.error(
103
+ f"{operation_name}_query_failed",
104
+ error=error_str,
105
+ error_type=type(primary_error).__name__,
106
+ **context
107
+ )
108
+ raise primary_error
109
+
110
+
111
+ def sanitize_jsonb_field(value: Any, field_name: str, default: dict = None) -> dict:
112
+ """
113
+ Sanitize a JSONB field value to ensure it's a valid dict.
114
+
115
+ Args:
116
+ value: The value to sanitize
117
+ field_name: Name of the field for logging
118
+ default: Default value if sanitization fails
119
+
120
+ Returns:
121
+ Valid dict or default
122
+ """
123
+ if default is None:
124
+ default = {}
125
+
126
+ if value is None:
127
+ return default
128
+
129
+ if isinstance(value, dict):
130
+ return value
131
+
132
+ logger.debug(
133
+ "invalid_jsonb_field_sanitized",
134
+ field_name=field_name,
135
+ type=type(value).__name__
136
+ )
137
+
138
+ return default
@@ -0,0 +1,138 @@
1
+ """
2
+ Task Planning Library
3
+
4
+ This package provides utilities for AI-powered task planning including:
5
+ - Modular workflow components (agents, hooks, cache, runner)
6
+ - Helper functions for resource discovery and preparation
7
+ - Agent factory for creating planning agents
8
+ - SSE message formatting for streaming responses
9
+
10
+ Architecture:
11
+ - models.py: Pydantic schemas for step outputs
12
+ - cache.py: Pre-fetch caching with TTL
13
+ - agents.py: Agent factory functions
14
+ - hooks.py: Pre/post validation hooks
15
+ - workflow.py: Workflow factory
16
+ - runner.py: Workflow execution with streaming
17
+ """
18
+
19
+ from .helpers import (
20
+ make_json_serializable,
21
+ save_planning_prompt_debug,
22
+ format_sse_message,
23
+ )
24
+ from .agent_factory import create_planning_agent
25
+
26
+ # New modular API
27
+ from .cache import (
28
+ get_cached_prefetch,
29
+ set_cached_prefetch,
30
+ invalidate_prefetch_cache,
31
+ clear_prefetch_cache,
32
+ get_prefetch_cache,
33
+ PrefetchCache,
34
+ )
35
+ from .models import (
36
+ TaskAnalysisOutput,
37
+ ResourceDiscoveryOutput,
38
+ FastSelectionOutput,
39
+ CostEstimationOutput,
40
+ validate_resource_discovery,
41
+ )
42
+ from .agents import (
43
+ create_analysis_and_selection_agent,
44
+ create_plan_generation_agent,
45
+ create_fast_selection_agent,
46
+ create_task_analysis_agent,
47
+ create_cost_estimation_agent,
48
+ build_prefetch_tools,
49
+ build_search_tools,
50
+ )
51
+ from .hooks import (
52
+ validate_task_input,
53
+ validate_prefetch_context,
54
+ validate_step1_output,
55
+ validate_step2_output,
56
+ InputValidationError,
57
+ OutputValidationError,
58
+ EntityNotFoundError,
59
+ HallucinatedIdError,
60
+ )
61
+ from .workflow import (
62
+ create_planning_workflow,
63
+ create_fast_planning_workflow,
64
+ create_workflow_with_config,
65
+ WorkflowConfig,
66
+ get_litellm_config,
67
+ create_model,
68
+ prefetch_resources,
69
+ )
70
+ from .runner import (
71
+ run_workflow_stream,
72
+ run_fast_workflow_stream,
73
+ execute_step,
74
+ extract_json_from_content,
75
+ STEP_DESCRIPTIONS,
76
+ STEP_STAGE_NAMES,
77
+ STEP_PROGRESS_MAP,
78
+ )
79
+
80
+ __all__ = [
81
+ # Legacy helpers
82
+ "make_json_serializable",
83
+ "save_planning_prompt_debug",
84
+ "format_sse_message",
85
+ "create_planning_agent",
86
+
87
+ # Cache
88
+ "get_cached_prefetch",
89
+ "set_cached_prefetch",
90
+ "invalidate_prefetch_cache",
91
+ "clear_prefetch_cache",
92
+ "get_prefetch_cache",
93
+ "PrefetchCache",
94
+
95
+ # Models
96
+ "TaskAnalysisOutput",
97
+ "ResourceDiscoveryOutput",
98
+ "FastSelectionOutput",
99
+ "CostEstimationOutput",
100
+ "validate_resource_discovery",
101
+
102
+ # Agents
103
+ "create_analysis_and_selection_agent",
104
+ "create_plan_generation_agent",
105
+ "create_fast_selection_agent",
106
+ "create_task_analysis_agent",
107
+ "create_cost_estimation_agent",
108
+ "build_prefetch_tools",
109
+ "build_search_tools",
110
+
111
+ # Hooks
112
+ "validate_task_input",
113
+ "validate_prefetch_context",
114
+ "validate_step1_output",
115
+ "validate_step2_output",
116
+ "InputValidationError",
117
+ "OutputValidationError",
118
+ "EntityNotFoundError",
119
+ "HallucinatedIdError",
120
+
121
+ # Workflow
122
+ "create_planning_workflow",
123
+ "create_fast_planning_workflow",
124
+ "create_workflow_with_config",
125
+ "WorkflowConfig",
126
+ "get_litellm_config",
127
+ "create_model",
128
+ "prefetch_resources",
129
+
130
+ # Runner
131
+ "run_workflow_stream",
132
+ "run_fast_workflow_stream",
133
+ "execute_step",
134
+ "extract_json_from_content",
135
+ "STEP_DESCRIPTIONS",
136
+ "STEP_STAGE_NAMES",
137
+ "STEP_PROGRESS_MAP",
138
+ ]
@@ -0,0 +1,308 @@
1
+ """
2
+ Task Planning Agent Factory
3
+ """
4
+ from typing import Optional, Callable
5
+ from sqlalchemy.orm import Session
6
+ import structlog
7
+ import os
8
+
9
+ from agno.agent import Agent
10
+ from agno.models.litellm import LiteLLM
11
+ from control_plane_api.app.models.task_planning import TaskPlanResponse
12
+ from control_plane_api.app.lib.planning_tools import (
13
+ AgentsContextTools,
14
+ TeamsContextTools,
15
+ EnvironmentsContextTools,
16
+ ResourcesContextTools,
17
+ KnowledgeContextTools,
18
+ )
19
+ from control_plane_api.app.lib.planning_tools.context_graph_tools import ContextGraphPlanningTools
20
+
21
+ logger = structlog.get_logger()
22
+
23
+
24
+ def create_planning_agent(
25
+ organization_id: Optional[str] = None,
26
+ db: Optional[Session] = None,
27
+ api_token: str = None,
28
+ tool_hook: Optional[Callable] = None,
29
+ quick_mode: bool = False
30
+ ) -> Agent:
31
+ """
32
+ Create an Agno agent for task planning using LiteLLM with context tools
33
+
34
+ Args:
35
+ organization_id: Optional organization ID for filtering resources
36
+ db: Database session to pass to tools
37
+ api_token: API token for accessing organizational knowledge (required)
38
+ tool_hook: Optional hook to capture tool executions for streaming
39
+ quick_mode: If True, use faster, cheaper model for quick planning (Haiku instead of Sonnet)
40
+ """
41
+ # Get LiteLLM configuration
42
+ litellm_api_url = (
43
+ os.getenv("LITELLM_API_URL") or
44
+ os.getenv("LITELLM_API_BASE") or
45
+ "https://llm-proxy.kubiya.ai"
46
+ ).strip()
47
+
48
+ litellm_api_key = os.getenv("LITELLM_API_KEY", "").strip()
49
+
50
+ if not litellm_api_key:
51
+ raise ValueError("LITELLM_API_KEY environment variable not set")
52
+
53
+ # Use same model for both modes (Sonnet 4)
54
+ # Note: quick_mode parameter kept for future use if needed
55
+ model = os.getenv("LITELLM_DEFAULT_MODEL", "kubiya/claude-sonnet-4").strip()
56
+ logger.info("creating_planning_agent", model=model, quick_mode=quick_mode)
57
+
58
+ logger.info(
59
+ "creating_agno_planning_agent_with_tools",
60
+ litellm_api_url=litellm_api_url,
61
+ model=model,
62
+ has_api_key=bool(litellm_api_key),
63
+ organization_id=organization_id,
64
+ )
65
+
66
+ # Initialize context tools with database session
67
+ # NOTE: Keep agents_tools and teams_tools for backward compatibility,
68
+ # but planning agent should primarily use context_graph_tools for intelligent discovery
69
+ agents_tools = AgentsContextTools(db=db, organization_id=organization_id)
70
+ teams_tools = TeamsContextTools(db=db, organization_id=organization_id)
71
+ environments_tools = EnvironmentsContextTools(db=db, organization_id=organization_id)
72
+ resources_tools = ResourcesContextTools(db=db, organization_id=organization_id)
73
+ knowledge_tools = KnowledgeContextTools(db=db, organization_id=organization_id, api_token=api_token)
74
+
75
+ # NEW: Add context graph tools for intelligent resource discovery
76
+ context_graph_tools = ContextGraphPlanningTools(
77
+ db=db,
78
+ organization_id=organization_id,
79
+ api_token=api_token
80
+ )
81
+
82
+ # Build tools list with context graph tools FIRST (higher priority for tool-based discovery)
83
+ tools_list = [
84
+ context_graph_tools, # Primary discovery method via context graph
85
+ agents_tools, # Fallback for direct agent queries
86
+ teams_tools, # Fallback for direct team queries
87
+ environments_tools,
88
+ resources_tools,
89
+ knowledge_tools, # Include knowledge tools for comprehensive planning
90
+ ]
91
+
92
+ logger.info("planning_agent_tools_initialized",
93
+ tools_count=len(tools_list),
94
+ has_context_graph=True,
95
+ has_knowledge=True,
96
+ has_api_token=bool(api_token))
97
+
98
+ # Create fast planning agent optimized for speed
99
+ planning_agent = Agent(
100
+ name="Task Planning Agent",
101
+ role="Expert project manager and task planner",
102
+ model=LiteLLM(
103
+ id=f"openai/{model}",
104
+ api_base=litellm_api_url,
105
+ api_key=litellm_api_key,
106
+ request_params={
107
+ "timeout": 120, # 2 minute timeout for LiteLLM requests
108
+ },
109
+ ),
110
+ # NOTE: output_schema blocks reasoning streams! Removed to enable real-time streaming.
111
+ # We'll parse the JSON response manually after streaming completes.
112
+ # output_schema=TaskPlanResponse,
113
+ tools=tools_list,
114
+ tool_hooks=[tool_hook] if tool_hook else None, # FIX: Agno expects tool_hooks (plural) as a list
115
+ instructions=[
116
+ "You are a CONCISE task planning analyst producing KEY INSIGHTS for structured output conversion.",
117
+ "",
118
+ "**CRITICAL - Be CONCISE:**",
119
+ "- You are Agent 1 in a two-agent workflow - provide KEY POINTS ONLY",
120
+ "- Agent 2 will convert your analysis to JSON - keep it SHORT and FOCUSED",
121
+ "- DO NOT produce verbose reasoning - focus on ESSENTIAL insights",
122
+ "- DO NOT return JSON - return brief analysis that answers: WHO, WHAT, HOW, WHEN",
123
+ "",
124
+ "**Required Analysis (Keep Each Section Brief):**",
125
+ "",
126
+ "1. **Task Summary** (2-3 sentences):",
127
+ " - What needs to be done and why",
128
+ "",
129
+ "2. **Recommended Agent/Team** (1-2 sentences):",
130
+ " - Which agent/team should handle this",
131
+ " - Key reason: relevant skills + available secrets/env_vars",
132
+ "",
133
+ "3. **Complexity Assessment** (1 sentence):",
134
+ " - Story points (1-20) and justification",
135
+ "",
136
+ "4. **Task Breakdown** (List format):",
137
+ " - Task 1: [title] - [what to do] - [which skills/secrets to use]",
138
+ " - Task 2: [title] - [what to do] - [dependencies: task 1]",
139
+ " - Keep each task description to 1-2 sentences max",
140
+ "",
141
+ "5. **Prerequisites** (bullet list if any):",
142
+ " - Required setup or dependencies",
143
+ "",
144
+ "6. **Risks** (bullet list if any):",
145
+ " - Key risks to be aware of",
146
+ "",
147
+ "**Available Tools** (use sparingly):",
148
+ "- list_agents() - Get available agents",
149
+ "- get_agent_details(id) - Get specific agent info",
150
+ "- query_knowledge(q) - Search knowledge base",
151
+ "",
152
+ "**Agent Context Format:**",
153
+ "- Agent skills: agent['skills'] array",
154
+ "- Secrets: agent['execution_environment']['secrets'] keys",
155
+ "- Env vars: agent['execution_environment']['env_vars'] keys",
156
+ "",
157
+ "**Example Output Format:**",
158
+ "```",
159
+ "Task: Deploy auth service to production",
160
+ "",
161
+ "Recommended: DevOps Agent",
162
+ "Reason: Has aws_ec2 skill and AWS_ACCESS_KEY_ID secret",
163
+ "",
164
+ "Complexity: 8 story points (multi-step deployment)",
165
+ "",
166
+ "Tasks:",
167
+ "1. Validate deployment config - check YAML syntax - uses kubectl skill",
168
+ "2. Deploy to staging - run kubectl apply - uses KUBECONFIG env var - depends on task 1",
169
+ "3. Run smoke tests - verify endpoints - uses curl",
170
+ "4. Promote to prod - kubectl apply to prod namespace - depends on tasks 2,3",
171
+ "",
172
+ "Prerequisites:",
173
+ "- Valid kubeconfig for target cluster",
174
+ "",
175
+ "Risks:",
176
+ "- Downtime during deployment",
177
+ "```",
178
+ "",
179
+ "REMEMBER: Keep it SHORT. Agent 2 handles JSON structuring.",
180
+ ],
181
+ description="Fast task planner for AI agent teams",
182
+ markdown=False,
183
+ add_history_to_context=False, # Disable for speed
184
+ retries=3, # Increased retries for reliability
185
+ )
186
+
187
+ return planning_agent
188
+
189
+
190
+ def create_structuring_agent() -> Agent:
191
+ """
192
+ Create a fast structuring agent that converts reasoning output to structured JSON.
193
+
194
+ This is Agent 2 in the two-agent workflow:
195
+ 1. Agent 1 (planning_agent) streams reasoning/thinking
196
+ 2. Agent 2 (structuring_agent) converts reasoning to TaskPlanResponse
197
+
198
+ Returns:
199
+ Agent configured with output_schema for structured JSON output
200
+ """
201
+ # Get LiteLLM configuration
202
+ litellm_api_url = (
203
+ os.getenv("LITELLM_API_URL") or
204
+ os.getenv("LITELLM_API_BASE") or
205
+ "https://llm-proxy.kubiya.ai"
206
+ ).strip()
207
+
208
+ litellm_api_key = os.getenv("LITELLM_API_KEY", "").strip()
209
+
210
+ if not litellm_api_key:
211
+ raise ValueError("LITELLM_API_KEY environment variable not set")
212
+
213
+ # Use same model as Agent 1 for structuring (Sonnet 4)
214
+ # Can be overridden with LITELLM_STRUCTURING_MODEL env var if Haiku is available
215
+ model = os.getenv("LITELLM_STRUCTURING_MODEL", os.getenv("LITELLM_DEFAULT_MODEL", "kubiya/claude-sonnet-4")).strip()
216
+ logger.info("creating_structuring_agent", model=model)
217
+
218
+ structuring_agent = Agent(
219
+ name="Task Structuring Agent",
220
+ role="Expert at converting task planning analysis into structured JSON",
221
+ model=LiteLLM(
222
+ id=f"openai/{model}",
223
+ api_base=litellm_api_url,
224
+ api_key=litellm_api_key,
225
+ request_params={
226
+ "timeout": 60, # 1 minute timeout for structuring
227
+ },
228
+ ),
229
+ output_schema=TaskPlanResponse, # IMPORTANT: This enforces structured output
230
+ tools=[], # No tools needed for structuring
231
+ instructions=[
232
+ "You are a task structuring agent that converts planning analysis into structured JSON.",
233
+ "",
234
+ "**Your Job:**",
235
+ "- You will receive detailed planning analysis and reasoning from another agent",
236
+ "- Extract all the key information from that analysis",
237
+ "- Convert it into a properly structured TaskPlanResponse JSON object",
238
+ "",
239
+ "**CRITICAL Requirements:**",
240
+ "- You MUST return valid JSON matching the TaskPlanResponse schema",
241
+ "- DO NOT add any reasoning, explanations, or markdown",
242
+ "- ONLY return the structured JSON object",
243
+ "- Ensure all required fields are populated with data from the analysis",
244
+ "",
245
+ "**Task Breakdown Fields:**",
246
+ "- Extract tasks with: id, title, description, details, test_strategy, priority, dependencies",
247
+ "- Extract skills_to_use, env_vars_to_use, secrets_to_use, knowledge_references from the analysis",
248
+ "- Ensure task IDs are sequential integers starting from 1",
249
+ "- Set dependencies as arrays of task IDs ([] if no dependencies)",
250
+ "",
251
+ "**If Information is Missing:**",
252
+ "- Use reasonable defaults based on the task description",
253
+ "- Set array fields to [] if not specified (never null)",
254
+ "- Provide basic but complete task breakdowns even if analysis is sparse",
255
+ ],
256
+ description="Fast structuring agent for converting analysis to JSON",
257
+ markdown=False,
258
+ add_history_to_context=False,
259
+ )
260
+
261
+ logger.info("structuring_agent_created", model=model)
262
+ return structuring_agent
263
+
264
+
265
+ def create_planning_workflow(
266
+ organization_id: Optional[str] = None,
267
+ db: Optional[Session] = None,
268
+ api_token: str = None,
269
+ tool_hook: Optional[Callable] = None,
270
+ ) -> "Workflow":
271
+ """
272
+ Create an Agno Workflow that chains the reasoning agent → structuring agent.
273
+
274
+ This implements the proper two-agent workflow:
275
+ 1. Agent 1 (reasoning): Analyzes task, uses tools, streams thinking
276
+ 2. Agent 2 (structuring): Converts analysis to TaskPlanResponse JSON
277
+
278
+ Args:
279
+ organization_id: Optional organization ID for filtering resources
280
+ db: Database session to pass to tools
281
+ api_token: API token for accessing organizational knowledge
282
+ tool_hook: Optional hook to capture tool executions for streaming
283
+
284
+ Returns:
285
+ Workflow with two steps: reasoning → structuring
286
+ """
287
+ from agno.workflow import Workflow
288
+
289
+ # Create Agent 1 (reasoning with tools)
290
+ reasoning_agent = create_planning_agent(
291
+ organization_id=organization_id,
292
+ db=db,
293
+ api_token=api_token,
294
+ tool_hook=tool_hook
295
+ )
296
+
297
+ # Create Agent 2 (structuring without tools)
298
+ structuring_agent = create_structuring_agent()
299
+
300
+ # Chain them in a workflow
301
+ workflow = Workflow(
302
+ name="Task Planning Workflow",
303
+ steps=[reasoning_agent, structuring_agent],
304
+ description="Two-step workflow: analyze task → structure output"
305
+ )
306
+
307
+ logger.info("planning_workflow_created", steps=2)
308
+ return workflow