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,366 @@
1
+ """
2
+ Generic template resolution service.
3
+
4
+ Recursively resolves templates in any data structure (strings, dicts, lists).
5
+ This service is used on the worker side to compile templates in runtime configurations,
6
+ system prompts, descriptions, and any other text-based fields.
7
+ """
8
+
9
+ import structlog
10
+ from typing import Any, Dict, List, Optional, Union
11
+ from control_plane_api.app.lib.templating.types import TemplateContext
12
+ from control_plane_api.app.lib.templating.compiler import TemplateCompiler
13
+ from control_plane_api.app.lib.templating.engine import TemplateEngine, get_default_engine
14
+
15
+ logger = structlog.get_logger()
16
+
17
+
18
+ class TemplateResolutionError(Exception):
19
+ """Raised when template resolution fails."""
20
+ pass
21
+
22
+
23
+ class TemplateResolver:
24
+ """
25
+ Generic template resolver that recursively processes data structures.
26
+
27
+ This resolver can process:
28
+ - Strings: Compile templates
29
+ - Dicts: Recursively process all values
30
+ - Lists: Recursively process all items
31
+ - Other types: Return as-is
32
+
33
+ Usage:
34
+ resolver = TemplateResolver(context)
35
+ resolved_config = resolver.resolve(config)
36
+ """
37
+
38
+ def __init__(
39
+ self,
40
+ context: TemplateContext,
41
+ engine: TemplateEngine = None,
42
+ strict: bool = False,
43
+ skip_on_error: bool = False
44
+ ):
45
+ """
46
+ Initialize the template resolver.
47
+
48
+ Args:
49
+ context: Template context with available values
50
+ engine: Template engine to use. If None, uses default engine.
51
+ strict: If True, raise error on missing variables. If False, log warning.
52
+ skip_on_error: If True, return original value on error instead of raising.
53
+ """
54
+ self.context = context
55
+ self.engine = engine if engine is not None else get_default_engine()
56
+ self.compiler = TemplateCompiler(self.engine)
57
+ self.strict = strict
58
+ self.skip_on_error = skip_on_error
59
+ self._resolution_count = 0
60
+ self._error_count = 0
61
+
62
+ def resolve(self, value: Any) -> Any:
63
+ """
64
+ Recursively resolve templates in any data structure.
65
+
66
+ Args:
67
+ value: Value to resolve (string, dict, list, or other)
68
+
69
+ Returns:
70
+ Resolved value with all templates compiled
71
+
72
+ Raises:
73
+ TemplateResolutionError: If strict=True and resolution fails
74
+ """
75
+ try:
76
+ resolved = self._resolve_recursive(value)
77
+ logger.info(
78
+ "template_resolution_completed",
79
+ resolution_count=self._resolution_count,
80
+ error_count=self._error_count
81
+ )
82
+ return resolved
83
+ except Exception as e:
84
+ if not self.skip_on_error:
85
+ raise TemplateResolutionError(f"Template resolution failed: {str(e)}") from e
86
+ logger.error("template_resolution_failed", error=str(e), exc_info=True)
87
+ return value
88
+
89
+ def _resolve_recursive(self, value: Any, path: str = "$") -> Any:
90
+ """
91
+ Recursively resolve templates in a value.
92
+
93
+ Args:
94
+ value: Value to resolve
95
+ path: JSON path for logging (e.g., "$.config.system_prompt")
96
+
97
+ Returns:
98
+ Resolved value
99
+ """
100
+ # Handle None
101
+ if value is None:
102
+ return None
103
+
104
+ # Handle strings (compile templates)
105
+ if isinstance(value, str):
106
+ return self._resolve_string(value, path)
107
+
108
+ # Handle dictionaries (recurse into values)
109
+ if isinstance(value, dict):
110
+ return self._resolve_dict(value, path)
111
+
112
+ # Handle lists (recurse into items)
113
+ if isinstance(value, list):
114
+ return self._resolve_list(value, path)
115
+
116
+ # Handle other types (return as-is)
117
+ return value
118
+
119
+ def _resolve_string(self, value: str, path: str) -> str:
120
+ """
121
+ Resolve templates in a string.
122
+
123
+ Args:
124
+ value: String value to resolve
125
+ path: JSON path for logging
126
+
127
+ Returns:
128
+ Resolved string
129
+ """
130
+ # Check if string contains templates
131
+ parse_result = self.engine.parse(value)
132
+
133
+ # If no variables, return as-is (optimization)
134
+ if not parse_result.variables:
135
+ return value
136
+
137
+ # Compile the template
138
+ try:
139
+ compile_result = self.compiler.compile(value, self.context)
140
+
141
+ if not compile_result.success:
142
+ self._error_count += 1
143
+ error_msg = f"Template compilation failed at {path}: {compile_result.error}"
144
+
145
+ if self.strict:
146
+ raise TemplateResolutionError(error_msg)
147
+
148
+ logger.warning(
149
+ "template_compilation_failed",
150
+ path=path,
151
+ error=compile_result.error,
152
+ original_value=value
153
+ )
154
+
155
+ if self.skip_on_error:
156
+ return value
157
+
158
+ raise TemplateResolutionError(error_msg)
159
+
160
+ self._resolution_count += 1
161
+ logger.debug(
162
+ "template_resolved",
163
+ path=path,
164
+ variable_count=len(parse_result.variables),
165
+ original_length=len(value),
166
+ resolved_length=len(compile_result.compiled)
167
+ )
168
+
169
+ return compile_result.compiled
170
+
171
+ except Exception as e:
172
+ self._error_count += 1
173
+ error_msg = f"Template resolution error at {path}: {str(e)}"
174
+
175
+ if self.strict:
176
+ raise TemplateResolutionError(error_msg) from e
177
+
178
+ logger.warning(
179
+ "template_resolution_error",
180
+ path=path,
181
+ error=str(e),
182
+ original_value=value
183
+ )
184
+
185
+ if self.skip_on_error:
186
+ return value
187
+
188
+ raise TemplateResolutionError(error_msg) from e
189
+
190
+ def _resolve_dict(self, value: Dict[str, Any], path: str) -> Dict[str, Any]:
191
+ """
192
+ Recursively resolve templates in a dictionary.
193
+
194
+ Args:
195
+ value: Dictionary to resolve
196
+ path: JSON path for logging
197
+
198
+ Returns:
199
+ Resolved dictionary
200
+ """
201
+ resolved = {}
202
+ for key, val in value.items():
203
+ key_path = f"{path}.{key}" if path else key
204
+ resolved[key] = self._resolve_recursive(val, key_path)
205
+ return resolved
206
+
207
+ def _resolve_list(self, value: List[Any], path: str) -> List[Any]:
208
+ """
209
+ Recursively resolve templates in a list.
210
+
211
+ Args:
212
+ value: List to resolve
213
+ path: JSON path for logging
214
+
215
+ Returns:
216
+ Resolved list
217
+ """
218
+ resolved = []
219
+ for idx, item in enumerate(value):
220
+ item_path = f"{path}[{idx}]"
221
+ resolved.append(self._resolve_recursive(item, item_path))
222
+ return resolved
223
+
224
+ @property
225
+ def stats(self) -> Dict[str, int]:
226
+ """
227
+ Get resolution statistics.
228
+
229
+ Returns:
230
+ Dictionary with resolution_count and error_count
231
+ """
232
+ return {
233
+ "resolution_count": self._resolution_count,
234
+ "error_count": self._error_count
235
+ }
236
+
237
+
238
+ def resolve_templates(
239
+ data: Any,
240
+ context: TemplateContext,
241
+ strict: bool = False,
242
+ skip_on_error: bool = False
243
+ ) -> Any:
244
+ """
245
+ Convenience function to resolve templates in any data structure.
246
+
247
+ Args:
248
+ data: Data to resolve (string, dict, list, or other)
249
+ context: Template context with available values
250
+ strict: If True, raise error on missing variables
251
+ skip_on_error: If True, return original value on error
252
+
253
+ Returns:
254
+ Resolved data with all templates compiled
255
+
256
+ Example:
257
+ config = {
258
+ "system_prompt": "You are {{agent_name}} running on {{.env.HOST}}",
259
+ "mcp_servers": {
260
+ "github": {
261
+ "url": "https://{{.env.GITHUB_HOST}}/api",
262
+ "headers": {
263
+ "Authorization": "Bearer {{.secret.github_token}}"
264
+ }
265
+ }
266
+ }
267
+ }
268
+
269
+ context = TemplateContext(
270
+ variables={"agent_name": "MyAgent"},
271
+ secrets={"github_token": "ghp_xxx"},
272
+ env_vars={"HOST": "api.example.com", "GITHUB_HOST": "github.com"}
273
+ )
274
+
275
+ resolved = resolve_templates(config, context)
276
+ # All templates in the config will be resolved
277
+ """
278
+ resolver = TemplateResolver(context, strict=strict, skip_on_error=skip_on_error)
279
+ return resolver.resolve(data)
280
+
281
+
282
+ def has_templates(value: Any) -> bool:
283
+ """
284
+ Check if a value contains any templates.
285
+
286
+ Args:
287
+ value: Value to check (string, dict, list, or other)
288
+
289
+ Returns:
290
+ True if value contains templates, False otherwise
291
+ """
292
+ engine = get_default_engine()
293
+
294
+ def _check_recursive(val: Any) -> bool:
295
+ if val is None:
296
+ return False
297
+
298
+ if isinstance(val, str):
299
+ parse_result = engine.parse(val)
300
+ return len(parse_result.variables) > 0
301
+
302
+ if isinstance(val, dict):
303
+ return any(_check_recursive(v) for v in val.values())
304
+
305
+ if isinstance(val, list):
306
+ return any(_check_recursive(item) for item in val)
307
+
308
+ return False
309
+
310
+ return _check_recursive(value)
311
+
312
+
313
+ def extract_all_variables(data: Any) -> Dict[str, List[str]]:
314
+ """
315
+ Extract all template variables from any data structure.
316
+
317
+ Args:
318
+ data: Data to analyze (string, dict, list, or other)
319
+
320
+ Returns:
321
+ Dictionary with 'secrets', 'env_vars', and 'variables' lists
322
+
323
+ Example:
324
+ config = {
325
+ "prompt": "Hello {{user}}",
326
+ "api_key": "{{.secret.github_token}}",
327
+ "host": "{{.env.API_HOST}}"
328
+ }
329
+
330
+ variables = extract_all_variables(config)
331
+ # Returns: {
332
+ # 'secrets': ['github_token'],
333
+ # 'env_vars': ['API_HOST'],
334
+ # 'variables': ['user']
335
+ # }
336
+ """
337
+ engine = get_default_engine()
338
+ secrets = set()
339
+ env_vars = set()
340
+ variables = set()
341
+
342
+ def _extract_recursive(val: Any):
343
+ if val is None:
344
+ return
345
+
346
+ if isinstance(val, str):
347
+ parse_result = engine.parse(val)
348
+ secrets.update(v.display_name for v in parse_result.secret_variables)
349
+ env_vars.update(v.display_name for v in parse_result.env_variables)
350
+ variables.update(v.name for v in parse_result.simple_variables)
351
+
352
+ elif isinstance(val, dict):
353
+ for v in val.values():
354
+ _extract_recursive(v)
355
+
356
+ elif isinstance(val, list):
357
+ for item in val:
358
+ _extract_recursive(item)
359
+
360
+ _extract_recursive(data)
361
+
362
+ return {
363
+ "secrets": sorted(list(secrets)),
364
+ "env_vars": sorted(list(env_vars)),
365
+ "variables": sorted(list(variables))
366
+ }
@@ -0,0 +1,214 @@
1
+ """
2
+ Core type definitions for the template engine.
3
+
4
+ This module defines all data classes, enums, and type definitions used
5
+ throughout the templating system.
6
+ """
7
+
8
+ from dataclasses import dataclass, field
9
+ from enum import Enum
10
+ from typing import Dict, Any, List, Optional
11
+
12
+
13
+ class TemplateVariableType(str, Enum):
14
+ """Types of template variables supported by the engine."""
15
+ SIMPLE = "simple" # {{variable}}
16
+ SECRET = "secret" # {{.secret.name}}
17
+ ENV = "env" # {{.env.VAR}}
18
+ GRAPH = "graph" # {{.graph.node-id}}
19
+
20
+
21
+ @dataclass
22
+ class TemplateVariable:
23
+ """
24
+ Represents a template variable found in a template string.
25
+
26
+ Attributes:
27
+ name: Full variable name (e.g., "api_key" or "secret.github_token")
28
+ type: Type of template variable
29
+ raw: Raw template string as it appears in the template
30
+ start: Start position in the template string
31
+ end: End position in the template string
32
+ """
33
+ name: str
34
+ type: TemplateVariableType
35
+ raw: str
36
+ start: int
37
+ end: int
38
+
39
+ @property
40
+ def display_name(self) -> str:
41
+ """
42
+ Get display name for UI/error messages.
43
+
44
+ Removes type prefixes to show just the variable name:
45
+ - "secret.api_key" -> "api_key"
46
+ - "env.API_KEY" -> "API_KEY"
47
+ - "graph.node-123" -> "node-123"
48
+ - "variable" -> "variable"
49
+ """
50
+ if self.type == TemplateVariableType.SECRET:
51
+ return self.name.replace("secret.", "", 1)
52
+ elif self.type == TemplateVariableType.ENV:
53
+ return self.name.replace("env.", "", 1)
54
+ elif self.type == TemplateVariableType.GRAPH:
55
+ return self.name.replace("graph.", "", 1)
56
+ return self.name
57
+
58
+
59
+ @dataclass
60
+ class ValidationError:
61
+ """
62
+ Represents a validation error in a template.
63
+
64
+ Attributes:
65
+ message: Human-readable error message
66
+ variable: Variable that caused the error (if applicable)
67
+ position: Character position in template where error occurred
68
+ code: Machine-readable error code for programmatic handling
69
+ """
70
+ message: str
71
+ variable: Optional[TemplateVariable] = None
72
+ position: Optional[int] = None
73
+ code: Optional[str] = None
74
+
75
+
76
+ @dataclass
77
+ class ParseResult:
78
+ """
79
+ Result of parsing a template string.
80
+
81
+ Attributes:
82
+ template: Original template string
83
+ variables: List of variables found in the template
84
+ errors: List of parsing/syntax errors
85
+ """
86
+ template: str
87
+ variables: List[TemplateVariable] = field(default_factory=list)
88
+ errors: List[ValidationError] = field(default_factory=list)
89
+
90
+ @property
91
+ def is_valid(self) -> bool:
92
+ """Check if template is syntactically valid."""
93
+ return len(self.errors) == 0
94
+
95
+ @property
96
+ def simple_variables(self) -> List[TemplateVariable]:
97
+ """Get all simple variables ({{variable}})."""
98
+ return [v for v in self.variables if v.type == TemplateVariableType.SIMPLE]
99
+
100
+ @property
101
+ def secret_variables(self) -> List[TemplateVariable]:
102
+ """Get all secret variables ({{.secret.name}})."""
103
+ return [v for v in self.variables if v.type == TemplateVariableType.SECRET]
104
+
105
+ @property
106
+ def env_variables(self) -> List[TemplateVariable]:
107
+ """Get all environment variables ({{.env.VAR}})."""
108
+ return [v for v in self.variables if v.type == TemplateVariableType.ENV]
109
+
110
+ @property
111
+ def graph_variables(self) -> List[TemplateVariable]:
112
+ """Get all graph node variables ({{.graph.node-id}})."""
113
+ return [v for v in self.variables if v.type == TemplateVariableType.GRAPH]
114
+
115
+
116
+ @dataclass
117
+ class TemplateContext:
118
+ """
119
+ Context for template resolution.
120
+
121
+ Provides all available values for template variable substitution.
122
+
123
+ Attributes:
124
+ variables: Simple variable name -> value mapping
125
+ secrets: Secret name -> secret value mapping
126
+ env_vars: Environment variable name -> value mapping
127
+ graph_nodes: Context graph node ID -> node data mapping (optional, fetched on demand)
128
+ graph_api_base: Base URL for context graph API
129
+ graph_api_key: API key for context graph API
130
+ graph_org_id: Organization ID for context graph queries
131
+ """
132
+ variables: Dict[str, Any] = field(default_factory=dict)
133
+ secrets: Dict[str, str] = field(default_factory=dict)
134
+ env_vars: Dict[str, str] = field(default_factory=dict)
135
+ graph_nodes: Optional[Dict[str, Dict[str, Any]]] = None
136
+ graph_api_base: Optional[str] = None
137
+ graph_api_key: Optional[str] = None
138
+ graph_org_id: Optional[str] = None
139
+
140
+
141
+ @dataclass
142
+ class ValidationResult:
143
+ """
144
+ Result of template validation.
145
+
146
+ Attributes:
147
+ valid: Whether the template is valid
148
+ errors: List of validation errors
149
+ warnings: List of non-fatal warnings
150
+ variables: List of variables found in the template
151
+ """
152
+ valid: bool
153
+ errors: List[ValidationError] = field(default_factory=list)
154
+ warnings: List[str] = field(default_factory=list)
155
+ variables: List[TemplateVariable] = field(default_factory=list)
156
+
157
+ @property
158
+ def missing_secrets(self) -> List[str]:
159
+ """Get list of missing secret names."""
160
+ return [
161
+ err.variable.display_name
162
+ for err in self.errors
163
+ if err.variable
164
+ and err.variable.type == TemplateVariableType.SECRET
165
+ and err.code == "MISSING_SECRET"
166
+ ]
167
+
168
+ @property
169
+ def missing_env_vars(self) -> List[str]:
170
+ """Get list of missing environment variable names."""
171
+ return [
172
+ err.variable.display_name
173
+ for err in self.errors
174
+ if err.variable
175
+ and err.variable.type == TemplateVariableType.ENV
176
+ and err.code == "MISSING_ENV_VAR"
177
+ ]
178
+
179
+ @property
180
+ def missing_variables(self) -> List[str]:
181
+ """Get list of missing simple variable names."""
182
+ return [
183
+ err.variable.name
184
+ for err in self.errors
185
+ if err.variable
186
+ and err.variable.type == TemplateVariableType.SIMPLE
187
+ and err.code == "MISSING_VARIABLE"
188
+ ]
189
+
190
+ @property
191
+ def missing_graph_nodes(self) -> List[str]:
192
+ """Get list of missing graph node IDs."""
193
+ return [
194
+ err.variable.display_name
195
+ for err in self.errors
196
+ if err.variable
197
+ and err.variable.type == TemplateVariableType.GRAPH
198
+ and err.code == "MISSING_GRAPH_NODE"
199
+ ]
200
+
201
+
202
+ @dataclass
203
+ class CompileResult:
204
+ """
205
+ Result of template compilation.
206
+
207
+ Attributes:
208
+ compiled: Compiled template string with variables substituted
209
+ success: Whether compilation succeeded
210
+ error: Error message if compilation failed
211
+ """
212
+ compiled: str
213
+ success: bool = True
214
+ error: Optional[str] = None