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,323 @@
1
+ """
2
+ Model Pricing and AEM Weight Configuration
3
+
4
+ This module defines pricing tiers and Agentic Engineering Minutes (AEM) weights
5
+ for different model families.
6
+
7
+ AEM Formula: Runtime (minutes) × Model Weight × Tool Calls Weight
8
+
9
+ Model Weights:
10
+ - Opus-class (most capable): 2.0x weight
11
+ - Sonnet-class (balanced): 1.0x weight
12
+ - Haiku-class (fast): 0.5x weight
13
+ """
14
+
15
+ from typing import Dict, Any
16
+ from enum import Enum
17
+
18
+
19
+ class ModelTier(str, Enum):
20
+ """Universal model capability tiers (provider-agnostic)"""
21
+ PREMIUM = "premium" # Most capable: Opus, GPT-4, o1, Gemini Pro (weight >= 1.5)
22
+ MID = "mid" # Balanced: Sonnet, GPT-4o, Gemini Flash (weight 0.8-1.4)
23
+ BASIC = "basic" # Fast/efficient: Haiku, GPT-3.5, mini models (weight < 0.8)
24
+ CUSTOM = "custom" # Custom/unknown models
25
+
26
+
27
+ # Model Weight Configuration for AEM Calculation
28
+ MODEL_WEIGHTS: Dict[str, float] = {
29
+ # Anthropic Claude Models
30
+ "claude-opus-4": 2.0,
31
+ "claude-4-opus": 2.0,
32
+ "claude-3-opus": 2.0,
33
+ "claude-3-opus-20240229": 2.0,
34
+
35
+ "claude-sonnet-4": 1.0,
36
+ "claude-4-sonnet": 1.0,
37
+ "claude-3.5-sonnet": 1.0,
38
+ "claude-3-5-sonnet-20241022": 1.0,
39
+ "claude-3-sonnet": 1.0,
40
+ "claude-3-sonnet-20240229": 1.0,
41
+
42
+ "claude-haiku-4": 0.5,
43
+ "claude-4-haiku": 0.5,
44
+ "claude-3.5-haiku": 0.5,
45
+ "claude-3-5-haiku-20241022": 0.5,
46
+ "claude-3-haiku": 0.5,
47
+ "claude-3-haiku-20240307": 0.5,
48
+
49
+ # OpenAI Models
50
+ "gpt-4": 2.0,
51
+ "gpt-4-turbo": 2.0,
52
+ "gpt-4-turbo-preview": 2.0,
53
+ "gpt-4-0125-preview": 2.0,
54
+ "gpt-4-1106-preview": 2.0,
55
+ "gpt-4o": 1.3, # As shown in the image
56
+ "gpt-4o-mini": 0.7,
57
+
58
+ "gpt-3.5-turbo": 0.5,
59
+ "gpt-3.5-turbo-16k": 0.5,
60
+
61
+ # Google Models
62
+ "gemini-1.5-pro": 1.5,
63
+ "gemini-1.5-flash": 0.7,
64
+ "gemini-pro": 1.0,
65
+
66
+ # Meta Models
67
+ "llama-3-70b": 1.2,
68
+ "llama-3-8b": 0.5,
69
+
70
+ # Mistral Models
71
+ "mistral-large": 1.5,
72
+ "mistral-medium": 1.0,
73
+ "mistral-small": 0.5,
74
+ }
75
+
76
+
77
+ # Token Pricing per 1M tokens (in USD)
78
+ TOKEN_PRICING: Dict[str, Dict[str, float]] = {
79
+ # Anthropic Claude
80
+ "claude-opus-4": {
81
+ "input": 15.00,
82
+ "output": 75.00,
83
+ "cache_read": 1.50,
84
+ "cache_creation": 18.75,
85
+ },
86
+ "claude-sonnet-4": {
87
+ "input": 3.00,
88
+ "output": 15.00,
89
+ "cache_read": 0.30,
90
+ "cache_creation": 3.75,
91
+ },
92
+ "claude-haiku-4": {
93
+ "input": 0.80,
94
+ "output": 4.00,
95
+ "cache_read": 0.08,
96
+ "cache_creation": 1.00,
97
+ },
98
+
99
+ # OpenAI
100
+ "gpt-4": {
101
+ "input": 30.00,
102
+ "output": 60.00,
103
+ "cache_read": 0.0,
104
+ "cache_creation": 0.0,
105
+ },
106
+ "gpt-4o": {
107
+ "input": 5.00,
108
+ "output": 15.00,
109
+ "cache_read": 0.0,
110
+ "cache_creation": 0.0,
111
+ },
112
+ "gpt-3.5-turbo": {
113
+ "input": 0.50,
114
+ "output": 1.50,
115
+ "cache_read": 0.0,
116
+ "cache_creation": 0.0,
117
+ },
118
+
119
+ # Google Gemini
120
+ "gemini-1.5-pro": {
121
+ "input": 3.50,
122
+ "output": 10.50,
123
+ "cache_read": 0.0,
124
+ "cache_creation": 0.0,
125
+ },
126
+ "gemini-1.5-flash": {
127
+ "input": 0.35,
128
+ "output": 1.05,
129
+ "cache_read": 0.0,
130
+ "cache_creation": 0.0,
131
+ },
132
+ }
133
+
134
+
135
+ # AEM Pricing Configuration
136
+ AEM_PRICING: Dict[str, float] = {
137
+ "saas_prepaid_per_minute": 0.15, # $0.15/min for SaaS/Hybrid
138
+ "on_prem_unlimited": 0.0, # Unlimited for on-prem
139
+ }
140
+
141
+
142
+ def get_model_weight(model: str) -> float:
143
+ """
144
+ Get the AEM weight for a model.
145
+
146
+ Args:
147
+ model: Model identifier
148
+
149
+ Returns:
150
+ Weight multiplier for AEM calculation (default 1.0)
151
+ """
152
+ # Normalize model name
153
+ model_lower = model.lower().strip()
154
+
155
+ # Try exact match first
156
+ if model_lower in MODEL_WEIGHTS:
157
+ return MODEL_WEIGHTS[model_lower]
158
+
159
+ # Try fuzzy matching by keywords
160
+ if "opus" in model_lower:
161
+ return 2.0
162
+ elif "sonnet" in model_lower:
163
+ return 1.0
164
+ elif "haiku" in model_lower:
165
+ return 0.5
166
+ elif "gpt-4" in model_lower and "turbo" in model_lower:
167
+ return 2.0
168
+ elif "gpt-4o" in model_lower:
169
+ return 1.3
170
+ elif "gpt-3.5" in model_lower:
171
+ return 0.5
172
+ elif "gemini" in model_lower and "pro" in model_lower:
173
+ return 1.5
174
+ elif "gemini" in model_lower and "flash" in model_lower:
175
+ return 0.7
176
+
177
+ # Default weight
178
+ return 1.0
179
+
180
+
181
+ def get_model_tier(model: str) -> ModelTier:
182
+ """
183
+ Determine the tier/class of a model using provider-agnostic naming.
184
+
185
+ Tier Classification:
186
+ - Premium (weight >= 1.5): Most capable models (Claude Opus, GPT-4, o1, Gemini Pro)
187
+ - Mid (weight 0.8-1.4): Balanced models (Claude Sonnet, GPT-4o, Gemini Flash)
188
+ - Basic (weight < 0.8): Fast/efficient models (Claude Haiku, GPT-3.5, mini models)
189
+
190
+ Args:
191
+ model: Model identifier
192
+
193
+ Returns:
194
+ ModelTier enum value
195
+ """
196
+ weight = get_model_weight(model)
197
+
198
+ if weight >= 1.5:
199
+ return ModelTier.PREMIUM
200
+ elif weight >= 0.8:
201
+ return ModelTier.MID
202
+ elif weight >= 0.3:
203
+ return ModelTier.BASIC
204
+ else:
205
+ return ModelTier.CUSTOM
206
+
207
+
208
+ def calculate_token_cost(
209
+ model: str,
210
+ input_tokens: int,
211
+ output_tokens: int,
212
+ cache_read_tokens: int = 0,
213
+ cache_creation_tokens: int = 0,
214
+ ) -> Dict[str, float]:
215
+ """
216
+ Calculate token costs based on model pricing.
217
+
218
+ Args:
219
+ model: Model identifier
220
+ input_tokens: Number of input tokens
221
+ output_tokens: Number of output tokens
222
+ cache_read_tokens: Number of cached tokens read
223
+ cache_creation_tokens: Number of tokens used for cache creation
224
+
225
+ Returns:
226
+ Dict with cost breakdown
227
+ """
228
+ # Normalize model name
229
+ model_lower = model.lower().strip()
230
+
231
+ # Get pricing (use closest match or default to sonnet pricing)
232
+ pricing = None
233
+
234
+ # Try exact match
235
+ for price_key in TOKEN_PRICING:
236
+ if price_key in model_lower or model_lower in price_key:
237
+ pricing = TOKEN_PRICING[price_key]
238
+ break
239
+
240
+ # Default to sonnet pricing if no match
241
+ if pricing is None:
242
+ pricing = TOKEN_PRICING["claude-sonnet-4"]
243
+
244
+ # Calculate costs (pricing is per 1M tokens)
245
+ input_cost = (input_tokens / 1_000_000) * pricing["input"]
246
+ output_cost = (output_tokens / 1_000_000) * pricing["output"]
247
+ cache_read_cost = (cache_read_tokens / 1_000_000) * pricing["cache_read"]
248
+ cache_creation_cost = (cache_creation_tokens / 1_000_000) * pricing["cache_creation"]
249
+
250
+ return {
251
+ "input_cost": round(input_cost, 6),
252
+ "output_cost": round(output_cost, 6),
253
+ "cache_read_cost": round(cache_read_cost, 6),
254
+ "cache_creation_cost": round(cache_creation_cost, 6),
255
+ "total_cost": round(input_cost + output_cost + cache_read_cost + cache_creation_cost, 6),
256
+ }
257
+
258
+
259
+ def calculate_aem(
260
+ duration_ms: int,
261
+ model: str,
262
+ tool_calls_count: int,
263
+ tool_calls_weight: float = 1.0,
264
+ ) -> Dict[str, float]:
265
+ """
266
+ Calculate Agentic Engineering Minutes (AEM).
267
+
268
+ Formula: Runtime (minutes) × Model Weight × Tool Calls Weight
269
+
270
+ Args:
271
+ duration_ms: Turn duration in milliseconds
272
+ model: Model identifier
273
+ tool_calls_count: Number of tool calls in this turn
274
+ tool_calls_weight: Weight multiplier for tool complexity (default 1.0)
275
+
276
+ Returns:
277
+ Dict with AEM metrics
278
+ """
279
+ # Convert duration to minutes
280
+ runtime_minutes = duration_ms / 60_000.0
281
+
282
+ # Get model weight
283
+ model_weight = get_model_weight(model)
284
+
285
+ # Calculate tool calls weight (simple linear for now, can be made more complex)
286
+ # Example: Each tool call adds to complexity
287
+ # From the image example: 200 tool calls = 3.9 weight
288
+ # This suggests approximately: tool_calls_weight = (tool_calls_count / 50) if tool_calls_count > 0 else 1.0
289
+ if tool_calls_count > 0:
290
+ calculated_tool_weight = max(1.0, tool_calls_count / 50.0) # Roughly matches 200 calls = 4.0
291
+ else:
292
+ calculated_tool_weight = 1.0
293
+
294
+ # Override with provided weight if specified
295
+ final_tool_weight = tool_calls_weight if tool_calls_weight != 1.0 else calculated_tool_weight
296
+
297
+ # Calculate AEM value
298
+ aem_value = runtime_minutes * model_weight * final_tool_weight
299
+
300
+ # Calculate AEM cost (using SaaS pricing)
301
+ aem_cost = aem_value * AEM_PRICING["saas_prepaid_per_minute"]
302
+
303
+ return {
304
+ "runtime_minutes": round(runtime_minutes, 4),
305
+ "model_weight": round(model_weight, 2),
306
+ "tool_calls_weight": round(final_tool_weight, 2),
307
+ "aem_value": round(aem_value, 4),
308
+ "aem_cost": round(aem_cost, 4),
309
+ "model_tier": get_model_tier(model).value,
310
+ }
311
+
312
+
313
+ # Export configuration for external use
314
+ __all__ = [
315
+ "ModelTier",
316
+ "MODEL_WEIGHTS",
317
+ "TOKEN_PRICING",
318
+ "AEM_PRICING",
319
+ "get_model_weight",
320
+ "get_model_tier",
321
+ "calculate_token_cost",
322
+ "calculate_aem",
323
+ ]
@@ -0,0 +1,159 @@
1
+ """
2
+ Storage configuration settings.
3
+
4
+ Manages storage provider configuration and quota settings.
5
+ """
6
+
7
+ from pydantic_settings import BaseSettings
8
+ from pydantic import Field, AliasChoices
9
+ from typing import Optional
10
+
11
+
12
+ class StorageConfig(BaseSettings):
13
+ """Storage provider and quota configuration."""
14
+
15
+ # ============================================================================
16
+ # Provider Selection
17
+ # ============================================================================
18
+
19
+ storage_provider: Optional[str] = Field(
20
+ default=None,
21
+ description="Storage provider type: vercel_blob, s3, azure_blob, gcs. REQUIRED - no default",
22
+ validation_alias=AliasChoices("STORAGE_PROVIDER", "storage_provider")
23
+ )
24
+
25
+ # ============================================================================
26
+ # Vercel Blob Configuration
27
+ # ============================================================================
28
+
29
+ vercel_blob_token: Optional[str] = Field(
30
+ default=None,
31
+ description="Vercel Blob storage authentication token",
32
+ validation_alias=AliasChoices("VERCEL_BLOB_TOKEN", "vercel_blob_token")
33
+ )
34
+
35
+ vercel_blob_store_name: Optional[str] = Field(
36
+ default=None,
37
+ description="Vercel Blob store name (optional, uses default store if not specified)",
38
+ validation_alias=AliasChoices("VERCEL_BLOB_STORE_NAME", "vercel_blob_store_name")
39
+ )
40
+
41
+ # ============================================================================
42
+ # S3 Configuration (Future)
43
+ # ============================================================================
44
+
45
+ s3_bucket_name: Optional[str] = Field(
46
+ default=None,
47
+ description="AWS S3 bucket name",
48
+ validation_alias=AliasChoices("S3_BUCKET_NAME", "s3_bucket_name")
49
+ )
50
+
51
+ s3_region: Optional[str] = Field(
52
+ default=None,
53
+ description="AWS S3 region",
54
+ validation_alias=AliasChoices("S3_REGION", "s3_region")
55
+ )
56
+
57
+ s3_access_key: Optional[str] = Field(
58
+ default=None,
59
+ description="AWS S3 access key ID",
60
+ validation_alias=AliasChoices("S3_ACCESS_KEY", "AWS_ACCESS_KEY_ID", "s3_access_key")
61
+ )
62
+
63
+ s3_secret_key: Optional[str] = Field(
64
+ default=None,
65
+ description="AWS S3 secret access key",
66
+ validation_alias=AliasChoices("S3_SECRET_KEY", "AWS_SECRET_ACCESS_KEY", "s3_secret_key")
67
+ )
68
+
69
+ # ============================================================================
70
+ # Azure Blob Configuration (Future)
71
+ # ============================================================================
72
+
73
+ azure_blob_connection_string: Optional[str] = Field(
74
+ default=None,
75
+ description="Azure Blob Storage connection string",
76
+ validation_alias=AliasChoices(
77
+ "AZURE_BLOB_CONNECTION_STRING",
78
+ "AZURE_STORAGE_CONNECTION_STRING",
79
+ "azure_blob_connection_string"
80
+ )
81
+ )
82
+
83
+ azure_blob_container_name: Optional[str] = Field(
84
+ default=None,
85
+ description="Azure Blob container name",
86
+ validation_alias=AliasChoices("AZURE_BLOB_CONTAINER_NAME", "azure_blob_container_name")
87
+ )
88
+
89
+ # ============================================================================
90
+ # GCS Configuration (Future)
91
+ # ============================================================================
92
+
93
+ gcs_bucket_name: Optional[str] = Field(
94
+ default=None,
95
+ description="Google Cloud Storage bucket name",
96
+ validation_alias=AliasChoices("GCS_BUCKET_NAME", "gcs_bucket_name")
97
+ )
98
+
99
+ gcs_credentials_path: Optional[str] = Field(
100
+ default=None,
101
+ description="Path to GCS service account credentials JSON file",
102
+ validation_alias=AliasChoices("GCS_CREDENTIALS_PATH", "GOOGLE_APPLICATION_CREDENTIALS", "gcs_credentials_path")
103
+ )
104
+
105
+ # ============================================================================
106
+ # Quota Settings
107
+ # ============================================================================
108
+
109
+ storage_default_limit_gb: int = Field(
110
+ default=1,
111
+ description="Default storage quota per organization in gigabytes",
112
+ validation_alias=AliasChoices("STORAGE_DEFAULT_LIMIT_GB", "storage_default_limit_gb"),
113
+ ge=0
114
+ )
115
+
116
+ storage_limits_config_path: str = Field(
117
+ default="conf/storage/limits_override.yaml",
118
+ description="Path to YAML file with per-organization quota overrides",
119
+ validation_alias=AliasChoices("STORAGE_LIMITS_CONFIG_PATH", "storage_limits_config_path")
120
+ )
121
+
122
+ # ============================================================================
123
+ # Feature Flags
124
+ # ============================================================================
125
+
126
+ storage_enable_versioning: bool = Field(
127
+ default=False,
128
+ description="Enable file versioning (future feature)",
129
+ validation_alias=AliasChoices("STORAGE_ENABLE_VERSIONING", "storage_enable_versioning")
130
+ )
131
+
132
+ storage_enable_encryption: bool = Field(
133
+ default=False,
134
+ description="Enable client-side encryption (future feature)",
135
+ validation_alias=AliasChoices("STORAGE_ENABLE_ENCRYPTION", "storage_enable_encryption")
136
+ )
137
+
138
+ class Config:
139
+ """Pydantic configuration."""
140
+ env_file = ".env.local"
141
+ env_file_encoding = "utf-8"
142
+ case_sensitive = False
143
+
144
+
145
+ # Singleton instance
146
+ _storage_config: Optional[StorageConfig] = None
147
+
148
+
149
+ def get_storage_config() -> StorageConfig:
150
+ """
151
+ Get or create storage configuration singleton.
152
+
153
+ Returns:
154
+ StorageConfig instance
155
+ """
156
+ global _storage_config
157
+ if _storage_config is None:
158
+ _storage_config = StorageConfig()
159
+ return _storage_config
@@ -0,0 +1,115 @@
1
+ from pydantic_settings import BaseSettings
2
+ from pydantic import model_validator
3
+ from typing import Optional
4
+ import os
5
+
6
+
7
+ class Settings(BaseSettings):
8
+ """Application settings loaded from environment variables"""
9
+
10
+ # API Settings
11
+ API_HOST: str = "0.0.0.0"
12
+ API_PORT: int = 7777
13
+ API_TITLE: str = "Agent Control Plane"
14
+ API_VERSION: str = "0.1.0"
15
+ API_DESCRIPTION: str = "Multi-tenant agent orchestration with Temporal workflows"
16
+
17
+ # Supabase Settings (replaces DATABASE_URL for serverless)
18
+ SUPABASE_URL: str = "" # Required: Set via environment variable
19
+ SUPABASE_ANON_KEY: Optional[str] = None
20
+ SUPABASE_SERVICE_KEY: str = "" # Required: Set via environment variable for admin operations
21
+
22
+ # Legacy Database URL (kept for backward compatibility)
23
+ DATABASE_URL: Optional[str] = None
24
+
25
+ @model_validator(mode='after')
26
+ def set_database_url_fallback(self):
27
+ """Set DATABASE_URL from SUPABASE_POSTGRES_URL if not already set (for Vercel compatibility)"""
28
+ if not self.DATABASE_URL:
29
+ # Check for Vercel's SUPABASE_POSTGRES_URL or other variants
30
+ supabase_db_url = (
31
+ os.environ.get("SUPABASE_POSTGRES_URL") or
32
+ os.environ.get("SUPABASE_POSTGRES_PRISMA_URL") or
33
+ os.environ.get("SUPABASE_DB_URL")
34
+ )
35
+ if supabase_db_url:
36
+ # Fix URL format for SQLAlchemy 2.0+ (postgres:// -> postgresql://)
37
+ if supabase_db_url.startswith("postgres://"):
38
+ supabase_db_url = supabase_db_url.replace("postgres://", "postgresql://", 1)
39
+ # Remove invalid Supabase pooler parameters that SQLAlchemy doesn't understand
40
+ supabase_db_url = supabase_db_url.replace("&supa=base-pooler.x", "")
41
+ self.DATABASE_URL = supabase_db_url
42
+
43
+ # Also fix DATABASE_URL if it was already set with old postgres:// scheme
44
+ if self.DATABASE_URL and self.DATABASE_URL.startswith("postgres://"):
45
+ self.DATABASE_URL = self.DATABASE_URL.replace("postgres://", "postgresql://", 1)
46
+
47
+ # Remove invalid Supabase pooler parameters from DATABASE_URL
48
+ if self.DATABASE_URL:
49
+ self.DATABASE_URL = self.DATABASE_URL.replace("&supa=base-pooler.x", "")
50
+
51
+ return self
52
+
53
+ # Redis Settings (from Composer)
54
+ REDIS_URL: str = "redis://localhost:6379/0"
55
+ REDIS_HOST: Optional[str] = None
56
+ REDIS_PORT: int = 6379
57
+ REDIS_PASSWORD: Optional[str] = None
58
+ REDIS_DB: int = 0
59
+
60
+ # Temporal Settings
61
+ TEMPORAL_HOST: str = "localhost:7233"
62
+ TEMPORAL_NAMESPACE: str = "default"
63
+ TEMPORAL_CLIENT_CERT_PATH: Optional[str] = None
64
+ TEMPORAL_CLIENT_KEY_PATH: Optional[str] = None
65
+
66
+ # Security Settings
67
+ SECRET_KEY: str = "change-this-secret-key-in-production"
68
+ ALGORITHM: str = "HS256"
69
+ ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
70
+
71
+ # Logging
72
+ LOG_LEVEL: str = "info"
73
+
74
+ # CORS
75
+ CORS_ORIGINS: list[str] = ["*"]
76
+
77
+ # LiteLLM Settings
78
+ LITELLM_API_BASE: str = "https://llm-proxy.kubiya.ai"
79
+ LITELLM_API_KEY: str = "" # Required: Set via environment variable
80
+ LITELLM_DEFAULT_MODEL: str = "kubiya/claude-sonnet-4"
81
+ LITELLM_TIMEOUT: int = 300
82
+ LITELLM_MODELS_CACHE_TTL: int = 300 # Cache TTL in seconds (default: 5 minutes)
83
+
84
+ # Kubiya API Settings
85
+ KUBIYA_API_BASE: str = "https://api.kubiya.ai"
86
+
87
+ # Context Graph API Settings
88
+ CONTEXT_GRAPH_API_BASE: str = "https://context-graph-api.dev.kubiya.ai"
89
+ CONTEXT_GRAPH_API_TIMEOUT: int = 30
90
+
91
+ # Environment
92
+ ENVIRONMENT: str = "development" # development, staging, production
93
+
94
+ # OpenTelemetry (OTEL) Settings for Distributed Tracing
95
+ OTEL_ENABLED: bool = True
96
+ OTEL_EXPORTER_OTLP_ENDPOINT: Optional[str] = None # e.g., "http://localhost:4317" for gRPC
97
+ OTEL_EXPORTER_OTLP_PROTOCOL: str = "grpc" # "grpc" or "http"
98
+ OTEL_SERVICE_NAME: str = "agent-control-plane"
99
+ OTEL_RESOURCE_ATTRIBUTES: str = "" # e.g., "deployment.environment=production"
100
+ OTEL_TRACES_SAMPLER: str = "parentbased_always_on" # or "parentbased_traceidratio"
101
+ OTEL_TRACES_SAMPLER_ARG: Optional[float] = None # e.g., 0.1 for 10% sampling
102
+
103
+ # Local Trace Storage Settings (for observability UI)
104
+ OTEL_LOCAL_STORAGE_ENABLED: bool = True # Store traces locally in PostgreSQL
105
+ OTEL_LOCAL_STORAGE_BATCH_SIZE: int = 100 # Number of spans to batch before inserting
106
+ OTEL_LOCAL_STORAGE_FLUSH_INTERVAL: int = 1000 # Max time (ms) before flushing batch
107
+ OTEL_LOCAL_STORAGE_RETENTION_DAYS: int = 30 # Days to retain traces
108
+
109
+ class Config:
110
+ env_file = ".env"
111
+ case_sensitive = True
112
+ extra = "ignore" # Allow extra environment variables (for worker-specific vars)
113
+
114
+
115
+ settings = Settings()
File without changes