agent-devkit 0.1.6 → 0.2.0

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 (551) hide show
  1. package/README.md +13 -1
  2. package/package.json +1 -1
  3. package/runtime/README.md +53 -1
  4. package/runtime/agent +5 -0
  5. package/runtime/agents/README.md +26 -0
  6. package/runtime/agents/agent-devkit-agent-builder/AGENTS.md +24 -0
  7. package/runtime/agents/agent-devkit-agent-builder/README.md +37 -0
  8. package/runtime/agents/agent-devkit-agent-builder/agent.yaml +46 -0
  9. package/runtime/agents/agent-devkit-agent-builder/capabilities/plan-agent/capability.yaml +29 -0
  10. package/runtime/agents/agent-devkit-agent-builder/capabilities/plan-agent/decision-rules.md +7 -0
  11. package/runtime/agents/agent-devkit-agent-builder/capabilities/plan-agent/runner.py +33 -0
  12. package/runtime/agents/agent-devkit-agent-builder/capabilities/plan-agent/workflow.md +8 -0
  13. package/runtime/agents/agent-devkit-agent-builder/capabilities/scaffold-agent/capability.yaml +31 -0
  14. package/runtime/agents/agent-devkit-agent-builder/capabilities/scaffold-agent/decision-rules.md +9 -0
  15. package/runtime/agents/agent-devkit-agent-builder/capabilities/scaffold-agent/runner.py +39 -0
  16. package/runtime/agents/agent-devkit-agent-builder/capabilities/scaffold-agent/workflow.md +8 -0
  17. package/runtime/agents/agent-devkit-agent-builder/capabilities/validate-agent-contract/capability.yaml +28 -0
  18. package/runtime/agents/agent-devkit-agent-builder/capabilities/validate-agent-contract/decision-rules.md +6 -0
  19. package/runtime/agents/agent-devkit-agent-builder/capabilities/validate-agent-contract/runner.py +33 -0
  20. package/runtime/agents/agent-devkit-agent-builder/capabilities/validate-agent-contract/workflow.md +7 -0
  21. package/runtime/agents/agent-devkit-agent-builder/infra/integrations/agent-devkit/agent_builder_repository.py +527 -0
  22. package/runtime/agents/agent-devkit-agent-builder/knowledge/context.md +15 -0
  23. package/runtime/agents/agent-devkit-agent-builder/knowledge/policies.yaml +11 -0
  24. package/runtime/agents/agent-devkit-agent-builder/knowledge/system.md +11 -0
  25. package/runtime/agents/agent-devkit-agent-builder/templates/agent-plan-output.md +20 -0
  26. package/runtime/agents/agent-devkit-agent-builder/templates/scaffold-plan-output.md +13 -0
  27. package/runtime/agents/agent-devkit-agent-builder/templates/validation-report-output.md +13 -0
  28. package/runtime/agents/agent-devkit-agent-builder/tests/test_runners.py +188 -0
  29. package/runtime/agents/automation-architect/AGENTS.md +11 -0
  30. package/runtime/agents/automation-architect/README.md +27 -0
  31. package/runtime/agents/automation-architect/agent.yaml +57 -0
  32. package/runtime/agents/automation-architect/capabilities/classify-automation-request/capability.yaml +35 -0
  33. package/runtime/agents/automation-architect/capabilities/classify-automation-request/decision-rules.md +10 -0
  34. package/runtime/agents/automation-architect/capabilities/classify-automation-request/runner.py +37 -0
  35. package/runtime/agents/automation-architect/capabilities/classify-automation-request/workflow.md +7 -0
  36. package/runtime/agents/automation-architect/capabilities/delegate-automation-build/capability.yaml +34 -0
  37. package/runtime/agents/automation-architect/capabilities/delegate-automation-build/decision-rules.md +7 -0
  38. package/runtime/agents/automation-architect/capabilities/delegate-automation-build/runner.py +37 -0
  39. package/runtime/agents/automation-architect/capabilities/delegate-automation-build/workflow.md +6 -0
  40. package/runtime/agents/automation-architect/capabilities/plan-automation-solution/capability.yaml +35 -0
  41. package/runtime/agents/automation-architect/capabilities/plan-automation-solution/decision-rules.md +7 -0
  42. package/runtime/agents/automation-architect/capabilities/plan-automation-solution/runner.py +37 -0
  43. package/runtime/agents/automation-architect/capabilities/plan-automation-solution/workflow.md +7 -0
  44. package/runtime/agents/automation-architect/capabilities/review-automation-solution/capability.yaml +36 -0
  45. package/runtime/agents/automation-architect/capabilities/review-automation-solution/decision-rules.md +7 -0
  46. package/runtime/agents/automation-architect/capabilities/review-automation-solution/runner.py +39 -0
  47. package/runtime/agents/automation-architect/capabilities/review-automation-solution/workflow.md +7 -0
  48. package/runtime/agents/automation-architect/infra/integrations/automation-architecture/automation_architecture_repository.py +481 -0
  49. package/runtime/agents/automation-architect/knowledge/context.md +22 -0
  50. package/runtime/agents/automation-architect/knowledge/policies.yaml +20 -0
  51. package/runtime/agents/automation-architect/knowledge/system.md +8 -0
  52. package/runtime/agents/automation-architect/templates/automation-classification.md +6 -0
  53. package/runtime/agents/automation-architect/templates/automation-plan.md +5 -0
  54. package/runtime/agents/automation-architect/tests/test_runners.py +135 -0
  55. package/runtime/agents/aws-architecture-analyst/agent.yaml +17 -4
  56. package/runtime/agents/aws-cloudwatch-log-analyzer/agent.yaml +12 -2
  57. package/runtime/agents/aws-cloudwatch-log-analyzer/capabilities/analyze-service-error/capability.yaml +16 -0
  58. package/runtime/agents/aws-lambda-builder/AGENTS.md +27 -0
  59. package/runtime/agents/aws-lambda-builder/README.md +21 -0
  60. package/runtime/agents/aws-lambda-builder/agent.yaml +46 -0
  61. package/runtime/agents/aws-lambda-builder/capabilities/deploy-lambda-plan/capability.yaml +18 -0
  62. package/runtime/agents/aws-lambda-builder/capabilities/deploy-lambda-plan/decision-rules.md +6 -0
  63. package/runtime/agents/aws-lambda-builder/capabilities/deploy-lambda-plan/runner.py +33 -0
  64. package/runtime/agents/aws-lambda-builder/capabilities/deploy-lambda-plan/workflow.md +6 -0
  65. package/runtime/agents/aws-lambda-builder/capabilities/generate-lambda-project/capability.yaml +20 -0
  66. package/runtime/agents/aws-lambda-builder/capabilities/generate-lambda-project/decision-rules.md +6 -0
  67. package/runtime/agents/aws-lambda-builder/capabilities/generate-lambda-project/runner.py +39 -0
  68. package/runtime/agents/aws-lambda-builder/capabilities/generate-lambda-project/workflow.md +7 -0
  69. package/runtime/agents/aws-lambda-builder/capabilities/package-lambda/capability.yaml +22 -0
  70. package/runtime/agents/aws-lambda-builder/capabilities/package-lambda/decision-rules.md +6 -0
  71. package/runtime/agents/aws-lambda-builder/capabilities/package-lambda/runner.py +41 -0
  72. package/runtime/agents/aws-lambda-builder/capabilities/package-lambda/workflow.md +6 -0
  73. package/runtime/agents/aws-lambda-builder/capabilities/plan-lambda/capability.yaml +18 -0
  74. package/runtime/agents/aws-lambda-builder/capabilities/plan-lambda/decision-rules.md +7 -0
  75. package/runtime/agents/aws-lambda-builder/capabilities/plan-lambda/runner.py +33 -0
  76. package/runtime/agents/aws-lambda-builder/capabilities/plan-lambda/workflow.md +6 -0
  77. package/runtime/agents/aws-lambda-builder/capabilities/review-lambda-security/capability.yaml +18 -0
  78. package/runtime/agents/aws-lambda-builder/capabilities/review-lambda-security/decision-rules.md +7 -0
  79. package/runtime/agents/aws-lambda-builder/capabilities/review-lambda-security/runner.py +33 -0
  80. package/runtime/agents/aws-lambda-builder/capabilities/review-lambda-security/workflow.md +5 -0
  81. package/runtime/agents/aws-lambda-builder/infra/integrations/aws-lambda/aws_lambda_repository.py +688 -0
  82. package/runtime/agents/aws-lambda-builder/knowledge/context.md +12 -0
  83. package/runtime/agents/aws-lambda-builder/knowledge/policies.yaml +23 -0
  84. package/runtime/agents/aws-lambda-builder/knowledge/system.md +10 -0
  85. package/runtime/agents/aws-lambda-builder/templates/lambda-deploy-plan.md +3 -0
  86. package/runtime/agents/aws-lambda-builder/templates/lambda-package.md +3 -0
  87. package/runtime/agents/aws-lambda-builder/templates/lambda-plan.md +3 -0
  88. package/runtime/agents/aws-lambda-builder/templates/lambda-readme.md +3 -0
  89. package/runtime/agents/aws-lambda-builder/templates/lambda-security-review.md +3 -0
  90. package/runtime/agents/aws-lambda-builder/tests/test_runners.py +355 -0
  91. package/runtime/agents/aws-operations-operator/agent.yaml +18 -6
  92. package/runtime/agents/aws-security-governance-auditor/agent.yaml +17 -5
  93. package/runtime/agents/azure-devops-orchestrator/agent.yaml +15 -2
  94. package/runtime/agents/azure-devops-orchestrator/capabilities/read-card/capability.yaml +29 -0
  95. package/runtime/agents/bpo-analyser/agent.yaml +12 -2
  96. package/runtime/agents/bpo-analyser/knowledge/policies.yaml +2 -2
  97. package/runtime/agents/data-scientist-analyst/agent.yaml +16 -4
  98. package/runtime/agents/data-scientist-analyst/capabilities/generate-data-report/capability.yaml +1 -1
  99. package/runtime/agents/data-scientist-analyst/capabilities/generate-reconciliation-report/capability.yaml +1 -1
  100. package/runtime/agents/data-scientist-analyst/capabilities/run-data-pipeline/capability.yaml +1 -1
  101. package/runtime/agents/data-scientist-analyst/infra/integrations/agent-bridge/methods/analyze-sql-source.yaml +1 -1
  102. package/runtime/agents/data-scientist-analyst/knowledge/policies.yaml +4 -4
  103. package/runtime/agents/data-scientist-analyst/knowledge/system.md +1 -1
  104. package/runtime/agents/data-scientist-analyst/tests/test_runners.py +1 -1
  105. package/runtime/agents/database-change-operator/agent.yaml +12 -1
  106. package/runtime/agents/docker-container-builder/AGENTS.md +27 -0
  107. package/runtime/agents/docker-container-builder/README.md +21 -0
  108. package/runtime/agents/docker-container-builder/agent.yaml +52 -0
  109. package/runtime/agents/docker-container-builder/capabilities/analyze-containerization-target/capability.yaml +18 -0
  110. package/runtime/agents/docker-container-builder/capabilities/analyze-containerization-target/decision-rules.md +6 -0
  111. package/runtime/agents/docker-container-builder/capabilities/analyze-containerization-target/runner.py +32 -0
  112. package/runtime/agents/docker-container-builder/capabilities/analyze-containerization-target/workflow.md +6 -0
  113. package/runtime/agents/docker-container-builder/capabilities/generate-compose/capability.yaml +18 -0
  114. package/runtime/agents/docker-container-builder/capabilities/generate-compose/decision-rules.md +7 -0
  115. package/runtime/agents/docker-container-builder/capabilities/generate-compose/runner.py +32 -0
  116. package/runtime/agents/docker-container-builder/capabilities/generate-compose/workflow.md +6 -0
  117. package/runtime/agents/docker-container-builder/capabilities/generate-container-project-files/capability.yaml +20 -0
  118. package/runtime/agents/docker-container-builder/capabilities/generate-container-project-files/decision-rules.md +7 -0
  119. package/runtime/agents/docker-container-builder/capabilities/generate-container-project-files/runner.py +38 -0
  120. package/runtime/agents/docker-container-builder/capabilities/generate-container-project-files/workflow.md +7 -0
  121. package/runtime/agents/docker-container-builder/capabilities/generate-dockerfile/capability.yaml +18 -0
  122. package/runtime/agents/docker-container-builder/capabilities/generate-dockerfile/decision-rules.md +6 -0
  123. package/runtime/agents/docker-container-builder/capabilities/generate-dockerfile/runner.py +32 -0
  124. package/runtime/agents/docker-container-builder/capabilities/generate-dockerfile/workflow.md +7 -0
  125. package/runtime/agents/docker-container-builder/capabilities/plan-image-build/capability.yaml +18 -0
  126. package/runtime/agents/docker-container-builder/capabilities/plan-image-build/decision-rules.md +6 -0
  127. package/runtime/agents/docker-container-builder/capabilities/plan-image-build/runner.py +32 -0
  128. package/runtime/agents/docker-container-builder/capabilities/plan-image-build/workflow.md +6 -0
  129. package/runtime/agents/docker-container-builder/capabilities/review-docker-security/capability.yaml +21 -0
  130. package/runtime/agents/docker-container-builder/capabilities/review-docker-security/decision-rules.md +6 -0
  131. package/runtime/agents/docker-container-builder/capabilities/review-docker-security/runner.py +43 -0
  132. package/runtime/agents/docker-container-builder/capabilities/review-docker-security/workflow.md +5 -0
  133. package/runtime/agents/docker-container-builder/infra/integrations/docker-container/docker_container_repository.py +837 -0
  134. package/runtime/agents/docker-container-builder/knowledge/context.md +21 -0
  135. package/runtime/agents/docker-container-builder/knowledge/policies.yaml +13 -0
  136. package/runtime/agents/docker-container-builder/knowledge/system.md +21 -0
  137. package/runtime/agents/docker-container-builder/templates/container-plan.md +4 -0
  138. package/runtime/agents/docker-container-builder/templates/container-review.md +4 -0
  139. package/runtime/agents/docker-container-builder/templates/docker-compose.md +5 -0
  140. package/runtime/agents/docker-container-builder/templates/docker-readme.md +3 -0
  141. package/runtime/agents/docker-container-builder/templates/dockerfile.md +5 -0
  142. package/runtime/agents/docker-container-builder/tests/test_runners.py +255 -0
  143. package/runtime/agents/drawio-diagram-builder/agent.yaml +11 -2
  144. package/runtime/agents/drawio-diagram-builder/capabilities/execute-diagram-delivery/capability.yaml +1 -1
  145. package/runtime/agents/drawio-diagram-builder/capabilities/read-azure-card-context/capability.yaml +1 -1
  146. package/runtime/agents/elasticsearch-log-analyzer/agent.yaml +14 -2
  147. package/runtime/agents/elasticsearch-log-analyzer/capabilities/analyze-service-errors/capability.yaml +14 -0
  148. package/runtime/agents/excel-workbook-builder/agent.yaml +10 -0
  149. package/runtime/agents/excel-workbook-builder/capabilities/create-template/capability.yaml +1 -1
  150. package/runtime/agents/excel-workbook-builder/capabilities/create-template/workflow.md +1 -1
  151. package/runtime/agents/excel-workbook-builder/capabilities/create-template-version/capability.yaml +1 -1
  152. package/runtime/agents/excel-workbook-builder/capabilities/generate-template-input-file/capability.yaml +1 -2
  153. package/runtime/agents/excel-workbook-builder/capabilities/refine-template/capability.yaml +1 -1
  154. package/runtime/agents/excel-workbook-builder/capabilities/register-template/capability.yaml +1 -2
  155. package/runtime/agents/excel-workbook-builder/capabilities/register-template/workflow.md +1 -1
  156. package/runtime/agents/execution-loop-builder/AGENTS.md +24 -0
  157. package/runtime/agents/execution-loop-builder/README.md +19 -0
  158. package/runtime/agents/execution-loop-builder/agent.yaml +49 -0
  159. package/runtime/agents/execution-loop-builder/capabilities/generate-loop-project-files/capability.yaml +20 -0
  160. package/runtime/agents/execution-loop-builder/capabilities/generate-loop-project-files/decision-rules.md +6 -0
  161. package/runtime/agents/execution-loop-builder/capabilities/generate-loop-project-files/runner.py +38 -0
  162. package/runtime/agents/execution-loop-builder/capabilities/generate-loop-project-files/workflow.md +7 -0
  163. package/runtime/agents/execution-loop-builder/capabilities/generate-loop-runner/capability.yaml +18 -0
  164. package/runtime/agents/execution-loop-builder/capabilities/generate-loop-runner/decision-rules.md +5 -0
  165. package/runtime/agents/execution-loop-builder/capabilities/generate-loop-runner/runner.py +32 -0
  166. package/runtime/agents/execution-loop-builder/capabilities/generate-loop-runner/workflow.md +6 -0
  167. package/runtime/agents/execution-loop-builder/capabilities/plan-execution-loop/capability.yaml +18 -0
  168. package/runtime/agents/execution-loop-builder/capabilities/plan-execution-loop/decision-rules.md +6 -0
  169. package/runtime/agents/execution-loop-builder/capabilities/plan-execution-loop/runner.py +32 -0
  170. package/runtime/agents/execution-loop-builder/capabilities/plan-execution-loop/workflow.md +6 -0
  171. package/runtime/agents/execution-loop-builder/capabilities/register-loop-task/capability.yaml +19 -0
  172. package/runtime/agents/execution-loop-builder/capabilities/register-loop-task/decision-rules.md +6 -0
  173. package/runtime/agents/execution-loop-builder/capabilities/register-loop-task/runner.py +36 -0
  174. package/runtime/agents/execution-loop-builder/capabilities/register-loop-task/workflow.md +6 -0
  175. package/runtime/agents/execution-loop-builder/capabilities/review-loop-safety/capability.yaml +19 -0
  176. package/runtime/agents/execution-loop-builder/capabilities/review-loop-safety/decision-rules.md +6 -0
  177. package/runtime/agents/execution-loop-builder/capabilities/review-loop-safety/runner.py +39 -0
  178. package/runtime/agents/execution-loop-builder/capabilities/review-loop-safety/workflow.md +5 -0
  179. package/runtime/agents/execution-loop-builder/infra/integrations/execution-loop/execution_loop_repository.py +608 -0
  180. package/runtime/agents/execution-loop-builder/knowledge/context.md +26 -0
  181. package/runtime/agents/execution-loop-builder/knowledge/policies.yaml +13 -0
  182. package/runtime/agents/execution-loop-builder/knowledge/system.md +19 -0
  183. package/runtime/agents/execution-loop-builder/templates/loop-plan.md +3 -0
  184. package/runtime/agents/execution-loop-builder/templates/loop-readme.md +3 -0
  185. package/runtime/agents/execution-loop-builder/templates/loop-review.md +3 -0
  186. package/runtime/agents/execution-loop-builder/templates/loop-runner.py +2 -0
  187. package/runtime/agents/execution-loop-builder/tests/test_runners.py +274 -0
  188. package/runtime/agents/execution-reviewer/agent.yaml +6 -4
  189. package/runtime/agents/execution-reviewer/capabilities/review-agent-result/capability.yaml +1 -2
  190. package/runtime/agents/execution-reviewer/capabilities/review-final-output/capability.yaml +1 -2
  191. package/runtime/agents/execution-reviewer/capabilities/review-plan/capability.yaml +1 -2
  192. package/runtime/agents/figma-ui-ux-product-designer/agent.yaml +17 -5
  193. package/runtime/agents/figma-ui-ux-product-designer/capabilities/analyze-product-context/capability.yaml +1 -1
  194. package/runtime/agents/figma-ui-ux-product-designer/capabilities/conduct-design-interview/capability.yaml +1 -1
  195. package/runtime/agents/figma-ui-ux-product-designer/capabilities/conduct-design-review-session/capability.yaml +1 -1
  196. package/runtime/agents/figma-ui-ux-product-designer/capabilities/generate-dev-handoff/capability.yaml +1 -1
  197. package/runtime/agents/figma-ui-ux-product-designer/capabilities/generate-user-journey-diagram/capability.yaml +1 -1
  198. package/runtime/agents/figma-ui-ux-product-designer/capabilities/ingest-design-source/capability.yaml +1 -1
  199. package/runtime/agents/figma-ui-ux-product-designer/capabilities/triage-design-feedback/capability.yaml +1 -1
  200. package/runtime/agents/generic-agent-builder/AGENTS.md +20 -0
  201. package/runtime/agents/generic-agent-builder/README.md +40 -0
  202. package/runtime/agents/generic-agent-builder/agent.yaml +43 -0
  203. package/runtime/agents/generic-agent-builder/capabilities/generate-agent-instructions/capability.yaml +18 -0
  204. package/runtime/agents/generic-agent-builder/capabilities/generate-agent-instructions/decision-rules.md +5 -0
  205. package/runtime/agents/generic-agent-builder/capabilities/generate-agent-instructions/runner.py +33 -0
  206. package/runtime/agents/generic-agent-builder/capabilities/generate-agent-instructions/workflow.md +6 -0
  207. package/runtime/agents/generic-agent-builder/capabilities/generate-project-agent-files/capability.yaml +20 -0
  208. package/runtime/agents/generic-agent-builder/capabilities/generate-project-agent-files/decision-rules.md +6 -0
  209. package/runtime/agents/generic-agent-builder/capabilities/generate-project-agent-files/runner.py +39 -0
  210. package/runtime/agents/generic-agent-builder/capabilities/generate-project-agent-files/workflow.md +7 -0
  211. package/runtime/agents/generic-agent-builder/capabilities/generate-skill/capability.yaml +18 -0
  212. package/runtime/agents/generic-agent-builder/capabilities/generate-skill/decision-rules.md +5 -0
  213. package/runtime/agents/generic-agent-builder/capabilities/generate-skill/runner.py +33 -0
  214. package/runtime/agents/generic-agent-builder/capabilities/generate-skill/workflow.md +5 -0
  215. package/runtime/agents/generic-agent-builder/capabilities/plan-generic-agent/capability.yaml +18 -0
  216. package/runtime/agents/generic-agent-builder/capabilities/plan-generic-agent/decision-rules.md +6 -0
  217. package/runtime/agents/generic-agent-builder/capabilities/plan-generic-agent/runner.py +33 -0
  218. package/runtime/agents/generic-agent-builder/capabilities/plan-generic-agent/workflow.md +6 -0
  219. package/runtime/agents/generic-agent-builder/capabilities/review-generic-agent/capability.yaml +20 -0
  220. package/runtime/agents/generic-agent-builder/capabilities/review-generic-agent/decision-rules.md +6 -0
  221. package/runtime/agents/generic-agent-builder/capabilities/review-generic-agent/runner.py +40 -0
  222. package/runtime/agents/generic-agent-builder/capabilities/review-generic-agent/workflow.md +7 -0
  223. package/runtime/agents/generic-agent-builder/infra/integrations/generic-agent/generic_agent_repository.py +445 -0
  224. package/runtime/agents/generic-agent-builder/knowledge/context.md +11 -0
  225. package/runtime/agents/generic-agent-builder/knowledge/policies.yaml +12 -0
  226. package/runtime/agents/generic-agent-builder/knowledge/system.md +17 -0
  227. package/runtime/agents/generic-agent-builder/templates/generic-agent-instructions.md +17 -0
  228. package/runtime/agents/generic-agent-builder/templates/generic-review-report.md +13 -0
  229. package/runtime/agents/generic-agent-builder/templates/generic-skill.md +14 -0
  230. package/runtime/agents/generic-agent-builder/tests/test_runners.py +220 -0
  231. package/runtime/agents/github-pr-reviewer/agent.yaml +17 -5
  232. package/runtime/agents/github-pr-reviewer/capabilities/create-review-automation/capability.yaml +1 -1
  233. package/runtime/agents/github-pr-reviewer/capabilities/inspect-pr/capability.yaml +1 -1
  234. package/runtime/agents/github-pr-reviewer/capabilities/list-review-requests/capability.yaml +1 -1
  235. package/runtime/agents/github-pr-reviewer/capabilities/review-pr-diff/capability.yaml +1 -1
  236. package/runtime/agents/knowledge-generator/agent.yaml +13 -3
  237. package/runtime/agents/knowledge-generator/capabilities/generate-knowledge/capability.yaml +1 -1
  238. package/runtime/agents/local-llm-operator/agent.yaml +6 -4
  239. package/runtime/agents/local-llm-operator/capabilities/delegate-operational-task/capability.yaml +1 -2
  240. package/runtime/agents/local-llm-operator/capabilities/inspect-local-models/capability.yaml +1 -2
  241. package/runtime/agents/local-llm-operator/capabilities/select-local-worker/capability.yaml +1 -2
  242. package/runtime/agents/n1-support-agent/agent.yaml +40 -1
  243. package/runtime/agents/n2-support-agent/agent.yaml +41 -2
  244. package/runtime/agents/n2-support-agent/knowledge/policies.yaml +2 -2
  245. package/runtime/agents/notification-operator/AGENTS.md +11 -0
  246. package/runtime/agents/notification-operator/README.md +15 -0
  247. package/runtime/agents/notification-operator/agent.yaml +43 -0
  248. package/runtime/agents/notification-operator/capabilities/configure-notification-channel/capability.yaml +19 -0
  249. package/runtime/agents/notification-operator/capabilities/configure-notification-channel/decision-rules.md +6 -0
  250. package/runtime/agents/notification-operator/capabilities/configure-notification-channel/runner.py +33 -0
  251. package/runtime/agents/notification-operator/capabilities/configure-notification-channel/workflow.md +6 -0
  252. package/runtime/agents/notification-operator/capabilities/format-task-completion-notification/capability.yaml +25 -0
  253. package/runtime/agents/notification-operator/capabilities/format-task-completion-notification/decision-rules.md +7 -0
  254. package/runtime/agents/notification-operator/capabilities/format-task-completion-notification/runner.py +49 -0
  255. package/runtime/agents/notification-operator/capabilities/format-task-completion-notification/workflow.md +6 -0
  256. package/runtime/agents/notification-operator/capabilities/send-task-completion-notification/capability.yaml +27 -0
  257. package/runtime/agents/notification-operator/capabilities/send-task-completion-notification/decision-rules.md +6 -0
  258. package/runtime/agents/notification-operator/capabilities/send-task-completion-notification/runner.py +68 -0
  259. package/runtime/agents/notification-operator/capabilities/send-task-completion-notification/workflow.md +7 -0
  260. package/runtime/agents/notification-operator/infra/README.md +6 -0
  261. package/runtime/agents/notification-operator/knowledge/context.md +10 -0
  262. package/runtime/agents/notification-operator/knowledge/policies.yaml +9 -0
  263. package/runtime/agents/notification-operator/knowledge/system.md +7 -0
  264. package/runtime/agents/notification-operator/templates/README.md +6 -0
  265. package/runtime/agents/notification-operator/tests/test_runners.py +108 -0
  266. package/runtime/agents/playwright-automation-builder/AGENTS.md +23 -0
  267. package/runtime/agents/playwright-automation-builder/README.md +43 -0
  268. package/runtime/agents/playwright-automation-builder/agent.yaml +48 -0
  269. package/runtime/agents/playwright-automation-builder/capabilities/generate-playwright-project-files/capability.yaml +20 -0
  270. package/runtime/agents/playwright-automation-builder/capabilities/generate-playwright-project-files/decision-rules.md +6 -0
  271. package/runtime/agents/playwright-automation-builder/capabilities/generate-playwright-project-files/runner.py +38 -0
  272. package/runtime/agents/playwright-automation-builder/capabilities/generate-playwright-project-files/workflow.md +6 -0
  273. package/runtime/agents/playwright-automation-builder/capabilities/generate-playwright-script/capability.yaml +18 -0
  274. package/runtime/agents/playwright-automation-builder/capabilities/generate-playwright-script/decision-rules.md +6 -0
  275. package/runtime/agents/playwright-automation-builder/capabilities/generate-playwright-script/runner.py +32 -0
  276. package/runtime/agents/playwright-automation-builder/capabilities/generate-playwright-script/workflow.md +6 -0
  277. package/runtime/agents/playwright-automation-builder/capabilities/plan-playwright-automation/capability.yaml +18 -0
  278. package/runtime/agents/playwright-automation-builder/capabilities/plan-playwright-automation/decision-rules.md +6 -0
  279. package/runtime/agents/playwright-automation-builder/capabilities/plan-playwright-automation/runner.py +32 -0
  280. package/runtime/agents/playwright-automation-builder/capabilities/plan-playwright-automation/workflow.md +6 -0
  281. package/runtime/agents/playwright-automation-builder/capabilities/review-playwright-artifacts/capability.yaml +19 -0
  282. package/runtime/agents/playwright-automation-builder/capabilities/review-playwright-artifacts/decision-rules.md +6 -0
  283. package/runtime/agents/playwright-automation-builder/capabilities/review-playwright-artifacts/runner.py +33 -0
  284. package/runtime/agents/playwright-automation-builder/capabilities/review-playwright-artifacts/workflow.md +6 -0
  285. package/runtime/agents/playwright-automation-builder/capabilities/run-playwright-check/capability.yaml +22 -0
  286. package/runtime/agents/playwright-automation-builder/capabilities/run-playwright-check/decision-rules.md +6 -0
  287. package/runtime/agents/playwright-automation-builder/capabilities/run-playwright-check/runner.py +40 -0
  288. package/runtime/agents/playwright-automation-builder/capabilities/run-playwright-check/workflow.md +6 -0
  289. package/runtime/agents/playwright-automation-builder/capabilities/wrap-playwright-as-capability/capability.yaml +22 -0
  290. package/runtime/agents/playwright-automation-builder/capabilities/wrap-playwright-as-capability/decision-rules.md +6 -0
  291. package/runtime/agents/playwright-automation-builder/capabilities/wrap-playwright-as-capability/runner.py +42 -0
  292. package/runtime/agents/playwright-automation-builder/capabilities/wrap-playwright-as-capability/workflow.md +6 -0
  293. package/runtime/agents/playwright-automation-builder/infra/integrations/playwright-automation/playwright_automation_repository.py +865 -0
  294. package/runtime/agents/playwright-automation-builder/knowledge/context.md +19 -0
  295. package/runtime/agents/playwright-automation-builder/knowledge/policies.yaml +25 -0
  296. package/runtime/agents/playwright-automation-builder/knowledge/system.md +19 -0
  297. package/runtime/agents/playwright-automation-builder/templates/capability-wrapper.md +4 -0
  298. package/runtime/agents/playwright-automation-builder/templates/playwright-automation.py +12 -0
  299. package/runtime/agents/playwright-automation-builder/templates/playwright-readme.md +13 -0
  300. package/runtime/agents/playwright-automation-builder/templates/playwright-review-report.md +9 -0
  301. package/runtime/agents/playwright-automation-builder/templates/playwright-test.py +2 -0
  302. package/runtime/agents/playwright-automation-builder/tests/test_runners.py +261 -0
  303. package/runtime/agents/postgres-data-analyzer/agent.yaml +13 -2
  304. package/runtime/agents/presentation-deck-builder/agent.yaml +14 -3
  305. package/runtime/agents/presentation-deck-builder/capabilities/create-template/capability.yaml +1 -1
  306. package/runtime/agents/presentation-deck-builder/capabilities/create-template-version/capability.yaml +1 -1
  307. package/runtime/agents/presentation-deck-builder/capabilities/generate-template-input-file/capability.yaml +1 -1
  308. package/runtime/agents/presentation-deck-builder/capabilities/refine-template/capability.yaml +1 -1
  309. package/runtime/agents/presentation-deck-builder/capabilities/register-template/capability.yaml +1 -1
  310. package/runtime/agents/presentation-deck-builder/knowledge/prompts/create-template.md +1 -1
  311. package/runtime/agents/presentation-deck-builder/knowledge/prompts/generate-template-input-file.md +1 -1
  312. package/runtime/agents/provider-configurator/agent.yaml +6 -4
  313. package/runtime/agents/provider-configurator/capabilities/collect-provider-credentials/capability.yaml +1 -2
  314. package/runtime/agents/provider-configurator/capabilities/configure-provider-source/capability.yaml +1 -2
  315. package/runtime/agents/provider-configurator/capabilities/validate-provider-readiness/capability.yaml +1 -2
  316. package/runtime/agents/pyautogui-automation-builder/AGENTS.md +32 -0
  317. package/runtime/agents/pyautogui-automation-builder/README.md +44 -0
  318. package/runtime/agents/pyautogui-automation-builder/agent.yaml +45 -0
  319. package/runtime/agents/pyautogui-automation-builder/capabilities/generate-pyautogui-project-files/capability.yaml +20 -0
  320. package/runtime/agents/pyautogui-automation-builder/capabilities/generate-pyautogui-project-files/decision-rules.md +6 -0
  321. package/runtime/agents/pyautogui-automation-builder/capabilities/generate-pyautogui-project-files/runner.py +39 -0
  322. package/runtime/agents/pyautogui-automation-builder/capabilities/generate-pyautogui-project-files/workflow.md +7 -0
  323. package/runtime/agents/pyautogui-automation-builder/capabilities/generate-pyautogui-script/capability.yaml +18 -0
  324. package/runtime/agents/pyautogui-automation-builder/capabilities/generate-pyautogui-script/decision-rules.md +7 -0
  325. package/runtime/agents/pyautogui-automation-builder/capabilities/generate-pyautogui-script/runner.py +33 -0
  326. package/runtime/agents/pyautogui-automation-builder/capabilities/generate-pyautogui-script/workflow.md +7 -0
  327. package/runtime/agents/pyautogui-automation-builder/capabilities/plan-desktop-automation/capability.yaml +18 -0
  328. package/runtime/agents/pyautogui-automation-builder/capabilities/plan-desktop-automation/decision-rules.md +8 -0
  329. package/runtime/agents/pyautogui-automation-builder/capabilities/plan-desktop-automation/runner.py +33 -0
  330. package/runtime/agents/pyautogui-automation-builder/capabilities/plan-desktop-automation/workflow.md +9 -0
  331. package/runtime/agents/pyautogui-automation-builder/capabilities/review-pyautogui-script/capability.yaml +20 -0
  332. package/runtime/agents/pyautogui-automation-builder/capabilities/review-pyautogui-script/decision-rules.md +8 -0
  333. package/runtime/agents/pyautogui-automation-builder/capabilities/review-pyautogui-script/runner.py +43 -0
  334. package/runtime/agents/pyautogui-automation-builder/capabilities/review-pyautogui-script/workflow.md +7 -0
  335. package/runtime/agents/pyautogui-automation-builder/capabilities/wrap-pyautogui-as-capability/capability.yaml +22 -0
  336. package/runtime/agents/pyautogui-automation-builder/capabilities/wrap-pyautogui-as-capability/decision-rules.md +6 -0
  337. package/runtime/agents/pyautogui-automation-builder/capabilities/wrap-pyautogui-as-capability/runner.py +43 -0
  338. package/runtime/agents/pyautogui-automation-builder/capabilities/wrap-pyautogui-as-capability/workflow.md +7 -0
  339. package/runtime/agents/pyautogui-automation-builder/infra/integrations/pyautogui-automation/pyautogui_automation_repository.py +856 -0
  340. package/runtime/agents/pyautogui-automation-builder/knowledge/context.md +17 -0
  341. package/runtime/agents/pyautogui-automation-builder/knowledge/policies.yaml +24 -0
  342. package/runtime/agents/pyautogui-automation-builder/knowledge/system.md +13 -0
  343. package/runtime/agents/pyautogui-automation-builder/templates/capability-wrapper.md +3 -0
  344. package/runtime/agents/pyautogui-automation-builder/templates/pyautogui-automation.py +12 -0
  345. package/runtime/agents/pyautogui-automation-builder/templates/pyautogui-readme.md +3 -0
  346. package/runtime/agents/pyautogui-automation-builder/templates/pyautogui-review-report.md +3 -0
  347. package/runtime/agents/pyautogui-automation-builder/templates/pyautogui-test.py +2 -0
  348. package/runtime/agents/pyautogui-automation-builder/tests/test_runners.py +376 -0
  349. package/runtime/agents/python-automation-builder/AGENTS.md +25 -0
  350. package/runtime/agents/python-automation-builder/README.md +43 -0
  351. package/runtime/agents/python-automation-builder/agent.yaml +45 -0
  352. package/runtime/agents/python-automation-builder/capabilities/generate-automation-project-files/capability.yaml +20 -0
  353. package/runtime/agents/python-automation-builder/capabilities/generate-automation-project-files/decision-rules.md +6 -0
  354. package/runtime/agents/python-automation-builder/capabilities/generate-automation-project-files/runner.py +39 -0
  355. package/runtime/agents/python-automation-builder/capabilities/generate-automation-project-files/workflow.md +7 -0
  356. package/runtime/agents/python-automation-builder/capabilities/generate-python-automation/capability.yaml +18 -0
  357. package/runtime/agents/python-automation-builder/capabilities/generate-python-automation/decision-rules.md +5 -0
  358. package/runtime/agents/python-automation-builder/capabilities/generate-python-automation/runner.py +33 -0
  359. package/runtime/agents/python-automation-builder/capabilities/generate-python-automation/workflow.md +5 -0
  360. package/runtime/agents/python-automation-builder/capabilities/plan-python-automation/capability.yaml +18 -0
  361. package/runtime/agents/python-automation-builder/capabilities/plan-python-automation/decision-rules.md +6 -0
  362. package/runtime/agents/python-automation-builder/capabilities/plan-python-automation/runner.py +33 -0
  363. package/runtime/agents/python-automation-builder/capabilities/plan-python-automation/workflow.md +6 -0
  364. package/runtime/agents/python-automation-builder/capabilities/review-python-automation/capability.yaml +20 -0
  365. package/runtime/agents/python-automation-builder/capabilities/review-python-automation/decision-rules.md +6 -0
  366. package/runtime/agents/python-automation-builder/capabilities/review-python-automation/runner.py +43 -0
  367. package/runtime/agents/python-automation-builder/capabilities/review-python-automation/workflow.md +5 -0
  368. package/runtime/agents/python-automation-builder/capabilities/wrap-automation-as-capability/capability.yaml +22 -0
  369. package/runtime/agents/python-automation-builder/capabilities/wrap-automation-as-capability/decision-rules.md +6 -0
  370. package/runtime/agents/python-automation-builder/capabilities/wrap-automation-as-capability/runner.py +43 -0
  371. package/runtime/agents/python-automation-builder/capabilities/wrap-automation-as-capability/workflow.md +6 -0
  372. package/runtime/agents/python-automation-builder/infra/integrations/python-automation/python_automation_repository.py +717 -0
  373. package/runtime/agents/python-automation-builder/knowledge/context.md +15 -0
  374. package/runtime/agents/python-automation-builder/knowledge/policies.yaml +12 -0
  375. package/runtime/agents/python-automation-builder/knowledge/system.md +19 -0
  376. package/runtime/agents/python-automation-builder/templates/automation-readme.md +13 -0
  377. package/runtime/agents/python-automation-builder/templates/automation-review-report.md +13 -0
  378. package/runtime/agents/python-automation-builder/templates/automation-test.py +9 -0
  379. package/runtime/agents/python-automation-builder/templates/automation.py +19 -0
  380. package/runtime/agents/python-automation-builder/templates/capability-wrapper.md +4 -0
  381. package/runtime/agents/python-automation-builder/tests/test_runners.py +292 -0
  382. package/runtime/agents/selenium-automation-builder/AGENTS.md +27 -0
  383. package/runtime/agents/selenium-automation-builder/README.md +40 -0
  384. package/runtime/agents/selenium-automation-builder/agent.yaml +45 -0
  385. package/runtime/agents/selenium-automation-builder/capabilities/generate-selenium-project-files/capability.yaml +20 -0
  386. package/runtime/agents/selenium-automation-builder/capabilities/generate-selenium-project-files/decision-rules.md +6 -0
  387. package/runtime/agents/selenium-automation-builder/capabilities/generate-selenium-project-files/runner.py +39 -0
  388. package/runtime/agents/selenium-automation-builder/capabilities/generate-selenium-project-files/workflow.md +7 -0
  389. package/runtime/agents/selenium-automation-builder/capabilities/generate-selenium-script/capability.yaml +18 -0
  390. package/runtime/agents/selenium-automation-builder/capabilities/generate-selenium-script/decision-rules.md +6 -0
  391. package/runtime/agents/selenium-automation-builder/capabilities/generate-selenium-script/runner.py +33 -0
  392. package/runtime/agents/selenium-automation-builder/capabilities/generate-selenium-script/workflow.md +6 -0
  393. package/runtime/agents/selenium-automation-builder/capabilities/plan-selenium-automation/capability.yaml +18 -0
  394. package/runtime/agents/selenium-automation-builder/capabilities/plan-selenium-automation/decision-rules.md +6 -0
  395. package/runtime/agents/selenium-automation-builder/capabilities/plan-selenium-automation/runner.py +33 -0
  396. package/runtime/agents/selenium-automation-builder/capabilities/plan-selenium-automation/workflow.md +6 -0
  397. package/runtime/agents/selenium-automation-builder/capabilities/review-selenium-script/capability.yaml +20 -0
  398. package/runtime/agents/selenium-automation-builder/capabilities/review-selenium-script/decision-rules.md +6 -0
  399. package/runtime/agents/selenium-automation-builder/capabilities/review-selenium-script/runner.py +40 -0
  400. package/runtime/agents/selenium-automation-builder/capabilities/review-selenium-script/workflow.md +6 -0
  401. package/runtime/agents/selenium-automation-builder/capabilities/wrap-selenium-as-capability/capability.yaml +22 -0
  402. package/runtime/agents/selenium-automation-builder/capabilities/wrap-selenium-as-capability/decision-rules.md +6 -0
  403. package/runtime/agents/selenium-automation-builder/capabilities/wrap-selenium-as-capability/runner.py +43 -0
  404. package/runtime/agents/selenium-automation-builder/capabilities/wrap-selenium-as-capability/workflow.md +6 -0
  405. package/runtime/agents/selenium-automation-builder/infra/integrations/selenium-automation/selenium_automation_repository.py +793 -0
  406. package/runtime/agents/selenium-automation-builder/knowledge/context.md +15 -0
  407. package/runtime/agents/selenium-automation-builder/knowledge/policies.yaml +17 -0
  408. package/runtime/agents/selenium-automation-builder/knowledge/system.md +18 -0
  409. package/runtime/agents/selenium-automation-builder/templates/capability-wrapper.md +4 -0
  410. package/runtime/agents/selenium-automation-builder/templates/selenium-automation.py +20 -0
  411. package/runtime/agents/selenium-automation-builder/templates/selenium-readme.md +13 -0
  412. package/runtime/agents/selenium-automation-builder/templates/selenium-review-report.md +13 -0
  413. package/runtime/agents/selenium-automation-builder/templates/selenium-test.py +9 -0
  414. package/runtime/agents/selenium-automation-builder/tests/test_runners.py +282 -0
  415. package/runtime/agents/software-specification-analyst/agent.yaml +17 -4
  416. package/runtime/agents/software-specification-analyst/capabilities/analyze-multiple-projects/capability.yaml +1 -1
  417. package/runtime/agents/software-specification-analyst/capabilities/analyze-project-context/capability.yaml +1 -1
  418. package/runtime/agents/software-specification-analyst/capabilities/conduct-requirements-interview/capability.yaml +1 -1
  419. package/runtime/agents/software-specification-analyst/capabilities/create-complete-spec/capability.yaml +1 -1
  420. package/runtime/agents/software-specification-analyst/capabilities/create-final-spec-from-analysis/capability.yaml +1 -1
  421. package/runtime/agents/software-specification-analyst/capabilities/create-functional-spec/capability.yaml +11 -0
  422. package/runtime/agents/software-specification-analyst/capabilities/create-technical-spec/capability.yaml +12 -0
  423. package/runtime/agents/software-specification-analyst/capabilities/refine-analysis-with-feedback/capability.yaml +1 -1
  424. package/runtime/agents/software-specification-analyst/capabilities/write-user-stories/capability.yaml +12 -0
  425. package/runtime/agents/sqlserver-change-operator/agent.yaml +12 -1
  426. package/runtime/agents/sqlserver-data-analyzer/agent.yaml +13 -2
  427. package/runtime/agents/supabase-project-analyst/AGENTS.md +29 -0
  428. package/runtime/agents/supabase-project-analyst/README.md +23 -0
  429. package/runtime/agents/supabase-project-analyst/agent.yaml +53 -0
  430. package/runtime/agents/supabase-project-analyst/capabilities/audit-auth-security/capability.yaml +18 -0
  431. package/runtime/agents/supabase-project-analyst/capabilities/audit-auth-security/decision-rules.md +5 -0
  432. package/runtime/agents/supabase-project-analyst/capabilities/audit-auth-security/runner.py +32 -0
  433. package/runtime/agents/supabase-project-analyst/capabilities/audit-auth-security/workflow.md +6 -0
  434. package/runtime/agents/supabase-project-analyst/capabilities/audit-rls-policies/capability.yaml +18 -0
  435. package/runtime/agents/supabase-project-analyst/capabilities/audit-rls-policies/decision-rules.md +6 -0
  436. package/runtime/agents/supabase-project-analyst/capabilities/audit-rls-policies/runner.py +32 -0
  437. package/runtime/agents/supabase-project-analyst/capabilities/audit-rls-policies/workflow.md +7 -0
  438. package/runtime/agents/supabase-project-analyst/capabilities/audit-storage-policies/capability.yaml +18 -0
  439. package/runtime/agents/supabase-project-analyst/capabilities/audit-storage-policies/decision-rules.md +5 -0
  440. package/runtime/agents/supabase-project-analyst/capabilities/audit-storage-policies/runner.py +32 -0
  441. package/runtime/agents/supabase-project-analyst/capabilities/audit-storage-policies/workflow.md +6 -0
  442. package/runtime/agents/supabase-project-analyst/capabilities/generate-supabase-report/capability.yaml +18 -0
  443. package/runtime/agents/supabase-project-analyst/capabilities/generate-supabase-report/decision-rules.md +6 -0
  444. package/runtime/agents/supabase-project-analyst/capabilities/generate-supabase-report/runner.py +32 -0
  445. package/runtime/agents/supabase-project-analyst/capabilities/generate-supabase-report/workflow.md +6 -0
  446. package/runtime/agents/supabase-project-analyst/capabilities/inspect-supabase-project/capability.yaml +19 -0
  447. package/runtime/agents/supabase-project-analyst/capabilities/inspect-supabase-project/decision-rules.md +6 -0
  448. package/runtime/agents/supabase-project-analyst/capabilities/inspect-supabase-project/runner.py +36 -0
  449. package/runtime/agents/supabase-project-analyst/capabilities/inspect-supabase-project/workflow.md +7 -0
  450. package/runtime/agents/supabase-project-analyst/capabilities/plan-supabase-fix/capability.yaml +18 -0
  451. package/runtime/agents/supabase-project-analyst/capabilities/plan-supabase-fix/decision-rules.md +6 -0
  452. package/runtime/agents/supabase-project-analyst/capabilities/plan-supabase-fix/runner.py +32 -0
  453. package/runtime/agents/supabase-project-analyst/capabilities/plan-supabase-fix/workflow.md +6 -0
  454. package/runtime/agents/supabase-project-analyst/capabilities/review-migrations/capability.yaml +18 -0
  455. package/runtime/agents/supabase-project-analyst/capabilities/review-migrations/decision-rules.md +6 -0
  456. package/runtime/agents/supabase-project-analyst/capabilities/review-migrations/runner.py +32 -0
  457. package/runtime/agents/supabase-project-analyst/capabilities/review-migrations/workflow.md +5 -0
  458. package/runtime/agents/supabase-project-analyst/infra/integrations/supabase-project/supabase_project_repository.py +589 -0
  459. package/runtime/agents/supabase-project-analyst/knowledge/context.md +11 -0
  460. package/runtime/agents/supabase-project-analyst/knowledge/policies.yaml +24 -0
  461. package/runtime/agents/supabase-project-analyst/knowledge/system.md +10 -0
  462. package/runtime/agents/supabase-project-analyst/templates/supabase-audit.md +3 -0
  463. package/runtime/agents/supabase-project-analyst/templates/supabase-fix-plan.md +3 -0
  464. package/runtime/agents/supabase-project-analyst/templates/supabase-inspection.md +3 -0
  465. package/runtime/agents/supabase-project-analyst/templates/supabase-report.md +3 -0
  466. package/runtime/agents/supabase-project-analyst/tests/test_runners.py +239 -0
  467. package/runtime/agents/task-orchestrator/agent.yaml +25 -3
  468. package/runtime/agents/task-orchestrator/capabilities/plan-task/capability.yaml +1 -2
  469. package/runtime/agents/task-orchestrator/capabilities/select-specialists/capability.yaml +1 -2
  470. package/runtime/agents/technical-integration-analyst/agent.yaml +15 -2
  471. package/runtime/agents/topdesk-orchestrator/agent.yaml +10 -2
  472. package/runtime/cli/aikit/__init__.py +1 -1
  473. package/runtime/cli/aikit/acceptance.py +166 -0
  474. package/runtime/cli/aikit/agent_executor.py +26 -3
  475. package/runtime/cli/aikit/agent_registry.py +244 -5
  476. package/runtime/cli/aikit/architecture.py +84 -0
  477. package/runtime/cli/aikit/audit.py +172 -3
  478. package/runtime/cli/aikit/autonomy.py +237 -0
  479. package/runtime/cli/aikit/capability_runtime.py +522 -0
  480. package/runtime/cli/aikit/catalog.py +246 -0
  481. package/runtime/cli/aikit/cli_dispatch.py +1078 -0
  482. package/runtime/cli/aikit/cli_parser.py +409 -0
  483. package/runtime/cli/aikit/collaboration.py +359 -0
  484. package/runtime/cli/aikit/configuration_orchestrator.py +52 -26
  485. package/runtime/cli/aikit/contribution.py +105 -0
  486. package/runtime/cli/aikit/core/__init__.py +1 -0
  487. package/runtime/cli/aikit/core/capability_contract.py +112 -0
  488. package/runtime/cli/aikit/core/requests.py +69 -0
  489. package/runtime/cli/aikit/core/runtime.py +64 -0
  490. package/runtime/cli/aikit/diagnostics.py +8 -2
  491. package/runtime/cli/aikit/doctor_runtime.py +79 -0
  492. package/runtime/cli/aikit/errors.py +7 -0
  493. package/runtime/cli/aikit/eval.py +158 -0
  494. package/runtime/cli/aikit/execution_reviewer.py +21 -0
  495. package/runtime/cli/aikit/extensions.py +140 -0
  496. package/runtime/cli/aikit/fallback.py +1 -0
  497. package/runtime/cli/aikit/github_pr.py +23 -0
  498. package/runtime/cli/aikit/guardrails.py +25 -10
  499. package/runtime/cli/aikit/human_output.py +1026 -0
  500. package/runtime/cli/aikit/impact_map.py +294 -0
  501. package/runtime/cli/aikit/interactive_wizard.py +79 -0
  502. package/runtime/cli/aikit/local_llm_operator.py +35 -1
  503. package/runtime/cli/aikit/main.py +9 -2834
  504. package/runtime/cli/aikit/mcp_manifest.py +229 -0
  505. package/runtime/cli/aikit/mcp_server.py +132 -0
  506. package/runtime/cli/aikit/mcp_tools.py +262 -0
  507. package/runtime/cli/aikit/mini_brain.py +227 -0
  508. package/runtime/cli/aikit/model_router.py +182 -18
  509. package/runtime/cli/aikit/module_controller.py +335 -0
  510. package/runtime/cli/aikit/natural_prompt_runtime.py +538 -0
  511. package/runtime/cli/aikit/notifications.py +716 -2
  512. package/runtime/cli/aikit/ollama.py +1 -0
  513. package/runtime/cli/aikit/orchestrator.py +809 -119
  514. package/runtime/cli/aikit/output.py +63 -2
  515. package/runtime/cli/aikit/permissions.py +14 -4
  516. package/runtime/cli/aikit/prompt_injection.py +57 -0
  517. package/runtime/cli/aikit/review_gate.py +38 -6
  518. package/runtime/cli/aikit/roadmap.py +195 -0
  519. package/runtime/cli/aikit/roadmap_cli.py +70 -0
  520. package/runtime/cli/aikit/router.py +41 -12
  521. package/runtime/cli/aikit/router_explain.py +152 -0
  522. package/runtime/cli/aikit/runtime_paths.py +11 -0
  523. package/runtime/cli/aikit/secrets.py +113 -0
  524. package/runtime/cli/aikit/sessions.py +88 -2
  525. package/runtime/cli/aikit/setup_wizard_payload.py +32 -0
  526. package/runtime/cli/aikit/sources.py +298 -50
  527. package/runtime/cli/aikit/tasks.py +449 -21
  528. package/runtime/cli/aikit/wizard_state.py +15 -1
  529. package/runtime/cli/aikit/workflows.py +115 -0
  530. package/runtime/cli/aikit/write_policy.py +108 -0
  531. package/runtime/plugins/claude-code-ai-devkit/README.md +17 -0
  532. package/runtime/plugins/claude-code-ai-devkit/agents/README.md +29 -2
  533. package/runtime/plugins/claude-code-ai-devkit/agents/agent-devkit-db-analyst.md +44 -0
  534. package/runtime/plugins/claude-code-ai-devkit/agents/agent-devkit-execution-reviewer.md +38 -0
  535. package/runtime/plugins/claude-code-ai-devkit/agents/agent-devkit-pr-reviewer.md +42 -0
  536. package/runtime/plugins/claude-code-ai-devkit/agents/agent-devkit-repo-explorer.md +40 -0
  537. package/runtime/plugins/claude-code-ai-devkit/agents/agent-devkit-support-triage.md +43 -0
  538. package/runtime/plugins/claude-code-ai-devkit/plugin.json +1 -1
  539. package/runtime/plugins/claude-code-ai-devkit/skills/ai-devkit-router/SKILL.md +16 -0
  540. package/runtime/plugins/claude-skill-ai-devkit/ai-devkit/SKILL.md +1 -0
  541. package/runtime/plugins/claude-skill-ai-devkit/ai-devkit/references/subagents.md +21 -0
  542. package/runtime/plugins/claude-skill-ai-devkit/plugin.json +1 -1
  543. package/runtime/providers/azure-devops.yaml +9 -0
  544. package/runtime/providers/github.yaml +4 -0
  545. package/runtime/providers/local-notification.yaml +5 -2
  546. package/runtime/providers/local-scheduler.yaml +1 -1
  547. package/runtime/providers/supabase.yaml +46 -0
  548. package/runtime/scripts/release-catalog-snapshot.json +543 -0
  549. package/runtime/scripts/release-gate.py +141 -1
  550. package/runtime/scripts/validate-repo.py +312 -0
  551. package/runtime/vendor/skills/napkin/napkin.md +15 -9
