ouroboros-ai 0.26.7.dev3__tar.gz → 0.26.7.dev5__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.
Potentially problematic release.
This version of ouroboros-ai might be problematic. Click here for more details.
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/PKG-INFO +1 -1
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/_version.py +2 -2
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/client/adapter.py +7 -12
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/server/adapter.py +10 -0
- ouroboros_ai-0.26.7.dev5/src/ouroboros/mcp/tools/bridge_mixin.py +52 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/tools/execution_handlers.py +4 -1
- ouroboros_ai-0.26.7.dev5/tests/unit/mcp/client/test_adapter_transport_lifecycle.py +225 -0
- ouroboros_ai-0.26.7.dev5/tests/unit/mcp/tools/test_mcp_manager_wiring.py +145 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.claude/settings.json +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.claude-plugin/.mcp.json +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.claude-plugin/marketplace.json +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.claude-plugin/plugin.json +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.env.example +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.github/ISSUE_TEMPLATE/question.yml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.github/workflows/dev-publish.yml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.github/workflows/lint.yml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.github/workflows/release.yml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.github/workflows/test.yml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.gitignore +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.mcp.json +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.ouroboros/mechanical.toml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.pre-commit-config.yaml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.python-version +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/CHANGELOG.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/CLAUDE.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/CODE_OF_CONDUCT.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/CONTRIBUTING.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/HANDOFF.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/LICENSE +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/README.ko.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/README.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/SECURITY.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/UNINSTALL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/commands/cancel.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/commands/evaluate.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/commands/evolve.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/commands/help.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/commands/interview.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/commands/ralph.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/commands/run.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/commands/seed.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/commands/setup.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/commands/status.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/commands/tutorial.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/commands/unstuck.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/commands/welcome.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/.gitignore +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/Cargo.lock +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/Cargo.toml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/README.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/src/db.rs +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/src/main.rs +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/src/mock.rs +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/src/state.rs +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/src/views/dashboard.rs +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/src/views/execution.rs +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/src/views/lineage.rs +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/src/views/logs.rs +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/src/views/mod.rs +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/src/views/session_selector.rs +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/README.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/api/README.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/api/core.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/api/mcp.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/architecture.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/cli-reference.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/config-reference.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/contributing/architecture-overview.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/contributing/findings-registry.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/contributing/issue-quality-policy.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/contributing/key-patterns.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/contributing/testing-guide.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/examples/mcp-config.yaml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/getting-started.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/guides/evaluation-pipeline.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/guides/evolution-loop.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/guides/issue-176-subagent-mcp-inheritance.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/guides/seed-authoring.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/guides/tui-usage.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/images/PLACEHOLDER_README.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/images/ouroboros.png +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/platform-support.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/runtime-capability-matrix.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/runtime-guides/claude-code.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/docs/runtime-guides/codex.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/examples/coordinator_test_seed.yaml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/examples/dummy_seed.yaml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/examples/parallel_subac_test_seed.yaml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/examples/subac_test_seed.yaml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/examples/task_manager/README.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/examples/task_manager/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/examples/task_manager/__main__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/examples/task_manager/cli.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/examples/task_manager/models.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/examples/task_manager/storage.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/examples/test_display.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/hooks/hooks.json +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/llms-full.txt +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/llms.txt +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/project-context.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/pyproject.toml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/scripts/drift-monitor.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/scripts/install.sh +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/scripts/keyword-detector.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/scripts/mcp-serve.sh +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/scripts/ralph-rewind.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/scripts/ralph.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/scripts/ralph.sh +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/scripts/session-start.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/scripts/sync-plugin-version.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/scripts/version-check.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/brownfield/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/cancel/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/evaluate/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/evolve/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/help/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/interview/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/pm/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/publish/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/qa/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/ralph/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/run/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/seed/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/setup/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/status/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/tutorial/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/unstuck/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/update/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/skills/welcome/SKILL.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/__main__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/advocate.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/analysis-agent.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/architect.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/breadth-keeper.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/code-executor.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/codebase-explorer.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/consensus-reviewer.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/contrarian.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/evaluator.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/hacker.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/judge.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/loader.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/ontologist.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/ontology-analyst.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/qa-judge.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/research-agent.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/researcher.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/seed-architect.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/seed-closer.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/semantic-evaluator.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/simplifier.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/agents/socratic-interviewer.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/bigbang/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/bigbang/ambiguity.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/bigbang/brownfield.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/bigbang/explore.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/bigbang/interview.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/bigbang/pm_completion.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/bigbang/pm_document.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/bigbang/pm_interview.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/bigbang/pm_seed.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/bigbang/question_classifier.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/bigbang/seed_generator.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/commands/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/commands/cancel.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/commands/config.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/commands/init.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/commands/mcp.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/commands/pm.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/commands/run.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/commands/setup.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/commands/status.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/commands/tui.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/commands/uninstall.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/formatters/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/formatters/panels.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/formatters/progress.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/formatters/prompting.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/formatters/tables.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/formatters/workflow_display.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/cli/main.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/codex/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/codex/artifacts.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/codex/ouroboros.md +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/codex_permissions.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/config/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/config/loader.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/config/models.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/ac_tree.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/context.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/errors.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/file_lock.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/git_workflow.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/initial_context.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/json_utils.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/lineage.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/ontology_aspect.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/ontology_questions.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/project_paths.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/security.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/seed.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/text.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/types.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/core/worktree.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evaluation/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evaluation/artifact_collector.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evaluation/consensus.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evaluation/json_utils.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evaluation/languages.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evaluation/mechanical.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evaluation/models.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evaluation/pipeline.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evaluation/semantic.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evaluation/trigger.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evaluation/verification_artifacts.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/events/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/events/base.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/events/decomposition.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/events/evaluation.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/events/interview.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/events/lineage.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/events/ontology.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evolution/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evolution/convergence.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evolution/loop.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evolution/projector.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evolution/reflect.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evolution/regression.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/evolution/wonder.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/execution/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/execution/atomicity.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/execution/decomposition.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/execution/double_diamond.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/execution/subagent.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/client/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/client/manager.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/client/protocol.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/errors.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/job_manager.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/resources/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/resources/handlers.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/server/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/server/protocol.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/server/security.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/tools/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/tools/authoring_handlers.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/tools/brownfield_handler.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/tools/dashboard.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/tools/definitions.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/tools/evaluation_handlers.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/tools/evolution_handlers.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/tools/job_handlers.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/tools/pm_handler.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/tools/qa.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/tools/query_handlers.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/tools/registry.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/types.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/observability/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/observability/drift.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/observability/logging.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/observability/retrospective.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/adapter.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/codex_cli_runtime.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/command_dispatcher.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/coordinator.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/dependency_analyzer.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/events.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/execution_runtime_scope.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/execution_strategy.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/heartbeat.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/level_context.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/mcp_config.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/mcp_tools.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/parallel_executor.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/parallel_executor_models.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/runner.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/runtime_factory.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/runtime_message_projection.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/session.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/orchestrator/workflow_state.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/persistence/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/persistence/brownfield.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/persistence/checkpoint.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/persistence/event_store.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/persistence/migrations/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/persistence/migrations/runner.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/persistence/migrations/scripts/001_initial.sql +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/persistence/migrations/scripts/002_brownfield.sql +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/persistence/schema.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/persistence/uow.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/plugin/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/plugin/agents/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/plugin/agents/pool.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/plugin/agents/registry.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/plugin/orchestration/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/plugin/orchestration/router.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/plugin/orchestration/scheduler.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/plugin/skills/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/plugin/skills/docs.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/plugin/skills/executor.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/plugin/skills/keywords.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/plugin/skills/registry.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/pm/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/pm/handoff.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/pm/renderer.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/providers/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/providers/anthropic_adapter.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/providers/base.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/providers/claude_code_adapter.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/providers/codex_cli_adapter.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/providers/codex_cli_stream.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/providers/factory.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/providers/litellm_adapter.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/py.typed +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/resilience/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/resilience/lateral.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/resilience/stagnation.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/routing/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/routing/complexity.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/routing/downgrade.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/routing/escalation.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/routing/router.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/routing/tiers.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/secondary/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/secondary/scheduler.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/secondary/todo_registry.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/strategies/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/strategies/devil_advocate.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/app.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/components/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/components/agents_panel.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/components/event_log.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/components/progress.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/components/token_tracker.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/events.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/screens/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/screens/confirm_rewind.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/screens/dashboard.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/screens/dashboard_v2.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/screens/dashboard_v3.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/screens/debug.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/screens/execution.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/screens/hud_dashboard.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/screens/lineage_detail.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/screens/lineage_selector.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/screens/logs.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/screens/session_selector.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/widgets/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/widgets/ac_progress.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/widgets/ac_tree.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/widgets/agent_activity.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/widgets/cost_tracker.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/widgets/drift_meter.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/widgets/lineage_tree.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/widgets/parallel_graph.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/tui/widgets/phase_progress.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/verification/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/verification/extractor.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/verification/models.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/verification/verifier.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/conftest.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/e2e/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/e2e/conftest.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/e2e/test_cli_commands.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/e2e/test_full_workflow.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/e2e/test_session_persistence.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/fixtures/test_atomicity_seed.yml +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/integration/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/integration/conftest.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/integration/mcp/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/integration/mcp/conftest.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/integration/mcp/test_client_adapter.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/integration/mcp/test_client_manager.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/integration/mcp/test_server_adapter.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/integration/plugin/test_orchestration.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/integration/test_codex_cli_passthrough_smoke.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/integration/test_codex_skill_fallback.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/integration/test_codex_skill_smoke.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/integration/test_entry_point.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/agents/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/agents/test_loader.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/test_ambiguity.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/test_brownfield.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/test_classifier_context.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/test_decide_later_items.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/test_explore.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/test_interview.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/test_pm_completion.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/test_pm_document_generator.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/test_pm_document_writer.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/test_pm_interview.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/test_pm_interview_brownfield_db.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/test_pm_seed_ac12.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/test_pm_seed_save.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/test_question_classifier.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/bigbang/test_seed_generator.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/formatters/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/formatters/test_console.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/formatters/test_panels.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/formatters/test_progress.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/formatters/test_prompting.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/formatters/test_tables.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/formatters/test_workflow_display.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_cancel.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_config.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_init_pm_seed_detection.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_init_runtime.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_main.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_mcp_nested_guard.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_mcp_startup_cleanup.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_pm.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_pm_brownfield.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_pm_completion.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_pm_interactive_logging.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_pm_missing_litellm.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_pm_overwrite.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_pm_runtime_adapter.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_pm_select_repos.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_run_qa.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_setup.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/cli/test_uninstall.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/config/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/config/test_loader.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/config/test_models.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/core/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/core/test_ac_tree.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/core/test_context.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/core/test_errors.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/core/test_git_workflow.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/core/test_initial_context.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/core/test_lineage.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/core/test_ontology_aspect.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/core/test_ontology_questions.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/core/test_security.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/core/test_seed.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/core/test_types.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/core/test_worktree.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/evaluation/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/evaluation/test_consensus.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/evaluation/test_json_utils.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/evaluation/test_languages.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/evaluation/test_mechanical.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/evaluation/test_models.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/evaluation/test_semantic.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/evaluation/test_trigger.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/evaluation/test_verification_artifacts.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/events/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/events/test_base.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/events/test_decomposition_events.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/evolution/test_wonder_scope.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/execution/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/execution/test_atomicity.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/execution/test_decomposition.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/execution/test_double_diamond.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/execution/test_subagent_isolation.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/client/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/client/test_adapter.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/client/test_manager.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/conftest.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/server/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/server/test_adapter.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/server/test_security.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/test_errors.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/test_job_manager.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/test_types.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/tools/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/tools/conftest.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/tools/test_brownfield_handler.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/tools/test_definitions.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/tools/test_evaluation_handler.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/tools/test_pm_handler.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/tools/test_pm_handler_generate.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/tools/test_pm_handler_pending_reframe.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/tools/test_qa_integration.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/tools/test_qa_parser.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/mcp/tools/test_registry.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/observability/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/observability/test_drift.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/observability/test_logging.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/observability/test_retrospective.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_adapter.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_codex_cli_runtime.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_codex_recursion_guard.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_command_dispatcher.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_coordinator.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_dependency_analyzer.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_events.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_execution_runtime_scope.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_execution_strategy.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_inflight_cancellation.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_level_context.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_mcp_config.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_mcp_tools.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_parallel_executor.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_parallel_executor_retry_resume.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_runner.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_runner_cancellation.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_runtime_factory.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_runtime_message_projection.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_session.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/orchestrator/test_workflow_state.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/persistence/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/persistence/test_brownfield_store.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/persistence/test_checkpoint.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/persistence/test_event_store.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/persistence/test_schema.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/persistence/test_uow.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/plugin/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/plugin/agents/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/plugin/agents/test_registry.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/plugin/orchestration/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/plugin/orchestration/test_model_router.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/plugin/skills/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/plugin/skills/test_keywords.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/plugin/skills/test_registry.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/pm/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/pm/test_renderer.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/providers/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/providers/test_base.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/providers/test_claude_code_adapter.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/providers/test_codex_cli_adapter.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/providers/test_factory.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/providers/test_litellm_adapter.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/resilience/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/resilience/test_lateral.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/resilience/test_stagnation.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/routing/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/routing/test_complexity.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/routing/test_downgrade.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/routing/test_escalation.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/routing/test_router.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/routing/test_tiers.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/scripts/test_keyword_detector.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/scripts/test_version_check.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/secondary/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/secondary/test_scheduler.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/secondary/test_todo_registry.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_artifact_collector.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_codex_artifacts.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_convergence.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_dashboard.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_dependencies_configured.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_evolve_rewind.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_evolve_step.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_graceful_shutdown.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_main_entry_point.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_module_structure.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_project_initialization.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_projector_rewind.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_ralph_parser.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_ralph_rewind.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_regression.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_tooling_configuration.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/test_verification.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/tui/__init__.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/tui/test_app.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/tui/test_cancelled_display.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/tui/test_events.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/tui/test_lineage_viewer.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/tui/test_screens.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/tui/test_session_selector_replay.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tests/unit/tui/test_widgets.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/tools/sync_github_project.py +0 -0
- {ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/uv.lock +0 -0
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.26.7.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 26, 7, '
|
|
21
|
+
__version__ = version = '0.26.7.dev5'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 26, 7, 'dev5')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -289,26 +289,21 @@ class MCPClientAdapter:
|
|
|
289
289
|
async def disconnect(self) -> Result[None, MCPClientError]:
|
|
290
290
|
"""Disconnect from the current MCP server.
|
|
291
291
|
|
|
292
|
+
Releases both the MCP session and the underlying transport context
|
|
293
|
+
manager in reverse acquisition order. Always attempts to close both
|
|
294
|
+
resources even when one teardown raises.
|
|
295
|
+
|
|
292
296
|
Returns:
|
|
293
297
|
Result containing None on success or MCPClientError on failure.
|
|
294
298
|
"""
|
|
295
299
|
if self._session is None and self._transport_cm is None:
|
|
296
300
|
return Result.ok(None)
|
|
297
301
|
|
|
298
|
-
|
|
299
|
-
transport_cm = self._transport_cm
|
|
300
|
-
self._session = None
|
|
301
|
-
self._transport_cm = None
|
|
302
|
-
self._read_stream = None
|
|
303
|
-
self._write_stream = None
|
|
304
|
-
self._server_info = None
|
|
302
|
+
server_name = self._config.name if self._config else "unknown"
|
|
305
303
|
|
|
306
304
|
try:
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
if transport_cm is not None:
|
|
310
|
-
await transport_cm.__aexit__(None, None, None)
|
|
311
|
-
log.info("mcp.disconnected", server=self._config.name if self._config else "unknown")
|
|
305
|
+
await self._reset_connection_state()
|
|
306
|
+
log.info("mcp.disconnected", server=server_name)
|
|
312
307
|
return Result.ok(None)
|
|
313
308
|
except Exception as e:
|
|
314
309
|
return Result.err(
|
|
@@ -569,6 +569,7 @@ def create_ouroboros_server(
|
|
|
569
569
|
state_dir: Any | None = None,
|
|
570
570
|
runtime_backend: str | None = None,
|
|
571
571
|
llm_backend: str | None = None,
|
|
572
|
+
mcp_bridge: Any | None = None,
|
|
572
573
|
) -> MCPServerAdapter:
|
|
573
574
|
"""Create an Ouroboros MCP server with all tools and dependencies wired.
|
|
574
575
|
|
|
@@ -1239,6 +1240,15 @@ def create_ouroboros_server(
|
|
|
1239
1240
|
# The server owns the shared event store lifecycle
|
|
1240
1241
|
server.register_owned_resource(event_store)
|
|
1241
1242
|
|
|
1243
|
+
# Inject bridge into all BridgeAwareMixin handlers (loop-based auto-discovery)
|
|
1244
|
+
if mcp_bridge is not None:
|
|
1245
|
+
from ouroboros.mcp.tools.bridge_mixin import inject_bridge
|
|
1246
|
+
|
|
1247
|
+
injected = [type(h).__name__ for h in tool_handlers if inject_bridge(h, mcp_bridge)]
|
|
1248
|
+
if injected:
|
|
1249
|
+
log.info("mcp.bridge.injected", handlers=injected)
|
|
1250
|
+
server.register_owned_resource(mcp_bridge)
|
|
1251
|
+
|
|
1242
1252
|
# Register all tools with the server
|
|
1243
1253
|
for handler in tool_handlers:
|
|
1244
1254
|
server.register_tool(handler)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""BridgeAwareMixin for MCP tool handlers that need external MCP access.
|
|
2
|
+
|
|
3
|
+
Handlers that inherit from this mixin will automatically receive
|
|
4
|
+
an MCPClientManager reference when an MCPBridge is configured,
|
|
5
|
+
via loop-based injection in the composition root.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class BridgeAwareMixin:
|
|
16
|
+
"""Mixin for handlers that need access to external MCP servers.
|
|
17
|
+
|
|
18
|
+
Provides ``mcp_manager`` and ``mcp_tool_prefix`` fields that are
|
|
19
|
+
injected by the composition root when an MCPBridge is configured.
|
|
20
|
+
Both fields default to None/"" so handlers work without a bridge.
|
|
21
|
+
|
|
22
|
+
Usage::
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class MyHandler(BridgeAwareMixin):
|
|
26
|
+
other_field: str = ""
|
|
27
|
+
|
|
28
|
+
async def handle(self, arguments):
|
|
29
|
+
if self.mcp_manager:
|
|
30
|
+
tools = await self.mcp_manager.list_all_tools()
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
mcp_manager: Any | None = field(default=None, repr=False)
|
|
34
|
+
mcp_tool_prefix: str = ""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def inject_bridge(handler: object, bridge: object | None) -> bool:
|
|
38
|
+
"""Inject bridge manager into a BridgeAwareMixin handler.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
handler: A tool handler, possibly BridgeAwareMixin.
|
|
42
|
+
bridge: An MCPBridge instance (must have .manager and .tool_prefix).
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
True if injection was performed, False otherwise.
|
|
46
|
+
"""
|
|
47
|
+
if bridge is None or not isinstance(handler, BridgeAwareMixin):
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
handler.mcp_manager = getattr(bridge, "manager", None)
|
|
51
|
+
handler.mcp_tool_prefix = getattr(bridge, "tool_prefix", "")
|
|
52
|
+
return True
|
{ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/src/ouroboros/mcp/tools/execution_handlers.py
RENAMED
|
@@ -32,6 +32,7 @@ from ouroboros.core.worktree import (
|
|
|
32
32
|
from ouroboros.evaluation.verification_artifacts import build_verification_artifacts
|
|
33
33
|
from ouroboros.mcp.errors import MCPServerError, MCPToolError
|
|
34
34
|
from ouroboros.mcp.job_manager import JobLinks, JobManager
|
|
35
|
+
from ouroboros.mcp.tools.bridge_mixin import BridgeAwareMixin
|
|
35
36
|
from ouroboros.mcp.types import (
|
|
36
37
|
ContentType,
|
|
37
38
|
MCPContentItem,
|
|
@@ -97,7 +98,7 @@ def _extract_inherited_effective_tools(arguments: dict[str, Any]) -> list[str] |
|
|
|
97
98
|
|
|
98
99
|
|
|
99
100
|
@dataclass
|
|
100
|
-
class ExecuteSeedHandler:
|
|
101
|
+
class ExecuteSeedHandler(BridgeAwareMixin):
|
|
101
102
|
"""Handler for the execute_seed tool.
|
|
102
103
|
|
|
103
104
|
Executes a seed (task specification) in the Ouroboros system.
|
|
@@ -394,6 +395,8 @@ class ExecuteSeedHandler:
|
|
|
394
395
|
adapter=agent_adapter,
|
|
395
396
|
event_store=event_store,
|
|
396
397
|
console=console,
|
|
398
|
+
mcp_manager=self.mcp_manager,
|
|
399
|
+
mcp_tool_prefix=self.mcp_tool_prefix,
|
|
397
400
|
debug=False,
|
|
398
401
|
enable_decomposition=True,
|
|
399
402
|
inherited_runtime_handle=inherited_runtime_handle,
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"""Tests for STDIO transport context manager lifecycle in MCPClientAdapter.
|
|
2
|
+
|
|
3
|
+
Covers the edge cases identified in PR #263 review:
|
|
4
|
+
1. Rollback on failed initialization (transport entered but session fails)
|
|
5
|
+
2. disconnect() cleans transport when session is None (partial connect)
|
|
6
|
+
3. disconnect() closes transport even when session.__aexit__ raises
|
|
7
|
+
4. Transport teardown errors are surfaced, not swallowed
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from unittest.mock import AsyncMock, MagicMock, patch
|
|
13
|
+
|
|
14
|
+
import pytest
|
|
15
|
+
|
|
16
|
+
from ouroboros.mcp.client.adapter import MCPClientAdapter
|
|
17
|
+
from ouroboros.mcp.types import MCPServerConfig, TransportType
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _make_stdio_config(name: str = "test") -> MCPServerConfig:
|
|
21
|
+
return MCPServerConfig(
|
|
22
|
+
name=name,
|
|
23
|
+
transport=TransportType.STDIO,
|
|
24
|
+
command="echo",
|
|
25
|
+
args=("hello",),
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _mock_transport_cm(read=None, write=None):
|
|
30
|
+
"""Create a mock stdio_client context manager."""
|
|
31
|
+
cm = MagicMock()
|
|
32
|
+
cm.__aenter__ = AsyncMock(return_value=(read or MagicMock(), write or MagicMock()))
|
|
33
|
+
cm.__aexit__ = AsyncMock(return_value=None)
|
|
34
|
+
return cm
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _mock_session(*, init_fail=False, exit_fail=False):
|
|
38
|
+
"""Create a mock ClientSession."""
|
|
39
|
+
session = MagicMock()
|
|
40
|
+
session.__aenter__ = AsyncMock(return_value=session)
|
|
41
|
+
if exit_fail:
|
|
42
|
+
session.__aexit__ = AsyncMock(side_effect=RuntimeError("session exit boom"))
|
|
43
|
+
else:
|
|
44
|
+
session.__aexit__ = AsyncMock(return_value=None)
|
|
45
|
+
if init_fail:
|
|
46
|
+
session.initialize = AsyncMock(side_effect=ConnectionError("init failed"))
|
|
47
|
+
else:
|
|
48
|
+
session.initialize = AsyncMock(
|
|
49
|
+
return_value=MagicMock(
|
|
50
|
+
serverInfo=MagicMock(name="test", version="1.0"),
|
|
51
|
+
protocolVersion="2024-11-05",
|
|
52
|
+
capabilities=MagicMock(tools=None, resources=None, prompts=None, logging=None),
|
|
53
|
+
)
|
|
54
|
+
)
|
|
55
|
+
return session
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class TestConnectRollback:
|
|
59
|
+
"""Finding #1: rollback transport on failed session init."""
|
|
60
|
+
|
|
61
|
+
@pytest.mark.asyncio
|
|
62
|
+
async def test_transport_closed_when_session_init_fails(self):
|
|
63
|
+
"""If initialize() fails after transport is entered, transport must be closed."""
|
|
64
|
+
adapter = MCPClientAdapter(max_retries=1)
|
|
65
|
+
transport_cm = _mock_transport_cm()
|
|
66
|
+
session = _mock_session(init_fail=True)
|
|
67
|
+
|
|
68
|
+
with (
|
|
69
|
+
patch("mcp.client.stdio.stdio_client", return_value=transport_cm),
|
|
70
|
+
patch("mcp.ClientSession", return_value=session),
|
|
71
|
+
):
|
|
72
|
+
result = await adapter.connect(_make_stdio_config())
|
|
73
|
+
|
|
74
|
+
assert result.is_err
|
|
75
|
+
# Transport must have been cleaned up (called once per retry attempt)
|
|
76
|
+
transport_cm.__aexit__.assert_called_with(None, None, None)
|
|
77
|
+
assert adapter._transport_cm is None
|
|
78
|
+
assert adapter._session is None
|
|
79
|
+
|
|
80
|
+
@pytest.mark.asyncio
|
|
81
|
+
async def test_transport_closed_when_session_enter_fails(self):
|
|
82
|
+
"""If session.__aenter__ fails, transport must be closed."""
|
|
83
|
+
adapter = MCPClientAdapter()
|
|
84
|
+
transport_cm = _mock_transport_cm()
|
|
85
|
+
session = MagicMock()
|
|
86
|
+
session.__aenter__ = AsyncMock(side_effect=RuntimeError("session enter boom"))
|
|
87
|
+
|
|
88
|
+
with (
|
|
89
|
+
patch("mcp.client.stdio.stdio_client", return_value=transport_cm),
|
|
90
|
+
patch("mcp.ClientSession", return_value=session),
|
|
91
|
+
):
|
|
92
|
+
result = await adapter.connect(_make_stdio_config())
|
|
93
|
+
|
|
94
|
+
assert result.is_err
|
|
95
|
+
transport_cm.__aexit__.assert_called_once()
|
|
96
|
+
assert adapter._transport_cm is None
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class TestDisconnectPartialConnect:
|
|
100
|
+
"""Finding #2: disconnect() must clean transport even when session is None."""
|
|
101
|
+
|
|
102
|
+
@pytest.mark.asyncio
|
|
103
|
+
async def test_disconnect_cleans_orphaned_transport(self):
|
|
104
|
+
"""If _session is None but _transport_cm is set, disconnect must close it."""
|
|
105
|
+
adapter = MCPClientAdapter()
|
|
106
|
+
adapter._config = _make_stdio_config()
|
|
107
|
+
adapter._session = None # No session
|
|
108
|
+
|
|
109
|
+
transport_cm = _mock_transport_cm()
|
|
110
|
+
adapter._transport_cm = transport_cm # But transport is open
|
|
111
|
+
|
|
112
|
+
result = await adapter.disconnect()
|
|
113
|
+
assert result.is_ok
|
|
114
|
+
transport_cm.__aexit__.assert_called_once_with(None, None, None)
|
|
115
|
+
assert adapter._transport_cm is None
|
|
116
|
+
|
|
117
|
+
@pytest.mark.asyncio
|
|
118
|
+
async def test_disconnect_noop_when_both_none(self):
|
|
119
|
+
"""If both session and transport are None, disconnect is a no-op."""
|
|
120
|
+
adapter = MCPClientAdapter()
|
|
121
|
+
result = await adapter.disconnect()
|
|
122
|
+
assert result.is_ok
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class TestDisconnectSessionFailure:
|
|
126
|
+
"""Finding #3: transport cleanup must run even when session exit raises."""
|
|
127
|
+
|
|
128
|
+
@pytest.mark.asyncio
|
|
129
|
+
async def test_transport_closed_when_session_exit_raises(self):
|
|
130
|
+
"""If session.__aexit__ raises, transport must still be closed."""
|
|
131
|
+
adapter = MCPClientAdapter()
|
|
132
|
+
adapter._config = _make_stdio_config()
|
|
133
|
+
|
|
134
|
+
session = _mock_session(exit_fail=True)
|
|
135
|
+
adapter._session = session
|
|
136
|
+
|
|
137
|
+
transport_cm = _mock_transport_cm()
|
|
138
|
+
adapter._transport_cm = transport_cm
|
|
139
|
+
|
|
140
|
+
result = await adapter.disconnect()
|
|
141
|
+
# Should report the error
|
|
142
|
+
assert result.is_err
|
|
143
|
+
# But transport must still be cleaned up
|
|
144
|
+
transport_cm.__aexit__.assert_called_once_with(None, None, None)
|
|
145
|
+
assert adapter._transport_cm is None
|
|
146
|
+
assert adapter._session is None
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class TestDisconnectErrorReporting:
|
|
150
|
+
"""Finding #4: transport teardown errors must be surfaced."""
|
|
151
|
+
|
|
152
|
+
@pytest.mark.asyncio
|
|
153
|
+
async def test_transport_exit_error_is_reported(self):
|
|
154
|
+
"""If transport.__aexit__ raises, the error must be in the Result."""
|
|
155
|
+
adapter = MCPClientAdapter()
|
|
156
|
+
adapter._config = _make_stdio_config()
|
|
157
|
+
adapter._session = None # Only transport
|
|
158
|
+
|
|
159
|
+
transport_cm = MagicMock()
|
|
160
|
+
transport_cm.__aexit__ = AsyncMock(side_effect=OSError("pipe broken"))
|
|
161
|
+
adapter._transport_cm = transport_cm
|
|
162
|
+
|
|
163
|
+
result = await adapter.disconnect()
|
|
164
|
+
assert result.is_err
|
|
165
|
+
assert "pipe broken" in str(result.error)
|
|
166
|
+
# Transport ref still cleaned up
|
|
167
|
+
assert adapter._transport_cm is None
|
|
168
|
+
|
|
169
|
+
@pytest.mark.asyncio
|
|
170
|
+
async def test_both_errors_reported_session_first(self):
|
|
171
|
+
"""If both session and transport raise, session error is primary."""
|
|
172
|
+
adapter = MCPClientAdapter()
|
|
173
|
+
adapter._config = _make_stdio_config()
|
|
174
|
+
|
|
175
|
+
session = _mock_session(exit_fail=True)
|
|
176
|
+
adapter._session = session
|
|
177
|
+
|
|
178
|
+
transport_cm = MagicMock()
|
|
179
|
+
transport_cm.__aexit__ = AsyncMock(side_effect=OSError("transport boom"))
|
|
180
|
+
adapter._transport_cm = transport_cm
|
|
181
|
+
|
|
182
|
+
result = await adapter.disconnect()
|
|
183
|
+
assert result.is_err
|
|
184
|
+
# First error (session) is primary
|
|
185
|
+
assert "session exit boom" in str(result.error)
|
|
186
|
+
# Both resources cleaned up
|
|
187
|
+
assert adapter._session is None
|
|
188
|
+
assert adapter._transport_cm is None
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
class TestHappyPath:
|
|
192
|
+
"""Verify the fix doesn't break normal connect/disconnect."""
|
|
193
|
+
|
|
194
|
+
@pytest.mark.asyncio
|
|
195
|
+
async def test_normal_connect_stores_transport_cm(self):
|
|
196
|
+
adapter = MCPClientAdapter()
|
|
197
|
+
transport_cm = _mock_transport_cm()
|
|
198
|
+
session = _mock_session()
|
|
199
|
+
|
|
200
|
+
with (
|
|
201
|
+
patch("mcp.client.stdio.stdio_client", return_value=transport_cm),
|
|
202
|
+
patch("mcp.ClientSession", return_value=session),
|
|
203
|
+
):
|
|
204
|
+
result = await adapter.connect(_make_stdio_config())
|
|
205
|
+
|
|
206
|
+
assert result.is_ok
|
|
207
|
+
assert adapter._transport_cm is transport_cm
|
|
208
|
+
assert adapter._session is not None
|
|
209
|
+
|
|
210
|
+
@pytest.mark.asyncio
|
|
211
|
+
async def test_normal_disconnect_cleans_both(self):
|
|
212
|
+
adapter = MCPClientAdapter()
|
|
213
|
+
adapter._config = _make_stdio_config()
|
|
214
|
+
|
|
215
|
+
session = _mock_session()
|
|
216
|
+
adapter._session = session
|
|
217
|
+
transport_cm = _mock_transport_cm()
|
|
218
|
+
adapter._transport_cm = transport_cm
|
|
219
|
+
|
|
220
|
+
result = await adapter.disconnect()
|
|
221
|
+
assert result.is_ok
|
|
222
|
+
session.__aexit__.assert_called_once()
|
|
223
|
+
transport_cm.__aexit__.assert_called_once()
|
|
224
|
+
assert adapter._session is None
|
|
225
|
+
assert adapter._transport_cm is None
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""Tests for mcp_manager wiring via BridgeAwareMixin and inject_bridge.
|
|
2
|
+
|
|
3
|
+
Covers:
|
|
4
|
+
- BridgeAwareMixin fields default to None/""
|
|
5
|
+
- ExecuteSeedHandler inherits BridgeAwareMixin
|
|
6
|
+
- inject_bridge auto-discovers and injects into mixin handlers
|
|
7
|
+
- create_ouroboros_server loop-based bridge injection
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from unittest.mock import MagicMock
|
|
13
|
+
|
|
14
|
+
from ouroboros.mcp.tools.bridge_mixin import BridgeAwareMixin, inject_bridge
|
|
15
|
+
from ouroboros.mcp.tools.definitions import get_ouroboros_tools
|
|
16
|
+
from ouroboros.mcp.tools.execution_handlers import ExecuteSeedHandler
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TestBridgeAwareMixin:
|
|
20
|
+
"""Verify the mixin provides correct defaults."""
|
|
21
|
+
|
|
22
|
+
def test_handler_is_bridge_aware(self):
|
|
23
|
+
assert issubclass(ExecuteSeedHandler, BridgeAwareMixin)
|
|
24
|
+
|
|
25
|
+
def test_defaults_to_none(self):
|
|
26
|
+
handler = ExecuteSeedHandler()
|
|
27
|
+
assert handler.mcp_manager is None
|
|
28
|
+
assert handler.mcp_tool_prefix == ""
|
|
29
|
+
|
|
30
|
+
def test_accepts_mcp_manager_directly(self):
|
|
31
|
+
mock = MagicMock()
|
|
32
|
+
handler = ExecuteSeedHandler(mcp_manager=mock, mcp_tool_prefix="pfx_")
|
|
33
|
+
assert handler.mcp_manager is mock
|
|
34
|
+
assert handler.mcp_tool_prefix == "pfx_"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class TestInjectBridge:
|
|
38
|
+
"""Verify inject_bridge auto-discovery and injection."""
|
|
39
|
+
|
|
40
|
+
def test_injects_into_bridge_aware_handler(self):
|
|
41
|
+
handler = ExecuteSeedHandler()
|
|
42
|
+
bridge = MagicMock()
|
|
43
|
+
bridge.manager = MagicMock(name="FakeManager")
|
|
44
|
+
bridge.tool_prefix = "ext_"
|
|
45
|
+
|
|
46
|
+
result = inject_bridge(handler, bridge)
|
|
47
|
+
|
|
48
|
+
assert result is True
|
|
49
|
+
assert handler.mcp_manager is bridge.manager
|
|
50
|
+
assert handler.mcp_tool_prefix == "ext_"
|
|
51
|
+
|
|
52
|
+
def test_skips_non_bridge_aware_handler(self):
|
|
53
|
+
handler = MagicMock(spec=[]) # No BridgeAwareMixin
|
|
54
|
+
bridge = MagicMock()
|
|
55
|
+
|
|
56
|
+
result = inject_bridge(handler, bridge)
|
|
57
|
+
assert result is False
|
|
58
|
+
|
|
59
|
+
def test_skips_when_bridge_is_none(self):
|
|
60
|
+
handler = ExecuteSeedHandler()
|
|
61
|
+
result = inject_bridge(handler, None)
|
|
62
|
+
assert result is False
|
|
63
|
+
assert handler.mcp_manager is None
|
|
64
|
+
|
|
65
|
+
def test_handles_bridge_without_tool_prefix(self):
|
|
66
|
+
handler = ExecuteSeedHandler()
|
|
67
|
+
bridge = MagicMock(spec=["manager"]) # No tool_prefix attr
|
|
68
|
+
bridge.manager = MagicMock()
|
|
69
|
+
|
|
70
|
+
result = inject_bridge(handler, bridge)
|
|
71
|
+
assert result is True
|
|
72
|
+
assert handler.mcp_manager is bridge.manager
|
|
73
|
+
assert handler.mcp_tool_prefix == "" # getattr fallback
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class TestGetOuroborosTools:
|
|
77
|
+
"""Verify tools can be created and later injected."""
|
|
78
|
+
|
|
79
|
+
def test_default_tools_have_no_manager(self):
|
|
80
|
+
tools = get_ouroboros_tools()
|
|
81
|
+
exec_handler = tools[0]
|
|
82
|
+
assert isinstance(exec_handler, ExecuteSeedHandler)
|
|
83
|
+
assert exec_handler.mcp_manager is None
|
|
84
|
+
|
|
85
|
+
def test_tool_count_unchanged(self):
|
|
86
|
+
tools = get_ouroboros_tools()
|
|
87
|
+
assert len(tools) >= 20 # Sanity check
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class TestCompositionRoot:
|
|
91
|
+
"""Verify create_ouroboros_server loop-based bridge injection."""
|
|
92
|
+
|
|
93
|
+
def test_bridge_injected_into_execute_handler(self):
|
|
94
|
+
from ouroboros.mcp.server.adapter import create_ouroboros_server
|
|
95
|
+
|
|
96
|
+
mock_bridge = MagicMock()
|
|
97
|
+
mock_bridge.manager = MagicMock(name="FakeManager")
|
|
98
|
+
mock_bridge.tool_prefix = "ext_"
|
|
99
|
+
|
|
100
|
+
server = create_ouroboros_server(mcp_bridge=mock_bridge)
|
|
101
|
+
|
|
102
|
+
exec_handler = None
|
|
103
|
+
for handler in server._tool_handlers.values():
|
|
104
|
+
if isinstance(handler, ExecuteSeedHandler):
|
|
105
|
+
exec_handler = handler
|
|
106
|
+
break
|
|
107
|
+
|
|
108
|
+
assert exec_handler is not None
|
|
109
|
+
assert exec_handler.mcp_manager is mock_bridge.manager
|
|
110
|
+
assert exec_handler.mcp_tool_prefix == "ext_"
|
|
111
|
+
|
|
112
|
+
def test_bridge_registered_as_owned_resource(self):
|
|
113
|
+
from ouroboros.mcp.server.adapter import create_ouroboros_server
|
|
114
|
+
|
|
115
|
+
mock_bridge = MagicMock()
|
|
116
|
+
mock_bridge.manager = MagicMock()
|
|
117
|
+
mock_bridge.tool_prefix = ""
|
|
118
|
+
|
|
119
|
+
server = create_ouroboros_server(mcp_bridge=mock_bridge)
|
|
120
|
+
assert mock_bridge in server._owned_resources
|
|
121
|
+
|
|
122
|
+
def test_no_bridge_leaves_handler_with_none(self):
|
|
123
|
+
from ouroboros.mcp.server.adapter import create_ouroboros_server
|
|
124
|
+
|
|
125
|
+
server = create_ouroboros_server()
|
|
126
|
+
|
|
127
|
+
exec_handler = None
|
|
128
|
+
for handler in server._tool_handlers.values():
|
|
129
|
+
if isinstance(handler, ExecuteSeedHandler):
|
|
130
|
+
exec_handler = handler
|
|
131
|
+
break
|
|
132
|
+
|
|
133
|
+
assert exec_handler is not None
|
|
134
|
+
assert exec_handler.mcp_manager is None
|
|
135
|
+
|
|
136
|
+
def test_no_bridge_not_in_owned_resources(self):
|
|
137
|
+
from ouroboros.mcp.server.adapter import create_ouroboros_server
|
|
138
|
+
|
|
139
|
+
server = create_ouroboros_server()
|
|
140
|
+
bridge_resources = [
|
|
141
|
+
r
|
|
142
|
+
for r in server._owned_resources
|
|
143
|
+
if hasattr(r, "tool_prefix") and hasattr(r, "manager")
|
|
144
|
+
]
|
|
145
|
+
assert len(bridge_resources) == 0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/.github/ISSUE_TEMPLATE/feature_request.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/src/views/dashboard.rs
RENAMED
|
File without changes
|
{ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/src/views/execution.rs
RENAMED
|
File without changes
|
{ouroboros_ai-0.26.7.dev3 → ouroboros_ai-0.26.7.dev5}/crates/ouroboros-tui/src/views/lineage.rs
RENAMED
|
File without changes
|