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,85 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Parser for environment variable template variables: {{.env.VAR}}
|
|
3
|
+
|
|
4
|
+
Supports referencing environment variables.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
from typing import Optional
|
|
9
|
+
from control_plane_api.app.lib.templating.parsers.base import BaseParser
|
|
10
|
+
from control_plane_api.app.lib.templating.types import TemplateVariable, TemplateVariableType
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class EnvVariableParser(BaseParser):
|
|
14
|
+
"""
|
|
15
|
+
Parser for environment variable template variables.
|
|
16
|
+
|
|
17
|
+
Syntax: {{.env.VARIABLE_NAME}}
|
|
18
|
+
Valid names: alphanumeric characters and underscores (following Unix conventions)
|
|
19
|
+
Examples: {{.env.API_KEY}}, {{.env.DATABASE_URL}}, {{.env.PORT}}
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
_pattern = re.compile(r"\{\{\.env\.([a-zA-Z_][a-zA-Z0-9_]*)\}\}")
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def pattern(self) -> re.Pattern:
|
|
26
|
+
"""Pattern to match environment variables: {{.env.VAR}}"""
|
|
27
|
+
return self._pattern
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def variable_type(self) -> TemplateVariableType:
|
|
31
|
+
"""Returns ENV variable type."""
|
|
32
|
+
return TemplateVariableType.ENV
|
|
33
|
+
|
|
34
|
+
def parse_match(self, match: re.Match, template: str) -> Optional[TemplateVariable]:
|
|
35
|
+
"""
|
|
36
|
+
Parse a regex match into a TemplateVariable.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
match: Regex match object for {{.env.VAR}}
|
|
40
|
+
template: Full template string
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
TemplateVariable with the parsed information
|
|
44
|
+
"""
|
|
45
|
+
env_var_name = match.group(1)
|
|
46
|
+
raw = match.group(0)
|
|
47
|
+
start = match.start()
|
|
48
|
+
end = match.end()
|
|
49
|
+
|
|
50
|
+
# Additional validation
|
|
51
|
+
if not self.validate_name(env_var_name):
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
# Store with "env." prefix for consistency
|
|
55
|
+
name = f"env.{env_var_name}"
|
|
56
|
+
|
|
57
|
+
return TemplateVariable(
|
|
58
|
+
name=name,
|
|
59
|
+
type=self.variable_type,
|
|
60
|
+
raw=raw,
|
|
61
|
+
start=start,
|
|
62
|
+
end=end
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
def validate_name(self, name: str) -> bool:
|
|
66
|
+
"""
|
|
67
|
+
Validate environment variable name.
|
|
68
|
+
|
|
69
|
+
Rules (following Unix conventions):
|
|
70
|
+
- Must start with a letter or underscore
|
|
71
|
+
- Can contain letters, digits, and underscores
|
|
72
|
+
- Cannot be empty
|
|
73
|
+
- By convention, usually uppercase but not required
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
name: Environment variable name to validate
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
True if valid, False otherwise
|
|
80
|
+
"""
|
|
81
|
+
if not name:
|
|
82
|
+
return False
|
|
83
|
+
|
|
84
|
+
# Must start with letter or underscore, contain only alphanumeric and underscores
|
|
85
|
+
return bool(re.match(r"^[a-zA-Z_][a-zA-Z0-9_]*$", name))
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Parser for context graph node template variables: {{.graph.node-id}}
|
|
3
|
+
|
|
4
|
+
Supports referencing nodes from the context graph by their ID.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
from typing import Optional
|
|
9
|
+
from control_plane_api.app.lib.templating.parsers.base import BaseParser
|
|
10
|
+
from control_plane_api.app.lib.templating.types import TemplateVariable, TemplateVariableType
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class GraphNodeParser(BaseParser):
|
|
14
|
+
"""
|
|
15
|
+
Parser for context graph node template variables.
|
|
16
|
+
|
|
17
|
+
Syntax: {{.graph.node-id}}
|
|
18
|
+
Valid node IDs: alphanumeric characters, underscores, hyphens, and dots
|
|
19
|
+
Examples: {{.graph.user-123}}, {{.graph.repo_456}}, {{.graph.service.prod}}
|
|
20
|
+
|
|
21
|
+
When compiled, these variables will be replaced with formatted node data including:
|
|
22
|
+
- Node properties (metadata)
|
|
23
|
+
- Relationships (incoming/outgoing)
|
|
24
|
+
- Labels and types
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
_pattern = re.compile(r"\{\{\.graph\.([a-zA-Z0-9._-]+)\}\}")
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def pattern(self) -> re.Pattern:
|
|
31
|
+
"""Pattern to match graph node variables: {{.graph.node-id}}"""
|
|
32
|
+
return self._pattern
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def variable_type(self) -> TemplateVariableType:
|
|
36
|
+
"""Returns GRAPH variable type."""
|
|
37
|
+
return TemplateVariableType.GRAPH
|
|
38
|
+
|
|
39
|
+
def parse_match(self, match: re.Match, template: str) -> Optional[TemplateVariable]:
|
|
40
|
+
"""
|
|
41
|
+
Parse a regex match into a TemplateVariable.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
match: Regex match object for {{.graph.node-id}}
|
|
45
|
+
template: Full template string
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
TemplateVariable with the parsed information
|
|
49
|
+
"""
|
|
50
|
+
node_id = match.group(1)
|
|
51
|
+
raw = match.group(0)
|
|
52
|
+
start = match.start()
|
|
53
|
+
end = match.end()
|
|
54
|
+
|
|
55
|
+
# Additional validation
|
|
56
|
+
if not self.validate_node_id(node_id):
|
|
57
|
+
return None
|
|
58
|
+
|
|
59
|
+
# Store with "graph." prefix for consistency
|
|
60
|
+
name = f"graph.{node_id}"
|
|
61
|
+
|
|
62
|
+
return TemplateVariable(
|
|
63
|
+
name=name,
|
|
64
|
+
type=self.variable_type,
|
|
65
|
+
raw=raw,
|
|
66
|
+
start=start,
|
|
67
|
+
end=end
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
def validate_name(self, name: str) -> bool:
|
|
71
|
+
"""
|
|
72
|
+
Validate variable name (implements BaseParser abstract method).
|
|
73
|
+
|
|
74
|
+
For graph variables, the name format is "graph.node-id".
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
name: Variable name to validate
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
True if valid, False otherwise
|
|
81
|
+
"""
|
|
82
|
+
if not name or not name.startswith("graph."):
|
|
83
|
+
return False
|
|
84
|
+
|
|
85
|
+
# Extract node ID after "graph." prefix
|
|
86
|
+
node_id = name[6:] # len("graph.") == 6
|
|
87
|
+
return self.validate_node_id(node_id)
|
|
88
|
+
|
|
89
|
+
def validate_node_id(self, node_id: str) -> bool:
|
|
90
|
+
"""
|
|
91
|
+
Validate node ID.
|
|
92
|
+
|
|
93
|
+
Rules:
|
|
94
|
+
- Must contain only alphanumeric characters, underscores, hyphens, and dots
|
|
95
|
+
- Cannot be empty
|
|
96
|
+
- Cannot start or end with special characters (best practice)
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
node_id: Node ID to validate
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
True if valid, False otherwise
|
|
103
|
+
"""
|
|
104
|
+
if not node_id:
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
# Basic pattern check - allow alphanumeric, underscore, hyphen, and dot
|
|
108
|
+
# Allow single character IDs or multi-character with proper start/end
|
|
109
|
+
if not re.match(r"^[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]$|^[a-zA-Z0-9]$", node_id):
|
|
110
|
+
return False
|
|
111
|
+
|
|
112
|
+
return True
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Parser for secret template variables: {{.secret.name}}
|
|
3
|
+
|
|
4
|
+
Supports referencing secrets from the vault.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
from typing import Optional
|
|
9
|
+
from control_plane_api.app.lib.templating.parsers.base import BaseParser
|
|
10
|
+
from control_plane_api.app.lib.templating.types import TemplateVariable, TemplateVariableType
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SecretVariableParser(BaseParser):
|
|
14
|
+
"""
|
|
15
|
+
Parser for secret template variables.
|
|
16
|
+
|
|
17
|
+
Syntax: {{.secret.secret_name}}
|
|
18
|
+
Valid names: alphanumeric characters, underscores, and hyphens
|
|
19
|
+
Examples: {{.secret.api_key}}, {{.secret.github-token}}, {{.secret.db_password}}
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
_pattern = re.compile(r"\{\{\.secret\.([a-zA-Z0-9_-]+)\}\}")
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def pattern(self) -> re.Pattern:
|
|
26
|
+
"""Pattern to match secret variables: {{.secret.name}}"""
|
|
27
|
+
return self._pattern
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def variable_type(self) -> TemplateVariableType:
|
|
31
|
+
"""Returns SECRET variable type."""
|
|
32
|
+
return TemplateVariableType.SECRET
|
|
33
|
+
|
|
34
|
+
def parse_match(self, match: re.Match, template: str) -> Optional[TemplateVariable]:
|
|
35
|
+
"""
|
|
36
|
+
Parse a regex match into a TemplateVariable.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
match: Regex match object for {{.secret.name}}
|
|
40
|
+
template: Full template string
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
TemplateVariable with the parsed information
|
|
44
|
+
"""
|
|
45
|
+
secret_name = match.group(1)
|
|
46
|
+
raw = match.group(0)
|
|
47
|
+
start = match.start()
|
|
48
|
+
end = match.end()
|
|
49
|
+
|
|
50
|
+
# Additional validation
|
|
51
|
+
if not self.validate_name(secret_name):
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
# Store with "secret." prefix for consistency
|
|
55
|
+
name = f"secret.{secret_name}"
|
|
56
|
+
|
|
57
|
+
return TemplateVariable(
|
|
58
|
+
name=name,
|
|
59
|
+
type=self.variable_type,
|
|
60
|
+
raw=raw,
|
|
61
|
+
start=start,
|
|
62
|
+
end=end
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
def validate_name(self, name: str) -> bool:
|
|
66
|
+
"""
|
|
67
|
+
Validate secret name.
|
|
68
|
+
|
|
69
|
+
Rules:
|
|
70
|
+
- Must contain only alphanumeric characters, underscores, and hyphens
|
|
71
|
+
- Cannot be empty
|
|
72
|
+
- Cannot start or end with hyphen or underscore (best practice)
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
name: Secret name to validate
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
True if valid, False otherwise
|
|
79
|
+
"""
|
|
80
|
+
if not name:
|
|
81
|
+
return False
|
|
82
|
+
|
|
83
|
+
# Basic pattern check
|
|
84
|
+
if not re.match(r"^[a-zA-Z0-9][a-zA-Z0-9_-]*[a-zA-Z0-9]$|^[a-zA-Z0-9]$", name):
|
|
85
|
+
return False
|
|
86
|
+
|
|
87
|
+
return True
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Parser for simple template variables: {{variable}}
|
|
3
|
+
|
|
4
|
+
Supports basic variable substitution with alphanumeric names and underscores.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
from typing import Optional
|
|
9
|
+
from control_plane_api.app.lib.templating.parsers.base import BaseParser
|
|
10
|
+
from control_plane_api.app.lib.templating.types import TemplateVariable, TemplateVariableType
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SimpleVariableParser(BaseParser):
|
|
14
|
+
"""
|
|
15
|
+
Parser for simple template variables.
|
|
16
|
+
|
|
17
|
+
Syntax: {{variable_name}}
|
|
18
|
+
Valid names: alphanumeric characters and underscores only
|
|
19
|
+
Examples: {{user}}, {{api_key}}, {{database_name}}
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
_pattern = re.compile(r"\{\{([a-zA-Z0-9_]+)\}\}")
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def pattern(self) -> re.Pattern:
|
|
26
|
+
"""Pattern to match simple variables: {{variable}}"""
|
|
27
|
+
return self._pattern
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def variable_type(self) -> TemplateVariableType:
|
|
31
|
+
"""Returns SIMPLE variable type."""
|
|
32
|
+
return TemplateVariableType.SIMPLE
|
|
33
|
+
|
|
34
|
+
def parse_match(self, match: re.Match, template: str) -> Optional[TemplateVariable]:
|
|
35
|
+
"""
|
|
36
|
+
Parse a regex match into a TemplateVariable.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
match: Regex match object for {{variable}}
|
|
40
|
+
template: Full template string
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
TemplateVariable with the parsed information
|
|
44
|
+
"""
|
|
45
|
+
name = match.group(1)
|
|
46
|
+
raw = match.group(0)
|
|
47
|
+
start = match.start()
|
|
48
|
+
end = match.end()
|
|
49
|
+
|
|
50
|
+
# Additional validation
|
|
51
|
+
if not self.validate_name(name):
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
return TemplateVariable(
|
|
55
|
+
name=name,
|
|
56
|
+
type=self.variable_type,
|
|
57
|
+
raw=raw,
|
|
58
|
+
start=start,
|
|
59
|
+
end=end
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
def validate_name(self, name: str) -> bool:
|
|
63
|
+
"""
|
|
64
|
+
Validate simple variable name.
|
|
65
|
+
|
|
66
|
+
Rules:
|
|
67
|
+
- Must contain only alphanumeric characters and underscores
|
|
68
|
+
- Cannot be empty
|
|
69
|
+
- Cannot start with a number (enforced by pattern)
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
name: Variable name to validate
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
True if valid, False otherwise
|
|
76
|
+
"""
|
|
77
|
+
if not name:
|
|
78
|
+
return False
|
|
79
|
+
|
|
80
|
+
# Check pattern (redundant but explicit)
|
|
81
|
+
return bool(re.match(r"^[a-zA-Z_][a-zA-Z0-9_]*$", name))
|