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.
- control_plane_api/LICENSE +676 -0
- control_plane_api/README.md +350 -0
- control_plane_api/__init__.py +4 -0
- control_plane_api/__version__.py +8 -0
- control_plane_api/alembic/README +1 -0
- control_plane_api/alembic/env.py +121 -0
- control_plane_api/alembic/script.py.mako +28 -0
- control_plane_api/alembic/versions/2613c65c3dbe_initial_database_setup.py +32 -0
- control_plane_api/alembic/versions/2df520d4927d_merge_heads.py +28 -0
- control_plane_api/alembic/versions/43abf98d6a01_add_paused_status_to_executions.py +73 -0
- control_plane_api/alembic/versions/6289854264cb_merge_multiple_heads.py +28 -0
- control_plane_api/alembic/versions/6a4d4dc3d8dc_generate_execution_transitions.py +50 -0
- control_plane_api/alembic/versions/87d11cf0a783_add_disconnected_status_to_worker_.py +44 -0
- control_plane_api/alembic/versions/add_ephemeral_queue_support.py +85 -0
- control_plane_api/alembic/versions/add_model_type_to_llm_models.py +31 -0
- control_plane_api/alembic/versions/add_plan_executions_table.py +114 -0
- control_plane_api/alembic/versions/add_trace_span_tables.py +154 -0
- control_plane_api/alembic/versions/add_user_info_to_traces.py +36 -0
- control_plane_api/alembic/versions/adjusting_foreign_keys.py +32 -0
- control_plane_api/alembic/versions/b4983d976db2_initial_tables.py +1128 -0
- control_plane_api/alembic/versions/d181a3b40e71_rename_custom_metadata_to_metadata_in_.py +50 -0
- control_plane_api/alembic/versions/df9117888e82_add_missing_columns.py +82 -0
- control_plane_api/alembic/versions/f25de6ad895a_missing_migrations.py +34 -0
- control_plane_api/alembic/versions/f71305fb69b9_fix_ephemeral_queue_deletion_foreign_key.py +54 -0
- control_plane_api/alembic/versions/mark_local_exec_queues_as_ephemeral.py +68 -0
- control_plane_api/alembic.ini +148 -0
- control_plane_api/api/index.py +12 -0
- control_plane_api/app/__init__.py +11 -0
- control_plane_api/app/activities/__init__.py +20 -0
- control_plane_api/app/activities/agent_activities.py +384 -0
- control_plane_api/app/activities/plan_generation_activities.py +499 -0
- control_plane_api/app/activities/team_activities.py +424 -0
- control_plane_api/app/activities/temporal_cloud_activities.py +588 -0
- control_plane_api/app/config/__init__.py +35 -0
- control_plane_api/app/config/api_config.py +469 -0
- control_plane_api/app/config/config_loader.py +224 -0
- control_plane_api/app/config/model_pricing.py +323 -0
- control_plane_api/app/config/storage_config.py +159 -0
- control_plane_api/app/config.py +115 -0
- control_plane_api/app/controllers/__init__.py +0 -0
- control_plane_api/app/controllers/execution_environment_controller.py +1315 -0
- control_plane_api/app/database.py +135 -0
- control_plane_api/app/exceptions.py +408 -0
- control_plane_api/app/lib/__init__.py +11 -0
- control_plane_api/app/lib/environment.py +65 -0
- control_plane_api/app/lib/event_bus/__init__.py +17 -0
- control_plane_api/app/lib/event_bus/base.py +136 -0
- control_plane_api/app/lib/event_bus/manager.py +335 -0
- control_plane_api/app/lib/event_bus/providers/__init__.py +6 -0
- control_plane_api/app/lib/event_bus/providers/http_provider.py +166 -0
- control_plane_api/app/lib/event_bus/providers/nats_provider.py +324 -0
- control_plane_api/app/lib/event_bus/providers/redis_provider.py +233 -0
- control_plane_api/app/lib/event_bus/providers/websocket_provider.py +497 -0
- control_plane_api/app/lib/job_executor.py +330 -0
- control_plane_api/app/lib/kubiya_client.py +293 -0
- control_plane_api/app/lib/litellm_pricing.py +166 -0
- control_plane_api/app/lib/mcp_validation.py +163 -0
- control_plane_api/app/lib/nats/__init__.py +13 -0
- control_plane_api/app/lib/nats/credentials_manager.py +288 -0
- control_plane_api/app/lib/nats/listener.py +374 -0
- control_plane_api/app/lib/planning_prompt_builder.py +153 -0
- control_plane_api/app/lib/planning_tools/__init__.py +41 -0
- control_plane_api/app/lib/planning_tools/agents.py +409 -0
- control_plane_api/app/lib/planning_tools/agno_toolkit.py +836 -0
- control_plane_api/app/lib/planning_tools/base.py +119 -0
- control_plane_api/app/lib/planning_tools/cognitive_memory_tools.py +403 -0
- control_plane_api/app/lib/planning_tools/context_graph_tools.py +545 -0
- control_plane_api/app/lib/planning_tools/environments.py +218 -0
- control_plane_api/app/lib/planning_tools/knowledge.py +204 -0
- control_plane_api/app/lib/planning_tools/models.py +93 -0
- control_plane_api/app/lib/planning_tools/planning_service.py +646 -0
- control_plane_api/app/lib/planning_tools/resources.py +242 -0
- control_plane_api/app/lib/planning_tools/teams.py +334 -0
- control_plane_api/app/lib/policy_enforcer_client.py +1016 -0
- control_plane_api/app/lib/redis_client.py +803 -0
- control_plane_api/app/lib/sqlalchemy_utils.py +486 -0
- control_plane_api/app/lib/state_transition_tools/__init__.py +7 -0
- control_plane_api/app/lib/state_transition_tools/execution_context.py +388 -0
- control_plane_api/app/lib/storage/__init__.py +20 -0
- control_plane_api/app/lib/storage/base_provider.py +274 -0
- control_plane_api/app/lib/storage/provider_factory.py +157 -0
- control_plane_api/app/lib/storage/vercel_blob_provider.py +468 -0
- control_plane_api/app/lib/supabase.py +71 -0
- control_plane_api/app/lib/supabase_utils.py +138 -0
- control_plane_api/app/lib/task_planning/__init__.py +138 -0
- control_plane_api/app/lib/task_planning/agent_factory.py +308 -0
- control_plane_api/app/lib/task_planning/agents.py +389 -0
- control_plane_api/app/lib/task_planning/cache.py +218 -0
- control_plane_api/app/lib/task_planning/entity_resolver.py +273 -0
- control_plane_api/app/lib/task_planning/helpers.py +293 -0
- control_plane_api/app/lib/task_planning/hooks.py +474 -0
- control_plane_api/app/lib/task_planning/models.py +503 -0
- control_plane_api/app/lib/task_planning/plan_validator.py +166 -0
- control_plane_api/app/lib/task_planning/planning_workflow.py +2911 -0
- control_plane_api/app/lib/task_planning/runner.py +656 -0
- control_plane_api/app/lib/task_planning/streaming_hook.py +213 -0
- control_plane_api/app/lib/task_planning/workflow.py +424 -0
- control_plane_api/app/lib/templating/__init__.py +88 -0
- control_plane_api/app/lib/templating/compiler.py +278 -0
- control_plane_api/app/lib/templating/engine.py +178 -0
- control_plane_api/app/lib/templating/parsers/__init__.py +29 -0
- control_plane_api/app/lib/templating/parsers/base.py +96 -0
- control_plane_api/app/lib/templating/parsers/env.py +85 -0
- control_plane_api/app/lib/templating/parsers/graph.py +112 -0
- control_plane_api/app/lib/templating/parsers/secret.py +87 -0
- control_plane_api/app/lib/templating/parsers/simple.py +81 -0
- control_plane_api/app/lib/templating/resolver.py +366 -0
- control_plane_api/app/lib/templating/types.py +214 -0
- control_plane_api/app/lib/templating/validator.py +201 -0
- control_plane_api/app/lib/temporal_client.py +232 -0
- control_plane_api/app/lib/temporal_credentials_cache.py +178 -0
- control_plane_api/app/lib/temporal_credentials_service.py +203 -0
- control_plane_api/app/lib/validation/__init__.py +24 -0
- control_plane_api/app/lib/validation/runtime_validation.py +388 -0
- control_plane_api/app/main.py +531 -0
- control_plane_api/app/middleware/__init__.py +10 -0
- control_plane_api/app/middleware/auth.py +645 -0
- control_plane_api/app/middleware/exception_handler.py +267 -0
- control_plane_api/app/middleware/prometheus_middleware.py +173 -0
- control_plane_api/app/middleware/rate_limiting.py +384 -0
- control_plane_api/app/middleware/request_id.py +202 -0
- control_plane_api/app/models/__init__.py +40 -0
- control_plane_api/app/models/agent.py +90 -0
- control_plane_api/app/models/analytics.py +206 -0
- control_plane_api/app/models/associations.py +107 -0
- control_plane_api/app/models/auth_user.py +73 -0
- control_plane_api/app/models/context.py +161 -0
- control_plane_api/app/models/custom_integration.py +99 -0
- control_plane_api/app/models/environment.py +64 -0
- control_plane_api/app/models/execution.py +125 -0
- control_plane_api/app/models/execution_transition.py +50 -0
- control_plane_api/app/models/job.py +159 -0
- control_plane_api/app/models/llm_model.py +78 -0
- control_plane_api/app/models/orchestration.py +66 -0
- control_plane_api/app/models/plan_execution.py +102 -0
- control_plane_api/app/models/presence.py +49 -0
- control_plane_api/app/models/project.py +61 -0
- control_plane_api/app/models/project_management.py +85 -0
- control_plane_api/app/models/session.py +29 -0
- control_plane_api/app/models/skill.py +155 -0
- control_plane_api/app/models/system_tables.py +43 -0
- control_plane_api/app/models/task_planning.py +372 -0
- control_plane_api/app/models/team.py +86 -0
- control_plane_api/app/models/trace.py +257 -0
- control_plane_api/app/models/user_profile.py +54 -0
- control_plane_api/app/models/worker.py +221 -0
- control_plane_api/app/models/workflow.py +161 -0
- control_plane_api/app/models/workspace.py +50 -0
- control_plane_api/app/observability/__init__.py +177 -0
- control_plane_api/app/observability/context_logging.py +475 -0
- control_plane_api/app/observability/decorators.py +337 -0
- control_plane_api/app/observability/local_span_processor.py +702 -0
- control_plane_api/app/observability/metrics.py +303 -0
- control_plane_api/app/observability/middleware.py +246 -0
- control_plane_api/app/observability/optional.py +115 -0
- control_plane_api/app/observability/tracing.py +382 -0
- control_plane_api/app/policies/README.md +149 -0
- control_plane_api/app/policies/approved_users.rego +62 -0
- control_plane_api/app/policies/business_hours.rego +51 -0
- control_plane_api/app/policies/rate_limiting.rego +100 -0
- control_plane_api/app/policies/tool_enforcement/README.md +336 -0
- control_plane_api/app/policies/tool_enforcement/bash_command_validation.rego +71 -0
- control_plane_api/app/policies/tool_enforcement/business_hours_enforcement.rego +82 -0
- control_plane_api/app/policies/tool_enforcement/mcp_tool_allowlist.rego +58 -0
- control_plane_api/app/policies/tool_enforcement/production_safeguards.rego +80 -0
- control_plane_api/app/policies/tool_enforcement/role_based_tool_access.rego +44 -0
- control_plane_api/app/policies/tool_restrictions.rego +86 -0
- control_plane_api/app/routers/__init__.py +4 -0
- control_plane_api/app/routers/agents.py +382 -0
- control_plane_api/app/routers/agents_v2.py +1598 -0
- control_plane_api/app/routers/analytics.py +1310 -0
- control_plane_api/app/routers/auth.py +59 -0
- control_plane_api/app/routers/client_config.py +57 -0
- control_plane_api/app/routers/context_graph.py +561 -0
- control_plane_api/app/routers/context_manager.py +577 -0
- control_plane_api/app/routers/custom_integrations.py +490 -0
- control_plane_api/app/routers/enforcer.py +132 -0
- control_plane_api/app/routers/environment_context.py +252 -0
- control_plane_api/app/routers/environments.py +761 -0
- control_plane_api/app/routers/execution_environment.py +847 -0
- control_plane_api/app/routers/executions/__init__.py +28 -0
- control_plane_api/app/routers/executions/router.py +286 -0
- control_plane_api/app/routers/executions/services/__init__.py +22 -0
- control_plane_api/app/routers/executions/services/demo_worker_health.py +156 -0
- control_plane_api/app/routers/executions/services/status_service.py +420 -0
- control_plane_api/app/routers/executions/services/test_worker_health.py +480 -0
- control_plane_api/app/routers/executions/services/worker_health.py +514 -0
- control_plane_api/app/routers/executions/streaming/__init__.py +22 -0
- control_plane_api/app/routers/executions/streaming/deduplication.py +352 -0
- control_plane_api/app/routers/executions/streaming/event_buffer.py +353 -0
- control_plane_api/app/routers/executions/streaming/event_formatter.py +964 -0
- control_plane_api/app/routers/executions/streaming/history_loader.py +588 -0
- control_plane_api/app/routers/executions/streaming/live_source.py +693 -0
- control_plane_api/app/routers/executions/streaming/streamer.py +849 -0
- control_plane_api/app/routers/executions.py +4888 -0
- control_plane_api/app/routers/health.py +165 -0
- control_plane_api/app/routers/health_v2.py +394 -0
- control_plane_api/app/routers/integration_templates.py +496 -0
- control_plane_api/app/routers/integrations.py +287 -0
- control_plane_api/app/routers/jobs.py +1809 -0
- control_plane_api/app/routers/metrics.py +517 -0
- control_plane_api/app/routers/models.py +82 -0
- control_plane_api/app/routers/models_v2.py +628 -0
- control_plane_api/app/routers/plan_executions.py +1481 -0
- control_plane_api/app/routers/plan_generation_async.py +304 -0
- control_plane_api/app/routers/policies.py +669 -0
- control_plane_api/app/routers/presence.py +234 -0
- control_plane_api/app/routers/projects.py +987 -0
- control_plane_api/app/routers/runners.py +379 -0
- control_plane_api/app/routers/runtimes.py +172 -0
- control_plane_api/app/routers/secrets.py +171 -0
- control_plane_api/app/routers/skills.py +1010 -0
- control_plane_api/app/routers/skills_definitions.py +140 -0
- control_plane_api/app/routers/storage.py +456 -0
- control_plane_api/app/routers/task_planning.py +611 -0
- control_plane_api/app/routers/task_queues.py +650 -0
- control_plane_api/app/routers/team_context.py +274 -0
- control_plane_api/app/routers/teams.py +1747 -0
- control_plane_api/app/routers/templates.py +248 -0
- control_plane_api/app/routers/traces.py +571 -0
- control_plane_api/app/routers/websocket_client.py +479 -0
- control_plane_api/app/routers/websocket_executions_status.py +437 -0
- control_plane_api/app/routers/websocket_gateway.py +323 -0
- control_plane_api/app/routers/websocket_traces.py +576 -0
- control_plane_api/app/routers/worker_queues.py +2555 -0
- control_plane_api/app/routers/worker_websocket.py +419 -0
- control_plane_api/app/routers/workers.py +1004 -0
- control_plane_api/app/routers/workflows.py +204 -0
- control_plane_api/app/runtimes/__init__.py +6 -0
- control_plane_api/app/runtimes/validation.py +344 -0
- control_plane_api/app/schemas/__init__.py +1 -0
- control_plane_api/app/schemas/job_schemas.py +302 -0
- control_plane_api/app/schemas/mcp_schemas.py +311 -0
- control_plane_api/app/schemas/template_schemas.py +133 -0
- control_plane_api/app/schemas/trace_schemas.py +168 -0
- control_plane_api/app/schemas/worker_queue_observability_schemas.py +165 -0
- control_plane_api/app/services/__init__.py +1 -0
- control_plane_api/app/services/agno_planning_strategy.py +233 -0
- control_plane_api/app/services/agno_service.py +838 -0
- control_plane_api/app/services/claude_code_planning_service.py +203 -0
- control_plane_api/app/services/context_graph_client.py +224 -0
- control_plane_api/app/services/custom_integration_service.py +415 -0
- control_plane_api/app/services/integration_resolution_service.py +345 -0
- control_plane_api/app/services/litellm_service.py +394 -0
- control_plane_api/app/services/plan_generator.py +79 -0
- control_plane_api/app/services/planning_strategy.py +66 -0
- control_plane_api/app/services/planning_strategy_factory.py +118 -0
- control_plane_api/app/services/policy_service.py +615 -0
- control_plane_api/app/services/state_transition_service.py +755 -0
- control_plane_api/app/services/storage_service.py +593 -0
- control_plane_api/app/services/temporal_cloud_provisioning.py +150 -0
- control_plane_api/app/services/toolsets/context_graph_skill.py +432 -0
- control_plane_api/app/services/trace_retention.py +354 -0
- control_plane_api/app/services/worker_queue_metrics_service.py +190 -0
- control_plane_api/app/services/workflow_cancellation_manager.py +135 -0
- control_plane_api/app/services/workflow_operations_service.py +611 -0
- control_plane_api/app/skills/__init__.py +100 -0
- control_plane_api/app/skills/base.py +239 -0
- control_plane_api/app/skills/builtin/__init__.py +37 -0
- control_plane_api/app/skills/builtin/agent_communication/__init__.py +8 -0
- control_plane_api/app/skills/builtin/agent_communication/skill.py +246 -0
- control_plane_api/app/skills/builtin/code_ingestion/__init__.py +4 -0
- control_plane_api/app/skills/builtin/code_ingestion/skill.py +267 -0
- control_plane_api/app/skills/builtin/cognitive_memory/__init__.py +4 -0
- control_plane_api/app/skills/builtin/cognitive_memory/skill.py +174 -0
- control_plane_api/app/skills/builtin/contextual_awareness/__init__.py +4 -0
- control_plane_api/app/skills/builtin/contextual_awareness/skill.py +387 -0
- control_plane_api/app/skills/builtin/data_visualization/__init__.py +4 -0
- control_plane_api/app/skills/builtin/data_visualization/skill.py +154 -0
- control_plane_api/app/skills/builtin/docker/__init__.py +4 -0
- control_plane_api/app/skills/builtin/docker/skill.py +104 -0
- control_plane_api/app/skills/builtin/file_generation/__init__.py +4 -0
- control_plane_api/app/skills/builtin/file_generation/skill.py +94 -0
- control_plane_api/app/skills/builtin/file_system/__init__.py +4 -0
- control_plane_api/app/skills/builtin/file_system/skill.py +110 -0
- control_plane_api/app/skills/builtin/knowledge_api/__init__.py +5 -0
- control_plane_api/app/skills/builtin/knowledge_api/skill.py +124 -0
- control_plane_api/app/skills/builtin/python/__init__.py +4 -0
- control_plane_api/app/skills/builtin/python/skill.py +92 -0
- control_plane_api/app/skills/builtin/remote_filesystem/__init__.py +5 -0
- control_plane_api/app/skills/builtin/remote_filesystem/skill.py +170 -0
- control_plane_api/app/skills/builtin/shell/__init__.py +4 -0
- control_plane_api/app/skills/builtin/shell/skill.py +161 -0
- control_plane_api/app/skills/builtin/slack/__init__.py +3 -0
- control_plane_api/app/skills/builtin/slack/skill.py +302 -0
- control_plane_api/app/skills/builtin/workflow_executor/__init__.py +4 -0
- control_plane_api/app/skills/builtin/workflow_executor/skill.py +469 -0
- control_plane_api/app/skills/business_intelligence.py +189 -0
- control_plane_api/app/skills/config.py +63 -0
- control_plane_api/app/skills/loaders/__init__.py +14 -0
- control_plane_api/app/skills/loaders/base.py +73 -0
- control_plane_api/app/skills/loaders/filesystem_loader.py +199 -0
- control_plane_api/app/skills/registry.py +125 -0
- control_plane_api/app/utils/helpers.py +12 -0
- control_plane_api/app/utils/workflow_executor.py +354 -0
- control_plane_api/app/workflows/__init__.py +11 -0
- control_plane_api/app/workflows/agent_execution.py +520 -0
- control_plane_api/app/workflows/agent_execution_with_skills.py +223 -0
- control_plane_api/app/workflows/namespace_provisioning.py +326 -0
- control_plane_api/app/workflows/plan_generation.py +254 -0
- control_plane_api/app/workflows/team_execution.py +442 -0
- control_plane_api/scripts/seed_models.py +240 -0
- control_plane_api/scripts/validate_existing_tool_names.py +492 -0
- control_plane_api/shared/__init__.py +8 -0
- control_plane_api/shared/version.py +17 -0
- control_plane_api/test_deduplication.py +274 -0
- control_plane_api/test_executor_deduplication_e2e.py +309 -0
- control_plane_api/test_job_execution_e2e.py +283 -0
- control_plane_api/test_real_integration.py +193 -0
- control_plane_api/version.py +38 -0
- control_plane_api/worker/__init__.py +0 -0
- control_plane_api/worker/activities/__init__.py +0 -0
- control_plane_api/worker/activities/agent_activities.py +1585 -0
- control_plane_api/worker/activities/approval_activities.py +234 -0
- control_plane_api/worker/activities/job_activities.py +199 -0
- control_plane_api/worker/activities/runtime_activities.py +1167 -0
- control_plane_api/worker/activities/skill_activities.py +282 -0
- control_plane_api/worker/activities/team_activities.py +479 -0
- control_plane_api/worker/agent_runtime_server.py +370 -0
- control_plane_api/worker/binary_manager.py +333 -0
- control_plane_api/worker/config/__init__.py +31 -0
- control_plane_api/worker/config/worker_config.py +273 -0
- control_plane_api/worker/control_plane_client.py +1491 -0
- control_plane_api/worker/examples/analytics_integration_example.py +362 -0
- control_plane_api/worker/health_monitor.py +159 -0
- control_plane_api/worker/metrics.py +237 -0
- control_plane_api/worker/models/__init__.py +1 -0
- control_plane_api/worker/models/error_events.py +105 -0
- control_plane_api/worker/models/inputs.py +89 -0
- control_plane_api/worker/runtimes/__init__.py +35 -0
- control_plane_api/worker/runtimes/agent_runtime/runtime.py +485 -0
- control_plane_api/worker/runtimes/agno/__init__.py +34 -0
- control_plane_api/worker/runtimes/agno/config.py +248 -0
- control_plane_api/worker/runtimes/agno/hooks.py +385 -0
- control_plane_api/worker/runtimes/agno/mcp_builder.py +195 -0
- control_plane_api/worker/runtimes/agno/runtime.py +1063 -0
- control_plane_api/worker/runtimes/agno/utils.py +163 -0
- control_plane_api/worker/runtimes/base.py +979 -0
- control_plane_api/worker/runtimes/claude_code/__init__.py +38 -0
- control_plane_api/worker/runtimes/claude_code/cleanup.py +184 -0
- control_plane_api/worker/runtimes/claude_code/client_pool.py +529 -0
- control_plane_api/worker/runtimes/claude_code/config.py +829 -0
- control_plane_api/worker/runtimes/claude_code/hooks.py +482 -0
- control_plane_api/worker/runtimes/claude_code/litellm_proxy.py +1702 -0
- control_plane_api/worker/runtimes/claude_code/mcp_builder.py +467 -0
- control_plane_api/worker/runtimes/claude_code/mcp_discovery.py +558 -0
- control_plane_api/worker/runtimes/claude_code/runtime.py +1546 -0
- control_plane_api/worker/runtimes/claude_code/tool_mapper.py +403 -0
- control_plane_api/worker/runtimes/claude_code/utils.py +149 -0
- control_plane_api/worker/runtimes/factory.py +173 -0
- control_plane_api/worker/runtimes/model_utils.py +107 -0
- control_plane_api/worker/runtimes/validation.py +93 -0
- control_plane_api/worker/services/__init__.py +1 -0
- control_plane_api/worker/services/agent_communication_tools.py +908 -0
- control_plane_api/worker/services/agent_executor.py +485 -0
- control_plane_api/worker/services/agent_executor_v2.py +793 -0
- control_plane_api/worker/services/analytics_collector.py +457 -0
- control_plane_api/worker/services/analytics_service.py +464 -0
- control_plane_api/worker/services/approval_tools.py +310 -0
- control_plane_api/worker/services/approval_tools_agno.py +207 -0
- control_plane_api/worker/services/cancellation_manager.py +177 -0
- control_plane_api/worker/services/code_ingestion_tools.py +465 -0
- control_plane_api/worker/services/contextual_awareness_tools.py +405 -0
- control_plane_api/worker/services/data_visualization.py +834 -0
- control_plane_api/worker/services/event_publisher.py +531 -0
- control_plane_api/worker/services/jira_tools.py +257 -0
- control_plane_api/worker/services/remote_filesystem_tools.py +498 -0
- control_plane_api/worker/services/runtime_analytics.py +328 -0
- control_plane_api/worker/services/session_service.py +365 -0
- control_plane_api/worker/services/skill_context_enhancement.py +181 -0
- control_plane_api/worker/services/skill_factory.py +471 -0
- control_plane_api/worker/services/system_prompt_enhancement.py +410 -0
- control_plane_api/worker/services/team_executor.py +715 -0
- control_plane_api/worker/services/team_executor_v2.py +1866 -0
- control_plane_api/worker/services/tool_enforcement.py +254 -0
- control_plane_api/worker/services/workflow_executor/__init__.py +52 -0
- control_plane_api/worker/services/workflow_executor/event_processor.py +287 -0
- control_plane_api/worker/services/workflow_executor/event_publisher.py +210 -0
- control_plane_api/worker/services/workflow_executor/executors/__init__.py +15 -0
- control_plane_api/worker/services/workflow_executor/executors/base.py +270 -0
- control_plane_api/worker/services/workflow_executor/executors/json_executor.py +50 -0
- control_plane_api/worker/services/workflow_executor/executors/python_executor.py +50 -0
- control_plane_api/worker/services/workflow_executor/models.py +142 -0
- control_plane_api/worker/services/workflow_executor_tools.py +1748 -0
- control_plane_api/worker/skills/__init__.py +12 -0
- control_plane_api/worker/skills/builtin/context_graph_search/README.md +213 -0
- control_plane_api/worker/skills/builtin/context_graph_search/__init__.py +5 -0
- control_plane_api/worker/skills/builtin/context_graph_search/agno_impl.py +808 -0
- control_plane_api/worker/skills/builtin/context_graph_search/skill.yaml +67 -0
- control_plane_api/worker/skills/builtin/contextual_awareness/__init__.py +4 -0
- control_plane_api/worker/skills/builtin/contextual_awareness/agno_impl.py +62 -0
- control_plane_api/worker/skills/builtin/data_visualization/agno_impl.py +18 -0
- control_plane_api/worker/skills/builtin/data_visualization/skill.yaml +84 -0
- control_plane_api/worker/skills/builtin/docker/agno_impl.py +65 -0
- control_plane_api/worker/skills/builtin/docker/skill.yaml +60 -0
- control_plane_api/worker/skills/builtin/file_generation/agno_impl.py +47 -0
- control_plane_api/worker/skills/builtin/file_generation/skill.yaml +64 -0
- control_plane_api/worker/skills/builtin/file_system/agno_impl.py +32 -0
- control_plane_api/worker/skills/builtin/file_system/skill.yaml +54 -0
- control_plane_api/worker/skills/builtin/knowledge_api/__init__.py +4 -0
- control_plane_api/worker/skills/builtin/knowledge_api/agno_impl.py +50 -0
- control_plane_api/worker/skills/builtin/knowledge_api/skill.yaml +66 -0
- control_plane_api/worker/skills/builtin/python/agno_impl.py +25 -0
- control_plane_api/worker/skills/builtin/python/skill.yaml +60 -0
- control_plane_api/worker/skills/builtin/schema_fix_mixin.py +260 -0
- control_plane_api/worker/skills/builtin/shell/agno_impl.py +31 -0
- control_plane_api/worker/skills/builtin/shell/skill.yaml +60 -0
- control_plane_api/worker/skills/builtin/slack/__init__.py +3 -0
- control_plane_api/worker/skills/builtin/slack/agno_impl.py +1282 -0
- control_plane_api/worker/skills/builtin/slack/skill.yaml +276 -0
- control_plane_api/worker/skills/builtin/workflow_executor/agno_impl.py +62 -0
- control_plane_api/worker/skills/builtin/workflow_executor/skill.yaml +79 -0
- control_plane_api/worker/skills/loaders/__init__.py +5 -0
- control_plane_api/worker/skills/loaders/base.py +23 -0
- control_plane_api/worker/skills/loaders/filesystem_loader.py +357 -0
- control_plane_api/worker/skills/registry.py +208 -0
- control_plane_api/worker/tests/__init__.py +1 -0
- control_plane_api/worker/tests/conftest.py +12 -0
- control_plane_api/worker/tests/e2e/__init__.py +0 -0
- control_plane_api/worker/tests/e2e/test_context_graph_real_api.py +338 -0
- control_plane_api/worker/tests/e2e/test_context_graph_templates_e2e.py +523 -0
- control_plane_api/worker/tests/e2e/test_enforcement_e2e.py +344 -0
- control_plane_api/worker/tests/e2e/test_execution_flow.py +571 -0
- control_plane_api/worker/tests/e2e/test_single_execution_mode.py +656 -0
- control_plane_api/worker/tests/integration/__init__.py +0 -0
- control_plane_api/worker/tests/integration/test_builtin_skills_fixes.py +245 -0
- control_plane_api/worker/tests/integration/test_context_graph_search_integration.py +365 -0
- control_plane_api/worker/tests/integration/test_control_plane_integration.py +308 -0
- control_plane_api/worker/tests/integration/test_hook_enforcement_integration.py +579 -0
- control_plane_api/worker/tests/integration/test_scheduled_job_workflow.py +237 -0
- control_plane_api/worker/tests/integration/test_system_prompt_enhancement_integration.py +343 -0
- control_plane_api/worker/tests/unit/__init__.py +0 -0
- control_plane_api/worker/tests/unit/test_builtin_skill_autoload.py +396 -0
- control_plane_api/worker/tests/unit/test_context_graph_search.py +450 -0
- control_plane_api/worker/tests/unit/test_context_graph_templates.py +403 -0
- control_plane_api/worker/tests/unit/test_control_plane_client.py +401 -0
- control_plane_api/worker/tests/unit/test_control_plane_client_jobs.py +345 -0
- control_plane_api/worker/tests/unit/test_job_activities.py +353 -0
- control_plane_api/worker/tests/unit/test_skill_context_enhancement.py +321 -0
- control_plane_api/worker/tests/unit/test_system_prompt_enhancement.py +415 -0
- control_plane_api/worker/tests/unit/test_tool_enforcement.py +324 -0
- control_plane_api/worker/utils/__init__.py +1 -0
- control_plane_api/worker/utils/chunk_batcher.py +330 -0
- control_plane_api/worker/utils/environment.py +65 -0
- control_plane_api/worker/utils/error_publisher.py +260 -0
- control_plane_api/worker/utils/event_batcher.py +256 -0
- control_plane_api/worker/utils/logging_config.py +335 -0
- control_plane_api/worker/utils/logging_helper.py +326 -0
- control_plane_api/worker/utils/parameter_validator.py +120 -0
- control_plane_api/worker/utils/retry_utils.py +60 -0
- control_plane_api/worker/utils/streaming_utils.py +665 -0
- control_plane_api/worker/utils/tool_validation.py +332 -0
- control_plane_api/worker/utils/workspace_manager.py +163 -0
- control_plane_api/worker/websocket_client.py +393 -0
- control_plane_api/worker/worker.py +1297 -0
- control_plane_api/worker/workflows/__init__.py +0 -0
- control_plane_api/worker/workflows/agent_execution.py +909 -0
- control_plane_api/worker/workflows/scheduled_job_wrapper.py +332 -0
- control_plane_api/worker/workflows/team_execution.py +611 -0
- kubiya_control_plane_api-0.9.15.dist-info/METADATA +354 -0
- kubiya_control_plane_api-0.9.15.dist-info/RECORD +479 -0
- kubiya_control_plane_api-0.9.15.dist-info/WHEEL +5 -0
- kubiya_control_plane_api-0.9.15.dist-info/entry_points.txt +5 -0
- kubiya_control_plane_api-0.9.15.dist-info/licenses/LICENSE +676 -0
- kubiya_control_plane_api-0.9.15.dist-info/top_level.txt +3 -0
- scripts/__init__.py +1 -0
- scripts/migrations.py +39 -0
- scripts/seed_worker_queues.py +128 -0
- scripts/setup_agent_runtime.py +142 -0
- worker_internal/__init__.py +1 -0
- worker_internal/planner/__init__.py +1 -0
- worker_internal/planner/activities.py +1499 -0
- worker_internal/planner/agent_tools.py +197 -0
- worker_internal/planner/event_models.py +148 -0
- worker_internal/planner/event_publisher.py +67 -0
- worker_internal/planner/models.py +199 -0
- worker_internal/planner/retry_logic.py +134 -0
- worker_internal/planner/worker.py +300 -0
- 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
|