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,28 @@
1
+ """
2
+ Execution streaming components.
3
+
4
+ This package contains modular components for handling streaming execution data,
5
+ extracted from the monolithic executions.py router.
6
+ """
7
+
8
+ # Import main router and utilities from parent executions.py
9
+ # This allows: from control_plane_api.app.routers.executions import router, validate_job_exists
10
+ import sys
11
+ from pathlib import Path
12
+
13
+ # Import from the sibling executions.py file (not this package)
14
+ _parent_dir = Path(__file__).parent.parent
15
+ _executions_module_path = _parent_dir / "executions.py"
16
+
17
+ # We need to import from ../executions.py, not this package
18
+ # Python's import system sees this directory first, so we explicitly import the file
19
+ import importlib.util
20
+ spec = importlib.util.spec_from_file_location("_executions_module", _executions_module_path)
21
+ _executions_module = importlib.util.module_from_spec(spec)
22
+ spec.loader.exec_module(_executions_module)
23
+
24
+ # Re-export the main router and utilities
25
+ router = _executions_module.router
26
+ validate_job_exists = _executions_module.validate_job_exists
27
+
28
+ __all__ = ["router", "validate_job_exists"]
@@ -0,0 +1,286 @@
1
+ """
2
+ Clean streaming router using ExecutionStreamer architecture.
3
+
4
+ This module provides a clean FastAPI router for execution streaming
5
+ that replaces the monolithic ~2,100 line inline implementation with
6
+ the modular ExecutionStreamer class.
7
+
8
+ Architecture:
9
+ - Immediate connection acknowledgment (<50ms)
10
+ - Progressive historical message loading
11
+ - Live event streaming with gap recovery
12
+ - Graceful degradation when services unavailable
13
+ - Last-Event-ID resumption support
14
+
15
+ The endpoint uses ExecutionStreamer which orchestrates:
16
+ - HistoryLoader: Database message loading with Temporal fallback
17
+ - LiveEventSource: Redis event streaming with workflow state polling
18
+ - MessageDeduplicator: Deduplication across history and live phases
19
+ - EventBuffer: Gap detection and replay for reconnection
20
+ - EventFormatter: Consistent SSE formatting
21
+ - WorkerHealthChecker: Graceful degradation mode detection
22
+
23
+ Test Strategy:
24
+ - Integration test with real execution IDs
25
+ - Test all event types are emitted correctly
26
+ - Test Last-Event-ID resumption works
27
+ - Test graceful degradation modes
28
+ - Test backward compatibility with existing clients
29
+ """
30
+
31
+ import asyncio
32
+ import uuid as uuid_module
33
+ from typing import Optional
34
+
35
+ import structlog
36
+ from fastapi import APIRouter, Depends, HTTPException, Request
37
+ from fastapi.responses import StreamingResponse
38
+ from sqlalchemy.orm import Session
39
+
40
+ from control_plane_api.app.database import get_db
41
+ from control_plane_api.app.lib.redis_client import get_redis_client
42
+ from control_plane_api.app.lib.temporal_client import get_temporal_client
43
+ from control_plane_api.app.middleware.auth import get_current_organization
44
+ from control_plane_api.app.models.execution import Execution
45
+
46
+ from .streaming import ExecutionStreamer
47
+ from .services.worker_health import WorkerHealthChecker
48
+
49
+ logger = structlog.get_logger(__name__)
50
+
51
+ router = APIRouter()
52
+
53
+
54
+ @router.get("/{execution_id}/stream")
55
+ async def stream_execution(
56
+ execution_id: str,
57
+ request: Request,
58
+ last_event_id: Optional[str] = None,
59
+ organization: dict = Depends(get_current_organization),
60
+ db: Session = Depends(get_db),
61
+ ):
62
+ """
63
+ Stream execution updates using Server-Sent Events (SSE).
64
+
65
+ This endpoint provides real-time execution updates by combining:
66
+ 1. Historical messages from database (last 200 messages)
67
+ 2. Live events from Redis (sub-second latency)
68
+ 3. Workflow state from Temporal (200ms polling)
69
+
70
+ The endpoint supports:
71
+ - Progressive history loading (no blocking on full history)
72
+ - Last-Event-ID resumption for reconnection
73
+ - Gap detection and notification
74
+ - Graceful degradation when services unavailable
75
+ - Backward compatible with existing clients
76
+
77
+ Architecture:
78
+ This endpoint uses the ExecutionStreamer class which orchestrates
79
+ all phases of streaming:
80
+ 1. Immediate connection (<50ms)
81
+ 2. History loading (progressive, one message at a time)
82
+ 3. History completion notification
83
+ 4. Live event streaming (until workflow completes or timeout)
84
+
85
+ Gap Recovery:
86
+ - Supports Last-Event-ID pattern for reconnection
87
+ - Client sends last_event_id query param or Last-Event-ID header
88
+ - Server resumes from that point or detects gaps
89
+ - Buffered events replayed if available
90
+ - Client notified if gap unrecoverable
91
+
92
+ SSE Event Types:
93
+ - connected: Initial connection acknowledgment
94
+ - message: Chat message (history or live)
95
+ - message_chunk: Streaming message chunk
96
+ - member_message_chunk: Team member message chunk
97
+ - history_complete: All historical messages sent
98
+ - status: Execution status update
99
+ - tool_started: Tool execution started
100
+ - tool_completed: Tool execution completed
101
+ - degraded: Service degradation notification
102
+ - recovered: Service recovery notification
103
+ - gap_detected: Gap in event stream detected
104
+ - error: Error occurred
105
+ - keepalive: Connection keepalive (comment)
106
+
107
+ SSE Format:
108
+ - id: {execution_id}_{counter}_{timestamp_micros}
109
+ - event: {event_type}
110
+ - data: {json object}
111
+
112
+ Args:
113
+ execution_id: Execution ID to stream
114
+ request: FastAPI request object (for headers)
115
+ last_event_id: Last event ID received by client (for resumption)
116
+ organization: Authenticated organization (injected by auth middleware)
117
+ db: Database session (injected by dependency)
118
+
119
+ Returns:
120
+ StreamingResponse with text/event-stream content
121
+
122
+ Raises:
123
+ HTTPException 404: Execution not found or not authorized
124
+ HTTPException 500: Critical initialization error
125
+ """
126
+
127
+ # ========== AUTHENTICATION & AUTHORIZATION ==========
128
+ # Already handled by get_current_organization dependency
129
+ logger.info(
130
+ "stream_request_received",
131
+ execution_id=execution_id[:8],
132
+ organization_id=organization["id"][:8],
133
+ has_last_event_id=bool(last_event_id or request.headers.get("Last-Event-ID")),
134
+ )
135
+
136
+ # ========== GET EXECUTION TYPE FROM DATABASE ==========
137
+ # This determines the workflow ID format:
138
+ # - TEAM: "team-execution-{id}"
139
+ # - AGENT: "agent-execution-{id}" (default)
140
+ try:
141
+ execution_record = db.query(Execution).filter(
142
+ Execution.id == uuid_module.UUID(execution_id),
143
+ Execution.organization_id == organization["id"]
144
+ ).first()
145
+
146
+ if not execution_record:
147
+ raise HTTPException(
148
+ status_code=404,
149
+ detail=f"Execution {execution_id} not found or not authorized"
150
+ )
151
+
152
+ execution_type = execution_record.execution_type or "AGENT"
153
+
154
+ logger.info(
155
+ "execution_type_determined",
156
+ execution_id=execution_id[:8],
157
+ execution_type=execution_type,
158
+ )
159
+
160
+ except HTTPException:
161
+ raise
162
+ except Exception as e:
163
+ logger.error(
164
+ "failed_to_query_execution",
165
+ execution_id=execution_id[:8],
166
+ error=str(e),
167
+ error_type=type(e).__name__,
168
+ )
169
+ raise HTTPException(
170
+ status_code=500,
171
+ detail=f"Failed to query execution: {str(e)}"
172
+ )
173
+
174
+ # ========== INITIALIZE INFRASTRUCTURE CLIENTS ==========
175
+ # Get clients with graceful degradation support
176
+ # - Temporal client: 2s timeout to fail fast when worker down
177
+ # - Redis client: Can be None if not configured
178
+ # - Database session: Already available from dependency
179
+
180
+ # Redis client (optional, graceful degradation if None)
181
+ redis_client = get_redis_client()
182
+ if not redis_client:
183
+ logger.warning(
184
+ "redis_not_configured",
185
+ execution_id=execution_id[:8],
186
+ note="Live streaming will be unavailable"
187
+ )
188
+
189
+ # Temporal client with fast timeout (optional, graceful degradation)
190
+ temporal_client = None
191
+ try:
192
+ temporal_client = await asyncio.wait_for(
193
+ get_temporal_client(),
194
+ timeout=2.0 # Fail fast - don't block streaming
195
+ )
196
+ logger.info(
197
+ "temporal_client_connected",
198
+ execution_id=execution_id[:8],
199
+ )
200
+ except asyncio.TimeoutError:
201
+ logger.warning(
202
+ "temporal_connection_timeout",
203
+ execution_id=execution_id[:8],
204
+ timeout_seconds=2.0,
205
+ note="Workflow queries will be unavailable"
206
+ )
207
+ except Exception as temporal_error:
208
+ logger.warning(
209
+ "temporal_connection_failed",
210
+ execution_id=execution_id[:8],
211
+ error=str(temporal_error),
212
+ error_type=type(temporal_error).__name__,
213
+ note="Continuing without Temporal support"
214
+ )
215
+
216
+ # ========== PARSE LAST-EVENT-ID ==========
217
+ # Check both query param and header (EventSource sets header automatically)
218
+ parsed_last_event_id = last_event_id or request.headers.get("Last-Event-ID")
219
+
220
+ if parsed_last_event_id:
221
+ logger.info(
222
+ "resumption_requested",
223
+ execution_id=execution_id[:8],
224
+ last_event_id=parsed_last_event_id,
225
+ )
226
+
227
+ # ========== CREATE WORKER HEALTH CHECKER ==========
228
+ # This determines degradation mode based on service availability
229
+ health_checker = WorkerHealthChecker(
230
+ temporal_client=temporal_client,
231
+ redis_client=redis_client,
232
+ db_session=db,
233
+ )
234
+
235
+ # ========== INSTANTIATE EXECUTION STREAMER ==========
236
+ # This orchestrates all phases of streaming:
237
+ # 1. Immediate connection
238
+ # 2. Resumption (if Last-Event-ID provided)
239
+ # 3. Historical message loading
240
+ # 4. History completion notification
241
+ # 5. Live event streaming
242
+ try:
243
+ streamer = ExecutionStreamer(
244
+ execution_id=execution_id,
245
+ organization_id=organization["id"],
246
+ db_session=db,
247
+ redis_client=redis_client,
248
+ temporal_client=temporal_client,
249
+ last_event_id=parsed_last_event_id,
250
+ timeout_seconds=0, # 0 = no timeout, stream until task completes
251
+ execution_type=execution_type,
252
+ health_checker=health_checker,
253
+ )
254
+
255
+ logger.info(
256
+ "streamer_initialized",
257
+ execution_id=execution_id[:8],
258
+ execution_type=execution_type,
259
+ has_redis=bool(redis_client),
260
+ has_temporal=bool(temporal_client),
261
+ has_last_event_id=bool(parsed_last_event_id),
262
+ )
263
+
264
+ except Exception as e:
265
+ logger.error(
266
+ "failed_to_initialize_streamer",
267
+ execution_id=execution_id[:8],
268
+ error=str(e),
269
+ error_type=type(e).__name__,
270
+ )
271
+ raise HTTPException(
272
+ status_code=500,
273
+ detail=f"Failed to initialize streaming: {str(e)}"
274
+ )
275
+
276
+ # ========== RETURN STREAMING RESPONSE ==========
277
+ # StreamingResponse will call streamer.stream() which yields SSE events
278
+ return StreamingResponse(
279
+ streamer.stream(),
280
+ media_type="text/event-stream",
281
+ headers={
282
+ "Cache-Control": "no-cache",
283
+ "Connection": "keep-alive",
284
+ "X-Accel-Buffering": "no", # Disable nginx buffering for real-time
285
+ }
286
+ )
@@ -0,0 +1,22 @@
1
+ """Execution services package
2
+
3
+ This package contains service classes for execution-related functionality:
4
+ - worker_health: Worker and service health checking with graceful degradation
5
+ - status_service: Cached workflow status queries to reduce Temporal API load
6
+ """
7
+
8
+ from control_plane_api.app.routers.executions.services.worker_health import (
9
+ WorkerHealthChecker,
10
+ DegradationMode,
11
+ CAPABILITIES,
12
+ )
13
+ from control_plane_api.app.routers.executions.services.status_service import (
14
+ StatusService,
15
+ )
16
+
17
+ __all__ = [
18
+ "WorkerHealthChecker",
19
+ "DegradationMode",
20
+ "CAPABILITIES",
21
+ "StatusService",
22
+ ]
@@ -0,0 +1,156 @@
1
+ #!/usr/bin/env python
2
+ """Demo script for WorkerHealthChecker service
3
+
4
+ This script demonstrates the WorkerHealthChecker service in action.
5
+ It shows health checks, degradation modes, and capabilities.
6
+
7
+ Usage:
8
+ cd /Users/shaked/projects/agent-control-plane/control_plane_api/app/routers/executions/services
9
+ python demo_worker_health.py
10
+ """
11
+
12
+ import asyncio
13
+ import sys
14
+ from pathlib import Path
15
+
16
+ # Add parent directory to path for imports
17
+ sys.path.insert(0, str(Path(__file__).parent))
18
+
19
+ from worker_health import (
20
+ WorkerHealthChecker,
21
+ DegradationMode,
22
+ CAPABILITIES,
23
+ )
24
+
25
+
26
+ def print_section(title: str):
27
+ """Print a section header."""
28
+ print(f"\n{'=' * 60}")
29
+ print(f" {title}")
30
+ print(f"{'=' * 60}\n")
31
+
32
+
33
+ async def demo_no_services():
34
+ """Demo: No services available."""
35
+ print_section("Demo 1: No Services Available")
36
+
37
+ checker = WorkerHealthChecker(
38
+ temporal_client=None,
39
+ redis_client=None,
40
+ db_session=None,
41
+ )
42
+
43
+ print("Checking service health...")
44
+ results = await checker.check_all()
45
+ print(f" Temporal: {'✓' if results['temporal'] else '✗'}")
46
+ print(f" Redis: {'✓' if results['redis'] else '✗'}")
47
+ print(f" Database: {'✓' if results['database'] else '✗'}")
48
+
49
+ print("\nDetermining degradation mode...")
50
+ mode = await checker.get_degradation_mode()
51
+ print(f" Mode: {mode.value}")
52
+
53
+ print("\nAvailable capabilities:")
54
+ capabilities = checker.get_capabilities(mode)
55
+ if capabilities:
56
+ for cap in capabilities:
57
+ print(f" - {cap}")
58
+ else:
59
+ print(" (none)")
60
+
61
+
62
+ async def demo_cache_behavior():
63
+ """Demo: Cache behavior."""
64
+ print_section("Demo 2: Health Check Caching")
65
+
66
+ checker = WorkerHealthChecker(
67
+ temporal_client=None,
68
+ redis_client=None,
69
+ db_session=None,
70
+ cache_ttl=5 # 5 second cache
71
+ )
72
+
73
+ print("First health check (will hit services)...")
74
+ start = asyncio.get_event_loop().time()
75
+ await checker.check_all()
76
+ duration1 = asyncio.get_event_loop().time() - start
77
+ print(f" Duration: {duration1:.3f}s")
78
+
79
+ print("\nSecond health check (should use cache)...")
80
+ start = asyncio.get_event_loop().time()
81
+ await checker.check_all()
82
+ duration2 = asyncio.get_event_loop().time() - start
83
+ print(f" Duration: {duration2:.3f}s")
84
+
85
+ if duration2 < duration1:
86
+ print(f" ✓ Cache is working! Second check was faster.")
87
+ else:
88
+ print(f" ℹ Both checks were similar (expected if services are None)")
89
+
90
+ print("\nClearing cache...")
91
+ checker.clear_cache()
92
+ print(" ✓ Cache cleared")
93
+
94
+ print("\nThird health check (should hit services again)...")
95
+ start = asyncio.get_event_loop().time()
96
+ await checker.check_all()
97
+ duration3 = asyncio.get_event_loop().time() - start
98
+ print(f" Duration: {duration3:.3f}s")
99
+
100
+
101
+ async def demo_all_degradation_modes():
102
+ """Demo: All degradation modes."""
103
+ print_section("Demo 3: All Degradation Modes")
104
+
105
+ print("Degradation mode capabilities:\n")
106
+
107
+ for mode in DegradationMode:
108
+ capabilities = CAPABILITIES.get(mode, [])
109
+ print(f"{mode.value.upper()}")
110
+ print(f" Capabilities: {', '.join(capabilities) if capabilities else 'none'}")
111
+ print()
112
+
113
+
114
+ async def demo_timeout_behavior():
115
+ """Demo: Timeout behavior simulation."""
116
+ print_section("Demo 4: Timeout Behavior")
117
+
118
+ print("Health check timeouts:")
119
+ print(f" Temporal: {WorkerHealthChecker.TEMPORAL_TIMEOUT}s")
120
+ print(f" Redis: {WorkerHealthChecker.REDIS_TIMEOUT}s")
121
+ print(f" Database: {WorkerHealthChecker.DATABASE_TIMEOUT}s")
122
+
123
+ print("\nThese timeouts ensure the API remains responsive even when")
124
+ print("services are down or slow. Without timeouts, a client request")
125
+ print("could hang for 30+ seconds waiting for services to fail.")
126
+
127
+
128
+ async def main():
129
+ """Run all demos."""
130
+ print("\n" + "=" * 60)
131
+ print(" WorkerHealthChecker Service Demo")
132
+ print("=" * 60)
133
+ print("\nThis demo shows how the WorkerHealthChecker service works.")
134
+ print("It demonstrates health checks, degradation modes, and caching.")
135
+
136
+ try:
137
+ await demo_no_services()
138
+ await demo_cache_behavior()
139
+ await demo_all_degradation_modes()
140
+ await demo_timeout_behavior()
141
+
142
+ print_section("Demo Complete")
143
+ print("✓ All demos completed successfully")
144
+ print("\nFor integration examples, see:")
145
+ print(" - USAGE_EXAMPLE.md")
146
+ print(" - test_worker_health.py")
147
+ print()
148
+
149
+ except Exception as e:
150
+ print(f"\n✗ Demo failed: {e}")
151
+ import traceback
152
+ traceback.print_exc()
153
+
154
+
155
+ if __name__ == "__main__":
156
+ asyncio.run(main())