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,514 @@
1
+ """Worker Health Checker Service
2
+
3
+ This service detects worker and service availability to enable graceful degradation
4
+ when critical services (Temporal, Redis, Database) are unavailable.
5
+
6
+ Degradation Modes:
7
+ - FULL: All services available (Temporal + Redis + Database)
8
+ - HISTORY_ONLY: Only database available (can serve historical data)
9
+ - LIVE_ONLY: Only Redis available (can serve live events)
10
+ - DEGRADED: Partial functionality available
11
+ - UNAVAILABLE: Critical services down
12
+
13
+ Usage:
14
+ health_checker = WorkerHealthChecker(
15
+ temporal_client=temporal_client,
16
+ redis_client=redis_client,
17
+ db_session=db_session
18
+ )
19
+
20
+ mode = await health_checker.get_degradation_mode()
21
+ capabilities = health_checker.get_capabilities(mode)
22
+ """
23
+
24
+ import asyncio
25
+ import time
26
+ from enum import Enum
27
+ from typing import Dict, List, Optional, Any
28
+ import structlog
29
+ from sqlalchemy.orm import Session
30
+ from sqlalchemy import text
31
+
32
+ logger = structlog.get_logger()
33
+
34
+
35
+ class DegradationMode(Enum):
36
+ """Service degradation modes based on availability."""
37
+
38
+ FULL = "full" # All services available
39
+ HISTORY_ONLY = "history_only" # Only database available
40
+ LIVE_ONLY = "live_only" # Only Redis available
41
+ DEGRADED = "degraded" # Partial functionality
42
+ UNAVAILABLE = "unavailable" # Critical services down
43
+
44
+
45
+ # Capabilities available in each degradation mode
46
+ CAPABILITIES = {
47
+ DegradationMode.FULL: [
48
+ "history",
49
+ "live_events",
50
+ "status_updates",
51
+ "completion_detection",
52
+ "workflow_queries",
53
+ ],
54
+ DegradationMode.HISTORY_ONLY: [
55
+ "history",
56
+ ],
57
+ DegradationMode.LIVE_ONLY: [
58
+ "live_events",
59
+ ],
60
+ DegradationMode.DEGRADED: [
61
+ "partial_functionality",
62
+ ],
63
+ DegradationMode.UNAVAILABLE: [],
64
+ }
65
+
66
+
67
+ class WorkerHealthChecker:
68
+ """
69
+ Health checker for worker and service availability.
70
+
71
+ Performs health checks on critical services with proper timeouts to
72
+ avoid blocking operations. Results can be cached to prevent excessive
73
+ health check overhead.
74
+
75
+ Attributes:
76
+ temporal_client: Temporal client instance (optional)
77
+ redis_client: Redis client instance (optional)
78
+ db_session: Database session instance (optional)
79
+ cache_ttl: Time-to-live for health check cache in seconds
80
+ """
81
+
82
+ # Timeout values for health checks (in seconds)
83
+ TEMPORAL_TIMEOUT = 2.0 # Fast timeout - don't block on Temporal
84
+ REDIS_TIMEOUT = 1.0 # Redis should be fast
85
+ DATABASE_TIMEOUT = 1.0 # Database should be fast
86
+
87
+ def __init__(
88
+ self,
89
+ temporal_client=None,
90
+ redis_client=None,
91
+ db_session: Optional[Session] = None,
92
+ cache_ttl: int = 10, # Cache health check results for 10 seconds
93
+ ):
94
+ """
95
+ Initialize WorkerHealthChecker.
96
+
97
+ Args:
98
+ temporal_client: Temporal client instance (can be None)
99
+ redis_client: Redis client instance (can be None)
100
+ db_session: Database session instance (can be None)
101
+ cache_ttl: Cache TTL in seconds for health check results
102
+ """
103
+ self.temporal_client = temporal_client
104
+ self.redis_client = redis_client
105
+ self.db_session = db_session
106
+ self.cache_ttl = cache_ttl
107
+
108
+ # Cache health check results to avoid excessive checks
109
+ # Format: {"temporal": (timestamp, result), "redis": (timestamp, result), ...}
110
+ self._last_check: Dict[str, tuple[float, bool]] = {}
111
+
112
+ def _is_cached(self, service: str) -> Optional[bool]:
113
+ """
114
+ Check if health check result is cached and still valid.
115
+
116
+ Args:
117
+ service: Service name ("temporal", "redis", "database")
118
+
119
+ Returns:
120
+ Cached result if valid, None if cache miss or expired
121
+ """
122
+ if service not in self._last_check:
123
+ return None
124
+
125
+ timestamp, result = self._last_check[service]
126
+ if time.time() - timestamp < self.cache_ttl:
127
+ logger.debug(
128
+ "health_check_cache_hit",
129
+ service=service,
130
+ result=result,
131
+ age_seconds=time.time() - timestamp
132
+ )
133
+ return result
134
+
135
+ return None
136
+
137
+ def _cache_result(self, service: str, result: bool) -> None:
138
+ """
139
+ Cache health check result.
140
+
141
+ Args:
142
+ service: Service name ("temporal", "redis", "database")
143
+ result: Health check result (True if healthy)
144
+ """
145
+ self._last_check[service] = (time.time(), result)
146
+
147
+ async def check_temporal_connectivity(self) -> bool:
148
+ """
149
+ Check if Temporal is accessible.
150
+
151
+ Attempts to verify Temporal client is connected and responsive.
152
+ Uses a fast timeout (2 seconds) to fail quickly when worker is down.
153
+
154
+ Returns:
155
+ True if connected and responsive, False otherwise
156
+
157
+ Test Strategy:
158
+ - Test with Temporal unavailable (connection timeout)
159
+ - Test with Temporal available (successful connection)
160
+ - Test timeout behavior (should complete within 2 seconds)
161
+ """
162
+ # Check cache first
163
+ cached = self._is_cached("temporal")
164
+ if cached is not None:
165
+ return cached
166
+
167
+ if not self.temporal_client:
168
+ logger.debug("temporal_health_check_skipped", reason="no_client")
169
+ self._cache_result("temporal", False)
170
+ return False
171
+
172
+ try:
173
+ # Try to describe the client with timeout
174
+ # This is a lightweight operation that verifies connectivity
175
+ t0 = time.time()
176
+
177
+ # Try getting workflow service with timeout
178
+ result = await asyncio.wait_for(
179
+ self._check_temporal_service(),
180
+ timeout=self.TEMPORAL_TIMEOUT
181
+ )
182
+
183
+ duration_ms = int((time.time() - t0) * 1000)
184
+ logger.debug(
185
+ "temporal_health_check_passed",
186
+ duration_ms=duration_ms,
187
+ result=result
188
+ )
189
+
190
+ self._cache_result("temporal", result)
191
+ return result
192
+
193
+ except asyncio.TimeoutError:
194
+ duration_ms = int((time.time() - t0) * 1000)
195
+ logger.warning(
196
+ "temporal_health_check_timeout",
197
+ timeout_seconds=self.TEMPORAL_TIMEOUT,
198
+ duration_ms=duration_ms
199
+ )
200
+ self._cache_result("temporal", False)
201
+ return False
202
+
203
+ except Exception as e:
204
+ logger.warning(
205
+ "temporal_health_check_failed",
206
+ error=str(e),
207
+ error_type=type(e).__name__
208
+ )
209
+ self._cache_result("temporal", False)
210
+ return False
211
+
212
+ async def _check_temporal_service(self) -> bool:
213
+ """
214
+ Internal method to check Temporal service availability.
215
+
216
+ Returns:
217
+ True if service is accessible
218
+ """
219
+ try:
220
+ # Check if client has a workflow service
221
+ # This is a lightweight check that doesn't require a specific workflow
222
+ if hasattr(self.temporal_client, 'workflow_service'):
223
+ # Client is properly initialized
224
+ return True
225
+
226
+ # Fallback: Check if client object exists
227
+ return self.temporal_client is not None
228
+
229
+ except Exception as e:
230
+ logger.debug("temporal_service_check_error", error=str(e))
231
+ return False
232
+
233
+ async def check_redis_connectivity(self) -> bool:
234
+ """
235
+ Check if Redis is accessible.
236
+
237
+ Performs a simple PING operation to verify Redis connectivity.
238
+ Uses a 1-second timeout to fail quickly.
239
+
240
+ Returns:
241
+ True if connected and responsive, False otherwise
242
+
243
+ Test Strategy:
244
+ - Test with Redis unavailable (connection error)
245
+ - Test with Redis available (successful ping)
246
+ - Test timeout behavior (should complete within 1 second)
247
+ """
248
+ # Check cache first
249
+ cached = self._is_cached("redis")
250
+ if cached is not None:
251
+ return cached
252
+
253
+ if not self.redis_client:
254
+ logger.debug("redis_health_check_skipped", reason="no_client")
255
+ self._cache_result("redis", False)
256
+ return False
257
+
258
+ try:
259
+ t0 = time.time()
260
+
261
+ # Try a simple PING operation with timeout
262
+ result = await asyncio.wait_for(
263
+ self.redis_client.ping(),
264
+ timeout=self.REDIS_TIMEOUT
265
+ )
266
+
267
+ duration_ms = int((time.time() - t0) * 1000)
268
+
269
+ # Redis ping returns True/PONG on success
270
+ is_healthy = result is True or result == "PONG"
271
+
272
+ logger.debug(
273
+ "redis_health_check_passed",
274
+ duration_ms=duration_ms,
275
+ result=is_healthy
276
+ )
277
+
278
+ self._cache_result("redis", is_healthy)
279
+ return is_healthy
280
+
281
+ except asyncio.TimeoutError:
282
+ duration_ms = int((time.time() - t0) * 1000)
283
+ logger.warning(
284
+ "redis_health_check_timeout",
285
+ timeout_seconds=self.REDIS_TIMEOUT,
286
+ duration_ms=duration_ms
287
+ )
288
+ self._cache_result("redis", False)
289
+ return False
290
+
291
+ except Exception as e:
292
+ logger.warning(
293
+ "redis_health_check_failed",
294
+ error=str(e),
295
+ error_type=type(e).__name__
296
+ )
297
+ self._cache_result("redis", False)
298
+ return False
299
+
300
+ async def check_database_connectivity(self) -> bool:
301
+ """
302
+ Check if database is accessible.
303
+
304
+ Performs a simple SELECT 1 query to verify database connectivity.
305
+ Uses a 1-second timeout to fail quickly.
306
+
307
+ Returns:
308
+ True if connected and responsive, False otherwise
309
+
310
+ Test Strategy:
311
+ - Test with database unavailable (connection error)
312
+ - Test with database available (successful query)
313
+ - Test timeout behavior (should complete within 1 second)
314
+ """
315
+ # Check cache first
316
+ cached = self._is_cached("database")
317
+ if cached is not None:
318
+ return cached
319
+
320
+ if not self.db_session:
321
+ logger.debug("database_health_check_skipped", reason="no_session")
322
+ self._cache_result("database", False)
323
+ return False
324
+
325
+ try:
326
+ t0 = time.time()
327
+
328
+ # Try a simple query with timeout
329
+ result = await asyncio.wait_for(
330
+ self._check_database_query(),
331
+ timeout=self.DATABASE_TIMEOUT
332
+ )
333
+
334
+ duration_ms = int((time.time() - t0) * 1000)
335
+ logger.debug(
336
+ "database_health_check_passed",
337
+ duration_ms=duration_ms,
338
+ result=result
339
+ )
340
+
341
+ self._cache_result("database", result)
342
+ return result
343
+
344
+ except asyncio.TimeoutError:
345
+ duration_ms = int((time.time() - t0) * 1000)
346
+ logger.warning(
347
+ "database_health_check_timeout",
348
+ timeout_seconds=self.DATABASE_TIMEOUT,
349
+ duration_ms=duration_ms
350
+ )
351
+ self._cache_result("database", False)
352
+ return False
353
+
354
+ except Exception as e:
355
+ logger.warning(
356
+ "database_health_check_failed",
357
+ error=str(e),
358
+ error_type=type(e).__name__
359
+ )
360
+ self._cache_result("database", False)
361
+ return False
362
+
363
+ async def _check_database_query(self) -> bool:
364
+ """
365
+ Internal method to execute database health check query.
366
+
367
+ Returns:
368
+ True if query successful
369
+ """
370
+ try:
371
+ # Execute simple query to verify database connectivity
372
+ result = self.db_session.execute(text("SELECT 1"))
373
+
374
+ # Verify we got a result
375
+ if result:
376
+ return True
377
+
378
+ return False
379
+
380
+ except Exception as e:
381
+ logger.debug("database_query_error", error=str(e))
382
+ return False
383
+
384
+ async def check_all(self) -> Dict[str, bool]:
385
+ """
386
+ Run all health checks and return results.
387
+
388
+ Executes all health checks concurrently for efficiency.
389
+
390
+ Returns:
391
+ Dictionary with health check results:
392
+ {
393
+ "temporal": bool,
394
+ "redis": bool,
395
+ "database": bool
396
+ }
397
+
398
+ Test Strategy:
399
+ - Test with all services available
400
+ - Test with all services unavailable
401
+ - Test with mixed availability
402
+ """
403
+ # Run all checks concurrently for efficiency
404
+ temporal_check, redis_check, db_check = await asyncio.gather(
405
+ self.check_temporal_connectivity(),
406
+ self.check_redis_connectivity(),
407
+ self.check_database_connectivity(),
408
+ return_exceptions=True # Don't let one failure stop others
409
+ )
410
+
411
+ # Handle any exceptions from gather
412
+ temporal_ok = temporal_check if isinstance(temporal_check, bool) else False
413
+ redis_ok = redis_check if isinstance(redis_check, bool) else False
414
+ db_ok = db_check if isinstance(db_check, bool) else False
415
+
416
+ results = {
417
+ "temporal": temporal_ok,
418
+ "redis": redis_ok,
419
+ "database": db_ok,
420
+ }
421
+
422
+ logger.info("health_check_all_completed", **results)
423
+ return results
424
+
425
+ async def get_degradation_mode(self) -> DegradationMode:
426
+ """
427
+ Determine current degradation mode based on service availability.
428
+
429
+ Logic:
430
+ - All available: FULL
431
+ - Only DB: HISTORY_ONLY
432
+ - Only Redis: LIVE_ONLY
433
+ - Some available: DEGRADED
434
+ - None available: UNAVAILABLE
435
+
436
+ Returns:
437
+ Current degradation mode
438
+
439
+ Test Strategy:
440
+ - Test all degradation mode combinations
441
+ - Test mode selection logic
442
+ - Test with various service availability patterns
443
+ """
444
+ # Get health check results
445
+ temporal_ok = await self.check_temporal_connectivity()
446
+ redis_ok = await self.check_redis_connectivity()
447
+ db_ok = await self.check_database_connectivity()
448
+
449
+ # Determine degradation mode
450
+ if temporal_ok and redis_ok and db_ok:
451
+ mode = DegradationMode.FULL
452
+
453
+ elif db_ok and not (temporal_ok or redis_ok):
454
+ # Database only - can serve historical data
455
+ mode = DegradationMode.HISTORY_ONLY
456
+
457
+ elif redis_ok and not db_ok:
458
+ # Redis only - can serve live events (no history)
459
+ mode = DegradationMode.LIVE_ONLY
460
+
461
+ elif any([temporal_ok, redis_ok, db_ok]):
462
+ # Some services available but not full functionality
463
+ mode = DegradationMode.DEGRADED
464
+
465
+ else:
466
+ # Nothing available
467
+ mode = DegradationMode.UNAVAILABLE
468
+
469
+ logger.info(
470
+ "degradation_mode_determined",
471
+ mode=mode.value,
472
+ temporal=temporal_ok,
473
+ redis=redis_ok,
474
+ database=db_ok
475
+ )
476
+
477
+ return mode
478
+
479
+ def get_capabilities(self, mode: DegradationMode) -> List[str]:
480
+ """
481
+ Return list of available capabilities for given mode.
482
+
483
+ Args:
484
+ mode: Degradation mode
485
+
486
+ Returns:
487
+ List of capability names available in this mode
488
+
489
+ Examples:
490
+ >>> checker = WorkerHealthChecker()
491
+ >>> checker.get_capabilities(DegradationMode.FULL)
492
+ ['history', 'live_events', 'status_updates', 'completion_detection', 'workflow_queries']
493
+
494
+ >>> checker.get_capabilities(DegradationMode.HISTORY_ONLY)
495
+ ['history']
496
+ """
497
+ capabilities = CAPABILITIES.get(mode, [])
498
+
499
+ logger.debug(
500
+ "capabilities_retrieved",
501
+ mode=mode.value,
502
+ capabilities=capabilities
503
+ )
504
+
505
+ return capabilities
506
+
507
+ def clear_cache(self) -> None:
508
+ """
509
+ Clear all cached health check results.
510
+
511
+ Useful when you want to force fresh health checks.
512
+ """
513
+ self._last_check.clear()
514
+ logger.debug("health_check_cache_cleared")
@@ -0,0 +1,22 @@
1
+ """
2
+ Streaming execution components.
3
+
4
+ This module contains components for handling streaming execution data,
5
+ including deduplication, event management, and message processing.
6
+ """
7
+
8
+ from .deduplication import MessageDeduplicator
9
+ from .history_loader import HistoryLoader
10
+ from .live_source import LiveEventSource
11
+ from .event_buffer import EventBuffer
12
+ from .event_formatter import EventFormatter
13
+ from .streamer import ExecutionStreamer
14
+
15
+ __all__ = [
16
+ "MessageDeduplicator",
17
+ "HistoryLoader",
18
+ "LiveEventSource",
19
+ "EventBuffer",
20
+ "EventFormatter",
21
+ "ExecutionStreamer",
22
+ ]