@@ -8,12 +8,15 @@ from pathlib import Path
8
8
  from typing import Any
9
9
 
10
10
  from cli.aikit.agent_registry import find_capability, load_agent_registry
11
+ from cli.aikit.autonomy import build_autonomy_contract
12
+ from cli.aikit.collaboration import build_collaboration_graph, initial_shared_context, normalize_collaborative_task
11
13
  from cli.aikit.configuration_orchestrator import provider_setup_wizard
12
14
  from cli.aikit.memory import redact_secrets
13
15
  from cli.aikit.model_router import build_model_plan
14
16
  from cli.aikit.review_gate import build_review_gate
15
17
  from cli.aikit.router import route_prompt
16
18
  from cli.aikit.sources import SourceRegistryError, public_source, resolve_source
19
+ from cli.aikit.write_policy import normalize_write_policy, write_policy_public_fields
17
20
 
18
21
 
19
22
  RUNTIME_COORDINATOR = {
@@ -63,63 +66,92 @@ TOKEN_ALIASES = {
63
66
  "tecnica": {"technical", "architecture", "component"},
64
67
  "tecnico": {"technical", "architecture", "component"},
65
68
  }
66
- AGENT_ANCHORS = {
67
- "aws-architecture-analyst": {"aws", "arquitetura", "architecture", "workload", "resiliencia", "observability", "vpc"},
68
- "aws-cloudwatch-log-analyzer": {"aws", "cloudwatch", "log", "logs"},
69
- "aws-operations-operator": {"aws", "ecs", "lambda", "sqs", "cloudfront", "eventbridge"},
70
- "aws-security-governance-auditor": {"aws", "iam", "s3", "cloudtrail", "security", "seguranca"},
71
- "azure-devops-orchestrator": {"azure", "devops", "card", "workitem", "work", "item", "board"},
72
- "bpo-analyser": {"bpo", "cpf", "proposta", "proposal"},
73
- "data-scientist-analyst": {"dataset", "dados", "data", "cohort", "modelo", "estatistica"},
74
- "database-change-operator": {"postgres", "migration", "migracao", "database", "banco"},
75
- "drawio-diagram-builder": {"drawio", "diagrama", "diagram"},
76
- "elasticsearch-log-analyzer": {"elasticsearch", "elastic", "indice", "index", "logs", "log"},
77
- "excel-workbook-builder": {"excel", "planilha", "spreadsheet", "workbook"},
78
- "figma-ui-ux-product-designer": {"figma", "ui", "ux", "design", "tela", "wireframe"},
79
- "github-pr-reviewer": {"github", "gh", "pr", "prs", "pull", "request"},
80
- "knowledge-generator": {"knowledge", "conhecimento", "documentacao", "runbook"},
81
- "postgres-data-analyzer": {"postgres", "postgresql", "sql", "database", "banco"},
82
- "presentation-deck-builder": {"apresentacao", "presentation", "slides", "powerpoint", "deck"},
83
- "software-specification-analyst": {"especificacao", "specification", "requisitos", "requirements", "historia", "stories", "demanda"},
84
- "sqlserver-change-operator": {"sqlserver", "sql", "migration", "migracao", "banco"},
85
- "sqlserver-data-analyzer": {"sqlserver", "sql", "database", "banco", "tabela"},
86
- "technical-integration-analyst": {"integracao", "integration", "api", "rest", "soap", "sftp", "mcp"},
87
- "topdesk-orchestrator": {"topdesk", "chamado"},
88
- }
69
+ ROUTING_SELECTED_THRESHOLD = 3
70
+ ROUTING_AMBIGUITY_DELTA = 1
89
71
 
90
72
 
91
73
  def build_execution_plan(root: Path, prompt: str, *, dry_run: bool = False) -> dict[str, Any]:
92
74
  registry = load_agent_registry(root)
93
75
  safe_prompt = redact_secrets(prompt)
94
- route = route_prompt(prompt)
95
- domain_agent = select_domain_agent(registry, prompt, route)
96
- specialist_tasks = specialist_tasks_for_prompt(registry, prompt, route, domain_agent)
76
+ route = route_prompt(prompt, root=root)
77
+ routing_decision = decide_routing(registry, prompt, route)
78
+ domain_agent = select_domain_agent(registry, prompt, route, routing_decision)
79
+ specialist_tasks = specialist_tasks_for_prompt(registry, prompt, route, domain_agent, routing_decision)
97
80
  configuration_tasks = configuration_tasks_for(registry, root, prompt, route, specialist_tasks, dry_run=dry_run)
98
- model_plan = build_model_plan(prompt, route=route)
81
+ model_plan = build_model_plan(
82
+ prompt,
83
+ route=route,
84
+ routing_decision=routing_decision,
85
+ specialist_tasks=specialist_tasks,
86
+ configuration_tasks=configuration_tasks,
87
+ )
99
88
  model_plan = attach_local_llm_agent_contract(registry, model_plan)
100
89
  review_gate = build_review_gate(prompt, route=route, model_plan=model_plan)
90
+ review = review_task(registry, review_gate)
91
+ review = attach_review_dependencies(review, specialist_tasks)
92
+ collaboration_enabled = bool(specialist_tasks or configuration_tasks or review.get("required"))
93
+ collaboration_graph = build_collaboration_graph(specialist_tasks, configuration_tasks, review)
94
+ module_controller = module_controller_contract(domain_agent, specialist_tasks)
95
+ execution_model = execution_model_contract(domain_agent, review_gate, module_controller, model_plan)
96
+ policy_summary = policy_summary_for_plan(specialist_tasks, configuration_tasks, review)
97
+ autonomy_contract = build_autonomy_contract(
98
+ model_plan=model_plan,
99
+ routing_decision=routing_decision,
100
+ specialist_tasks=specialist_tasks,
101
+ configuration_tasks=configuration_tasks,
102
+ review_gate=review_gate,
103
+ execution_model=execution_model,
104
+ policy_summary=policy_summary,
105
+ collaboration_enabled=collaboration_enabled,
106
+ controller_enabled=bool(module_controller.get("enabled")),
107
+ )
108
+ execution_model = attach_autonomy_to_execution_model(execution_model, autonomy_contract)
101
109
  status = "needs-input" if configuration_tasks and not dry_run else "planned"
110
+ if routing_decision.get("status") in {"ambiguous", "low-confidence"} and not dry_run:
111
+ status = "needs-input"
112
+ if model_plan.get("strategy") == "human" and not dry_run:
113
+ status = "needs-input"
102
114
  return {
103
115
  "kind": "agentic-execution-plan",
104
116
  "schema_version": "ai-devkit.agentic-plan/v1",
105
117
  "status": status,
106
118
  "dry_run": dry_run,
107
119
  "prompt": safe_prompt,
108
- "coordinator_agent": runtime_agent(registry, "task-orchestrator", fallback=RUNTIME_COORDINATOR),
120
+ "coordinator_agent": runtime_agent_by_role(registry, "coordinator", fallback=RUNTIME_COORDINATOR),
109
121
  "domain_agent": domain_agent,
110
122
  "route": route,
123
+ "routing_decision": routing_decision,
111
124
  "model_plan": model_plan,
112
125
  "review_gate": review_gate,
113
126
  "specialist_tasks": specialist_tasks,
114
127
  "configuration_tasks": configuration_tasks,
115
- "review_task": review_task(registry, review_gate),
128
+ "review_task": review,
129
+ "collaboration_enabled": collaboration_enabled,
130
+ "collaboration_graph": collaboration_graph,
131
+ "shared_context": initial_shared_context(safe_prompt, routing_decision),
132
+ "execution_model": execution_model,
133
+ "autonomy_contract": autonomy_contract,
134
+ "stop_conditions": execution_model["stop_conditions"],
135
+ "module_controller": module_controller,
136
+ "controller_enabled": bool(module_controller.get("enabled")),
137
+ "policy_summary": policy_summary,
116
138
  "executed_tasks": [],
117
139
  "blocked_tasks": [],
118
- "trace": trace_for_plan(specialist_tasks, configuration_tasks, status=status),
140
+ "trace": trace_for_plan(
141
+ specialist_tasks,
142
+ configuration_tasks,
143
+ status=status,
144
+ coordinator_agent_id=runtime_agent_id(registry, "coordinator", RUNTIME_COORDINATOR["id"]),
145
+ ),
119
146
  }
120
147
 
121
148
 
122
- def select_domain_agent(registry: dict[str, Any], prompt: str, route: dict[str, Any] | None) -> dict[str, Any]:
149
+ def select_domain_agent(
150
+ registry: dict[str, Any],
151
+ prompt: str,
152
+ route: dict[str, Any] | None,
153
+ routing_decision: dict[str, Any] | None = None,
154
+ ) -> dict[str, Any]:
123
155
  normalized = normalize(prompt)
124
156
  agents = registry.get("agents") or {}
125
157
  if re.search(r"\bn1\b|primeiro nivel|1o nivel|1º nivel", normalized) and "n1-support-agent" in agents:
@@ -128,12 +160,13 @@ def select_domain_agent(registry: dict[str, Any], prompt: str, route: dict[str,
128
160
  return slim_agent(agents["n2-support-agent"])
129
161
  if route and route.get("agent_id") in agents:
130
162
  return slim_agent(agents[str(route["agent_id"])])
131
- matched_agent = best_agent_match(registry, prompt)
132
- if matched_agent:
133
- return slim_agent(matched_agent)
134
- if "task-orchestrator" in agents:
135
- return slim_agent(agents["task-orchestrator"])
136
- return dict(RUNTIME_COORDINATOR)
163
+ if routing_decision and routing_decision.get("status") in {"ambiguous", "low-confidence"}:
164
+ return runtime_agent_by_role(registry, "coordinator", fallback=RUNTIME_COORDINATOR)
165
+ if routing_decision and routing_decision.get("status") == "selected":
166
+ selected_agent_id = str(routing_decision.get("selected_agent_id") or "")
167
+ if selected_agent_id in agents:
168
+ return slim_agent(agents[selected_agent_id])
169
+ return runtime_agent_by_role(registry, "coordinator", fallback=RUNTIME_COORDINATOR)
137
170
 
138
171
 
139
172
  def specialist_tasks_for_prompt(
@@ -141,13 +174,29 @@ def specialist_tasks_for_prompt(
141
174
  prompt: str,
142
175
  route: dict[str, Any] | None,
143
176
  domain_agent: dict[str, Any],
177
+ routing_decision: dict[str, Any] | None = None,
144
178
  ) -> list[dict[str, Any]]:
179
+ if routing_decision and routing_decision.get("status") in {"ambiguous", "low-confidence"}:
180
+ return []
145
181
  if domain_agent.get("id") in {"n1-support-agent", "n2-support-agent"}:
146
182
  return orchestrated_tasks(registry, str(domain_agent["id"]), prompt, route)
147
183
  if route:
148
184
  task = task_from_route(registry, route)
149
185
  return [task] if task else []
150
- if domain_agent.get("id") and domain_agent.get("id") != "task-orchestrator":
186
+ if routing_decision and routing_decision.get("status") == "selected":
187
+ selected_agent_id = routing_decision.get("selected_agent_id")
188
+ selected_capability_id = routing_decision.get("selected_capability_id")
189
+ if selected_agent_id and selected_capability_id:
190
+ capability = find_capability(registry, str(selected_agent_id), str(selected_capability_id))
191
+ if capability:
192
+ task = base_task(capability, prompt=prompt)
193
+ task["primary"] = True
194
+ task["selection"] = {
195
+ "method": routing_decision.get("method"),
196
+ "score": routing_decision.get("score"),
197
+ }
198
+ return [task]
199
+ if domain_agent.get("id") and not is_runtime_agent(registry, str(domain_agent["id"])):
151
200
  task = best_capability_task(registry, str(domain_agent["id"]), prompt)
152
201
  return [task] if task else []
153
202
  return []
@@ -156,6 +205,7 @@ def specialist_tasks_for_prompt(
156
205
  def orchestrated_tasks(registry: dict[str, Any], agent_id: str, prompt: str, route: dict[str, Any] | None) -> list[dict[str, Any]]:
157
206
  agent = (registry.get("agents") or {}).get(agent_id) or {}
158
207
  tasks: list[dict[str, Any]] = []
208
+ previous_task_id: str | None = None
159
209
  for pair in agent.get("orchestrated_agents") or []:
160
210
  if "/" not in str(pair):
161
211
  continue
@@ -169,12 +219,21 @@ def orchestrated_tasks(registry: dict[str, Any], agent_id: str, prompt: str, rou
169
219
  task["entities"] = dict(route.get("entities") or {})
170
220
  task["provider"] = route.get("provider") or task.get("provider")
171
221
  task["primary"] = True
222
+ task["critical"] = True
223
+ task = normalize_collaborative_task(
224
+ task,
225
+ role=collaboration_role_for_task(task),
226
+ depends_on=[previous_task_id] if previous_task_id else [],
227
+ sequence=len(tasks) + 1,
228
+ )
172
229
  tasks.append(task)
230
+ previous_task_id = str(task.get("task_id") or task.get("id"))
173
231
  if route and not any(task.get("primary") for task in tasks):
174
232
  routed = task_from_route(registry, route)
175
233
  if routed:
176
234
  routed["primary"] = True
177
- tasks.insert(0, routed)
235
+ routed["critical"] = True
236
+ tasks.insert(0, normalize_collaborative_task(routed, role=collaboration_role_for_task(routed), sequence=0))
178
237
  return tasks
179
238
 
180
239
 
@@ -190,46 +249,458 @@ def task_from_route(registry: dict[str, Any], route: dict[str, Any]) -> dict[str
190
249
  return task
191
250
 
192
251
 
193
- def best_agent_match(registry: dict[str, Any], prompt: str) -> dict[str, Any] | None:
252
+ def decide_routing(registry: dict[str, Any], prompt: str, route: dict[str, Any] | None) -> dict[str, Any]:
253
+ support_agent_id = support_level_agent_id(registry, prompt)
254
+ if support_agent_id:
255
+ return enrich_routing_decision(
256
+ {
257
+ "status": "selected",
258
+ "method": "support-level-regex",
259
+ "selected_agent_id": support_agent_id,
260
+ "selected_capability_id": None,
261
+ "confidence": 0.98,
262
+ "score": None,
263
+ "candidates": [
264
+ {
265
+ "agent_id": support_agent_id,
266
+ "score": None,
267
+ "matched_anchors": [],
268
+ "matched_intents": ["support.level"],
269
+ "selected_capability_id": None,
270
+ "legacy_fallback": False,
271
+ }
272
+ ],
273
+ },
274
+ prompt=prompt,
275
+ )
276
+ if route:
277
+ return enrich_routing_decision(
278
+ {
279
+ "status": "deterministic",
280
+ "method": "deterministic-regex",
281
+ "selected_agent_id": route.get("agent_id"),
282
+ "selected_capability_id": route.get("capability_id"),
283
+ "confidence": 1.0,
284
+ "score": None,
285
+ "candidates": [
286
+ {
287
+ "agent_id": route.get("agent_id"),
288
+ "capability_id": route.get("capability_id"),
289
+ "score": None,
290
+ "matched_anchors": [route.get("intent")],
291
+ "matched_intents": [route.get("intent")],
292
+ "selected_capability_id": route.get("capability_id"),
293
+ "legacy_fallback": False,
294
+ }
295
+ ],
296
+ },
297
+ prompt=prompt,
298
+ )
299
+
300
+ candidates = routing_candidates(registry, prompt)
301
+ if not candidates:
302
+ return enrich_routing_decision(
303
+ {
304
+ "status": "no-match",
305
+ "method": "manifest-routing",
306
+ "selected_agent_id": None,
307
+ "selected_capability_id": None,
308
+ "confidence": 0.0,
309
+ "score": 0,
310
+ "candidates": [],
311
+ },
312
+ prompt=prompt,
313
+ )
314
+
315
+ top = candidates[0]
316
+ second = candidates[1] if len(candidates) > 1 else None
317
+ method = "legacy-fallback" if top.get("legacy_fallback") else "manifest-routing"
318
+ if int(top["score"]) < ROUTING_SELECTED_THRESHOLD:
319
+ status = "low-confidence"
320
+ selected_agent_id = None
321
+ selected_capability_id = None
322
+ confidence = 0.35
323
+ elif second and int(top["score"]) - int(second["score"]) <= ROUTING_AMBIGUITY_DELTA:
324
+ status = "ambiguous"
325
+ selected_agent_id = None
326
+ selected_capability_id = None
327
+ confidence = 0.5
328
+ else:
329
+ status = "selected"
330
+ selected_agent_id = top.get("agent_id")
331
+ selected_capability_id = top.get("selected_capability_id")
332
+ confidence = routing_confidence(int(top["score"]))
333
+
334
+ return enrich_routing_decision(
335
+ {
336
+ "status": status,
337
+ "method": method,
338
+ "selected_agent_id": selected_agent_id,
339
+ "selected_capability_id": selected_capability_id,
340
+ "confidence": confidence,
341
+ "score": top.get("score"),
342
+ "candidates": candidates[:5],
343
+ },
344
+ prompt=prompt,
345
+ )
346
+
347
+
348
+ def enrich_routing_decision(decision: dict[str, Any], *, prompt: str) -> dict[str, Any]:
349
+ result = dict(decision)
350
+ candidates = [item for item in result.get("candidates") or [] if isinstance(item, dict)]
351
+ result["confidence_label"] = routing_confidence_label(result.get("confidence"))
352
+ result["entities"] = extract_routing_entities(prompt)
353
+ result["alternatives"] = routing_alternatives(candidates, selected_agent_id=result.get("selected_agent_id"))
354
+ result["requires_confirmation"] = result.get("status") in {"ambiguous", "low-confidence"}
355
+ result["reason"] = routing_reason(result, candidates)
356
+ if result["requires_confirmation"]:
357
+ result["question"] = routing_confirmation_question(result, candidates)
358
+ result["options"] = routing_confirmation_options(candidates)
359
+ else:
360
+ result["question"] = None
361
+ result["options"] = []
362
+ return result
363
+
364
+
365
+ def routing_confidence_label(confidence: Any) -> str:
366
+ try:
367
+ value = float(confidence)
368
+ except (TypeError, ValueError):
369
+ return "low"
370
+ if value >= 0.75:
371
+ return "high"
372
+ if value >= 0.5:
373
+ return "medium"
374
+ return "low"
375
+
376
+
377
+ def routing_reason(decision: dict[str, Any], candidates: list[dict[str, Any]]) -> str:
378
+ status = decision.get("status")
379
+ method = decision.get("method")
380
+ if status == "deterministic":
381
+ return "Prompt matched a deterministic route with explicit entities."
382
+ if status == "no-match":
383
+ return "No manifest routing candidate matched enough prompt signals."
384
+ if status == "low-confidence":
385
+ top = candidates[0] if candidates else {}
386
+ return f"Best routing candidate {top.get('agent_id') or '-'} scored below the selection threshold."
387
+ if status == "ambiguous":
388
+ names = ", ".join(str(item.get("agent_id")) for item in candidates[:2] if item.get("agent_id"))
389
+ return f"Multiple routing candidates scored too closely: {names or '-'}."
390
+ if status == "selected":
391
+ top = candidates[0] if candidates else {}
392
+ agent = decision.get("selected_agent_id") or top.get("agent_id") or "-"
393
+ capability = decision.get("selected_capability_id") or top.get("selected_capability_id")
394
+ capability_text = f" and capability {capability}" if capability else ""
395
+ signals = routing_candidate_signal_text(top)
396
+ return f"Selected {agent}{capability_text} via {method} using {signals}."
397
+ return "Routing decision was produced by the planner."
398
+
399
+
400
+ def routing_candidate_signal_text(candidate: dict[str, Any]) -> str:
401
+ signals: list[str] = []
402
+ for field, label in (
403
+ ("matched_anchors", "anchors"),
404
+ ("matched_keywords", "keywords"),
405
+ ("matched_domains", "domains"),
406
+ ("matched_aliases", "aliases"),
407
+ ("matched_intents", "intents"),
408
+ ("matched_examples", "examples"),
409
+ ("selected_capability_matched_anchors", "capability anchors"),
410
+ ("selected_capability_matched_keywords", "capability keywords"),
411
+ ("selected_capability_matched_entities", "capability entities"),
412
+ ("selected_capability_matched_aliases", "capability aliases"),
413
+ ("selected_capability_matched_intents", "capability intents"),
414
+ ("selected_capability_matched_examples", "capability examples"),
415
+ ):
416
+ values = candidate.get(field) or []
417
+ if values:
418
+ signals.append(f"{label}: {', '.join(str(item) for item in values[:3])}")
419
+ return "; ".join(signals) if signals else "score overlap"
420
+
421
+
422
+ def routing_alternatives(candidates: list[dict[str, Any]], *, selected_agent_id: Any) -> list[dict[str, Any]]:
423
+ alternatives = []
424
+ for candidate in candidates:
425
+ if candidate.get("agent_id") == selected_agent_id:
426
+ continue
427
+ alternatives.append(
428
+ {
429
+ "agent_id": candidate.get("agent_id"),
430
+ "capability_id": candidate.get("selected_capability_id"),
431
+ "score": candidate.get("score"),
432
+ "reason": routing_candidate_signal_text(candidate),
433
+ }
434
+ )
435
+ return alternatives[:4]
436
+
437
+
438
+ def routing_confirmation_question(decision: dict[str, Any], candidates: list[dict[str, Any]]) -> str:
439
+ if decision.get("status") == "low-confidence":
440
+ return "Qual agente ou capability deve tratar este pedido?"
441
+ names = ", ".join(str(item.get("agent_id")) for item in candidates[:3] if item.get("agent_id"))
442
+ return f"Qual destes agentes deve tratar este pedido: {names or 'nenhum candidato claro'}?"
443
+
444
+
445
+ def routing_confirmation_options(candidates: list[dict[str, Any]]) -> list[dict[str, Any]]:
446
+ options = []
447
+ for candidate in candidates[:5]:
448
+ options.append(
449
+ {
450
+ "agent_id": candidate.get("agent_id"),
451
+ "capability_id": candidate.get("selected_capability_id"),
452
+ "score": candidate.get("score"),
453
+ "reason": routing_candidate_signal_text(candidate),
454
+ }
455
+ )
456
+ return options
457
+
458
+
459
+ def extract_routing_entities(prompt: str) -> dict[str, Any]:
460
+ entities: dict[str, Any] = {}
461
+ card_match = re.search(r"\b(?:card|cartao|tarefa|work\s*item)\s*#?(\d{2,})\b", prompt, re.IGNORECASE)
462
+ if card_match:
463
+ entities["card_id"] = card_match.group(1)
464
+ pr_match = re.search(r"\b(?:pr|pull\s+request)\s*#?(\d+)\b", prompt, re.IGNORECASE)
465
+ if pr_match:
466
+ entities["pr_id"] = pr_match.group(1)
467
+ return entities
468
+
469
+
470
+ def support_level_agent_id(registry: dict[str, Any], prompt: str) -> str | None:
471
+ normalized = normalize(prompt)
472
+ agents = registry.get("agents") or {}
473
+ if re.search(r"\bn1\b|primeiro nivel|1o nivel|1º nivel", normalized) and "n1-support-agent" in agents:
474
+ return "n1-support-agent"
475
+ if re.search(r"\bn2\b|segundo nivel|2o nivel|2º nivel", normalized) and "n2-support-agent" in agents:
476
+ return "n2-support-agent"
477
+ return None
478
+
479
+
480
+ def routing_candidates(registry: dict[str, Any], prompt: str) -> list[dict[str, Any]]:
194
481
  prompt_tokens = expanded_tokens(prompt)
195
482
  normalized_prompt = normalize(prompt)
196
- best: tuple[int, dict[str, Any] | None] = (0, None)
483
+ candidates: list[dict[str, Any]] = []
197
484
  for agent in (registry.get("agents") or {}).values():
198
- if not has_agent_anchor(str(agent.get("id") or ""), prompt_tokens, normalized_prompt):
485
+ if not isinstance(agent, dict):
486
+ continue
487
+ agent_id = str(agent.get("id") or "")
488
+ if is_runtime_agent(registry, agent_id):
489
+ continue
490
+ routing = routing_profile(agent)
491
+ anchors = set(routing.get("anchors") or [])
492
+ keywords = set(routing.get("keywords") or [])
493
+ domains = set(routing.get("domains") or [])
494
+ aliases = set(routing.get("aliases") or [])
495
+ has_declared_routing = bool(
496
+ anchors
497
+ or keywords
498
+ or domains
499
+ or aliases
500
+ or routing.get("intents")
501
+ or routing.get("examples")
502
+ )
503
+ matched_anchors = sorted(matched_routing_anchors(anchors, prompt_tokens, normalized_prompt))
504
+ matched_keywords = sorted(matched_routing_anchors(keywords, prompt_tokens, normalized_prompt))
505
+ matched_domains = sorted(matched_routing_anchors(domains, prompt_tokens, normalized_prompt))
506
+ matched_aliases = sorted(matched_routing_anchors(aliases, prompt_tokens, normalized_prompt))
507
+ matched_intents = sorted(matched_routing_intents(routing.get("intents") or [], prompt_tokens, normalized_prompt))
508
+ matched_examples = sorted(matched_routing_examples(routing.get("examples") or [], normalized_prompt))
509
+ capability_match = best_capability_route_match(agent, prompt)
510
+ if has_declared_routing and not (
511
+ matched_anchors
512
+ or matched_keywords
513
+ or matched_domains
514
+ or matched_aliases
515
+ or matched_intents
516
+ or matched_examples
517
+ or capability_match
518
+ ):
199
519
  continue
200
520
  agent_tokens = expanded_tokens(
201
521
  " ".join(
202
522
  [
203
- str(agent.get("id") or ""),
523
+ agent_id,
204
524
  str(agent.get("name") or ""),
205
525
  str(agent.get("purpose") or ""),
206
- " ".join(
207
- " ".join(
208
- [
209
- str(capability.get("short_id") or ""),
210
- str(capability.get("name") or ""),
211
- str(capability.get("purpose") or ""),
212
- ]
213
- )
214
- for capability in (agent.get("capabilities_index") or {}).values()
215
- if isinstance(capability, dict)
216
- ),
526
+ " ".join(str(item) for item in anchors),
527
+ " ".join(str(item) for item in keywords),
528
+ " ".join(str(item) for item in domains),
529
+ " ".join(str(item) for item in aliases),
530
+ " ".join(str(item) for item in routing.get("intents") or []),
531
+ " ".join(str(item) for item in routing.get("examples") or []),
217
532
  ]
218
533
  )
219
534
  )
220
535
  score = weighted_overlap(prompt_tokens, agent_tokens)
221
- if score > best[0]:
222
- best = (score, agent)
223
- return best[1] if best[0] >= 3 else None
536
+ score += 3 * len(matched_anchors)
537
+ score += 2 * len(matched_keywords)
538
+ score += 2 * len(matched_domains)
539
+ score += 2 * len(matched_aliases)
540
+ score += 2 * len(matched_intents)
541
+ score += 2 * len(matched_examples)
542
+ try:
543
+ score += int(routing.get("priority") or 0) // 50
544
+ except (TypeError, ValueError):
545
+ pass
546
+ if capability_match:
547
+ score += int(capability_match["score"])
548
+ if score <= 0:
549
+ continue
550
+ candidates.append(
551
+ {
552
+ "agent_id": agent_id,
553
+ "score": score,
554
+ "matched_anchors": matched_anchors,
555
+ "matched_keywords": matched_keywords,
556
+ "matched_domains": matched_domains,
557
+ "matched_aliases": matched_aliases,
558
+ "matched_intents": matched_intents,
559
+ "matched_examples": matched_examples,
560
+ "selected_capability_id": (capability_match or {}).get("capability_id"),
561
+ "selected_capability_score": (capability_match or {}).get("score"),
562
+ "selected_capability_matched_anchors": (capability_match or {}).get("matched_anchors", []),
563
+ "selected_capability_matched_keywords": (capability_match or {}).get("matched_keywords", []),
564
+ "selected_capability_matched_entities": (capability_match or {}).get("matched_entities", []),
565
+ "selected_capability_matched_aliases": (capability_match or {}).get("matched_aliases", []),
566
+ "selected_capability_matched_intents": (capability_match or {}).get("matched_intents", []),
567
+ "selected_capability_matched_examples": (capability_match or {}).get("matched_examples", []),
568
+ "legacy_fallback": False,
569
+ }
570
+ )
571
+ candidates.sort(key=lambda item: (-int(item["score"]), str(item["agent_id"])))
572
+ return candidates
573
+
574
+
575
+ def best_capability_route_match(agent: dict[str, Any], prompt: str) -> dict[str, Any] | None:
576
+ capabilities = [item for item in (agent.get("capabilities_index") or {}).values() if isinstance(item, dict)]
577
+ prompt_tokens = expanded_tokens(prompt)
578
+ normalized_prompt = normalize(prompt)
579
+ best: dict[str, Any] | None = None
580
+ for capability in capabilities:
581
+ routing = routing_profile(capability)
582
+ anchors = set(routing.get("anchors") or [])
583
+ keywords = set(routing.get("keywords") or [])
584
+ entities = set(routing.get("entities") or [])
585
+ aliases = set(routing.get("aliases") or [])
586
+ if not (anchors or keywords or entities or aliases or routing.get("intents") or routing.get("examples")):
587
+ continue
588
+ matched_anchors = sorted(matched_routing_anchors(anchors, prompt_tokens, normalized_prompt))
589
+ matched_keywords = sorted(matched_routing_anchors(keywords, prompt_tokens, normalized_prompt))
590
+ matched_entities = sorted(matched_routing_anchors(entities, prompt_tokens, normalized_prompt))
591
+ matched_aliases = sorted(matched_routing_anchors(aliases, prompt_tokens, normalized_prompt))
592
+ matched_intents = sorted(matched_routing_intents(routing.get("intents") or [], prompt_tokens, normalized_prompt))
593
+ matched_examples = sorted(matched_routing_examples(routing.get("examples") or [], normalized_prompt))
594
+ if not (
595
+ matched_anchors
596
+ or matched_keywords
597
+ or matched_entities
598
+ or matched_aliases
599
+ or matched_intents
600
+ or matched_examples
601
+ ):
602
+ continue
603
+ capability_tokens = expanded_tokens(
604
+ " ".join(
605
+ [
606
+ str(capability.get("short_id") or ""),
607
+ str(capability.get("name") or ""),
608
+ str(capability.get("purpose") or ""),
609
+ " ".join(str(item) for item in anchors),
610
+ " ".join(str(item) for item in keywords),
611
+ " ".join(str(item) for item in entities),
612
+ " ".join(str(item) for item in aliases),
613
+ " ".join(str(item) for item in routing.get("intents") or []),
614
+ " ".join(str(item) for item in routing.get("examples") or []),
615
+ ]
616
+ )
617
+ )
618
+ score = weighted_overlap(prompt_tokens, capability_tokens)
619
+ score += 3 * len(matched_anchors)
620
+ score += 2 * len(matched_keywords)
621
+ score += 2 * len(matched_entities)
622
+ score += 2 * len(matched_aliases)
623
+ score += 2 * len(matched_intents)
624
+ score += 2 * len(matched_examples)
625
+ try:
626
+ score += int(routing.get("priority") or 0) // 50
627
+ except (TypeError, ValueError):
628
+ pass
629
+ if score <= 0:
630
+ continue
631
+ candidate = {
632
+ "capability_id": capability.get("short_id"),
633
+ "score": score,
634
+ "matched_anchors": matched_anchors,
635
+ "matched_keywords": matched_keywords,
636
+ "matched_entities": matched_entities,
637
+ "matched_aliases": matched_aliases,
638
+ "matched_intents": matched_intents,
639
+ "matched_examples": matched_examples,
640
+ }
641
+ if best is None or int(candidate["score"]) > int(best["score"]):
642
+ best = candidate
643
+ return best
644
+
224
645
 
646
+ def matched_routing_anchors(anchors: set[str], prompt_tokens: set[str], normalized_prompt: str) -> set[str]:
647
+ matched: set[str] = set()
648
+ for anchor in anchors:
649
+ normalized_anchor = normalize(str(anchor))
650
+ if not normalized_anchor:
651
+ continue
652
+ anchor_tokens = expanded_tokens(normalized_anchor)
653
+ if anchor_tokens & prompt_tokens or (len(normalized_anchor) >= 5 and normalized_anchor in normalized_prompt):
654
+ matched.add(str(anchor))
655
+ return matched
225
656
 
226
- def has_agent_anchor(agent_id: str, prompt_tokens: set[str], normalized_prompt: str) -> bool:
227
- anchors = AGENT_ANCHORS.get(agent_id)
228
- if not anchors:
229
- return False
230
- if anchors & prompt_tokens:
231
- return True
232
- return any(anchor in normalized_prompt for anchor in anchors if len(anchor) >= 5)
657
+
658
+ def matched_routing_intents(intents: list[Any], prompt_tokens: set[str], normalized_prompt: str) -> set[str]:
659
+ matched: set[str] = set()
660
+ for intent in intents:
661
+ text = normalize(str(intent))
662
+ if not text:
663
+ continue
664
+ intent_tokens = expanded_tokens(text.replace(".", " ").replace("-", " "))
665
+ if intent_tokens and intent_tokens <= prompt_tokens:
666
+ matched.add(str(intent))
667
+ elif len(text) >= 5 and text in normalized_prompt:
668
+ matched.add(str(intent))
669
+ return matched
670
+
671
+
672
+ def matched_routing_examples(examples: list[Any], normalized_prompt: str) -> set[str]:
673
+ matched: set[str] = set()
674
+ raw_prompt_tokens = routing_text_tokens(normalized_prompt)
675
+ for example in examples:
676
+ text = normalize(str(example))
677
+ if not text:
678
+ continue
679
+ example_tokens = routing_text_tokens(text)
680
+ meaningful_tokens = example_tokens - STOP_WORDS
681
+ raw_overlap = meaningful_tokens & raw_prompt_tokens
682
+ if raw_overlap and len(raw_overlap) >= max(3, min(5, len(meaningful_tokens) // 2)):
683
+ matched.add(str(example))
684
+ elif len(text) >= 8 and text in normalized_prompt:
685
+ matched.add(str(example))
686
+ return matched
687
+
688
+
689
+ def routing_text_tokens(value: str) -> set[str]:
690
+ return {
691
+ token
692
+ for token in re.findall(r"[a-z0-9][a-z0-9._-]*", normalize(value))
693
+ if len(token) >= 3 and token not in STOP_WORDS
694
+ }
695
+
696
+
697
+ def routing_profile(item: dict[str, Any]) -> dict[str, Any]:
698
+ routing = item.get("routing") if isinstance(item.get("routing"), dict) else {}
699
+ return routing if isinstance(routing, dict) else {}
700
+
701
+
702
+ def routing_confidence(score: int) -> float:
703
+ return round(max(0.05, min(0.95, score / 12)), 2)
233
704
 
234
705
 
235
706
  def best_capability_task(registry: dict[str, Any], agent_id: str, prompt: str) -> dict[str, Any] | None:
@@ -237,11 +708,20 @@ def best_capability_task(registry: dict[str, Any], agent_id: str, prompt: str) -
237
708
  capabilities = [item for item in (agent.get("capabilities_index") or {}).values() if isinstance(item, dict)]
238
709
  if not capabilities:
239
710
  return None
711
+ route_match = best_capability_route_match(agent, prompt)
712
+ if route_match:
713
+ capability_id = route_match.get("capability_id")
714
+ capability = next((item for item in capabilities if item.get("short_id") == capability_id), None)
715
+ if capability:
716
+ task = base_task(capability, prompt=prompt)
717
+ task["primary"] = True
718
+ task["selection"] = {"method": "manifest-routing", "score": route_match.get("score")}
719
+ return task
240
720
  hinted = hinted_capability(capabilities, prompt)
241
721
  if hinted:
242
722
  task = base_task(hinted, prompt=prompt)
243
723
  task["primary"] = True
244
- task["selection"] = {"method": "registry-hint", "score": None}
724
+ task["selection"] = {"method": "legacy-hint", "score": None}
245
725
  return task
246
726
  prompt_tokens = expanded_tokens(prompt)
247
727
  best: tuple[int, dict[str, Any] | None] = (0, None)
@@ -287,13 +767,14 @@ def hinted_capability(capabilities: list[dict[str, Any]], prompt: str) -> dict[s
287
767
 
288
768
 
289
769
  def base_task(capability: dict[str, Any], *, prompt: str) -> dict[str, Any]:
290
- return {
770
+ task = {
291
771
  "id": f"{capability['agent_id']}.{capability['short_id']}",
292
772
  "agent_id": capability["agent_id"],
293
773
  "capability_id": capability["short_id"],
294
774
  "capability": capability["id"],
295
775
  "purpose": capability.get("purpose"),
296
- "write_policy": capability.get("write_policy") or "read_only",
776
+ "write_policy": normalize_write_policy(capability.get("write_policy")),
777
+ "write_policy_metadata": write_policy_public_fields(capability.get("write_policy"))["write_policy_metadata"],
297
778
  "provider": infer_provider(capability),
298
779
  "args": [],
299
780
  "entities": {},
@@ -302,6 +783,52 @@ def base_task(capability: dict[str, Any], *, prompt: str) -> dict[str, Any]:
302
783
  "prompt": redact_secrets(prompt),
303
784
  "primary": False,
304
785
  }
786
+ return normalize_collaborative_task(task, role=collaboration_role_for_task(task))
787
+
788
+
789
+ def collaboration_role_for_task(task: dict[str, Any]) -> str:
790
+ agent_id = str(task.get("agent_id") or "")
791
+ capability_id = str(task.get("capability_id") or "")
792
+ if agent_id == PROVIDER_CONFIGURATOR_AGENT_ID:
793
+ return "coordinator"
794
+ if agent_id == REVIEWER_AGENT_ID or capability_id.startswith("review"):
795
+ return "reviewer"
796
+ if capability_id.startswith(("read", "search", "list", "inspect", "load", "extract", "collect", "trace", "find")):
797
+ return "collector"
798
+ if capability_id.startswith(("update", "move", "comment", "assign", "attach", "register")):
799
+ return "coordinator"
800
+ return "analyzer"
801
+
802
+
803
+ def policy_summary_for_plan(
804
+ specialist_tasks: list[dict[str, Any]],
805
+ configuration_tasks: list[dict[str, Any]],
806
+ review: dict[str, Any],
807
+ ) -> dict[str, Any]:
808
+ tasks = [*specialist_tasks, *configuration_tasks]
809
+ if review:
810
+ tasks.append(review)
811
+ summary = {
812
+ "total_tasks": len(tasks),
813
+ "autonomous_safe": 0,
814
+ "requires_confirmation": 0,
815
+ "blocked_by_default": 0,
816
+ "unknown": 0,
817
+ "policies": {},
818
+ }
819
+ for task in tasks:
820
+ metadata = task.get("write_policy_metadata") if isinstance(task.get("write_policy_metadata"), dict) else {}
821
+ policy = str(metadata.get("canonical") or task.get("write_policy") or "unknown")
822
+ summary["policies"][policy] = int(summary["policies"].get(policy, 0)) + 1
823
+ if metadata.get("known") is False:
824
+ summary["unknown"] += 1
825
+ if metadata.get("autonomous_safe"):
826
+ summary["autonomous_safe"] += 1
827
+ if metadata.get("requires_confirmation"):
828
+ summary["requires_confirmation"] += 1
829
+ if metadata.get("blocked_by_default"):
830
+ summary["blocked_by_default"] += 1
831
+ return summary
305
832
 
306
833
 
307
834
  def configuration_tasks_for(
@@ -327,6 +854,7 @@ def configuration_tasks_for(
327
854
  provider_agents.setdefault(provider_id, str(task.get("agent_id") or ""))
328
855
  result: list[dict[str, Any]] = []
329
856
  seen: set[str] = set()
857
+ provider_configurator_id = runtime_agent_id(registry, "provider-configurator", PROVIDER_CONFIGURATOR_AGENT_ID)
330
858
  for provider in providers:
331
859
  if provider in seen:
332
860
  continue
@@ -339,21 +867,29 @@ def configuration_tasks_for(
339
867
  source = None
340
868
  if source:
341
869
  continue
342
- capability = find_capability(registry, PROVIDER_CONFIGURATOR_AGENT_ID, "configure-provider-source") or {}
870
+ capability = find_capability(registry, provider_configurator_id, "configure-provider-source") or {}
343
871
  wizard = provider_setup_wizard(root, provider, prompt=prompt, route=route, reason="Provider/source required by multi-agent plan.")
344
872
  result.append(
345
- {
346
- "id": f"provider-configurator.{provider}",
347
- "agent_id": PROVIDER_CONFIGURATOR_AGENT_ID,
348
- "capability_id": "configure-provider-source",
349
- "capability": capability.get("id") or "provider-configurator.configure-provider-source",
350
- "purpose": capability.get("purpose"),
351
- "write_policy": capability.get("write_policy") or "local-config-write",
352
- "path": capability.get("path"),
353
- "provider": provider,
354
- "status": "waiting-for-user",
355
- "setup_wizard": wizard,
356
- }
873
+ normalize_collaborative_task(
874
+ {
875
+ "id": f"{provider_configurator_id}.{provider}",
876
+ "agent_id": provider_configurator_id,
877
+ "capability_id": "configure-provider-source",
878
+ "capability": capability.get("id") or f"{provider_configurator_id}.configure-provider-source",
879
+ "purpose": capability.get("purpose"),
880
+ "write_policy": normalize_write_policy(capability.get("write_policy"), default="local_config_write"),
881
+ "write_policy_metadata": write_policy_public_fields(
882
+ capability.get("write_policy"),
883
+ default="local_config_write",
884
+ )["write_policy_metadata"],
885
+ "path": capability.get("path"),
886
+ "provider": provider,
887
+ "status": "waiting-for-user",
888
+ "setup_wizard": wizard,
889
+ },
890
+ role="coordinator",
891
+ sequence=len(result),
892
+ )
357
893
  )
358
894
  return result
359
895
 
@@ -383,31 +919,54 @@ def mark_plan_after_execution(plan: dict[str, Any], executed: list[dict[str, Any
383
919
  plan = dict(plan)
384
920
  plan["executed_tasks"] = executed
385
921
  plan["blocked_tasks"] = blocked
386
- if blocked and not executed:
922
+ controller_run = plan.get("module_controller_run") if isinstance(plan.get("module_controller_run"), dict) else {}
923
+ if controller_run.get("status") == "needs-input":
924
+ plan["status"] = "needs-input"
925
+ plan["human_escalations"] = list(controller_run.get("human_escalations") or [])
926
+ elif blocked and not executed:
387
927
  plan["status"] = "blocked"
388
928
  elif blocked and executed:
389
929
  plan["status"] = "partial"
390
930
  elif executed:
391
931
  plan["status"] = "ok"
392
- plan["trace"] = trace_for_plan(plan.get("specialist_tasks") or [], plan.get("configuration_tasks") or [], executed=executed, blocked=blocked, status=plan["status"])
932
+ coordinator = plan.get("coordinator_agent") if isinstance(plan.get("coordinator_agent"), dict) else {}
933
+ plan["trace"] = trace_for_plan(
934
+ plan.get("specialist_tasks") or [],
935
+ plan.get("configuration_tasks") or [],
936
+ executed=executed,
937
+ blocked=blocked,
938
+ status=plan["status"],
939
+ coordinator_agent_id=str(coordinator.get("id") or RUNTIME_COORDINATOR["id"]),
940
+ )
393
941
  return plan
394
942
 
395
943
 
396
944
  def review_task(registry: dict[str, Any], review_gate: dict[str, Any]) -> dict[str, Any]:
397
- capability = find_capability(registry, REVIEWER_AGENT_ID, "review-final-output") or {}
945
+ reviewer_agent_id = runtime_agent_id(registry, "reviewer", REVIEWER_AGENT_ID)
946
+ capability = find_capability(registry, reviewer_agent_id, "review-final-output") or {}
398
947
  task = {
399
- "id": "execution-reviewer.review-final-output",
400
- "agent_id": REVIEWER_AGENT_ID,
948
+ "id": f"{reviewer_agent_id}.review-final-output",
949
+ "agent_id": reviewer_agent_id,
401
950
  "capability_id": "review-final-output",
402
- "capability": capability.get("id") or "execution-reviewer.review-final-output",
951
+ "capability": capability.get("id") or f"{reviewer_agent_id}.review-final-output",
403
952
  "purpose": capability.get("purpose"),
404
- "write_policy": capability.get("write_policy") or "read-only",
953
+ "write_policy": normalize_write_policy(capability.get("write_policy")),
954
+ "write_policy_metadata": write_policy_public_fields(capability.get("write_policy"))["write_policy_metadata"],
405
955
  "path": capability.get("path"),
406
956
  "status": "pending" if review_gate.get("required") else "not-required",
407
957
  "required": bool(review_gate.get("required")),
408
958
  "preferred_reviewers": list(review_gate.get("preferred_reviewers") or []),
409
959
  }
410
- return task
960
+ return normalize_collaborative_task(task, role="reviewer")
961
+
962
+
963
+ def attach_review_dependencies(review: dict[str, Any], specialist_tasks: list[dict[str, Any]]) -> dict[str, Any]:
964
+ dependencies = [
965
+ str(task.get("task_id") or task.get("id"))
966
+ for task in specialist_tasks
967
+ if isinstance(task, dict) and (task.get("task_id") or task.get("id"))
968
+ ]
969
+ return normalize_collaborative_task(review, role="reviewer", depends_on=dependencies)
411
970
 
412
971
 
413
972
  def mark_review_task(plan: dict[str, Any], *, reviewer: str) -> dict[str, Any]:
@@ -426,68 +985,101 @@ def trace_for_plan(
426
985
  executed: list[dict[str, Any]] | None = None,
427
986
  blocked: list[dict[str, Any]] | None = None,
428
987
  status: str,
988
+ coordinator_agent_id: str = RUNTIME_COORDINATOR["id"],
429
989
  ) -> list[dict[str, Any]]:
430
- trace = [{"agent_id": RUNTIME_COORDINATOR["id"], "action": "plan", "status": status}]
431
- trace.extend({"agent_id": task["agent_id"], "action": "configure", "status": task.get("status")} for task in configuration_tasks)
432
- trace.extend({"agent_id": task["agent_id"], "action": "execute", "status": task.get("status")} for task in specialist_tasks)
433
- trace.extend({"agent_id": item["agent_id"], "action": "executed", "status": item.get("status")} for item in executed or [])
434
- trace.extend({"agent_id": item["agent_id"], "action": "blocked", "status": item.get("status")} for item in blocked or [])
990
+ trace = [{"agent_id": coordinator_agent_id, "action": "plan", "status": status}]
991
+ trace.extend(trace_task(task, action="delegate-config") for task in configuration_tasks)
992
+ trace.extend(trace_task(task, action="delegate") for task in specialist_tasks)
993
+ trace.extend(trace_result(item, action="handoff") for item in executed or [])
994
+ trace.extend(trace_result(item, action="blocked") for item in blocked or [])
435
995
  return trace
436
996
 
437
997
 
998
+ def trace_task(task: dict[str, Any], *, action: str) -> dict[str, Any]:
999
+ return {
1000
+ "task_id": task.get("task_id") or task.get("id"),
1001
+ "agent_id": task["agent_id"],
1002
+ "capability_id": task.get("capability_id"),
1003
+ "role": task.get("role"),
1004
+ "depends_on": list(task.get("depends_on") or []),
1005
+ "action": action,
1006
+ "status": task.get("status"),
1007
+ }
1008
+
1009
+
1010
+ def trace_result(item: dict[str, Any], *, action: str) -> dict[str, Any]:
1011
+ return {
1012
+ "task_id": item.get("task_id") or item.get("id"),
1013
+ "agent_id": item["agent_id"],
1014
+ "capability_id": item.get("capability_id"),
1015
+ "role": item.get("role"),
1016
+ "action": action,
1017
+ "status": item.get("status"),
1018
+ }
1019
+
1020
+
438
1021
  def infer_provider(capability: dict[str, Any]) -> str | None:
1022
+ if capability.get("provider"):
1023
+ return str(capability["provider"])
1024
+ runtime = capability.get("runtime") if isinstance(capability.get("runtime"), dict) else {}
1025
+ if runtime.get("provider"):
1026
+ return str(runtime["provider"])
1027
+ integration = capability.get("integration") if isinstance(capability.get("integration"), dict) else {}
1028
+ if integration.get("provider"):
1029
+ return str(integration["provider"])
439
1030
  requires = capability.get("requires") if isinstance(capability.get("requires"), dict) else {}
440
1031
  providers = requires.get("providers") if isinstance(requires.get("providers"), list) else []
441
1032
  if providers and isinstance(providers[0], dict):
442
1033
  return str(providers[0].get("id") or "") or None
443
- integration = capability.get("integration") if isinstance(capability.get("integration"), dict) else {}
444
- repository = str(integration.get("repository") or "")
445
- agent_id = str(capability.get("agent_id") or "")
446
- if "azure" in repository or agent_id == "azure-devops-orchestrator":
447
- return "azure-devops"
448
- if "topdesk" in repository or agent_id == "topdesk-orchestrator":
449
- return "topdesk"
450
- if "cloudwatch" in repository:
451
- return "aws-cloudwatch"
452
- if "elasticsearch" in repository:
453
- return "elasticsearch"
454
- if "sqlserver" in repository:
455
- return "sqlserver"
456
- if "postgres" in repository:
457
- return "postgres"
458
- if "/aws/" in repository or "aws-" in repository:
459
- return "aws"
460
1034
  return None
461
1035
 
462
1036
 
463
1037
  def attach_local_llm_agent_contract(registry: dict[str, Any], model_plan: dict[str, Any]) -> dict[str, Any]:
464
1038
  plan = dict(model_plan)
465
- agent = (registry.get("agents") or {}).get(LOCAL_LLM_OPERATOR_AGENT_ID)
466
- select_capability = find_capability(registry, LOCAL_LLM_OPERATOR_AGENT_ID, "select-local-worker") or {}
467
- delegate_capability = find_capability(registry, LOCAL_LLM_OPERATOR_AGENT_ID, "delegate-operational-task") or {}
1039
+ local_llm_agent_id = runtime_agent_id(registry, "local-worker", LOCAL_LLM_OPERATOR_AGENT_ID)
1040
+ agent = (registry.get("agents") or {}).get(local_llm_agent_id)
1041
+ select_capability = find_capability(registry, local_llm_agent_id, "select-local-worker") or {}
1042
+ delegate_capability = find_capability(registry, local_llm_agent_id, "delegate-operational-task") or {}
468
1043
  plan["operator_agent"] = slim_agent(agent) if isinstance(agent, dict) else {
469
- "id": LOCAL_LLM_OPERATOR_AGENT_ID,
1044
+ "id": local_llm_agent_id,
470
1045
  "name": "Local LLM Operator",
471
1046
  "kind": "runtime-agent",
472
1047
  }
473
1048
  plan["selection_capability"] = {
474
- "agent_id": LOCAL_LLM_OPERATOR_AGENT_ID,
1049
+ "agent_id": local_llm_agent_id,
475
1050
  "capability_id": "select-local-worker",
476
- "capability": select_capability.get("id") or "local-llm-operator.select-local-worker",
1051
+ "capability": select_capability.get("id") or f"{local_llm_agent_id}.select-local-worker",
477
1052
  }
478
1053
  plan["delegation_capability"] = {
479
- "agent_id": LOCAL_LLM_OPERATOR_AGENT_ID,
1054
+ "agent_id": local_llm_agent_id,
480
1055
  "capability_id": "delegate-operational-task",
481
- "capability": delegate_capability.get("id") or "local-llm-operator.delegate-operational-task",
1056
+ "capability": delegate_capability.get("id") or f"{local_llm_agent_id}.delegate-operational-task",
482
1057
  }
483
1058
  return plan
484
1059
 
485
1060
 
1061
+ def runtime_agent_by_role(registry: dict[str, Any], role: str, *, fallback: dict[str, Any]) -> dict[str, Any]:
1062
+ return runtime_agent(registry, runtime_agent_id(registry, role, str(fallback.get("id") or "")), fallback=fallback)
1063
+
1064
+
1065
+ def runtime_agent_id(registry: dict[str, Any], role: str, fallback_agent_id: str) -> str:
1066
+ runtime_roles = registry.get("runtime_roles") if isinstance(registry.get("runtime_roles"), dict) else {}
1067
+ return str(runtime_roles.get(role) or fallback_agent_id)
1068
+
1069
+
1070
+ def is_runtime_agent(registry: dict[str, Any], agent_id: str) -> bool:
1071
+ agent = (registry.get("agents") or {}).get(agent_id)
1072
+ if not isinstance(agent, dict):
1073
+ return agent_id in {RUNTIME_COORDINATOR["id"], REVIEWER_AGENT_ID, PROVIDER_CONFIGURATOR_AGENT_ID, LOCAL_LLM_OPERATOR_AGENT_ID}
1074
+ return agent.get("kind") == "runtime-agent" or bool(agent.get("runtime_role"))
1075
+
1076
+
486
1077
  def runtime_agent(registry: dict[str, Any], agent_id: str, *, fallback: dict[str, Any]) -> dict[str, Any]:
487
1078
  agent = (registry.get("agents") or {}).get(agent_id)
488
1079
  if isinstance(agent, dict):
489
1080
  public = slim_agent(agent)
490
- public["role"] = fallback.get("role")
1081
+ runtime_role = agent.get("runtime_role") if isinstance(agent.get("runtime_role"), dict) else {}
1082
+ public["role"] = runtime_role.get("kind") or fallback.get("role")
491
1083
  return public
492
1084
  return dict(fallback)
493
1085
 
@@ -499,9 +1091,107 @@ def slim_agent(agent: dict[str, Any]) -> dict[str, Any]:
499
1091
  "kind": agent.get("kind") or "specialist-agent",
500
1092
  "purpose": agent.get("purpose"),
501
1093
  "path": agent.get("path"),
1094
+ "agent_mode": agent.get("agent_mode") if isinstance(agent.get("agent_mode"), dict) else {},
1095
+ }
1096
+
1097
+
1098
+ def module_controller_contract(domain_agent: dict[str, Any], specialist_tasks: list[dict[str, Any]]) -> dict[str, Any]:
1099
+ mode = domain_agent.get("agent_mode") if isinstance(domain_agent.get("agent_mode"), dict) else {}
1100
+ if not mode:
1101
+ return {"enabled": False, "reason": "agent-mode-not-declared"}
1102
+ planned_capabilities = [
1103
+ f"{task.get('agent_id')}/{task.get('capability_id')}"
1104
+ for task in specialist_tasks
1105
+ if isinstance(task, dict) and task.get("agent_id") and task.get("capability_id")
1106
+ ]
1107
+ return {
1108
+ "enabled": True,
1109
+ "agent_id": domain_agent.get("id"),
1110
+ "mode": mode,
1111
+ "limits": {
1112
+ "max_steps": mode.get("max_steps"),
1113
+ "max_specialists": mode.get("max_specialists"),
1114
+ "max_llm_calls": mode.get("max_llm_calls"),
1115
+ "timeout_seconds": mode.get("timeout_seconds"),
1116
+ "external_writes": mode.get("external_writes"),
1117
+ "can_call_llm": mode.get("can_call_llm"),
1118
+ },
1119
+ "allowed_capabilities": list(mode.get("allowed_capabilities") or []),
1120
+ "planned_capabilities": planned_capabilities,
1121
+ "stop_conditions": list(mode.get("stop_conditions") or []),
1122
+ }
1123
+
1124
+
1125
+ def execution_model_contract(
1126
+ domain_agent: dict[str, Any],
1127
+ review_gate: dict[str, Any],
1128
+ module_controller: dict[str, Any],
1129
+ model_plan: dict[str, Any],
1130
+ ) -> dict[str, Any]:
1131
+ mode = domain_agent.get("agent_mode") if isinstance(domain_agent.get("agent_mode"), dict) else {}
1132
+ stop_conditions = list(mode.get("stop_conditions") or module_controller.get("stop_conditions") or [])
1133
+ if not stop_conditions:
1134
+ stop_conditions = ["success", "needs-input", "blocked", "max-steps"]
1135
+ max_llm_calls = resolve_model_limited_llm_calls(mode.get("max_llm_calls"), model_plan.get("max_llm_calls"))
1136
+ return {
1137
+ "schema_version": "ai-devkit.execution-model/v1",
1138
+ "decision_owner": "agent-devkit-core",
1139
+ "coordinator": "task-orchestrator",
1140
+ "domain_agent": domain_agent.get("id"),
1141
+ "review_required": bool(review_gate.get("required")),
1142
+ "model_strategy": model_plan.get("strategy"),
1143
+ "model_risk": model_plan.get("risk"),
1144
+ "model_confidence": model_plan.get("confidence"),
1145
+ "model_reason": model_plan.get("reason"),
1146
+ "model_fallback": model_plan.get("fallback"),
1147
+ "limits": {
1148
+ "max_steps": mode.get("max_steps") or 1,
1149
+ "max_specialists": mode.get("max_specialists") or 1,
1150
+ "max_llm_calls": max_llm_calls if max_llm_calls is not None else 0,
1151
+ "timeout_seconds": mode.get("timeout_seconds") or 300,
1152
+ },
1153
+ "allowed_side_effects": {
1154
+ "external_writes": mode.get("external_writes") is True,
1155
+ "can_call_capabilities": mode.get("can_call_capabilities") is True,
1156
+ "can_call_llm": False if max_llm_calls == 0 else mode.get("can_call_llm"),
1157
+ },
1158
+ "human_escalation_policy": {
1159
+ "on_low_confidence": True,
1160
+ "on_conflict": True,
1161
+ "on_high_risk": True,
1162
+ "on_reviewer_block": True,
1163
+ "on_policy_block": True,
1164
+ },
1165
+ "stop_conditions": stop_conditions,
502
1166
  }
503
1167
 
504
1168
 
1169
+ def attach_autonomy_to_execution_model(
1170
+ execution_model: dict[str, Any],
1171
+ autonomy_contract: dict[str, Any],
1172
+ ) -> dict[str, Any]:
1173
+ model = dict(execution_model)
1174
+ model["autonomy_level"] = autonomy_contract.get("level")
1175
+ model["autonomy_level_id"] = autonomy_contract.get("level_id")
1176
+ model["autonomy_status"] = autonomy_contract.get("status")
1177
+ model["execution_allowed"] = autonomy_contract.get("execution_allowed") is True
1178
+ model["requires_human"] = autonomy_contract.get("requires_human") is True
1179
+ model["requires_review"] = autonomy_contract.get("requires_review") is True
1180
+ return model
1181
+
1182
+
1183
+ def resolve_model_limited_llm_calls(mode_limit: Any, model_limit: Any) -> int:
1184
+ limits: list[int] = []
1185
+ for value in (mode_limit, model_limit):
1186
+ if value is None:
1187
+ continue
1188
+ try:
1189
+ limits.append(max(0, int(value)))
1190
+ except (TypeError, ValueError):
1191
+ continue
1192
+ return min(limits) if limits else 0
1193
+
1194
+
505
1195
  def normalize(prompt: str) -> str:
506
1196
  return " ".join(strip_accents(prompt).lower().split())
507
1197