kubiya-control-plane-api 0.9.15__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (479) hide show
  1. control_plane_api/LICENSE +676 -0
  2. control_plane_api/README.md +350 -0
  3. control_plane_api/__init__.py +4 -0
  4. control_plane_api/__version__.py +8 -0
  5. control_plane_api/alembic/README +1 -0
  6. control_plane_api/alembic/env.py +121 -0
  7. control_plane_api/alembic/script.py.mako +28 -0
  8. control_plane_api/alembic/versions/2613c65c3dbe_initial_database_setup.py +32 -0
  9. control_plane_api/alembic/versions/2df520d4927d_merge_heads.py +28 -0
  10. control_plane_api/alembic/versions/43abf98d6a01_add_paused_status_to_executions.py +73 -0
  11. control_plane_api/alembic/versions/6289854264cb_merge_multiple_heads.py +28 -0
  12. control_plane_api/alembic/versions/6a4d4dc3d8dc_generate_execution_transitions.py +50 -0
  13. control_plane_api/alembic/versions/87d11cf0a783_add_disconnected_status_to_worker_.py +44 -0
  14. control_plane_api/alembic/versions/add_ephemeral_queue_support.py +85 -0
  15. control_plane_api/alembic/versions/add_model_type_to_llm_models.py +31 -0
  16. control_plane_api/alembic/versions/add_plan_executions_table.py +114 -0
  17. control_plane_api/alembic/versions/add_trace_span_tables.py +154 -0
  18. control_plane_api/alembic/versions/add_user_info_to_traces.py +36 -0
  19. control_plane_api/alembic/versions/adjusting_foreign_keys.py +32 -0
  20. control_plane_api/alembic/versions/b4983d976db2_initial_tables.py +1128 -0
  21. control_plane_api/alembic/versions/d181a3b40e71_rename_custom_metadata_to_metadata_in_.py +50 -0
  22. control_plane_api/alembic/versions/df9117888e82_add_missing_columns.py +82 -0
  23. control_plane_api/alembic/versions/f25de6ad895a_missing_migrations.py +34 -0
  24. control_plane_api/alembic/versions/f71305fb69b9_fix_ephemeral_queue_deletion_foreign_key.py +54 -0
  25. control_plane_api/alembic/versions/mark_local_exec_queues_as_ephemeral.py +68 -0
  26. control_plane_api/alembic.ini +148 -0
  27. control_plane_api/api/index.py +12 -0
  28. control_plane_api/app/__init__.py +11 -0
  29. control_plane_api/app/activities/__init__.py +20 -0
  30. control_plane_api/app/activities/agent_activities.py +384 -0
  31. control_plane_api/app/activities/plan_generation_activities.py +499 -0
  32. control_plane_api/app/activities/team_activities.py +424 -0
  33. control_plane_api/app/activities/temporal_cloud_activities.py +588 -0
  34. control_plane_api/app/config/__init__.py +35 -0
  35. control_plane_api/app/config/api_config.py +469 -0
  36. control_plane_api/app/config/config_loader.py +224 -0
  37. control_plane_api/app/config/model_pricing.py +323 -0
  38. control_plane_api/app/config/storage_config.py +159 -0
  39. control_plane_api/app/config.py +115 -0
  40. control_plane_api/app/controllers/__init__.py +0 -0
  41. control_plane_api/app/controllers/execution_environment_controller.py +1315 -0
  42. control_plane_api/app/database.py +135 -0
  43. control_plane_api/app/exceptions.py +408 -0
  44. control_plane_api/app/lib/__init__.py +11 -0
  45. control_plane_api/app/lib/environment.py +65 -0
  46. control_plane_api/app/lib/event_bus/__init__.py +17 -0
  47. control_plane_api/app/lib/event_bus/base.py +136 -0
  48. control_plane_api/app/lib/event_bus/manager.py +335 -0
  49. control_plane_api/app/lib/event_bus/providers/__init__.py +6 -0
  50. control_plane_api/app/lib/event_bus/providers/http_provider.py +166 -0
  51. control_plane_api/app/lib/event_bus/providers/nats_provider.py +324 -0
  52. control_plane_api/app/lib/event_bus/providers/redis_provider.py +233 -0
  53. control_plane_api/app/lib/event_bus/providers/websocket_provider.py +497 -0
  54. control_plane_api/app/lib/job_executor.py +330 -0
  55. control_plane_api/app/lib/kubiya_client.py +293 -0
  56. control_plane_api/app/lib/litellm_pricing.py +166 -0
  57. control_plane_api/app/lib/mcp_validation.py +163 -0
  58. control_plane_api/app/lib/nats/__init__.py +13 -0
  59. control_plane_api/app/lib/nats/credentials_manager.py +288 -0
  60. control_plane_api/app/lib/nats/listener.py +374 -0
  61. control_plane_api/app/lib/planning_prompt_builder.py +153 -0
  62. control_plane_api/app/lib/planning_tools/__init__.py +41 -0
  63. control_plane_api/app/lib/planning_tools/agents.py +409 -0
  64. control_plane_api/app/lib/planning_tools/agno_toolkit.py +836 -0
  65. control_plane_api/app/lib/planning_tools/base.py +119 -0
  66. control_plane_api/app/lib/planning_tools/cognitive_memory_tools.py +403 -0
  67. control_plane_api/app/lib/planning_tools/context_graph_tools.py +545 -0
  68. control_plane_api/app/lib/planning_tools/environments.py +218 -0
  69. control_plane_api/app/lib/planning_tools/knowledge.py +204 -0
  70. control_plane_api/app/lib/planning_tools/models.py +93 -0
  71. control_plane_api/app/lib/planning_tools/planning_service.py +646 -0
  72. control_plane_api/app/lib/planning_tools/resources.py +242 -0
  73. control_plane_api/app/lib/planning_tools/teams.py +334 -0
  74. control_plane_api/app/lib/policy_enforcer_client.py +1016 -0
  75. control_plane_api/app/lib/redis_client.py +803 -0
  76. control_plane_api/app/lib/sqlalchemy_utils.py +486 -0
  77. control_plane_api/app/lib/state_transition_tools/__init__.py +7 -0
  78. control_plane_api/app/lib/state_transition_tools/execution_context.py +388 -0
  79. control_plane_api/app/lib/storage/__init__.py +20 -0
  80. control_plane_api/app/lib/storage/base_provider.py +274 -0
  81. control_plane_api/app/lib/storage/provider_factory.py +157 -0
  82. control_plane_api/app/lib/storage/vercel_blob_provider.py +468 -0
  83. control_plane_api/app/lib/supabase.py +71 -0
  84. control_plane_api/app/lib/supabase_utils.py +138 -0
  85. control_plane_api/app/lib/task_planning/__init__.py +138 -0
  86. control_plane_api/app/lib/task_planning/agent_factory.py +308 -0
  87. control_plane_api/app/lib/task_planning/agents.py +389 -0
  88. control_plane_api/app/lib/task_planning/cache.py +218 -0
  89. control_plane_api/app/lib/task_planning/entity_resolver.py +273 -0
  90. control_plane_api/app/lib/task_planning/helpers.py +293 -0
  91. control_plane_api/app/lib/task_planning/hooks.py +474 -0
  92. control_plane_api/app/lib/task_planning/models.py +503 -0
  93. control_plane_api/app/lib/task_planning/plan_validator.py +166 -0
  94. control_plane_api/app/lib/task_planning/planning_workflow.py +2911 -0
  95. control_plane_api/app/lib/task_planning/runner.py +656 -0
  96. control_plane_api/app/lib/task_planning/streaming_hook.py +213 -0
  97. control_plane_api/app/lib/task_planning/workflow.py +424 -0
  98. control_plane_api/app/lib/templating/__init__.py +88 -0
  99. control_plane_api/app/lib/templating/compiler.py +278 -0
  100. control_plane_api/app/lib/templating/engine.py +178 -0
  101. control_plane_api/app/lib/templating/parsers/__init__.py +29 -0
  102. control_plane_api/app/lib/templating/parsers/base.py +96 -0
  103. control_plane_api/app/lib/templating/parsers/env.py +85 -0
  104. control_plane_api/app/lib/templating/parsers/graph.py +112 -0
  105. control_plane_api/app/lib/templating/parsers/secret.py +87 -0
  106. control_plane_api/app/lib/templating/parsers/simple.py +81 -0
  107. control_plane_api/app/lib/templating/resolver.py +366 -0
  108. control_plane_api/app/lib/templating/types.py +214 -0
  109. control_plane_api/app/lib/templating/validator.py +201 -0
  110. control_plane_api/app/lib/temporal_client.py +232 -0
  111. control_plane_api/app/lib/temporal_credentials_cache.py +178 -0
  112. control_plane_api/app/lib/temporal_credentials_service.py +203 -0
  113. control_plane_api/app/lib/validation/__init__.py +24 -0
  114. control_plane_api/app/lib/validation/runtime_validation.py +388 -0
  115. control_plane_api/app/main.py +531 -0
  116. control_plane_api/app/middleware/__init__.py +10 -0
  117. control_plane_api/app/middleware/auth.py +645 -0
  118. control_plane_api/app/middleware/exception_handler.py +267 -0
  119. control_plane_api/app/middleware/prometheus_middleware.py +173 -0
  120. control_plane_api/app/middleware/rate_limiting.py +384 -0
  121. control_plane_api/app/middleware/request_id.py +202 -0
  122. control_plane_api/app/models/__init__.py +40 -0
  123. control_plane_api/app/models/agent.py +90 -0
  124. control_plane_api/app/models/analytics.py +206 -0
  125. control_plane_api/app/models/associations.py +107 -0
  126. control_plane_api/app/models/auth_user.py +73 -0
  127. control_plane_api/app/models/context.py +161 -0
  128. control_plane_api/app/models/custom_integration.py +99 -0
  129. control_plane_api/app/models/environment.py +64 -0
  130. control_plane_api/app/models/execution.py +125 -0
  131. control_plane_api/app/models/execution_transition.py +50 -0
  132. control_plane_api/app/models/job.py +159 -0
  133. control_plane_api/app/models/llm_model.py +78 -0
  134. control_plane_api/app/models/orchestration.py +66 -0
  135. control_plane_api/app/models/plan_execution.py +102 -0
  136. control_plane_api/app/models/presence.py +49 -0
  137. control_plane_api/app/models/project.py +61 -0
  138. control_plane_api/app/models/project_management.py +85 -0
  139. control_plane_api/app/models/session.py +29 -0
  140. control_plane_api/app/models/skill.py +155 -0
  141. control_plane_api/app/models/system_tables.py +43 -0
  142. control_plane_api/app/models/task_planning.py +372 -0
  143. control_plane_api/app/models/team.py +86 -0
  144. control_plane_api/app/models/trace.py +257 -0
  145. control_plane_api/app/models/user_profile.py +54 -0
  146. control_plane_api/app/models/worker.py +221 -0
  147. control_plane_api/app/models/workflow.py +161 -0
  148. control_plane_api/app/models/workspace.py +50 -0
  149. control_plane_api/app/observability/__init__.py +177 -0
  150. control_plane_api/app/observability/context_logging.py +475 -0
  151. control_plane_api/app/observability/decorators.py +337 -0
  152. control_plane_api/app/observability/local_span_processor.py +702 -0
  153. control_plane_api/app/observability/metrics.py +303 -0
  154. control_plane_api/app/observability/middleware.py +246 -0
  155. control_plane_api/app/observability/optional.py +115 -0
  156. control_plane_api/app/observability/tracing.py +382 -0
  157. control_plane_api/app/policies/README.md +149 -0
  158. control_plane_api/app/policies/approved_users.rego +62 -0
  159. control_plane_api/app/policies/business_hours.rego +51 -0
  160. control_plane_api/app/policies/rate_limiting.rego +100 -0
  161. control_plane_api/app/policies/tool_enforcement/README.md +336 -0
  162. control_plane_api/app/policies/tool_enforcement/bash_command_validation.rego +71 -0
  163. control_plane_api/app/policies/tool_enforcement/business_hours_enforcement.rego +82 -0
  164. control_plane_api/app/policies/tool_enforcement/mcp_tool_allowlist.rego +58 -0
  165. control_plane_api/app/policies/tool_enforcement/production_safeguards.rego +80 -0
  166. control_plane_api/app/policies/tool_enforcement/role_based_tool_access.rego +44 -0
  167. control_plane_api/app/policies/tool_restrictions.rego +86 -0
  168. control_plane_api/app/routers/__init__.py +4 -0
  169. control_plane_api/app/routers/agents.py +382 -0
  170. control_plane_api/app/routers/agents_v2.py +1598 -0
  171. control_plane_api/app/routers/analytics.py +1310 -0
  172. control_plane_api/app/routers/auth.py +59 -0
  173. control_plane_api/app/routers/client_config.py +57 -0
  174. control_plane_api/app/routers/context_graph.py +561 -0
  175. control_plane_api/app/routers/context_manager.py +577 -0
  176. control_plane_api/app/routers/custom_integrations.py +490 -0
  177. control_plane_api/app/routers/enforcer.py +132 -0
  178. control_plane_api/app/routers/environment_context.py +252 -0
  179. control_plane_api/app/routers/environments.py +761 -0
  180. control_plane_api/app/routers/execution_environment.py +847 -0
  181. control_plane_api/app/routers/executions/__init__.py +28 -0
  182. control_plane_api/app/routers/executions/router.py +286 -0
  183. control_plane_api/app/routers/executions/services/__init__.py +22 -0
  184. control_plane_api/app/routers/executions/services/demo_worker_health.py +156 -0
  185. control_plane_api/app/routers/executions/services/status_service.py +420 -0
  186. control_plane_api/app/routers/executions/services/test_worker_health.py +480 -0
  187. control_plane_api/app/routers/executions/services/worker_health.py +514 -0
  188. control_plane_api/app/routers/executions/streaming/__init__.py +22 -0
  189. control_plane_api/app/routers/executions/streaming/deduplication.py +352 -0
  190. control_plane_api/app/routers/executions/streaming/event_buffer.py +353 -0
  191. control_plane_api/app/routers/executions/streaming/event_formatter.py +964 -0
  192. control_plane_api/app/routers/executions/streaming/history_loader.py +588 -0
  193. control_plane_api/app/routers/executions/streaming/live_source.py +693 -0
  194. control_plane_api/app/routers/executions/streaming/streamer.py +849 -0
  195. control_plane_api/app/routers/executions.py +4888 -0
  196. control_plane_api/app/routers/health.py +165 -0
  197. control_plane_api/app/routers/health_v2.py +394 -0
  198. control_plane_api/app/routers/integration_templates.py +496 -0
  199. control_plane_api/app/routers/integrations.py +287 -0
  200. control_plane_api/app/routers/jobs.py +1809 -0
  201. control_plane_api/app/routers/metrics.py +517 -0
  202. control_plane_api/app/routers/models.py +82 -0
  203. control_plane_api/app/routers/models_v2.py +628 -0
  204. control_plane_api/app/routers/plan_executions.py +1481 -0
  205. control_plane_api/app/routers/plan_generation_async.py +304 -0
  206. control_plane_api/app/routers/policies.py +669 -0
  207. control_plane_api/app/routers/presence.py +234 -0
  208. control_plane_api/app/routers/projects.py +987 -0
  209. control_plane_api/app/routers/runners.py +379 -0
  210. control_plane_api/app/routers/runtimes.py +172 -0
  211. control_plane_api/app/routers/secrets.py +171 -0
  212. control_plane_api/app/routers/skills.py +1010 -0
  213. control_plane_api/app/routers/skills_definitions.py +140 -0
  214. control_plane_api/app/routers/storage.py +456 -0
  215. control_plane_api/app/routers/task_planning.py +611 -0
  216. control_plane_api/app/routers/task_queues.py +650 -0
  217. control_plane_api/app/routers/team_context.py +274 -0
  218. control_plane_api/app/routers/teams.py +1747 -0
  219. control_plane_api/app/routers/templates.py +248 -0
  220. control_plane_api/app/routers/traces.py +571 -0
  221. control_plane_api/app/routers/websocket_client.py +479 -0
  222. control_plane_api/app/routers/websocket_executions_status.py +437 -0
  223. control_plane_api/app/routers/websocket_gateway.py +323 -0
  224. control_plane_api/app/routers/websocket_traces.py +576 -0
  225. control_plane_api/app/routers/worker_queues.py +2555 -0
  226. control_plane_api/app/routers/worker_websocket.py +419 -0
  227. control_plane_api/app/routers/workers.py +1004 -0
  228. control_plane_api/app/routers/workflows.py +204 -0
  229. control_plane_api/app/runtimes/__init__.py +6 -0
  230. control_plane_api/app/runtimes/validation.py +344 -0
  231. control_plane_api/app/schemas/__init__.py +1 -0
  232. control_plane_api/app/schemas/job_schemas.py +302 -0
  233. control_plane_api/app/schemas/mcp_schemas.py +311 -0
  234. control_plane_api/app/schemas/template_schemas.py +133 -0
  235. control_plane_api/app/schemas/trace_schemas.py +168 -0
  236. control_plane_api/app/schemas/worker_queue_observability_schemas.py +165 -0
  237. control_plane_api/app/services/__init__.py +1 -0
  238. control_plane_api/app/services/agno_planning_strategy.py +233 -0
  239. control_plane_api/app/services/agno_service.py +838 -0
  240. control_plane_api/app/services/claude_code_planning_service.py +203 -0
  241. control_plane_api/app/services/context_graph_client.py +224 -0
  242. control_plane_api/app/services/custom_integration_service.py +415 -0
  243. control_plane_api/app/services/integration_resolution_service.py +345 -0
  244. control_plane_api/app/services/litellm_service.py +394 -0
  245. control_plane_api/app/services/plan_generator.py +79 -0
  246. control_plane_api/app/services/planning_strategy.py +66 -0
  247. control_plane_api/app/services/planning_strategy_factory.py +118 -0
  248. control_plane_api/app/services/policy_service.py +615 -0
  249. control_plane_api/app/services/state_transition_service.py +755 -0
  250. control_plane_api/app/services/storage_service.py +593 -0
  251. control_plane_api/app/services/temporal_cloud_provisioning.py +150 -0
  252. control_plane_api/app/services/toolsets/context_graph_skill.py +432 -0
  253. control_plane_api/app/services/trace_retention.py +354 -0
  254. control_plane_api/app/services/worker_queue_metrics_service.py +190 -0
  255. control_plane_api/app/services/workflow_cancellation_manager.py +135 -0
  256. control_plane_api/app/services/workflow_operations_service.py +611 -0
  257. control_plane_api/app/skills/__init__.py +100 -0
  258. control_plane_api/app/skills/base.py +239 -0
  259. control_plane_api/app/skills/builtin/__init__.py +37 -0
  260. control_plane_api/app/skills/builtin/agent_communication/__init__.py +8 -0
  261. control_plane_api/app/skills/builtin/agent_communication/skill.py +246 -0
  262. control_plane_api/app/skills/builtin/code_ingestion/__init__.py +4 -0
  263. control_plane_api/app/skills/builtin/code_ingestion/skill.py +267 -0
  264. control_plane_api/app/skills/builtin/cognitive_memory/__init__.py +4 -0
  265. control_plane_api/app/skills/builtin/cognitive_memory/skill.py +174 -0
  266. control_plane_api/app/skills/builtin/contextual_awareness/__init__.py +4 -0
  267. control_plane_api/app/skills/builtin/contextual_awareness/skill.py +387 -0
  268. control_plane_api/app/skills/builtin/data_visualization/__init__.py +4 -0
  269. control_plane_api/app/skills/builtin/data_visualization/skill.py +154 -0
  270. control_plane_api/app/skills/builtin/docker/__init__.py +4 -0
  271. control_plane_api/app/skills/builtin/docker/skill.py +104 -0
  272. control_plane_api/app/skills/builtin/file_generation/__init__.py +4 -0
  273. control_plane_api/app/skills/builtin/file_generation/skill.py +94 -0
  274. control_plane_api/app/skills/builtin/file_system/__init__.py +4 -0
  275. control_plane_api/app/skills/builtin/file_system/skill.py +110 -0
  276. control_plane_api/app/skills/builtin/knowledge_api/__init__.py +5 -0
  277. control_plane_api/app/skills/builtin/knowledge_api/skill.py +124 -0
  278. control_plane_api/app/skills/builtin/python/__init__.py +4 -0
  279. control_plane_api/app/skills/builtin/python/skill.py +92 -0
  280. control_plane_api/app/skills/builtin/remote_filesystem/__init__.py +5 -0
  281. control_plane_api/app/skills/builtin/remote_filesystem/skill.py +170 -0
  282. control_plane_api/app/skills/builtin/shell/__init__.py +4 -0
  283. control_plane_api/app/skills/builtin/shell/skill.py +161 -0
  284. control_plane_api/app/skills/builtin/slack/__init__.py +3 -0
  285. control_plane_api/app/skills/builtin/slack/skill.py +302 -0
  286. control_plane_api/app/skills/builtin/workflow_executor/__init__.py +4 -0
  287. control_plane_api/app/skills/builtin/workflow_executor/skill.py +469 -0
  288. control_plane_api/app/skills/business_intelligence.py +189 -0
  289. control_plane_api/app/skills/config.py +63 -0
  290. control_plane_api/app/skills/loaders/__init__.py +14 -0
  291. control_plane_api/app/skills/loaders/base.py +73 -0
  292. control_plane_api/app/skills/loaders/filesystem_loader.py +199 -0
  293. control_plane_api/app/skills/registry.py +125 -0
  294. control_plane_api/app/utils/helpers.py +12 -0
  295. control_plane_api/app/utils/workflow_executor.py +354 -0
  296. control_plane_api/app/workflows/__init__.py +11 -0
  297. control_plane_api/app/workflows/agent_execution.py +520 -0
  298. control_plane_api/app/workflows/agent_execution_with_skills.py +223 -0
  299. control_plane_api/app/workflows/namespace_provisioning.py +326 -0
  300. control_plane_api/app/workflows/plan_generation.py +254 -0
  301. control_plane_api/app/workflows/team_execution.py +442 -0
  302. control_plane_api/scripts/seed_models.py +240 -0
  303. control_plane_api/scripts/validate_existing_tool_names.py +492 -0
  304. control_plane_api/shared/__init__.py +8 -0
  305. control_plane_api/shared/version.py +17 -0
  306. control_plane_api/test_deduplication.py +274 -0
  307. control_plane_api/test_executor_deduplication_e2e.py +309 -0
  308. control_plane_api/test_job_execution_e2e.py +283 -0
  309. control_plane_api/test_real_integration.py +193 -0
  310. control_plane_api/version.py +38 -0
  311. control_plane_api/worker/__init__.py +0 -0
  312. control_plane_api/worker/activities/__init__.py +0 -0
  313. control_plane_api/worker/activities/agent_activities.py +1585 -0
  314. control_plane_api/worker/activities/approval_activities.py +234 -0
  315. control_plane_api/worker/activities/job_activities.py +199 -0
  316. control_plane_api/worker/activities/runtime_activities.py +1167 -0
  317. control_plane_api/worker/activities/skill_activities.py +282 -0
  318. control_plane_api/worker/activities/team_activities.py +479 -0
  319. control_plane_api/worker/agent_runtime_server.py +370 -0
  320. control_plane_api/worker/binary_manager.py +333 -0
  321. control_plane_api/worker/config/__init__.py +31 -0
  322. control_plane_api/worker/config/worker_config.py +273 -0
  323. control_plane_api/worker/control_plane_client.py +1491 -0
  324. control_plane_api/worker/examples/analytics_integration_example.py +362 -0
  325. control_plane_api/worker/health_monitor.py +159 -0
  326. control_plane_api/worker/metrics.py +237 -0
  327. control_plane_api/worker/models/__init__.py +1 -0
  328. control_plane_api/worker/models/error_events.py +105 -0
  329. control_plane_api/worker/models/inputs.py +89 -0
  330. control_plane_api/worker/runtimes/__init__.py +35 -0
  331. control_plane_api/worker/runtimes/agent_runtime/runtime.py +485 -0
  332. control_plane_api/worker/runtimes/agno/__init__.py +34 -0
  333. control_plane_api/worker/runtimes/agno/config.py +248 -0
  334. control_plane_api/worker/runtimes/agno/hooks.py +385 -0
  335. control_plane_api/worker/runtimes/agno/mcp_builder.py +195 -0
  336. control_plane_api/worker/runtimes/agno/runtime.py +1063 -0
  337. control_plane_api/worker/runtimes/agno/utils.py +163 -0
  338. control_plane_api/worker/runtimes/base.py +979 -0
  339. control_plane_api/worker/runtimes/claude_code/__init__.py +38 -0
  340. control_plane_api/worker/runtimes/claude_code/cleanup.py +184 -0
  341. control_plane_api/worker/runtimes/claude_code/client_pool.py +529 -0
  342. control_plane_api/worker/runtimes/claude_code/config.py +829 -0
  343. control_plane_api/worker/runtimes/claude_code/hooks.py +482 -0
  344. control_plane_api/worker/runtimes/claude_code/litellm_proxy.py +1702 -0
  345. control_plane_api/worker/runtimes/claude_code/mcp_builder.py +467 -0
  346. control_plane_api/worker/runtimes/claude_code/mcp_discovery.py +558 -0
  347. control_plane_api/worker/runtimes/claude_code/runtime.py +1546 -0
  348. control_plane_api/worker/runtimes/claude_code/tool_mapper.py +403 -0
  349. control_plane_api/worker/runtimes/claude_code/utils.py +149 -0
  350. control_plane_api/worker/runtimes/factory.py +173 -0
  351. control_plane_api/worker/runtimes/model_utils.py +107 -0
  352. control_plane_api/worker/runtimes/validation.py +93 -0
  353. control_plane_api/worker/services/__init__.py +1 -0
  354. control_plane_api/worker/services/agent_communication_tools.py +908 -0
  355. control_plane_api/worker/services/agent_executor.py +485 -0
  356. control_plane_api/worker/services/agent_executor_v2.py +793 -0
  357. control_plane_api/worker/services/analytics_collector.py +457 -0
  358. control_plane_api/worker/services/analytics_service.py +464 -0
  359. control_plane_api/worker/services/approval_tools.py +310 -0
  360. control_plane_api/worker/services/approval_tools_agno.py +207 -0
  361. control_plane_api/worker/services/cancellation_manager.py +177 -0
  362. control_plane_api/worker/services/code_ingestion_tools.py +465 -0
  363. control_plane_api/worker/services/contextual_awareness_tools.py +405 -0
  364. control_plane_api/worker/services/data_visualization.py +834 -0
  365. control_plane_api/worker/services/event_publisher.py +531 -0
  366. control_plane_api/worker/services/jira_tools.py +257 -0
  367. control_plane_api/worker/services/remote_filesystem_tools.py +498 -0
  368. control_plane_api/worker/services/runtime_analytics.py +328 -0
  369. control_plane_api/worker/services/session_service.py +365 -0
  370. control_plane_api/worker/services/skill_context_enhancement.py +181 -0
  371. control_plane_api/worker/services/skill_factory.py +471 -0
  372. control_plane_api/worker/services/system_prompt_enhancement.py +410 -0
  373. control_plane_api/worker/services/team_executor.py +715 -0
  374. control_plane_api/worker/services/team_executor_v2.py +1866 -0
  375. control_plane_api/worker/services/tool_enforcement.py +254 -0
  376. control_plane_api/worker/services/workflow_executor/__init__.py +52 -0
  377. control_plane_api/worker/services/workflow_executor/event_processor.py +287 -0
  378. control_plane_api/worker/services/workflow_executor/event_publisher.py +210 -0
  379. control_plane_api/worker/services/workflow_executor/executors/__init__.py +15 -0
  380. control_plane_api/worker/services/workflow_executor/executors/base.py +270 -0
  381. control_plane_api/worker/services/workflow_executor/executors/json_executor.py +50 -0
  382. control_plane_api/worker/services/workflow_executor/executors/python_executor.py +50 -0
  383. control_plane_api/worker/services/workflow_executor/models.py +142 -0
  384. control_plane_api/worker/services/workflow_executor_tools.py +1748 -0
  385. control_plane_api/worker/skills/__init__.py +12 -0
  386. control_plane_api/worker/skills/builtin/context_graph_search/README.md +213 -0
  387. control_plane_api/worker/skills/builtin/context_graph_search/__init__.py +5 -0
  388. control_plane_api/worker/skills/builtin/context_graph_search/agno_impl.py +808 -0
  389. control_plane_api/worker/skills/builtin/context_graph_search/skill.yaml +67 -0
  390. control_plane_api/worker/skills/builtin/contextual_awareness/__init__.py +4 -0
  391. control_plane_api/worker/skills/builtin/contextual_awareness/agno_impl.py +62 -0
  392. control_plane_api/worker/skills/builtin/data_visualization/agno_impl.py +18 -0
  393. control_plane_api/worker/skills/builtin/data_visualization/skill.yaml +84 -0
  394. control_plane_api/worker/skills/builtin/docker/agno_impl.py +65 -0
  395. control_plane_api/worker/skills/builtin/docker/skill.yaml +60 -0
  396. control_plane_api/worker/skills/builtin/file_generation/agno_impl.py +47 -0
  397. control_plane_api/worker/skills/builtin/file_generation/skill.yaml +64 -0
  398. control_plane_api/worker/skills/builtin/file_system/agno_impl.py +32 -0
  399. control_plane_api/worker/skills/builtin/file_system/skill.yaml +54 -0
  400. control_plane_api/worker/skills/builtin/knowledge_api/__init__.py +4 -0
  401. control_plane_api/worker/skills/builtin/knowledge_api/agno_impl.py +50 -0
  402. control_plane_api/worker/skills/builtin/knowledge_api/skill.yaml +66 -0
  403. control_plane_api/worker/skills/builtin/python/agno_impl.py +25 -0
  404. control_plane_api/worker/skills/builtin/python/skill.yaml +60 -0
  405. control_plane_api/worker/skills/builtin/schema_fix_mixin.py +260 -0
  406. control_plane_api/worker/skills/builtin/shell/agno_impl.py +31 -0
  407. control_plane_api/worker/skills/builtin/shell/skill.yaml +60 -0
  408. control_plane_api/worker/skills/builtin/slack/__init__.py +3 -0
  409. control_plane_api/worker/skills/builtin/slack/agno_impl.py +1282 -0
  410. control_plane_api/worker/skills/builtin/slack/skill.yaml +276 -0
  411. control_plane_api/worker/skills/builtin/workflow_executor/agno_impl.py +62 -0
  412. control_plane_api/worker/skills/builtin/workflow_executor/skill.yaml +79 -0
  413. control_plane_api/worker/skills/loaders/__init__.py +5 -0
  414. control_plane_api/worker/skills/loaders/base.py +23 -0
  415. control_plane_api/worker/skills/loaders/filesystem_loader.py +357 -0
  416. control_plane_api/worker/skills/registry.py +208 -0
  417. control_plane_api/worker/tests/__init__.py +1 -0
  418. control_plane_api/worker/tests/conftest.py +12 -0
  419. control_plane_api/worker/tests/e2e/__init__.py +0 -0
  420. control_plane_api/worker/tests/e2e/test_context_graph_real_api.py +338 -0
  421. control_plane_api/worker/tests/e2e/test_context_graph_templates_e2e.py +523 -0
  422. control_plane_api/worker/tests/e2e/test_enforcement_e2e.py +344 -0
  423. control_plane_api/worker/tests/e2e/test_execution_flow.py +571 -0
  424. control_plane_api/worker/tests/e2e/test_single_execution_mode.py +656 -0
  425. control_plane_api/worker/tests/integration/__init__.py +0 -0
  426. control_plane_api/worker/tests/integration/test_builtin_skills_fixes.py +245 -0
  427. control_plane_api/worker/tests/integration/test_context_graph_search_integration.py +365 -0
  428. control_plane_api/worker/tests/integration/test_control_plane_integration.py +308 -0
  429. control_plane_api/worker/tests/integration/test_hook_enforcement_integration.py +579 -0
  430. control_plane_api/worker/tests/integration/test_scheduled_job_workflow.py +237 -0
  431. control_plane_api/worker/tests/integration/test_system_prompt_enhancement_integration.py +343 -0
  432. control_plane_api/worker/tests/unit/__init__.py +0 -0
  433. control_plane_api/worker/tests/unit/test_builtin_skill_autoload.py +396 -0
  434. control_plane_api/worker/tests/unit/test_context_graph_search.py +450 -0
  435. control_plane_api/worker/tests/unit/test_context_graph_templates.py +403 -0
  436. control_plane_api/worker/tests/unit/test_control_plane_client.py +401 -0
  437. control_plane_api/worker/tests/unit/test_control_plane_client_jobs.py +345 -0
  438. control_plane_api/worker/tests/unit/test_job_activities.py +353 -0
  439. control_plane_api/worker/tests/unit/test_skill_context_enhancement.py +321 -0
  440. control_plane_api/worker/tests/unit/test_system_prompt_enhancement.py +415 -0
  441. control_plane_api/worker/tests/unit/test_tool_enforcement.py +324 -0
  442. control_plane_api/worker/utils/__init__.py +1 -0
  443. control_plane_api/worker/utils/chunk_batcher.py +330 -0
  444. control_plane_api/worker/utils/environment.py +65 -0
  445. control_plane_api/worker/utils/error_publisher.py +260 -0
  446. control_plane_api/worker/utils/event_batcher.py +256 -0
  447. control_plane_api/worker/utils/logging_config.py +335 -0
  448. control_plane_api/worker/utils/logging_helper.py +326 -0
  449. control_plane_api/worker/utils/parameter_validator.py +120 -0
  450. control_plane_api/worker/utils/retry_utils.py +60 -0
  451. control_plane_api/worker/utils/streaming_utils.py +665 -0
  452. control_plane_api/worker/utils/tool_validation.py +332 -0
  453. control_plane_api/worker/utils/workspace_manager.py +163 -0
  454. control_plane_api/worker/websocket_client.py +393 -0
  455. control_plane_api/worker/worker.py +1297 -0
  456. control_plane_api/worker/workflows/__init__.py +0 -0
  457. control_plane_api/worker/workflows/agent_execution.py +909 -0
  458. control_plane_api/worker/workflows/scheduled_job_wrapper.py +332 -0
  459. control_plane_api/worker/workflows/team_execution.py +611 -0
  460. kubiya_control_plane_api-0.9.15.dist-info/METADATA +354 -0
  461. kubiya_control_plane_api-0.9.15.dist-info/RECORD +479 -0
  462. kubiya_control_plane_api-0.9.15.dist-info/WHEEL +5 -0
  463. kubiya_control_plane_api-0.9.15.dist-info/entry_points.txt +5 -0
  464. kubiya_control_plane_api-0.9.15.dist-info/licenses/LICENSE +676 -0
  465. kubiya_control_plane_api-0.9.15.dist-info/top_level.txt +3 -0
  466. scripts/__init__.py +1 -0
  467. scripts/migrations.py +39 -0
  468. scripts/seed_worker_queues.py +128 -0
  469. scripts/setup_agent_runtime.py +142 -0
  470. worker_internal/__init__.py +1 -0
  471. worker_internal/planner/__init__.py +1 -0
  472. worker_internal/planner/activities.py +1499 -0
  473. worker_internal/planner/agent_tools.py +197 -0
  474. worker_internal/planner/event_models.py +148 -0
  475. worker_internal/planner/event_publisher.py +67 -0
  476. worker_internal/planner/models.py +199 -0
  477. worker_internal/planner/retry_logic.py +134 -0
  478. worker_internal/planner/worker.py +300 -0
  479. worker_internal/planner/workflows.py +970 -0
