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.
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/PKG-INFO +1 -1
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/pyproject.toml +1 -1
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/agent/factory.py +41 -10
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/server_hooks.py +1 -1
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/tool_filter.py +150 -97
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/app.py +231 -10
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/remote_client.py +42 -18
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/textual_adapter.py +43 -12
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/chat_input.py +48 -3
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/messages.py +13 -0
- talkops_opscloud-0.3.0b8/tests/unit_tests/test_plugin_agent_skill_mcp_scoping.py +498 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_tool_filter.py +61 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_tui_app.py +141 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/uv.lock +1 -1
- talkops_opscloud-0.3.0b7/tests/unit_tests/test_plugin_agent_skill_mcp_scoping.py +0 -228
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/.dockerignore +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/.env.example +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/.github/workflows/ci.yml +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/.github/workflows/release-pypi.yml +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/.gitignore +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/.python-version +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/LICENSE +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/README.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/assets/opscloud-banner.gif +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/Configuration.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/approval-mode.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/cli-reference.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/config.toml.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/credentials.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/goal-and-rubrics.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/hooks.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/mcp-tools.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/memory-and-skills.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/model-providers.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/overview.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/plugins.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/quickstart.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/remote-sandboxes.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/docs/opscloud-docs/subagents.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/scripts/install.sh +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/__main__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/_constants.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/_debug.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/_debug_buffer.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/_textual_patches.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/_version.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/agent/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/agent/config.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/approval_mode.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/backend/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/backend/composite.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/backend/local.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/backend/registry.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/backend/sandbox_config.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/backend/sandbox_factory.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/built_in_skills/remember/SKILL.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/built_in_skills/skill-creator/SKILL.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/commands/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/commands/auth.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/commands/doctor.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/commands/mcp.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/commands/threads.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/interactive.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/main.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/non_interactive.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/cli/server_manager.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/_base.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/_guards.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/_router.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/_types.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/auth.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/bug.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/clear.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/cloud.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/compact.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/config_cmd.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/context.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/cost.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/doctor.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/effort.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/exit_cmd.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/fast.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/help_cmd.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/mcp.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/model.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/permissions.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/plugins.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/pool.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/resume.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/core/skills.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/agents.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/btw.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/copy.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/goal.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/loop.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/memory.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/review.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/rubric.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/runtime.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/skill_creator.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/skill_invoke.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/tasks.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/trace.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/ui_toggles.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/power/version.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/commands/registry.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/adapters/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/adapters/postgres.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/adapters/sqlite.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/aws.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/cloud_profiles.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/env_vars.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/langsmith.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/manifest.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/metadata.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/paths.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/plugins.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/settings.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/store.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/store_factory.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/config/toml_config.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/editor.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/exceptions.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/file_ops.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/env.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/interrupt.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/models/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/models/adapters.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/models/config.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/models/domain.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/models/transport.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/hooks/tools.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/input.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/base.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/content_filter.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/event_bus.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/hooks.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/identity.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/notifications.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/stream_bridge.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/integrations/thread_store.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/json_types.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/config.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/discovery.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/mcp_info.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/middleware.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/preload.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/raw_config.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/semantic_profiler.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/session_manager.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/mcp/trust.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/memory/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/memory/branch.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/memory/guard.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/memory/onboarding.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/memory/registry.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/memory/store.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/_repository_bounds.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/ask_user.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/auto_mode.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/auto_mode_hitl.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/compaction.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/configurable_model.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/cost_tracking.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/glm_stall_recovery.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/goal_criteria.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/goal_state_notice.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/goal_tools.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/headless_mcp_guard.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/jev_model_router.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/local_context.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/mcp_context.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/mcp_middleware.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/memory_guard.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/model_retry.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/registry.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/reliable_rubric.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/resume_state.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/shell_allow_list.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/skills.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/subagent_artifacts.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/subagent_telemetry.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/subagents.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/unified_system_message.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/model/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/model/config.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/model/factory.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/model/pool.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/model/reasoning.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/offload.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/output.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/_json.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/adapters/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/adapters/agents.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/adapters/commands.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/adapters/mcp.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/adapters/skills.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/commands_cli.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/discovery.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/manifest.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/marketplace.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/models.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/project_plugins.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/protocol.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/store.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/plugins/substitution.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/project_utils.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/prompts/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/prompts/system.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/prompts/templates/system_prompt.md +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/prompts/types.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/rubrics/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/rubrics/evaluator.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/rubrics/evidence_extractor.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/rubrics/generator.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/rubrics/jev_compiler.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/rubrics/jev_grader.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/rubrics/middleware.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/schema/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/schema/interrupts.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/approval_mode.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/approval_mode_source.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/cli_ast_evaluator.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/jev_classifier.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/shell_safety.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/unicode_security.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/security/url_validation.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/server/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/server/_server_config.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/server/server.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/server/server_graph.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/commands.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/invocation.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/load.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/loader.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/merge.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/registry.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/sources.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/skills/trust.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/base.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/cloud_context.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/goal_channels.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/goal_state_limits.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/resume_state.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/service_context.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/session.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/state/state_migration.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/subagents/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/subagents/loader.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/subagents/subagents_parser.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/subagents/types.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/catalog.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/display.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/fetch_url.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/goal_tools.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/registry.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/thread.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/tools/web_search.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/app.tcss +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/clipboard.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/command_registry.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/message_store.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/permission_store.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/preferences.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/prompt_manager.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/theme.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/ui_help.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/_ask_user_types.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/_copy_spans.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/_inline_prompt.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/_js_eval_display.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/_links.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/_tool_stream.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/agent_selector.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/approval.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/ask_user.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/auth.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/auth_manager.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/auto_mode_notice.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/autocomplete.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/cloud_selector.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/config_manager.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/debug_console.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/devops_renderers.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/diff.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/effort_selector.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/goal_review.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/goal_status.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/infra_panel.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/install_confirm.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/loading.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/mcp_viewer.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/model_selector.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/notification_center.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/notification_settings.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/operation_card.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/permissions_manager.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/plugin_manager.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/pool_selector.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/preamble.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/skills_viewer.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/status.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/subagent_panel.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/theme_selector.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/thread_selector.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/toast.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/tool_display.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/tool_renderers.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/tool_widgets.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/welcome.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/ui/widgets/welcome_popup.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/utils/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/utils/cost_estimation.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/utils/git.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/utils/logger.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/utils/session_stats.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/utils/startup_error.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/conftest.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/evals/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/evals/datasets/aws_cloud_ops.yaml +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/evals/evaluators/__init__.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/evals/evaluators/output_evaluator.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/evals/evaluators/trajectory_evaluator.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/evals/runners/test_eval_runner.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/integration_tests/test_agent_lifecycle.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/integration_tests/test_server_lifecycle.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_agent_factory.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_approval_widget.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_ask_user.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_ast_evaluator.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_backend.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_chat_input_responsiveness.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_checkpointer.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_claude_opus_reasoning.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_cli_enhancements.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_cli_rubric.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_cloud_command.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_commands.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_config.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_cost_tracking.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_default_marketplace.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_goal_criteria.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_goal_state_limits.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_goal_state_notice.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_grader_tools.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_hitl.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_integrations_and_hooks.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_interrupt_schemas.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_jev_model_router.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_jev_rubrics.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_local_context.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_logging.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_mcp.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_mcp_middleware.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_mcp_viewer_and_command.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_memory.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_memory_enhancements.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_middleware_stack.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_model_providers.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_model_retry.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_plugin_manager_search.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_plugins.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_pool_persistence.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_project_plugins.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_prompts_and_schema.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_reliable_rubric.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_reload_restart.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_resume_state.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_resumed_thread_latency_fix.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_rubrics.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_security.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_server.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_server_hooks.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_skill_creator.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_skills.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_state.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_subagents.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_tools.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/tests/unit_tests/test_utils.py +0 -0
- {talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/uv-requirements.txt +0 -0
|
@@ -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",
|
|
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 =
|
|
607
|
-
mcp_configs: dict[str, Any] | 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
|
|
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
|
-
"
|
|
770
|
+
"Compiled subagent '%s' (tools: %d)",
|
|
752
771
|
subagent_name,
|
|
753
|
-
|
|
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
|
-
|
|
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=
|
|
871
|
+
MCPContextMiddleware(mcp_server_info=cached_infos, mcp_config=mcp_cfg_for_mw)
|
|
841
872
|
)
|
|
842
873
|
agent_middleware.append(MCPToolMiddleware())
|
|
843
874
|
|
{talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/server_hooks.py
RENAMED
|
@@ -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
|
{talkops_opscloud-0.3.0b7 → talkops_opscloud-0.3.0b8}/src/opscloud/middleware/tool_filter.py
RENAMED
|
@@ -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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if "_"
|
|
96
|
-
return
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
|
109
|
-
srv =
|
|
110
|
-
|
|
111
|
-
|
|
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
|
|
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
|
-
|
|
163
|
-
|
|
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
|
-
"""
|
|
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
|
-
|
|
170
|
-
|
|
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
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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)
|
|
279
|
-
|
|
280
|
-
|
|
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
|
|
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 =
|
|
353
|
+
server_name = qualifier
|
|
289
354
|
elif ":" in tool_name:
|
|
290
|
-
|
|
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
|
-
|
|
367
|
+
original_name = original_name or tool_name[len(srv) + 1 :]
|
|
296
368
|
break
|
|
297
369
|
|
|
298
|
-
if not
|
|
299
|
-
|
|
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
|
-
|
|
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
|
|
322
|
-
|
|
323
|
-
|
|
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
|
|