talkops-opscloud 0.3.0b7__tar.gz → 0.3.0b8__tar.gz

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 (400) hide show
  1. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/PKG-INFO +1 -1
  2. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/pyproject.toml +1 -1
  3. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/agent/factory.py +41 -10
  4. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/server_hooks.py +1 -1
  5. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/tool_filter.py +150 -97
  6. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/app.py +231 -10
  7. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/remote_client.py +42 -18
  8. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/textual_adapter.py +43 -12
  9. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/chat_input.py +48 -3
  10. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/messages.py +13 -0
  11. talkops_opscloud-0.3.0b8/tests/unit_tests/test_plugin_agent_skill_mcp_scoping.py +498 -0
  12. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_tool_filter.py +61 -0
  13. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_tui_app.py +141 -0
  14. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/uv.lock +1 -1
  15. talkops_opscloud-0.3.0b7/tests/unit_tests/test_plugin_agent_skill_mcp_scoping.py +0 -228
  16. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/.dockerignore +0 -0
  17. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/.env.example +0 -0
  18. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/.github/workflows/ci.yml +0 -0
  19. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/.github/workflows/release-pypi.yml +0 -0
  20. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/.gitignore +0 -0
  21. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/.python-version +0 -0
  22. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/LICENSE +0 -0
  23. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/README.md +0 -0
  24. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/assets/opscloud-banner.gif +0 -0
  25. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/Configuration.md +0 -0
  26. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/approval-mode.md +0 -0
  27. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/cli-reference.md +0 -0
  28. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/config.toml.md +0 -0
  29. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/credentials.md +0 -0
  30. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/goal-and-rubrics.md +0 -0
  31. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/hooks.md +0 -0
  32. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/mcp-tools.md +0 -0
  33. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/memory-and-skills.md +0 -0
  34. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/model-providers.md +0 -0
  35. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/overview.md +0 -0
  36. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/plugins.md +0 -0
  37. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/quickstart.md +0 -0
  38. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/remote-sandboxes.md +0 -0
  39. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/subagents.md +0 -0
  40. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/scripts/install.sh +0 -0
  41. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/__init__.py +0 -0
  42. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/__main__.py +0 -0
  43. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/_constants.py +0 -0
  44. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/_debug.py +0 -0
  45. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/_debug_buffer.py +0 -0
  46. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/_textual_patches.py +0 -0
  47. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/_version.py +0 -0
  48. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/agent/__init__.py +0 -0
  49. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/agent/config.py +0 -0
  50. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/approval_mode.py +0 -0
  51. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/backend/__init__.py +0 -0
  52. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/backend/composite.py +0 -0
  53. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/backend/local.py +0 -0
  54. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/backend/registry.py +0 -0
  55. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/backend/sandbox_config.py +0 -0
  56. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/backend/sandbox_factory.py +0 -0
  57. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/built_in_skills/remember/SKILL.md +0 -0
  58. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/built_in_skills/skill-creator/SKILL.md +0 -0
  59. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
  60. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
  61. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/__init__.py +0 -0
  62. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/commands/__init__.py +0 -0
  63. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/commands/auth.py +0 -0
  64. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/commands/doctor.py +0 -0
  65. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/commands/mcp.py +0 -0
  66. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/commands/threads.py +0 -0
  67. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/interactive.py +0 -0
  68. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/main.py +0 -0
  69. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/non_interactive.py +0 -0
  70. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/server_manager.py +0 -0
  71. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/__init__.py +0 -0
  72. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/_base.py +0 -0
  73. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/_guards.py +0 -0
  74. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/_router.py +0 -0
  75. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/_types.py +0 -0
  76. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/__init__.py +0 -0
  77. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/auth.py +0 -0
  78. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/bug.py +0 -0
  79. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/clear.py +0 -0
  80. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/cloud.py +0 -0
  81. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/compact.py +0 -0
  82. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/config_cmd.py +0 -0
  83. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/context.py +0 -0
  84. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/cost.py +0 -0
  85. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/doctor.py +0 -0
  86. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/effort.py +0 -0
  87. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/exit_cmd.py +0 -0
  88. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/fast.py +0 -0
  89. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/help_cmd.py +0 -0
  90. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/mcp.py +0 -0
  91. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/model.py +0 -0
  92. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/permissions.py +0 -0
  93. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/plugins.py +0 -0
  94. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/pool.py +0 -0
  95. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/resume.py +0 -0
  96. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/skills.py +0 -0
  97. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/__init__.py +0 -0
  98. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/agents.py +0 -0
  99. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/btw.py +0 -0
  100. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/copy.py +0 -0
  101. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/goal.py +0 -0
  102. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/loop.py +0 -0
  103. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/memory.py +0 -0
  104. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/review.py +0 -0
  105. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/rubric.py +0 -0
  106. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/runtime.py +0 -0
  107. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/skill_creator.py +0 -0
  108. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/skill_invoke.py +0 -0
  109. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/tasks.py +0 -0
  110. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/trace.py +0 -0
  111. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/ui_toggles.py +0 -0
  112. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/version.py +0 -0
  113. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/registry.py +0 -0
  114. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/__init__.py +0 -0
  115. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/adapters/__init__.py +0 -0
  116. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/adapters/postgres.py +0 -0
  117. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/adapters/sqlite.py +0 -0
  118. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/aws.py +0 -0
  119. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/cloud_profiles.py +0 -0
  120. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/env_vars.py +0 -0
  121. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/langsmith.py +0 -0
  122. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/manifest.py +0 -0
  123. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/metadata.py +0 -0
  124. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/paths.py +0 -0
  125. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/plugins.py +0 -0
  126. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/settings.py +0 -0
  127. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/store.py +0 -0
  128. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/store_factory.py +0 -0
  129. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/toml_config.py +0 -0
  130. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/editor.py +0 -0
  131. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/exceptions.py +0 -0
  132. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/file_ops.py +0 -0
  133. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/__init__.py +0 -0
  134. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/env.py +0 -0
  135. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/interrupt.py +0 -0
  136. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/models/__init__.py +0 -0
  137. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/models/adapters.py +0 -0
  138. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/models/config.py +0 -0
  139. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/models/domain.py +0 -0
  140. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/models/transport.py +0 -0
  141. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/tools.py +0 -0
  142. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/input.py +0 -0
  143. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/__init__.py +0 -0
  144. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/base.py +0 -0
  145. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/content_filter.py +0 -0
  146. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/event_bus.py +0 -0
  147. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/hooks.py +0 -0
  148. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/identity.py +0 -0
  149. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/notifications.py +0 -0
  150. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/stream_bridge.py +0 -0
  151. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/thread_store.py +0 -0
  152. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/json_types.py +0 -0
  153. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/__init__.py +0 -0
  154. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/config.py +0 -0
  155. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/discovery.py +0 -0
  156. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/mcp_info.py +0 -0
  157. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/middleware.py +0 -0
  158. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/preload.py +0 -0
  159. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/raw_config.py +0 -0
  160. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/semantic_profiler.py +0 -0
  161. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/session_manager.py +0 -0
  162. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/trust.py +0 -0
  163. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/memory/__init__.py +0 -0
  164. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/memory/branch.py +0 -0
  165. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/memory/guard.py +0 -0
  166. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/memory/onboarding.py +0 -0
  167. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/memory/registry.py +0 -0
  168. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/memory/store.py +0 -0
  169. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/__init__.py +0 -0
  170. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/_repository_bounds.py +0 -0
  171. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/ask_user.py +0 -0
  172. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/auto_mode.py +0 -0
  173. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/auto_mode_hitl.py +0 -0
  174. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/compaction.py +0 -0
  175. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/configurable_model.py +0 -0
  176. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/cost_tracking.py +0 -0
  177. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/glm_stall_recovery.py +0 -0
  178. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/goal_criteria.py +0 -0
  179. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/goal_state_notice.py +0 -0
  180. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/goal_tools.py +0 -0
  181. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/headless_mcp_guard.py +0 -0
  182. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/jev_model_router.py +0 -0
  183. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/local_context.py +0 -0
  184. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/mcp_context.py +0 -0
  185. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/mcp_middleware.py +0 -0
  186. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/memory_guard.py +0 -0
  187. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/model_retry.py +0 -0
  188. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/registry.py +0 -0
  189. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/reliable_rubric.py +0 -0
  190. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/resume_state.py +0 -0
  191. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/shell_allow_list.py +0 -0
  192. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/skills.py +0 -0
  193. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/subagent_artifacts.py +0 -0
  194. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/subagent_telemetry.py +0 -0
  195. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/subagents.py +0 -0
  196. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/unified_system_message.py +0 -0
  197. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/model/__init__.py +0 -0
  198. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/model/config.py +0 -0
  199. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/model/factory.py +0 -0
  200. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/model/pool.py +0 -0
  201. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/model/reasoning.py +0 -0
  202. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/offload.py +0 -0
  203. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/output.py +0 -0
  204. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/__init__.py +0 -0
  205. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/_json.py +0 -0
  206. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/adapters/__init__.py +0 -0
  207. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/adapters/agents.py +0 -0
  208. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/adapters/commands.py +0 -0
  209. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/adapters/mcp.py +0 -0
  210. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/adapters/skills.py +0 -0
  211. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/commands_cli.py +0 -0
  212. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/discovery.py +0 -0
  213. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/manifest.py +0 -0
  214. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/marketplace.py +0 -0
  215. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/models.py +0 -0
  216. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/project_plugins.py +0 -0
  217. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/protocol.py +0 -0
  218. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/store.py +0 -0
  219. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/substitution.py +0 -0
  220. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/project_utils.py +0 -0
  221. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/prompts/__init__.py +0 -0
  222. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/prompts/system.py +0 -0
  223. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/prompts/templates/system_prompt.md +0 -0
  224. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/prompts/types.py +0 -0
  225. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/rubrics/__init__.py +0 -0
  226. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/rubrics/evaluator.py +0 -0
  227. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/rubrics/evidence_extractor.py +0 -0
  228. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/rubrics/generator.py +0 -0
  229. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/rubrics/jev_compiler.py +0 -0
  230. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/rubrics/jev_grader.py +0 -0
  231. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/rubrics/middleware.py +0 -0
  232. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/schema/__init__.py +0 -0
  233. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/schema/interrupts.py +0 -0
  234. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/__init__.py +0 -0
  235. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/approval_mode.py +0 -0
  236. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/approval_mode_source.py +0 -0
  237. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/cli_ast_evaluator.py +0 -0
  238. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/jev_classifier.py +0 -0
  239. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/shell_safety.py +0 -0
  240. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/unicode_security.py +0 -0
  241. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/url_validation.py +0 -0
  242. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/server/__init__.py +0 -0
  243. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/server/_server_config.py +0 -0
  244. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/server/server.py +0 -0
  245. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/server/server_graph.py +0 -0
  246. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/__init__.py +0 -0
  247. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/commands.py +0 -0
  248. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/invocation.py +0 -0
  249. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/load.py +0 -0
  250. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/loader.py +0 -0
  251. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/merge.py +0 -0
  252. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/registry.py +0 -0
  253. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/sources.py +0 -0
  254. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/trust.py +0 -0
  255. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/__init__.py +0 -0
  256. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/base.py +0 -0
  257. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/cloud_context.py +0 -0
  258. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/goal_channels.py +0 -0
  259. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/goal_state_limits.py +0 -0
  260. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/resume_state.py +0 -0
  261. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/service_context.py +0 -0
  262. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/session.py +0 -0
  263. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/state_migration.py +0 -0
  264. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/subagents/__init__.py +0 -0
  265. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/subagents/loader.py +0 -0
  266. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/subagents/subagents_parser.py +0 -0
  267. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/subagents/types.py +0 -0
  268. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/__init__.py +0 -0
  269. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/catalog.py +0 -0
  270. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/display.py +0 -0
  271. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/fetch_url.py +0 -0
  272. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/goal_tools.py +0 -0
  273. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/registry.py +0 -0
  274. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/thread.py +0 -0
  275. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/web_search.py +0 -0
  276. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/__init__.py +0 -0
  277. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/app.tcss +0 -0
  278. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/clipboard.py +0 -0
  279. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/command_registry.py +0 -0
  280. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/message_store.py +0 -0
  281. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/permission_store.py +0 -0
  282. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/preferences.py +0 -0
  283. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/prompt_manager.py +0 -0
  284. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/theme.py +0 -0
  285. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/ui_help.py +0 -0
  286. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/__init__.py +0 -0
  287. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/_ask_user_types.py +0 -0
  288. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/_copy_spans.py +0 -0
  289. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/_inline_prompt.py +0 -0
  290. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/_js_eval_display.py +0 -0
  291. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/_links.py +0 -0
  292. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/_tool_stream.py +0 -0
  293. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/agent_selector.py +0 -0
  294. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/approval.py +0 -0
  295. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/ask_user.py +0 -0
  296. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/auth.py +0 -0
  297. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/auth_manager.py +0 -0
  298. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/auto_mode_notice.py +0 -0
  299. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/autocomplete.py +0 -0
  300. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/cloud_selector.py +0 -0
  301. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/config_manager.py +0 -0
  302. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/debug_console.py +0 -0
  303. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/devops_renderers.py +0 -0
  304. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/diff.py +0 -0
  305. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/effort_selector.py +0 -0
  306. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/goal_review.py +0 -0
  307. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/goal_status.py +0 -0
  308. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/infra_panel.py +0 -0
  309. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/install_confirm.py +0 -0
  310. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/loading.py +0 -0
  311. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/mcp_viewer.py +0 -0
  312. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/model_selector.py +0 -0
  313. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/notification_center.py +0 -0
  314. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/notification_settings.py +0 -0
  315. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/operation_card.py +0 -0
  316. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/permissions_manager.py +0 -0
  317. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/plugin_manager.py +0 -0
  318. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/pool_selector.py +0 -0
  319. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/preamble.py +0 -0
  320. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/skills_viewer.py +0 -0
  321. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/status.py +0 -0
  322. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/subagent_panel.py +0 -0
  323. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/theme_selector.py +0 -0
  324. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/thread_selector.py +0 -0
  325. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/toast.py +0 -0
  326. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/tool_display.py +0 -0
  327. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/tool_renderers.py +0 -0
  328. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/tool_widgets.py +0 -0
  329. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/welcome.py +0 -0
  330. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/welcome_popup.py +0 -0
  331. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/utils/__init__.py +0 -0
  332. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/utils/cost_estimation.py +0 -0
  333. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/utils/git.py +0 -0
  334. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/utils/logger.py +0 -0
  335. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/utils/session_stats.py +0 -0
  336. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/utils/startup_error.py +0 -0
  337. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/__init__.py +0 -0
  338. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/conftest.py +0 -0
  339. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/evals/__init__.py +0 -0
  340. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/evals/datasets/aws_cloud_ops.yaml +0 -0
  341. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/evals/evaluators/__init__.py +0 -0
  342. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/evals/evaluators/output_evaluator.py +0 -0
  343. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/evals/evaluators/trajectory_evaluator.py +0 -0
  344. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/evals/runners/test_eval_runner.py +0 -0
  345. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/integration_tests/test_agent_lifecycle.py +0 -0
  346. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/integration_tests/test_server_lifecycle.py +0 -0
  347. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_agent_factory.py +0 -0
  348. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_approval_widget.py +0 -0
  349. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_ask_user.py +0 -0
  350. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_ast_evaluator.py +0 -0
  351. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_backend.py +0 -0
  352. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_chat_input_responsiveness.py +0 -0
  353. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_checkpointer.py +0 -0
  354. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_claude_opus_reasoning.py +0 -0
  355. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_cli_enhancements.py +0 -0
  356. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_cli_rubric.py +0 -0
  357. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_cloud_command.py +0 -0
  358. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_commands.py +0 -0
  359. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_config.py +0 -0
  360. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_cost_tracking.py +0 -0
  361. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_default_marketplace.py +0 -0
  362. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_goal_criteria.py +0 -0
  363. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_goal_state_limits.py +0 -0
  364. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_goal_state_notice.py +0 -0
  365. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_grader_tools.py +0 -0
  366. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_hitl.py +0 -0
  367. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_integrations_and_hooks.py +0 -0
  368. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_interrupt_schemas.py +0 -0
  369. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_jev_model_router.py +0 -0
  370. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_jev_rubrics.py +0 -0
  371. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_local_context.py +0 -0
  372. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_logging.py +0 -0
  373. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_mcp.py +0 -0
  374. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_mcp_middleware.py +0 -0
  375. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_mcp_viewer_and_command.py +0 -0
  376. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_memory.py +0 -0
  377. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_memory_enhancements.py +0 -0
  378. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_middleware_stack.py +0 -0
  379. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_model_providers.py +0 -0
  380. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_model_retry.py +0 -0
  381. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_plugin_manager_search.py +0 -0
  382. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_plugins.py +0 -0
  383. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_pool_persistence.py +0 -0
  384. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_project_plugins.py +0 -0
  385. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_prompts_and_schema.py +0 -0
  386. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_reliable_rubric.py +0 -0
  387. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_reload_restart.py +0 -0
  388. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_resume_state.py +0 -0
  389. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_resumed_thread_latency_fix.py +0 -0
  390. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_rubrics.py +0 -0
  391. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_security.py +0 -0
  392. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_server.py +0 -0
  393. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_server_hooks.py +0 -0
  394. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_skill_creator.py +0 -0
  395. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_skills.py +0 -0
  396. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_state.py +0 -0
  397. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_subagents.py +0 -0
  398. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_tools.py +0 -0
  399. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_utils.py +0 -0
  400. {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/uv-requirements.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: talkops-opscloud
3
- Version: 0.3.0b7
3
+ Version: 0.3.0b8
4
4
  Summary: Extensible Terminal Multi-Agent Framework for Cloud Operations & DevOps Coding
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "talkops-opscloud"
3
- version = "0.3.0b7"
3
+ version = "0.3.0b8"
4
4
  description = "Extensible Terminal Multi-Agent Framework for Cloud Operations & DevOps Coding"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -415,9 +415,9 @@ def _subagent_cli_middleware(
415
415
 
416
416
  server_keys: list[str] = []
417
417
  if mcp_config:
418
- server_keys.extend(mcp_config.keys())
418
+ server_keys.extend(str(k) for k in mcp_config.keys())
419
419
  if mcp_server_info:
420
- server_keys.extend(getattr(s, "name", str(s)) for s in mcp_server_info)
420
+ server_keys.extend(str(getattr(s, "name", s)) for s in mcp_server_info)
421
421
 
422
422
  if allowed_tools or capabilities:
423
423
  middleware.append(
@@ -603,13 +603,16 @@ def create_opscloud_agent(
603
603
 
604
604
  # 5. MCP Discovery
605
605
  mcp_tools_list: list[BaseTool] = []
606
- cached_infos: list[Any] | None = None
607
- mcp_configs: dict[str, Any] | None = None
606
+ cached_infos: list[Any] | None = kwargs.get("mcp_server_info")
607
+ mcp_configs: dict[str, Any] | None = kwargs.get("mcp_config")
608
608
  if mcp_tools is not None:
609
609
  mcp_tools_list = list(mcp_tools)
610
610
  all_tools.extend(mcp_tools)
611
+ if mcp_configs is None:
612
+ mcp_configs = discover_mcp_configs(project_scope_root)
611
613
  else:
612
- mcp_configs = discover_mcp_configs(project_scope_root)
614
+ if mcp_configs is None:
615
+ mcp_configs = discover_mcp_configs(project_scope_root)
613
616
  from opscloud.mcp.preload import (
614
617
  get_cached_mcp_server_infos,
615
618
  preload_mcp_metadata,
@@ -707,6 +710,7 @@ def create_opscloud_agent(
707
710
  from deepagents.middleware.subagents import GENERAL_PURPOSE_SUBAGENT, SubAgent
708
711
 
709
712
  compiled_subagents: list[SubAgent] = []
713
+ base_subagent_tools = [t for t in all_tools if t not in mcp_tools_list]
710
714
  for name, subagent_meta in subagent_by_name.items():
711
715
  model_spec = subagent_meta.get("model")
712
716
  has_explicit_model = bool(model_spec)
@@ -723,6 +727,18 @@ def create_opscloud_agent(
723
727
  subagent_path = subagent_meta.get("path")
724
728
  custom_mw = subagent_meta.get("middleware")
725
729
 
730
+ # Build per-subagent MCP config and tools for this subagent
731
+ from opscloud.plugins.adapters.mcp import prepare_subagent_mcp
732
+
733
+ servers, subagent_mcp_tools, sub_mcp_server_infos = prepare_subagent_mcp(
734
+ subagent_name, subagent_meta, project_scope_root
735
+ )
736
+
737
+ if subagent_mcp_tools:
738
+ subagent_dict["tools"] = [*base_subagent_tools, *subagent_mcp_tools]
739
+ else:
740
+ subagent_dict["tools"] = list(base_subagent_tools)
741
+
726
742
  sub_middleware = _subagent_cli_middleware(
727
743
  has_explicit_model=has_explicit_model,
728
744
  assistant_id=assistant_id,
@@ -738,6 +754,9 @@ def create_opscloud_agent(
738
754
  worktree_root=effective_cwd,
739
755
  subagent_path=subagent_path if subagent_path else None,
740
756
  custom_middleware=custom_mw if isinstance(custom_mw, list) else None,
757
+ mcp_server_info=sub_mcp_server_infos or None,
758
+ mcp_config=servers or None,
759
+ mcp_tools=subagent_mcp_tools or None,
741
760
  backend=composite_backend,
742
761
  model=active_model,
743
762
  )
@@ -748,9 +767,10 @@ def create_opscloud_agent(
748
767
 
749
768
  compiled_subagents.append(cast(SubAgent, subagent_dict))
750
769
  logger.info(
751
- "Registered declarative subagent '%s'",
770
+ "Compiled subagent '%s' (tools: %d)",
752
771
  subagent_name,
753
- extra={"subagent": subagent_name},
772
+ len(subagent_dict.get("tools", [])),
773
+ extra={"subagent": subagent_name, "tools_count": len(subagent_dict.get("tools", []))},
754
774
  )
755
775
 
756
776
  if not any(sub.get("name") == GENERAL_PURPOSE_SUBAGENT["name"] for sub in compiled_subagents):
@@ -773,6 +793,7 @@ def create_opscloud_agent(
773
793
  "name": gp_name,
774
794
  "description": gp_description,
775
795
  "system_prompt": gp_system_prompt,
796
+ "tools": list(base_subagent_tools),
776
797
  "middleware": gp_middleware,
777
798
  }
778
799
  if interrupt_on is not None:
@@ -832,12 +853,22 @@ def create_opscloud_agent(
832
853
  agent_middleware.append(AskUserMiddleware())
833
854
 
834
855
  # 10.5 MCP tool arguments and error handling
835
- if mcp_tools_list:
836
- if cached_infos or mcp_configs:
856
+ if mcp_tools_list or cached_infos or mcp_configs:
857
+ mcp_cfg_for_mw = mcp_configs
858
+ if not mcp_cfg_for_mw and not cached_infos and mcp_tools_list:
859
+ synth_cfg: dict[str, Any] = {}
860
+ for t in mcp_tools_list:
861
+ srv = getattr(t, "metadata", {}).get("_mcp_server") if isinstance(getattr(t, "metadata", None), dict) else None
862
+ if srv and srv not in synth_cfg:
863
+ synth_cfg[srv] = {"command": "custom", "args": []}
864
+ if synth_cfg:
865
+ mcp_cfg_for_mw = synth_cfg
866
+
867
+ if cached_infos or mcp_cfg_for_mw:
837
868
  from opscloud.middleware.mcp_context import MCPContextMiddleware
838
869
 
839
870
  agent_middleware.append(
840
- MCPContextMiddleware(mcp_server_info=cached_infos, mcp_config=mcp_configs)
871
+ MCPContextMiddleware(mcp_server_info=cached_infos, mcp_config=mcp_cfg_for_mw)
841
872
  )
842
873
  agent_middleware.append(MCPToolMiddleware())
843
874
 
@@ -919,7 +919,7 @@ def _mcp_server_from_tool(tool: object | None) -> str | None:
919
919
  metadata = getattr(tool, "metadata", None)
920
920
  if not isinstance(metadata, Mapping):
921
921
  return None
922
- for key in ("mcp_server", "mcp_server_name", "server_name"):
922
+ for key in ("_mcp_server", "mcp_server", "mcp_server_name", "server_name"):
923
923
  value = metadata.get(key)
924
924
  if isinstance(value, str) and value:
925
925
  return value
@@ -68,47 +68,54 @@ def _mcp_original_name_from_tool(tool: object | None) -> str | None:
68
68
 
69
69
  def _parse_mcp_pattern(
70
70
  pattern: str,
71
- known_servers: set[str],
71
+ known_servers: set[str] | None = None,
72
72
  subagent_name: str | None = None,
73
73
  ) -> tuple[str | None, str | None]:
74
- """Parse (server_name, tool_pattern) from an MCP tool pattern.
74
+ """Parse (server_name, tool_pattern) from an MCP tool pattern generically.
75
75
 
76
- Supports:
77
- - mcp__plugin_<subagent>_<server>__<tool>
78
- - mcp__plugin__<subagent>__<server>__<tool>
76
+ Supports arbitrary namespaces and patterns:
79
77
  - mcp__<server>__<tool>
78
+ - mcp__<namespace>_<server>__<tool>
79
+ - mcp__<namespace>__<server>__<tool>
80
80
  - <server>:<tool>
81
81
  - <server>_*
82
82
  """
83
- if pattern.startswith("mcp__"):
84
- content = pattern[5:]
85
- parts = content.split("__")
86
- if len(parts) == 2:
87
- server_part, tool_pat = parts[0], parts[1]
88
- if server_part.startswith("plugin_"):
89
- rest = server_part[7:]
90
- if subagent_name and rest.startswith(f"{subagent_name}_"):
91
- return rest[len(subagent_name) + 1 :], tool_pat
92
- for srv in sorted(known_servers, key=len, reverse=True):
93
- if rest.endswith(f"_{srv}"):
94
- return srv, tool_pat
95
- if "_" in rest:
96
- return rest.rsplit("_", 1)[1], tool_pat
97
- return rest, tool_pat
98
- return server_part, tool_pat
99
- elif len(parts) >= 3:
100
- tool_pat = parts[-1]
101
- if parts[0] == "plugin":
102
- server = parts[-2]
103
- return server, tool_pat
104
- return parts[0], tool_pat
105
- elif ":" in pattern:
106
- srv, tool_pat = pattern.split(":", 1)
83
+ known = known_servers or set()
84
+ pat = pattern.strip()
85
+
86
+ if pat.startswith("mcp__"):
87
+ rest = pat[5:]
88
+ if "__" in rest:
89
+ qualifier, tool_pat = rest.rsplit("__", 1)
90
+ # 1. Direct match with known servers
91
+ if qualifier in known:
92
+ return qualifier, tool_pat
93
+ # 2. Check if qualifier ends with a known server (e.g. prefix_server or prefix__server)
94
+ for srv in sorted(known, key=len, reverse=True):
95
+ if qualifier.endswith(f"_{srv}") or qualifier.endswith(f"__{srv}"):
96
+ return srv, tool_pat
97
+ # 3. Subagent name check if provided
98
+ if subagent_name and (qualifier == subagent_name or qualifier.endswith(f"_{subagent_name}")):
99
+ return subagent_name, tool_pat
100
+ # 4. Fallback: extract last token
101
+ if "__" in qualifier:
102
+ return qualifier.rsplit("__", 1)[1], tool_pat
103
+ if "_" in qualifier:
104
+ return qualifier.rsplit("_", 1)[1], tool_pat
105
+ return qualifier, tool_pat
106
+ elif ":" in pat:
107
+ srv, tool_pat = pat.split(":", 1)
108
+ for known_srv in sorted(known, key=len, reverse=True):
109
+ if srv == known_srv or srv.endswith(f"_{known_srv}") or srv.endswith(f"__{known_srv}"):
110
+ return known_srv, tool_pat
107
111
  return srv, tool_pat
108
- elif pattern.endswith("_*"):
109
- srv = pattern[:-2]
110
- if srv in known_servers:
111
- return srv, "*"
112
+ elif pat.endswith("_*"):
113
+ srv = pat[:-2]
114
+ for known_srv in sorted(known, key=len, reverse=True):
115
+ if srv == known_srv or srv.endswith(f"_{known_srv}"):
116
+ return known_srv, "*"
117
+ return srv, "*"
118
+
112
119
  return None, None
113
120
 
114
121
 
@@ -117,7 +124,7 @@ def _expand_tool_patterns(
117
124
  known_servers: set[str] | None = None,
118
125
  subagent_name: str | None = None,
119
126
  ) -> tuple[str, ...]:
120
- """Expand tool pattern list with aliases, wire projections, and provider-safe variations."""
127
+ """Expand tool pattern list with aliases, wire projections, and standard MCP variations."""
121
128
  expanded: list[str] = []
122
129
  seen: set[str] = set()
123
130
 
@@ -141,9 +148,6 @@ def _expand_tool_patterns(
141
148
  _add(f"mcp__{server}__{tool_pat}")
142
149
  _add(f"{server}:{tool_pat}")
143
150
  _add(f"{server}_{tool_pat}")
144
- if subagent_name:
145
- _add(f"mcp__plugin_{subagent_name}_{server}__{tool_pat}")
146
- _add(f"mcp__plugin__{subagent_name}__{server}__{tool_pat}")
147
151
  if tool_pat == "*":
148
152
  _add(server)
149
153
  _add(f"{server}_*")
@@ -159,30 +163,60 @@ _GLOB_METACHARS = frozenset("*?[")
159
163
 
160
164
 
161
165
  def _entry_matches_tool(
162
- pattern: str,
163
- cand: str,
164
- base_name: str,
166
+ entry: str,
167
+ candidates: Sequence[str] | set[str],
165
168
  server_name: str | None = None,
169
+ original_name: str | None = None,
166
170
  ) -> bool:
167
- """Check if an allowed pattern matches a tool call under any valid naming projection."""
171
+ """Return True if a single filter entry matches any tool candidate.
172
+
173
+ Aligned directly with dcode's _entry_matches_tool candidate matching:
174
+ checks candidates via case-insensitive fnmatchcase when glob metachars are present,
175
+ or case-insensitive equality otherwise. Also checks structured MCP qualifiers.
176
+ """
177
+ entry_clean = entry.strip()
178
+ entry_lower = entry_clean.lower()
179
+ has_glob = any(ch in _GLOB_METACHARS for ch in entry_clean)
180
+
181
+ # 1. Match against generated candidates
182
+ for cand in candidates:
183
+ cand_lower = cand.lower()
184
+ if has_glob:
185
+ if fnmatch.fnmatchcase(cand_lower, entry_lower):
186
+ return True
187
+ else:
188
+ if cand_lower == entry_lower:
189
+ return True
190
+
191
+ # 2. Semantic matching for server-qualified patterns (e.g. "billing:*", "billing", "mcp__..._billing__*")
168
192
  if server_name:
169
- if pattern in {
170
- f"mcp__{server_name}__*",
171
- f"{server_name}:*",
172
- f"{server_name}_*",
173
- server_name,
174
- }:
175
- return True
176
- if fnmatch.fnmatch(server_name, pattern) or fnmatch.fnmatch(server_name.lower(), pattern.lower()):
193
+ srv_lower = server_name.lower()
194
+ if entry_lower in {srv_lower, f"{srv_lower}:*", f"{srv_lower}_*", f"mcp__{srv_lower}__*"}:
177
195
  return True
178
196
 
179
- is_glob = any(ch in _GLOB_METACHARS for ch in pattern)
180
- if is_glob:
181
- if fnmatch.fnmatch(cand, pattern) or fnmatch.fnmatch(cand.lower(), pattern.lower()):
182
- return True
183
- else:
184
- if cand == pattern or cand.lower() == pattern.lower():
185
- return True
197
+ # Parse qualifier and tool pattern from entry
198
+ tool_pat: str | None = None
199
+ qualifier: str | None = None
200
+ if entry_clean.startswith("mcp__") and "__" in entry_clean[5:]:
201
+ qualifier, tool_pat = entry_clean[5:].rsplit("__", 1)
202
+ elif ":" in entry_clean:
203
+ qualifier, tool_pat = entry_clean.split(":", 1)
204
+
205
+ if qualifier is not None and tool_pat is not None:
206
+ qual_lower = qualifier.lower()
207
+ if (
208
+ qual_lower == srv_lower
209
+ or qual_lower.endswith(f"_{srv_lower}")
210
+ or qual_lower.endswith(f"__{srv_lower}")
211
+ ):
212
+ if tool_pat == "*":
213
+ return True
214
+ if original_name:
215
+ orig_lower = original_name.lower()
216
+ pat_lower = tool_pat.lower()
217
+ if any(ch in _GLOB_METACHARS for ch in tool_pat):
218
+ return fnmatch.fnmatchcase(orig_lower, pat_lower)
219
+ return orig_lower == pat_lower
186
220
 
187
221
  return False
188
222
 
@@ -224,9 +258,7 @@ class ToolFilterMiddleware(AgentMiddleware[Any, Any]):
224
258
  if isinstance(item, dict):
225
259
  server = item.get("mcp_server")
226
260
  if server and item.get("allow_all"):
227
- patterns.append(f"mcp__{server}__*")
228
261
  patterns.append(f"{server}:*")
229
- patterns.append(f"{server}_*")
230
262
  if "tools" in item and isinstance(item["tools"], (list, tuple)):
231
263
  patterns.extend(str(t) for t in item["tools"])
232
264
  elif isinstance(item, str):
@@ -237,9 +269,7 @@ class ToolFilterMiddleware(AgentMiddleware[Any, Any]):
237
269
  if isinstance(cap, dict):
238
270
  server = cap.get("mcp_server")
239
271
  if server and cap.get("allow_all"):
240
- patterns.append(f"mcp__{server}__*")
241
272
  patterns.append(f"{server}:*")
242
- patterns.append(f"{server}_*")
243
273
  if "tools" in cap and isinstance(cap["tools"], (list, tuple)):
244
274
  patterns.extend(str(t) for t in cap["tools"])
245
275
  elif isinstance(cap, str):
@@ -251,6 +281,43 @@ class ToolFilterMiddleware(AgentMiddleware[Any, Any]):
251
281
  else ()
252
282
  )
253
283
 
284
+ def _get_tool_candidates(
285
+ self,
286
+ tool_name: str,
287
+ server_name: str | None = None,
288
+ original_name: str | None = None,
289
+ ) -> list[str]:
290
+ """Generate dcode-aligned candidate names for a tool."""
291
+ candidates: list[str] = [tool_name]
292
+ if original_name and original_name != tool_name:
293
+ candidates.append(original_name)
294
+
295
+ if server_name:
296
+ candidates.append(server_name)
297
+ if original_name:
298
+ candidates.extend([
299
+ f"{server_name}_{original_name}",
300
+ f"{server_name}:{original_name}",
301
+ f"mcp__{server_name}__{original_name}",
302
+ ])
303
+
304
+ # Aliases for native tools
305
+ clean = tool_name.lower()
306
+ if clean in TOOL_ALIAS_MAP:
307
+ candidates.extend(TOOL_ALIAS_MAP[clean])
308
+ for alias_key, alias_group in TOOL_ALIAS_MAP.items():
309
+ if tool_name in alias_group or clean in alias_group:
310
+ candidates.append(alias_key)
311
+ candidates.extend(alias_group)
312
+
313
+ from opscloud.hooks.tools import to_wire_tool_name
314
+
315
+ wire_name = to_wire_tool_name(tool_name, mcp_server=server_name)
316
+ if wire_name and wire_name not in candidates:
317
+ candidates.append(wire_name)
318
+
319
+ return list(dict.fromkeys(candidates))
320
+
254
321
  def is_tool_allowed(self, tool_name: str, tool_obj: Any = None) -> bool:
255
322
  """Check if a tool name matches any allowed patterns."""
256
323
  if tool_name in ALWAYS_ALLOWED_SYSTEM_TOOLS:
@@ -259,69 +326,55 @@ class ToolFilterMiddleware(AgentMiddleware[Any, Any]):
259
326
  return True
260
327
 
261
328
  server_name: str | None = None
262
- base_name: str | None = None
329
+ original_name: str | None = None
263
330
 
264
331
  if tool_obj is not None:
265
332
  server_name = _mcp_server_from_tool(tool_obj)
266
- base_name = _mcp_original_name_from_tool(tool_obj)
333
+ original_name = _mcp_original_name_from_tool(tool_obj)
267
334
  if server_name:
268
335
  self._known_mcp_servers.add(server_name)
269
336
  self._tool_to_server[tool_name] = server_name
270
337
 
271
338
  if not server_name and tool_name in self._tool_to_server:
272
339
  server_name = self._tool_to_server[tool_name]
273
- base_name = self._tool_to_orig_name.get(tool_name)
340
+ original_name = original_name or self._tool_to_orig_name.get(tool_name)
274
341
 
275
342
  if not server_name:
276
343
  if tool_name.startswith("mcp__"):
277
344
  parts = tool_name[5:].split("__")
278
- if len(parts) == 2:
279
- server_name, base_name = parts[0], parts[1]
280
- elif len(parts) >= 3:
281
- base_name = parts[-1]
282
- server_part = parts[-2]
345
+ if len(parts) >= 2:
346
+ original_name = original_name or parts[-1]
347
+ qualifier = parts[0] if len(parts) == 2 else parts[-2]
283
348
  for srv in sorted(self._known_mcp_servers, key=len, reverse=True):
284
- if parts[1].endswith(f"_{srv}") or parts[1].endswith(f"__{srv}") or parts[1] == srv:
349
+ if qualifier == srv or qualifier.endswith(f"_{srv}") or qualifier.endswith(f"__{srv}"):
285
350
  server_name = srv
286
351
  break
287
352
  if not server_name:
288
- server_name = server_part
353
+ server_name = qualifier
289
354
  elif ":" in tool_name:
290
- server_name, base_name = tool_name.split(":", 1)
355
+ srv, orig = tool_name.split(":", 1)
356
+ original_name = original_name or orig
357
+ for known_srv in sorted(self._known_mcp_servers, key=len, reverse=True):
358
+ if srv == known_srv or srv.endswith(f"_{known_srv}"):
359
+ server_name = known_srv
360
+ break
361
+ if not server_name:
362
+ server_name = srv
291
363
  else:
292
364
  for srv in sorted(self._known_mcp_servers, key=len, reverse=True):
293
365
  if tool_name.startswith(f"{srv}_"):
294
366
  server_name = srv
295
- base_name = tool_name[len(srv) + 1 :]
367
+ original_name = original_name or tool_name[len(srv) + 1 :]
296
368
  break
297
369
 
298
- if not base_name:
299
- base_name = tool_name
300
-
301
- candidates: list[str] = [tool_name, base_name]
302
- if server_name:
303
- candidates.extend([
304
- f"{server_name}_{base_name}",
305
- f"{server_name}:{base_name}",
306
- f"mcp__{server_name}__{base_name}",
307
- server_name,
308
- ])
309
- if self._subagent_name:
310
- candidates.extend([
311
- f"mcp__plugin_{self._subagent_name}_{server_name}__{base_name}",
312
- f"mcp__plugin__{self._subagent_name}__{server_name}__{base_name}",
313
- ])
314
-
315
- from opscloud.hooks.tools import to_wire_tool_name
370
+ if not original_name:
371
+ original_name = tool_name
316
372
 
317
- wire_name = to_wire_tool_name(tool_name, mcp_server=server_name)
318
- if wire_name not in candidates:
319
- candidates.append(wire_name)
373
+ candidates = self._get_tool_candidates(tool_name, server_name, original_name)
320
374
 
321
- for cand in candidates:
322
- for pattern in self._allowed_patterns:
323
- if _entry_matches_tool(pattern, cand, base_name, server_name):
324
- return True
375
+ for pattern in self._allowed_patterns:
376
+ if _entry_matches_tool(pattern, candidates, server_name=server_name, original_name=original_name):
377
+ return True
325
378
 
326
379
  return False
327
380