@@ -0,0 +1,545 @@
1
+ """
2
+ Context Graph Planning Tools
3
+
4
+ Provides intelligent resource discovery via context graph queries.
5
+ Replaces the anti-pattern of dumping all agents/teams into prompt.
6
+
7
+ This tool enables the planning agent to:
8
+ 1. Discover agents by capability/skill
9
+ 2. Search teams with specific capabilities
10
+ 3. Get full agent details on-demand
11
+ 4. Query context graph for relevant resources
12
+ 5. List available capabilities
13
+
14
+ Following the same pattern used by workers and skills for tool-based discovery.
15
+ """
16
+
17
+ import structlog
18
+ from typing import Optional, List, Dict, Any
19
+ from sqlalchemy import select
20
+ from sqlalchemy.orm import selectinload
21
+
22
+ from control_plane_api.app.lib.planning_tools.base import BasePlanningTools
23
+ from control_plane_api.app.services.context_graph_client import ContextGraphClient
24
+ from control_plane_api.app.models.agent import Agent
25
+
26
+ logger = structlog.get_logger(__name__)
27
+
28
+
29
+ class ContextGraphPlanningTools(BasePlanningTools):
30
+ """
31
+ Context graph tools for intelligent resource discovery during planning.
32
+
33
+ Usage pattern:
34
+ 1. AI analyzes task description
35
+ 2. AI identifies required capabilities (e.g., "kubernetes", "aws")
36
+ 3. AI calls search_agents_with_capability("kubernetes")
37
+ 4. AI gets relevant agent summaries
38
+ 5. AI optionally calls get_agent_full_details(agent_id) for specific agents
39
+ """
40
+
41
+ def __init__(
42
+ self,
43
+ db=None,
44
+ organization_id: Optional[str] = None,
45
+ api_token: Optional[str] = None,
46
+ graph_api_base: Optional[str] = None,
47
+ ):
48
+ """
49
+ Initialize context graph planning tools
50
+
51
+ Args:
52
+ db: Database session for direct data access
53
+ organization_id: Organization context for filtering
54
+ api_token: API token for context graph authentication
55
+ graph_api_base: Context graph API base URL (default: https://graph.kubiya.ai)
56
+ """
57
+ super().__init__(db=db, organization_id=organization_id)
58
+ self.name = "context_graph_planning_tools"
59
+ self.api_token = api_token
60
+ self.graph_client = ContextGraphClient(
61
+ api_base=graph_api_base or "https://graph.kubiya.ai",
62
+ api_token=api_token,
63
+ organization_id=organization_id
64
+ )
65
+
66
+ async def search_agents_with_capability(
67
+ self,
68
+ capability: str,
69
+ limit: int = 10
70
+ ) -> str:
71
+ """
72
+ Search for agents that have a specific capability (skill).
73
+
74
+ Args:
75
+ capability: Skill name (e.g., "kubectl", "aws_cli", "python")
76
+ limit: Maximum agents to return (default: 10)
77
+
78
+ Returns:
79
+ JSON string with matching agents:
80
+ [
81
+ {
82
+ "id": "agent-123",
83
+ "name": "DevOps Agent",
84
+ "description": "Handles K8s deployments",
85
+ "model_id": "claude-sonnet-4",
86
+ "skills": ["kubectl", "helm", "aws_cli"],
87
+ "has_secrets": ["KUBECONFIG", "AWS_ACCESS_KEY_ID"],
88
+ "has_env_vars": ["AWS_REGION"],
89
+ "status": "active"
90
+ },
91
+ ...
92
+ ]
93
+
94
+ Example:
95
+ AI: "I need to deploy to Kubernetes"
96
+ AI calls: search_agents_with_capability("kubectl")
97
+ Returns: Agents with kubectl skill
98
+ """
99
+ try:
100
+ logger.info(
101
+ "searching_agents_by_capability",
102
+ capability=capability,
103
+ limit=limit,
104
+ organization_id=self.organization_id
105
+ )
106
+
107
+ # Query context graph for agents with this skill
108
+ query = """
109
+ MATCH (a:Agent)-[:HAS_SKILL]->(s:Skill {name: $capability})
110
+ WHERE a.organization_id = $org_id
111
+ AND a.status = 'active'
112
+ OPTIONAL MATCH (a)-[:HAS_SKILL]->(other_skill:Skill)
113
+ OPTIONAL MATCH (a)-[:HAS_SECRET]->(secret:Secret)
114
+ OPTIONAL MATCH (a)-[:HAS_ENV_VAR]->(env:EnvVar)
115
+ RETURN
116
+ a.id as agent_id,
117
+ a.name as agent_name,
118
+ a.description as description,
119
+ a.model_id as model_id,
120
+ a.status as status,
121
+ collect(DISTINCT other_skill.name) as skills,
122
+ collect(DISTINCT secret.name) as secrets,
123
+ collect(DISTINCT env.name) as env_vars
124
+ LIMIT $limit
125
+ """
126
+
127
+ result = await self.graph_client.execute_query(
128
+ query=query,
129
+ parameters={
130
+ "capability": capability,
131
+ "org_id": self.organization_id,
132
+ "limit": limit
133
+ }
134
+ )
135
+
136
+ agents = []
137
+ for record in result.get("data", []):
138
+ agents.append({
139
+ "id": record["agent_id"],
140
+ "name": record["agent_name"],
141
+ "description": record["description"] or "",
142
+ "model_id": record["model_id"],
143
+ "skills": [s for s in record["skills"] if s],
144
+ "has_secrets": [s for s in record["secrets"] if s],
145
+ "has_env_vars": [e for e in record["env_vars"] if e],
146
+ "status": record["status"]
147
+ })
148
+
149
+ logger.info(
150
+ "agents_found_by_capability",
151
+ capability=capability,
152
+ count=len(agents)
153
+ )
154
+
155
+ return self._format_list_response(
156
+ agents,
157
+ f"Agents with '{capability}' capability",
158
+ ["name", "skills", "model_id", "description"]
159
+ )
160
+
161
+ except Exception as e:
162
+ logger.error(
163
+ "search_agents_error",
164
+ capability=capability,
165
+ error=str(e)
166
+ )
167
+ return f"Error searching agents: {str(e)}"
168
+
169
+ async def search_teams_with_capability(
170
+ self,
171
+ capability: str,
172
+ limit: int = 5
173
+ ) -> str:
174
+ """
175
+ Search for teams that have agents with a specific capability.
176
+
177
+ Args:
178
+ capability: Skill name needed
179
+ limit: Maximum teams to return
180
+
181
+ Returns:
182
+ JSON string with matching teams and their agent summaries
183
+
184
+ Example:
185
+ AI: "I need a team for multi-step deployment"
186
+ AI calls: search_teams_with_capability("kubernetes")
187
+ Returns: Teams with kubernetes-capable agents
188
+ """
189
+ try:
190
+ logger.info(
191
+ "searching_teams_by_capability",
192
+ capability=capability,
193
+ limit=limit,
194
+ organization_id=self.organization_id
195
+ )
196
+
197
+ query = """
198
+ MATCH (t:Team)-[:HAS_MEMBER]->(a:Agent)-[:HAS_SKILL]->(s:Skill {name: $capability})
199
+ WHERE t.organization_id = $org_id
200
+ AND t.status = 'active'
201
+ WITH t, collect(DISTINCT a.name) as agent_names, count(DISTINCT a) as agent_count
202
+ RETURN
203
+ t.id as team_id,
204
+ t.name as team_name,
205
+ t.description as description,
206
+ agent_names,
207
+ agent_count
208
+ LIMIT $limit
209
+ """
210
+
211
+ result = await self.graph_client.execute_query(
212
+ query=query,
213
+ parameters={
214
+ "capability": capability,
215
+ "org_id": self.organization_id,
216
+ "limit": limit
217
+ }
218
+ )
219
+
220
+ teams = []
221
+ for record in result.get("data", []):
222
+ teams.append({
223
+ "id": record["team_id"],
224
+ "name": record["team_name"],
225
+ "description": record["description"] or "",
226
+ "agent_count": record["agent_count"],
227
+ "agents": record["agent_names"][:5] # Show first 5
228
+ })
229
+
230
+ logger.info(
231
+ "teams_found_by_capability",
232
+ capability=capability,
233
+ count=len(teams)
234
+ )
235
+
236
+ return self._format_list_response(
237
+ teams,
238
+ f"Teams with '{capability}' capability",
239
+ ["name", "agent_count", "agents", "description"]
240
+ )
241
+
242
+ except Exception as e:
243
+ logger.error("search_teams_error", capability=capability, error=str(e))
244
+ return f"Error searching teams: {str(e)}"
245
+
246
+ async def get_agent_full_details(
247
+ self,
248
+ agent_id: str
249
+ ) -> str:
250
+ """
251
+ Get complete details for a specific agent.
252
+
253
+ Use this AFTER finding relevant agents to get full execution environment details.
254
+
255
+ Args:
256
+ agent_id: Agent ID to fetch
257
+
258
+ Returns:
259
+ JSON string with full agent details including:
260
+ - All skills with configurations
261
+ - All secrets (names only)
262
+ - All environment variables
263
+ - Execution environment settings
264
+ - Projects and environments
265
+
266
+ Example:
267
+ AI: "I found agent-123 with kubectl, let me get full details"
268
+ AI calls: get_agent_full_details("agent-123")
269
+ Returns: Complete agent config including secrets, env vars, etc.
270
+ """
271
+ try:
272
+ logger.info(
273
+ "getting_agent_full_details",
274
+ agent_id=agent_id,
275
+ organization_id=self.organization_id
276
+ )
277
+
278
+ # Fetch from database with full relationships
279
+ db = self._get_db()
280
+ agent = db.execute(
281
+ select(Agent)
282
+ .options(
283
+ selectinload(Agent.team),
284
+ selectinload(Agent.project),
285
+ selectinload(Agent.environment)
286
+ )
287
+ .where(
288
+ Agent.id == agent_id,
289
+ Agent.organization_id == self.organization_id
290
+ )
291
+ ).scalar_one_or_none()
292
+
293
+ if not agent:
294
+ return f"Agent {agent_id} not found"
295
+
296
+ # Build complete details
297
+ details = {
298
+ "id": str(agent.id),
299
+ "name": agent.name,
300
+ "description": agent.description,
301
+ "model_id": agent.model_id,
302
+ "status": agent.status,
303
+ "capabilities": agent.capabilities or [],
304
+ "runtime": agent.runtime,
305
+ "execution_environment": {
306
+ "secrets": {},
307
+ "env_vars": {},
308
+ "integration_ids": []
309
+ }
310
+ }
311
+
312
+ # Add execution environment
313
+ if agent.execution_environment:
314
+ exec_env = agent.execution_environment
315
+
316
+ # Show secret names only, not values (security)
317
+ if isinstance(exec_env, dict):
318
+ if exec_env.get("secrets"):
319
+ details["execution_environment"]["secrets"] = {
320
+ k: "***" for k in exec_env["secrets"].keys()
321
+ }
322
+ if exec_env.get("env_vars"):
323
+ details["execution_environment"]["env_vars"] = exec_env["env_vars"]
324
+ if exec_env.get("integration_ids"):
325
+ details["execution_environment"]["integration_ids"] = exec_env["integration_ids"]
326
+
327
+ # Add team info
328
+ if agent.team:
329
+ details["team"] = {
330
+ "id": str(agent.team.id),
331
+ "name": agent.team.name
332
+ }
333
+
334
+ # Add project info
335
+ if agent.project:
336
+ details["project"] = {
337
+ "id": str(agent.project.id),
338
+ "name": agent.project.name
339
+ }
340
+
341
+ # Add environment info
342
+ if agent.environment:
343
+ details["environment"] = {
344
+ "id": str(agent.environment.id),
345
+ "name": agent.environment.name
346
+ }
347
+
348
+ logger.info(
349
+ "agent_full_details_fetched",
350
+ agent_id=agent_id,
351
+ agent_name=agent.name
352
+ )
353
+
354
+ return self._format_detail_response(details, f"Agent: {agent.name}")
355
+
356
+ except Exception as e:
357
+ logger.error("get_agent_details_error", agent_id=agent_id, error=str(e))
358
+ return f"Error fetching agent details: {str(e)}"
359
+
360
+ async def search_context_graph(
361
+ self,
362
+ label: Optional[str] = None,
363
+ property_name: Optional[str] = None,
364
+ property_value: Optional[str] = None,
365
+ text_search: Optional[str] = None,
366
+ limit: int = 20
367
+ ) -> str:
368
+ """
369
+ Generic context graph search for discovering relevant resources.
370
+
371
+ Args:
372
+ label: Node label (e.g., "Service", "Repository", "User")
373
+ property_name: Property to filter on
374
+ property_value: Value to match
375
+ text_search: Free-text search across properties
376
+ limit: Maximum results
377
+
378
+ Returns:
379
+ JSON string with matching nodes
380
+
381
+ Examples:
382
+ - Find services: search_context_graph(label="Service")
383
+ - Find prod services: search_context_graph(label="Service", property_name="environment", property_value="production")
384
+ - Text search: search_context_graph(text_search="kubernetes deployment")
385
+ """
386
+ try:
387
+ logger.info(
388
+ "searching_context_graph",
389
+ label=label,
390
+ property_name=property_name,
391
+ text_search=text_search,
392
+ organization_id=self.organization_id
393
+ )
394
+
395
+ if text_search:
396
+ result = await self.graph_client.search_by_text(
397
+ search_text=text_search,
398
+ label=label,
399
+ limit=limit
400
+ )
401
+ else:
402
+ result = await self.graph_client.search_nodes(
403
+ label=label,
404
+ property_name=property_name,
405
+ property_value=property_value,
406
+ limit=limit
407
+ )
408
+
409
+ nodes = result.get("nodes", [])
410
+
411
+ logger.info(
412
+ "context_graph_search_complete",
413
+ label=label,
414
+ count=len(nodes)
415
+ )
416
+
417
+ return self._format_list_response(
418
+ nodes,
419
+ f"Context graph search results",
420
+ ["label", "properties"]
421
+ )
422
+
423
+ except Exception as e:
424
+ logger.error("context_graph_search_error", error=str(e))
425
+ return f"Error searching context graph: {str(e)}"
426
+
427
+ async def get_available_capabilities(self) -> str:
428
+ """
429
+ List all available capabilities (skills) in the organization.
430
+
431
+ Returns:
432
+ JSON string with skill names and usage counts
433
+
434
+ Example:
435
+ AI: "What capabilities are available?"
436
+ AI calls: get_available_capabilities()
437
+ Returns: ["kubectl", "aws_cli", "python", "terraform", ...]
438
+ AI can then search for agents with specific capabilities
439
+ """
440
+ try:
441
+ logger.info(
442
+ "getting_available_capabilities",
443
+ organization_id=self.organization_id
444
+ )
445
+
446
+ query = """
447
+ MATCH (s:Skill)<-[:HAS_SKILL]-(a:Agent)
448
+ WHERE a.organization_id = $org_id
449
+ AND a.status = 'active'
450
+ RETURN s.name as skill_name, count(a) as agent_count
451
+ ORDER BY agent_count DESC
452
+ LIMIT 50
453
+ """
454
+
455
+ result = await self.graph_client.execute_query(
456
+ query=query,
457
+ parameters={"org_id": self.organization_id}
458
+ )
459
+
460
+ capabilities = [
461
+ {
462
+ "skill": record["skill_name"],
463
+ "agent_count": record["agent_count"]
464
+ }
465
+ for record in result.get("data", [])
466
+ ]
467
+
468
+ logger.info(
469
+ "capabilities_fetched",
470
+ count=len(capabilities)
471
+ )
472
+
473
+ return self._format_list_response(
474
+ capabilities,
475
+ "Available capabilities",
476
+ ["skill", "agent_count"]
477
+ )
478
+
479
+ except Exception as e:
480
+ logger.error("get_capabilities_error", error=str(e))
481
+ return f"Error fetching capabilities: {str(e)}"
482
+
483
+ async def discover_agents_by_task(
484
+ self,
485
+ task_description: str,
486
+ limit: int = 5
487
+ ) -> str:
488
+ """
489
+ Intelligent agent discovery based on task description.
490
+
491
+ Uses text search across agent names, descriptions, and capabilities
492
+ to find relevant agents for a given task.
493
+
494
+ Args:
495
+ task_description: Description of the task (e.g., "deploy to kubernetes")
496
+ limit: Maximum agents to return
497
+
498
+ Returns:
499
+ JSON string with matching agents
500
+
501
+ Example:
502
+ AI: "Task: Deploy app to production Kubernetes cluster"
503
+ AI calls: discover_agents_by_task("deploy to kubernetes")
504
+ Returns: Agents with kubernetes-related skills and descriptions
505
+ """
506
+ try:
507
+ logger.info(
508
+ "discovering_agents_by_task",
509
+ task_description=task_description[:100],
510
+ organization_id=self.organization_id
511
+ )
512
+
513
+ # Search context graph using text search
514
+ result = await self.graph_client.search_by_text(
515
+ search_text=task_description,
516
+ label="Agent",
517
+ limit=limit
518
+ )
519
+
520
+ agents = []
521
+ for node in result.get("nodes", []):
522
+ props = node.get("properties", {})
523
+ if props.get("status") == "active":
524
+ agents.append({
525
+ "id": props.get("id"),
526
+ "name": props.get("name"),
527
+ "description": props.get("description", ""),
528
+ "model_id": props.get("model_id"),
529
+ "status": props.get("status")
530
+ })
531
+
532
+ logger.info(
533
+ "agents_discovered_by_task",
534
+ count=len(agents)
535
+ )
536
+
537
+ return self._format_list_response(
538
+ agents,
539
+ f"Agents matching task: {task_description[:50]}...",
540
+ ["name", "description", "model_id"]
541
+ )
542
+
543
+ except Exception as e:
544
+ logger.error("discover_agents_by_task_error", error=str(e))
545
+ return f"Error discovering agents: {str(e)}"