drydock-cli 2.8.7__tar.gz → 2.8.8__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.
- drydock_cli-2.8.8/.auto_release.lock +1 -0
- drydock_cli-2.8.8/DEEP_NOIR_PRD.md +111 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/PKG-INFO +1 -1
- drydock_cli-2.8.8/drydock/steering/sidecar/__init__.py +28 -0
- drydock_cli-2.8.8/drydock/steering/sidecar/header_parser.py +74 -0
- drydock_cli-2.8.8/drydock/steering/sidecar/server.py +251 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/pyproject.toml +1 -1
- drydock_cli-2.8.8/scripts/start_steering_sidecar.sh +52 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/trip_log.md +106 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/uv.lock +1 -1
- drydock_cli-2.8.7/.auto_release.lock +0 -1
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.claude/scheduled_tasks.lock +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.github/CODEOWNERS +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.github/workflows/build-and-upload.yml +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.github/workflows/ci.yml +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.github/workflows/issue-labeler.yml +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.github/workflows/release.yml +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.gitignore +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.pre-commit-config.yaml +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.python-version +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.typos.toml +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.vscode/extensions.json +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.vscode/launch.json +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/.vscode/settings.json +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/AGENTS.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/Admiral.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/CHANGELOG.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/CLAUDE.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/CONTRIBUTING.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/DEPLOYMENT.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/HLE_PRD.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/JETSON_BENCH.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/LICENSE +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/MODEL_SHORTCOMINGS.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/NOTICE +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/README.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/SOVEREIGN_PRD.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/TRIAGE_v1.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/action.yml +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/README.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results1.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results13.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results14.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results15.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results16.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results17.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results18.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results19.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results2.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results20.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results3.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results4.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results5.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results6.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results7.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results8.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results9.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/baseline_history/results_evolved_v1.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/distribution/zed/LICENSE +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/distribution/zed/extension.toml +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/distribution/zed/icons/mistral_vibe.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/docs/README.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/docs/acp-setup.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/docs/archive/BASELINE_412.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/docs/archive/Drydock_rebrand.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/docs/archive/OVERNIGHT_PROGRESS.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/docs/archive/OVERNIGHT_REPORT_2026_04_13.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/docs/archive/PERF_SWEEP_PLAN.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/docs/archive/PRD.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/docs/archive/drydock_terms.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/docs/archive/resume.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/docs/proxy-setup.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/__main__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/acp/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/acp/acp_agent_loop.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/acp/acp_logger.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/acp/entrypoint.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/acp/tools/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/acp/tools/base.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/acp/tools/builtins/bash.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/acp/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/acp/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/acp/tools/builtins/todo.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/acp/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/acp/tools/session_update.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/acp/utils.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/detectors.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/detectors_proposed.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/history.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/interventions.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/llm_analyzer.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/metrics.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/opus_escalator.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/persistence.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/policy.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/proposer.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/stager.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/task_classifier.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/tuning.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/validator.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/admiral/worker.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/autocompletion/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/autocompletion/base.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/autocompletion/path_completion.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/autocompletion/slash_command.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/cli.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/clipboard.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/commands.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/entrypoint.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/fix_windows_path.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/history_manager.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/terminal_setup.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/app.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/app.tcss +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/external_editor.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/compact.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/loading.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/messages.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/tools.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/windowing/history.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/textual_ui/windowing/state.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/update_notifier/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/update_notifier/update.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/cli/update_notifier/whats_new.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/agent_loop.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/agents/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/agents/manager.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/agents/models.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/auth/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/auth/crypto.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/auth/github.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/autocompletion/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/autocompletion/completers.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/autocompletion/file_indexer/store.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/autocompletion/fuzzy.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/autocompletion/path_prompt.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/build_orchestrator.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/checkpoint.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/classifier/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/classifier/__main__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/classifier/classifier.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/classifier/dispatcher.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/classifier/rules.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/classifier/signal.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/config/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/config/_dotenv.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/config/_settings.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/config/doctor.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/config/harness_files/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/config/harness_files/_harness_manager.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/config/harness_files/_paths.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/config/local_detect.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/config/migrate.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/consultant.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/context_recovery.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/drydock_states.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/hooks.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/llm/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/llm/backend/anthropic.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/llm/backend/base.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/llm/backend/factory.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/llm/backend/generic.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/llm/backend/mistral.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/llm/backend/vertex.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/llm/exceptions.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/llm/format.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/llm/message_utils.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/llm/types.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/logger.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/middleware.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/output_formatters.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/paths/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/paths/_drydock_home.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/paths/_local_config_walk.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/paths/conventions.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/plan_session.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/plugins.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/programmatic.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/prompts/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/prompts/builder.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/prompts/cli.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/prompts/compact.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/prompts/dangerous_directory.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/prompts/diagnostic.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/prompts/explore.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/prompts/gemma4.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/prompts/planner.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/prompts/project_context.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/prompts/tests.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/proxy_setup.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/session/agent_memory.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/session/checkpoints.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/session/session_loader.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/session/session_logger.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/session/session_migration.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/session/state_file.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/session_checker.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/skills/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/skills/manager.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/skills/models.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/skills/parser.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/slug.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/steering_hook.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/system_prompt.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/telemetry/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/telemetry/send.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/teleport/errors.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/teleport/git.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/teleport/nuage.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/teleport/teleport.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/teleport/types.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/base.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/_task_manager.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/ask_user_question.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/bash.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/cron.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/glob_tool.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/grep.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/invoke_skill.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/lsp.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/mcp_resources.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/notebook_edit.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/powershell.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/bash.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/cron.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/glob.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/grep.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/retrieve.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/task.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/todo.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/retrieve.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/task.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/todo.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/tool_search.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/webfetch.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/websearch.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/worktree.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/injection_guard.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/manager.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/mcp/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/mcp/registry.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/mcp/tools.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/mcp_sampling.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/ui.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/tools/utils.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/trusted_folders.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/types.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/core/utils.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/graphrag/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/graphrag/__main__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/graphrag/code_indexer.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/graphrag/retriever.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/graphrag/storage.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/graphrag/text_indexer.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/setup/onboarding/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/setup/onboarding/base.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/setup/onboarding/onboarding.tcss +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/setup/onboarding/screens/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/setup/onboarding/screens/api_key.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/setup/onboarding/screens/choice.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/setup/onboarding/screens/local_model.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/setup/onboarding/screens/welcome.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/api-design/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/audit-tests/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/batch/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/commit-code/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/context-summary/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/create-presentation/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/deep-research/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/deploy/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/diff-review/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/doc-gen/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/explain-code/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/explore-code/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/fix-issue/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/git-ops/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/init-project/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/investigate/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/loop/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/migrate/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/perf-analyze/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/plan-impl/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/pr-review/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/refactor/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/regex-help/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/review/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/security-review/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/ship/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/simplify/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/strong-tests/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/skills/test-verify/SKILL.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/steering/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/steering/__main__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/steering/applier.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/steering/config.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/steering/registry.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/steering/sandbox.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/steering/vectors.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock/whats_new.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/drydock-acp.spec +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/flake.lock +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/flake.nix +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/research/README.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/research/config_base.toml +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/research/config_best.toml +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/research/domain_spec.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/research/experimenter.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/research/kernel.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/research/mini_prd.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/research/mini_prompts.txt +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/research/proposer.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/research/results.tsv +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/README.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/admiral_probe.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/archive/auto_test_loop.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/archive/monitor_test_battery.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/archive/overnight_agents_test.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/archive/test_bank.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/archive/test_full.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/archive/test_smoke.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/archive/tui_test.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/audit_sampler.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/auto_generate_tests.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/auto_release.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/autonomous_review.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/autonomous_review_prompt.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/backup.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/bump_version.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/classify_pulse.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/consume_retrieval_queue.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/deploy_to_github.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/fetch_arxiv_abstracts.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/gen_2000_prompts.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/hle_eval.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/hle_eval_seed.jsonl +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/llm_balancer.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/notify_release.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/perf_baseline_when_idle.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/perf_sweep.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/poll_issues.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/publish_to_pypi.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/queue_top.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/ralph_loop.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/research_babysitter.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/shakedown.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/shakedown_interactive.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/shakedown_suite.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/shakedown_variance.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/stress_babysitter.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/stress_prompts_50.txt +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/stress_prompts_realuser.txt +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/stress_prompts_tool_agent.txt +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/stress_prompts_tool_agent_2000.txt +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/stress_shakedown.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/stress_telegram_status.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/stress_watcher.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/telegram_bot.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/scripts/vllm_failover.sh +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/conftest.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_acp.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_agent_thought.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_bash.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_compact_session_updates.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_content.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_initialize.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_list_sessions.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_load_session.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_multi_session.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_new_session.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_proxy_setup_acp.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_read_file.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_search_replace.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_set_config_option.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_set_mode.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_set_model.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_tool_call_session_update.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_utils.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/acp/test_write_file.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/autocompletion/test_file_indexer.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/autocompletion/test_fuzzy.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/autocompletion/test_path_completer_recursive.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/autocompletion/test_path_completion_controller.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/autocompletion/test_slash_command_controller.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/backend/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/backend/data/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/backend/data/fireworks.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/backend/data/mistral.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/backend/test_anthropic_adapter.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/backend/test_backend.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/backend/test_generic_adapter_sanitize.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/backend/test_reasoning_adapter.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/test_bell_notifications.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/test_braille_renderer.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/test_clipboard.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/test_commands.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/test_copy_shortcuts.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/test_external_editor.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/test_no_markup_static.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/test_question_app.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/test_spinner.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/test_switching_mode.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/test_ui_clipboard_notifications.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/test_ui_session_resume.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/test_ui_skill_dispatch.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/cli/textual_ui/test_session_picker.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/conftest.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_agents.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_auth_crypto.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_auth_github.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_circuit_breaker_count_escalation.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_circuit_breaker_readonly_threshold.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_config_load_dotenv.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_config_paths.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_config_resolution.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_file_logging.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_plan_session.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_proxy_setup.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_slug.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_telemetry_send.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_teleport_git.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_teleport_nuage.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_teleport_service.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_trusted_folders.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/core/test_utils.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/e2e/common.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/e2e/conftest.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/e2e/mock_server.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/e2e/test_cli_tui_onboarding.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/e2e/test_cli_tui_streaming.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/fixtures/doc_qa_system_prd.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/mock/__init__.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/mock/mock_backend_factory.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/mock/mock_entrypoint.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/mock/utils.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/onboarding/test_run_onboarding.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/onboarding/test_ui_onboarding.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/session/test_session_loader.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/session/test_session_logger.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/session/test_session_migration.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/skills/conftest.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/skills/test_manager.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/skills/test_models.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/skills/test_parser.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_code_block_horizontal_scrolling/test_snapshot_allows_horizontal_scrolling_for_long_code_blocks.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_empty_assistant_before_reasoning/test_snapshot_empty_assistant_removed_when_reasoning_starts.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/base_snapshot_test_app.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/conftest.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/snap_compare.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/stubs/fake_backend.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/stubs/fake_client.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/stubs/fake_tool.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_admiral.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_admiral_phase3.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_admiral_proposed.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_admiral_struggle_dedup.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_agent_auto_compact.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_agent_backend.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_agent_observer_streaming.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_agent_stats.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_agent_tasks.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_agent_tool_call.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_agents.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_bank_build.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_bank_debug.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_bank_multiagent.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_bank_prd.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_bank_prd_extended.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_bank_tools.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_bank_update.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_build_projects.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_checkpoint.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_classifier.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_cli_programmatic_preload.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_config_migration.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_context_recovery.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_current_bugs.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_dispatcher.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_drydock_regression.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_drydock_tasks.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_fake_tool_call_paren_syntax.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_full_regression.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_graphrag.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_hallucinated_tool_suppression.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_history_manager.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_integration.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_issue_fixes.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_local_detect.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_loop_detection.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_message_id.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_message_merging.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_middleware.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_multi_agent.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_read_file_not_found_listing.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_real_failures.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_real_issues.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_real_workflow.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_reasoning_content.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_retrieval_consumer.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_retrieve_tool.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_search_replace_args_not_truncated.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_smoke.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_steering.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_steering_hook.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_system_prompt.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_tagged_text.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_task_complete_nudge.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_tool_args.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_truncate_args_valid_json.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_truncated_arg_path_hint.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_truncated_search_replace_escalation.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_truncated_write_escalation.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_ui_external_editor.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_ui_input_history.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_user_issues.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_wall_of_text_rescue.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_workloads.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/test_write_file_missing_path.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/testbank_helpers.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_ask_user_question.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_bash.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_bash_binary_grep_hint.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_bash_consec_empty_search.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_bash_echo_escape_loop_breaker.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_bash_empty_search_loop_breaker.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_bash_error_loop_breaker.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_bash_exact_cmd_loop_breaker.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_bash_heredoc_confirmation.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_bash_kill_exit1_annotation.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_bash_python_c_syntaxerr_loop_breaker.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_exit_plan_mode.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_grep.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_hallucinated_retrieval_redirect.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_invoke_context.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_manager_gemma_derived_models.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_manager_get_tool_config.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_mcp.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_mcp_sampling.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_read_file_dedup_alternating_offset.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_read_file_dedup_reembed.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_read_file_directory.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_read_file_limit_truncation.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_search_replace_append_fallback.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_search_replace_dir_path.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_search_replace_empty_content.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_search_replace_file_not_found.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_search_replace_first_failure_hint.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_search_replace_hard_stop.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_search_replace_malformed_block.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_search_replace_no_op_loop_breaker.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_search_replace_placeholder.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_search_replace_refused_loop_breaker.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_task.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_ui_bash_execution.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_webfetch.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_websearch.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_write_file_dedup_missing_imports.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/tools/test_write_file_missing_path_hint.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/update_notifier/test_do_update.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/update_notifier/test_github_update_gateway.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/update_notifier/test_ui_update_notification.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/update_notifier/test_update_use_case.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/tests/update_notifier/test_whats_new.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/worked_examples/README.md +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/worked_examples/cli_subcommand_dispatch.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/worked_examples/lookup.json +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/worked_examples/sql_parser.py +0 -0
- {drydock_cli-2.8.7 → drydock_cli-2.8.8}/worked_examples/tree_walking_interpreter.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
4191814
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Deep Noir activation-patching PRD — reasoning steering, transformers-backed sidecar
|
|
2
|
+
|
|
3
|
+
**Status:** Draft, 2026-05-09. Phase 3 of HLE_PRD.
|
|
4
|
+
|
|
5
|
+
The v0 token-bias path (`LogitBiasSteeringApplier`) hit its expected ceiling: phase1_steered scored 1/20 = 5% on the worked-example seed, identical to the unsteered baseline. This PRD scopes the next-tier applier — real activation patching at a configurable decoder layer — using a `transformers`-backed sidecar process so we can validate the architecture before the bigger vLLM forward-hook port. Goal: get one steering vector to lift Phase 1 above 5/20 on the existing 20-question seed, proving reasoning steering works at all on quantized Gemma 4. Then port to vLLM for production speed.
|
|
6
|
+
|
|
7
|
+
## Why a sidecar (vs. patching the production server)
|
|
8
|
+
|
|
9
|
+
Production inference is llama.cpp Docker (remus, b9014). It does not expose a per-layer hidden-state hook, and rebuilding it with a custom hook costs weeks. vLLM has a `custom_ops` extension point but our prod stack moved off vLLM in May; rebuilding it for steering only would block other work.
|
|
10
|
+
|
|
11
|
+
A separate `transformers`-backed Python process gives us full forward-pass control today (`model.layers[L].register_forward_hook`), accepts the existing OpenAI-compatible request shape via a thin FastAPI wrapper, and runs on the same GPU pool. It will be **~10× slower than llama.cpp** because there's no batching/quant kernel, but research speed is the bottleneck right now, not throughput. Once one vector lifts Phase 1 we know the work is worth porting; until then, simple wins.
|
|
12
|
+
|
|
13
|
+
## Architecture
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
client (drydock TUI / hle_eval)
|
|
17
|
+
│ chat/completions
|
|
18
|
+
▼
|
|
19
|
+
llm_balancer (:8001)
|
|
20
|
+
│ routes by header X-Drydock-Steering
|
|
21
|
+
├─ no header → llama.cpp :8000 (current prod, fast, no steering)
|
|
22
|
+
└─ has header → drydock-steered :8002 (new sidecar, slow, hooks active)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- **`X-Drydock-Steering: show_work@18×0.6,verify@22×0.4`** — comma-separated `mode@layer×scale` triples. Empty/missing → balancer falls through to llama.cpp.
|
|
26
|
+
- **Sidecar process** (`drydock/steering/sidecar/server.py`):
|
|
27
|
+
- Loads Gemma 4 26B via `transformers.AutoModelForCausalLM` with the AWQ-4bit weights from `/data3/Models/Gemma-4-26B-A4B-it-AWQ-4bit/`.
|
|
28
|
+
- Pre-registers forward hooks on `model.layers[0..N]`. Each hook reads the requested mode/layer/scale from a thread-local context var and adds `scale × vector` to the residual stream.
|
|
29
|
+
- Exposes `/v1/chat/completions` (OpenAI shape) so the existing balancer can route to it transparently.
|
|
30
|
+
- **`agent_loop.py` change**: when a `SteeringDecision` is active, set the request header `X-Drydock-Steering: <serialized>`. No payload change.
|
|
31
|
+
|
|
32
|
+
The wire-level result: one HTTP header is the entire integration surface between the harness and the steered inference path. Adding/removing modes is a config change, not a code change.
|
|
33
|
+
|
|
34
|
+
## Vector training
|
|
35
|
+
|
|
36
|
+
For each candidate mode, the data pipeline is:
|
|
37
|
+
|
|
38
|
+
1. **Extract contrastive pairs** from `~/.drydock/admiral_history.log` and stress run logs. A pair = `(prompt, derailed_chain, good_chain)` where derailed = stalled/looped/wrong-answer turn, good = same-prompt turn that resolved correctly. Tag schema lives in `drydock/admiral/schema.py` (already records turn-level outcome).
|
|
39
|
+
2. **Capture residual streams**. Run each pair through the unsteered sidecar with hooks recording `hidden_states[L]` at every layer for the assistant's first 50 tokens. Save as `.pt` per pair.
|
|
40
|
+
3. **Compute the direction**. For layer L, the vector is `mean(good_streams[L]) - mean(derailed_streams[L])`, L1-normalized. Stored as `.npy` + manifest `.toml` in `~/.drydock/steering/vectors/<mode>/<layer>.npy`.
|
|
41
|
+
4. **Validate via sandbox**. The existing `drydock/steering/sandbox.py` harness runs a fixed prompt set with steering on/off and diffs outputs. Pass = no regression on a control set + measurable behavior change on the target set.
|
|
42
|
+
|
|
43
|
+
Initial three modes to train (chosen because they have the most signal in admiral_history):
|
|
44
|
+
|
|
45
|
+
| Mode | Direction | Target layer | Hypothesis |
|
|
46
|
+
|---|---|---|---|
|
|
47
|
+
| `show_work` | derailed = single-line answers; good = step-by-step intermediate computations | 16-20 | Push the model to write intermediate steps before committing to a final answer |
|
|
48
|
+
| `verify` | derailed = wrong-answer-then-stop; good = wrong-answer-then-recheck-then-corrected | 18-22 | Push toward second-pass verification before emitting `ANSWER:` |
|
|
49
|
+
| `cite_source` | derailed = made-up specifics; good = "per the chunk above," explicit quote | 14-18 | When retrieval surfaces an authoritative chunk, push toward grounding rather than re-deriving |
|
|
50
|
+
|
|
51
|
+
`show_work` is the obvious first one to validate against Phase 1's 1/20 floor.
|
|
52
|
+
|
|
53
|
+
## Milestones
|
|
54
|
+
|
|
55
|
+
| # | Deliverable | Sized at |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| 1 | `drydock/steering/sidecar/server.py` — bare FastAPI + transformers loader on :8002, no hooks yet, returns identical outputs to llama.cpp on a smoke prompt. Container or systemd unit. | 1 day |
|
|
58
|
+
| 2 | Forward-hook injection scaffolding. Header parsing, context-var dispatch, vector load on demand. Hook is a no-op (adds zero) so we verify the integration end-to-end with no behavior change. | 1 day |
|
|
59
|
+
| 3 | Vector capture pipeline. Script that takes `(prompt, completion)` pairs, runs them through sidecar with capture-mode hooks, saves residual streams. | 1 day |
|
|
60
|
+
| 4 | Vector training. Compute direction per layer from captured streams, write `.npy` + `.toml`. Two pass: a quick "any non-zero direction works" pre-flight, then real training on real pairs. | 1 day |
|
|
61
|
+
| 5 | First end-to-end run: `show_work@18×0.5` against Phase 1's 20 questions. | 0.5 day (eval is 2-3h compute) |
|
|
62
|
+
| 6 | If lift > 0/20, train two more (`verify`, `cite_source`) and re-run. If lift = 0/20, iterate on layer choice and scale before adding modes. | open-ended |
|
|
63
|
+
| 7 | Optional follow-on: vLLM forward-hook port for production speed, once at least one vector lifts a real benchmark. | 1-2 weeks, only after #6 succeeds |
|
|
64
|
+
|
|
65
|
+
Total to first signal: ~4-5 days of focused work. The biggest single risk is #4 producing junk vectors because the contrastive pair set is too small or too noisy.
|
|
66
|
+
|
|
67
|
+
## Success criteria
|
|
68
|
+
|
|
69
|
+
- **Required:** end-to-end loop works. A request with `X-Drydock-Steering: show_work@18×0.5` returns a different completion than the same request with no header, on the same prompt, deterministic seed. Sandbox eval reports a structured diff. (This is the architecture validation — proves the wiring is real, independent of whether any vector helps.)
|
|
70
|
+
- **Aspirational:** `show_work` lifts Phase 1's 1/20 baseline by at least +1 question (≥10%). Confirms reasoning steering is a real lever for HLE-style tasks on a quantized 26B.
|
|
71
|
+
- **Stretch:** Two of the three trained modes lift Phase 1 ≥10% individually; combined ≥3/20. Suggests vector composition isn't catastrophic and the path scales.
|
|
72
|
+
|
|
73
|
+
## Constraints / non-goals
|
|
74
|
+
|
|
75
|
+
- **AWQ-4bit only.** No fp16/bf16 path. Vectors are calibrated against the production runtime — no drift between sandbox and (eventual) prod.
|
|
76
|
+
- **No vLLM port in this PRD.** Mentioned in milestone #7 as a follow-on; only triggers if the sidecar proves the architecture.
|
|
77
|
+
- **Sidecar runs on existing GPU pool.** Either remus or romulus, but only one at a time — competes with stress run for VRAM. Schedule eval runs around stress windows.
|
|
78
|
+
- **No "real-time learning."** Vectors are trained offline from logs and shipped as `.npy` files. The sidecar's only runtime job is the forward-pass injection; it does not adapt during a request.
|
|
79
|
+
- **No mainline drydock dependency on the sidecar.** Sidecar can be down; balancer falls back to llama.cpp; production unaffected.
|
|
80
|
+
|
|
81
|
+
## Decisions (locked 2026-05-09)
|
|
82
|
+
|
|
83
|
+
- **Pair source: admiral_history only for v1.** ~3 weeks of stress + autonomous_review traces is the contrastive set. No synthetic pair generation in this PRD. If volume turns out to be insufficient (vector training produces near-zero directions), revisit in a follow-up.
|
|
84
|
+
- **Layer sweep: informed picks first, full sweep as fallback.** Start with the ranges suggested in the modes table (`show_work` 16-20, `verify` 18-22, `cite_source` 14-18). Pick the midpoint of each range as the first attempt. If the informed pick fails to lift Phase 1 by ≥10%, escalate to a full sweep across all layers for that mode before declaring the mode dead.
|
|
85
|
+
- **Stress run flips to steering-on by default once one vector lifts Phase 1.** Confirmed-working vectors become the new baseline for stress; the unsteered run becomes the control measured in periodic A/B comparisons rather than the default. Set via env var `DRYDOCK_STEERING_MODES=<mode1>,<mode2>` in `stress_babysitter.sh`'s spawn line.
|
|
86
|
+
|
|
87
|
+
## File map (planned)
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
drydock/steering/
|
|
91
|
+
├── sidecar/
|
|
92
|
+
│ ├── server.py # FastAPI + transformers, port :8002
|
|
93
|
+
│ ├── hooks.py # forward_hook implementations
|
|
94
|
+
│ └── header_parser.py # X-Drydock-Steering parsing + validation
|
|
95
|
+
├── train/
|
|
96
|
+
│ ├── extract_pairs.py # admiral_history → contrastive .jsonl
|
|
97
|
+
│ ├── capture.py # streams pairs through sidecar in capture mode
|
|
98
|
+
│ ├── compute_vector.py# good_mean - derailed_mean per layer
|
|
99
|
+
│ └── README.md # training pipeline runbook
|
|
100
|
+
└── (existing applier.py, registry.py, vectors.py, sandbox.py — unchanged)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
scripts/
|
|
104
|
+
├── start_steering_sidecar.sh # systemd unit equivalent for the sidecar
|
|
105
|
+
└── train_steering_vector.sh # one-shot wrapper around the train/ pipeline
|
|
106
|
+
|
|
107
|
+
## Reference signals (from current scaffolding)
|
|
108
|
+
|
|
109
|
+
- `drydock/steering/applier.py:14` — comment block already calls out `VllmSidecarSteeringApplier (TODO)` as the planned successor. This PRD picks up that thread and implements it as a transformers sidecar first.
|
|
110
|
+
- `drydock/core/agent_loop.py:2310` — the steering hook is already wired per-request and env-gated. Adding the header path is a 5-line change.
|
|
111
|
+
- `HLE_PRD.md` Phase 3 plan — names the three candidate modes (verify-before-answer, show-work-explicitly, consider-units, minimal-patch). This PRD adopts those as starting modes.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: drydock-cli
|
|
3
|
-
Version: 2.8.
|
|
3
|
+
Version: 2.8.8
|
|
4
4
|
Summary: Local-first CLI coding agent — tested with Gemma 4 26B via vLLM
|
|
5
5
|
Project-URL: Homepage, https://github.com/fbobe321/drydock
|
|
6
6
|
Project-URL: Repository, https://github.com/fbobe321/drydock
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Deep Noir activation-steering sidecar — transformers-backed inference.
|
|
2
|
+
|
|
3
|
+
A separate Python process (default port 8002) that loads Gemma 4 via
|
|
4
|
+
`transformers.AutoModelForCausalLM` so we have full forward-pass control
|
|
5
|
+
for activation patching at configurable decoder layers. Speaks the
|
|
6
|
+
OpenAI `/v1/chat/completions` shape so the existing `llm_balancer`
|
|
7
|
+
can route to it transparently when an `X-Drydock-Steering` header is
|
|
8
|
+
present on the request.
|
|
9
|
+
|
|
10
|
+
Why a sidecar (not a vLLM patch): vLLM doesn't expose per-layer hidden-
|
|
11
|
+
state hooks without a custom forward-pass build, and our production
|
|
12
|
+
stack moved off vLLM in May 2026. transformers gives us
|
|
13
|
+
`model.layers[L].register_forward_hook(...)` for free, at the cost of
|
|
14
|
+
~10× lower throughput. Acceptable for research-velocity vector
|
|
15
|
+
training and Phase 1 ablation eval; not for production stress.
|
|
16
|
+
|
|
17
|
+
Public surface:
|
|
18
|
+
from drydock.steering.sidecar.server import build_app
|
|
19
|
+
app = build_app() # FastAPI app, lazy model load
|
|
20
|
+
# Then: uvicorn ...:app --port 8002
|
|
21
|
+
|
|
22
|
+
CLI:
|
|
23
|
+
bash scripts/start_steering_sidecar.sh
|
|
24
|
+
bash scripts/start_steering_sidecar.sh --port 8002 --model /path/to/weights
|
|
25
|
+
|
|
26
|
+
See DEEP_NOIR_PRD.md for the architecture, training pipeline, and
|
|
27
|
+
milestones.
|
|
28
|
+
"""
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""Parse the `X-Drydock-Steering` HTTP header into structured directives.
|
|
2
|
+
|
|
3
|
+
Wire format:
|
|
4
|
+
X-Drydock-Steering: <mode>@<layer>×<scale>[,<mode>@<layer>×<scale>...]
|
|
5
|
+
|
|
6
|
+
The Unicode multiplication sign `×` is the separator between layer and
|
|
7
|
+
scale. ASCII `x` is also accepted (for shells and clients that mangle
|
|
8
|
+
Unicode).
|
|
9
|
+
|
|
10
|
+
Examples:
|
|
11
|
+
X-Drydock-Steering: show_work@18×0.6
|
|
12
|
+
X-Drydock-Steering: show_work@18×0.6,verify@22×0.4
|
|
13
|
+
X-Drydock-Steering: show_work@18x0.6 (ASCII fallback)
|
|
14
|
+
|
|
15
|
+
A missing or empty header → no steering, sidecar returns identical
|
|
16
|
+
output to llama.cpp on the same prompt. Malformed entries are
|
|
17
|
+
skipped with a logged warning rather than 400'd — the sidecar is
|
|
18
|
+
defensive in depth, like the existing `agent_loop.py` steering hook.
|
|
19
|
+
"""
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import logging
|
|
23
|
+
import re
|
|
24
|
+
from dataclasses import dataclass
|
|
25
|
+
|
|
26
|
+
logger = logging.getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass(frozen=True)
|
|
30
|
+
class SteeringDirective:
|
|
31
|
+
"""One mode/layer/scale triple parsed from the header."""
|
|
32
|
+
mode: str
|
|
33
|
+
layer: int
|
|
34
|
+
scale: float
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# `mode@layer×scale` or `mode@layerxscale`. mode is restricted to
|
|
38
|
+
# [a-z0-9_-] to keep the wire format safe across HTTP intermediaries.
|
|
39
|
+
_DIRECTIVE_RE = re.compile(
|
|
40
|
+
r"^(?P<mode>[a-z0-9_-]+)@(?P<layer>\d+)[×x](?P<scale>-?\d+(?:\.\d+)?)$"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def parse_header(value: str | None) -> list[SteeringDirective]:
|
|
45
|
+
"""Parse the X-Drydock-Steering header value.
|
|
46
|
+
|
|
47
|
+
Returns the list of valid directives. Missing/empty header → []. A
|
|
48
|
+
malformed entry is dropped with a warning rather than raising; we
|
|
49
|
+
never want a header parse error to 5xx an otherwise-good request.
|
|
50
|
+
"""
|
|
51
|
+
if not value:
|
|
52
|
+
return []
|
|
53
|
+
out: list[SteeringDirective] = []
|
|
54
|
+
for raw in value.split(","):
|
|
55
|
+
entry = raw.strip()
|
|
56
|
+
if not entry:
|
|
57
|
+
continue
|
|
58
|
+
m = _DIRECTIVE_RE.match(entry)
|
|
59
|
+
if not m:
|
|
60
|
+
logger.warning("steering header: ignoring malformed entry %r", entry)
|
|
61
|
+
continue
|
|
62
|
+
try:
|
|
63
|
+
out.append(
|
|
64
|
+
SteeringDirective(
|
|
65
|
+
mode=m.group("mode"),
|
|
66
|
+
layer=int(m.group("layer")),
|
|
67
|
+
scale=float(m.group("scale")),
|
|
68
|
+
)
|
|
69
|
+
)
|
|
70
|
+
except (ValueError, OverflowError) as e:
|
|
71
|
+
logger.warning(
|
|
72
|
+
"steering header: ignoring %r (parse error: %s)", entry, e
|
|
73
|
+
)
|
|
74
|
+
return out
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"""FastAPI server hosting a transformers-backed Gemma 4, OpenAI-compat shape.
|
|
2
|
+
|
|
3
|
+
Milestone 1 deliverable per DEEP_NOIR_PRD.md:
|
|
4
|
+
- Loads Gemma 4 from a local path via `transformers.AutoModelForCausalLM`.
|
|
5
|
+
- Speaks `POST /v1/chat/completions` (non-streaming first cut) and
|
|
6
|
+
`GET /v1/models` so the existing `llm_balancer.py` can route to it
|
|
7
|
+
the same way it routes to llama.cpp.
|
|
8
|
+
- NO forward hooks yet (Milestone 2). Returns identical outputs to
|
|
9
|
+
llama.cpp on a smoke prompt — that's the M1 acceptance check.
|
|
10
|
+
|
|
11
|
+
Lazy model load: the model is NOT loaded at import time. The first
|
|
12
|
+
inference request triggers `_load_model()` which holds a lock and
|
|
13
|
+
caches the result. This lets the FastAPI app start in <1s and reserve
|
|
14
|
+
its port even when GPU memory is tight; the heavy load only happens
|
|
15
|
+
when something actually wants steered inference.
|
|
16
|
+
|
|
17
|
+
Run:
|
|
18
|
+
bash scripts/start_steering_sidecar.sh
|
|
19
|
+
or:
|
|
20
|
+
/home/bobef/miniconda3/bin/python3 -m uvicorn \\
|
|
21
|
+
drydock.steering.sidecar.server:app --host 0.0.0.0 --port 8002
|
|
22
|
+
"""
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import logging
|
|
26
|
+
import os
|
|
27
|
+
import threading
|
|
28
|
+
import time
|
|
29
|
+
import uuid
|
|
30
|
+
from typing import Any
|
|
31
|
+
|
|
32
|
+
from fastapi import FastAPI, HTTPException, Request
|
|
33
|
+
from fastapi.responses import JSONResponse
|
|
34
|
+
|
|
35
|
+
logger = logging.getLogger(__name__)
|
|
36
|
+
|
|
37
|
+
# Default to the AWQ-4bit Gemma 4 weights (matches CLAUDE.md "active
|
|
38
|
+
# model" path). Override with DRYDOCK_STEERING_SIDECAR_MODEL_PATH.
|
|
39
|
+
_DEFAULT_MODEL_PATH = "/data3/Models/Gemma-4-26B-A4B-it-AWQ-4bit"
|
|
40
|
+
_MODEL_PATH = os.environ.get(
|
|
41
|
+
"DRYDOCK_STEERING_SIDECAR_MODEL_PATH", _DEFAULT_MODEL_PATH
|
|
42
|
+
)
|
|
43
|
+
# transformers picks the device automatically when device_map="auto",
|
|
44
|
+
# but operators often want to pin to a single GPU to avoid sharing
|
|
45
|
+
# with llama.cpp. CUDA_VISIBLE_DEVICES handles that at the env layer.
|
|
46
|
+
_DEVICE_MAP = os.environ.get("DRYDOCK_STEERING_SIDECAR_DEVICE_MAP", "auto")
|
|
47
|
+
# Reported model name in /v1/models. Matches what `start_gemma4.sh`
|
|
48
|
+
# reports so clients see a consistent name regardless of which
|
|
49
|
+
# backend serves them.
|
|
50
|
+
_REPORTED_MODEL_NAME = os.environ.get(
|
|
51
|
+
"DRYDOCK_STEERING_SIDECAR_MODEL_NAME", "gemma4"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
_MODEL_LOCK = threading.Lock()
|
|
56
|
+
_MODEL = None # type: ignore[var-annotated]
|
|
57
|
+
_TOKENIZER = None # type: ignore[var-annotated]
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _load_model() -> tuple[Any, Any]:
|
|
61
|
+
"""Lazy + thread-safe model load. Cached after the first call.
|
|
62
|
+
|
|
63
|
+
Returns `(model, tokenizer)`. Raises RuntimeError on any underlying
|
|
64
|
+
transformers/torch failure — the FastAPI handler converts that into
|
|
65
|
+
a 503 so the balancer can fall back to llama.cpp.
|
|
66
|
+
"""
|
|
67
|
+
global _MODEL, _TOKENIZER
|
|
68
|
+
if _MODEL is not None and _TOKENIZER is not None:
|
|
69
|
+
return _MODEL, _TOKENIZER
|
|
70
|
+
with _MODEL_LOCK:
|
|
71
|
+
if _MODEL is not None and _TOKENIZER is not None:
|
|
72
|
+
return _MODEL, _TOKENIZER
|
|
73
|
+
logger.info(
|
|
74
|
+
"steering sidecar: loading model from %s (device_map=%s)",
|
|
75
|
+
_MODEL_PATH, _DEVICE_MAP,
|
|
76
|
+
)
|
|
77
|
+
t0 = time.perf_counter()
|
|
78
|
+
try:
|
|
79
|
+
import torch # local import — only need it when actually loading
|
|
80
|
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
|
81
|
+
except ImportError as e:
|
|
82
|
+
raise RuntimeError(
|
|
83
|
+
f"steering sidecar: missing dependency ({e}). Install "
|
|
84
|
+
"transformers + torch (CUDA build) to use the sidecar."
|
|
85
|
+
) from e
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
tokenizer = AutoTokenizer.from_pretrained(
|
|
89
|
+
_MODEL_PATH, trust_remote_code=True
|
|
90
|
+
)
|
|
91
|
+
model = AutoModelForCausalLM.from_pretrained(
|
|
92
|
+
_MODEL_PATH,
|
|
93
|
+
device_map=_DEVICE_MAP,
|
|
94
|
+
torch_dtype="auto", # let the quant_config drive dtype
|
|
95
|
+
trust_remote_code=True,
|
|
96
|
+
)
|
|
97
|
+
model.eval()
|
|
98
|
+
except Exception as e:
|
|
99
|
+
raise RuntimeError(
|
|
100
|
+
f"steering sidecar: model load failed: {type(e).__name__}: {e}"
|
|
101
|
+
) from e
|
|
102
|
+
|
|
103
|
+
elapsed = time.perf_counter() - t0
|
|
104
|
+
logger.info(
|
|
105
|
+
"steering sidecar: model loaded in %.1fs (param dtype=%s)",
|
|
106
|
+
elapsed,
|
|
107
|
+
getattr(next(iter(model.parameters()), torch.tensor(0)), "dtype", "?"),
|
|
108
|
+
)
|
|
109
|
+
_MODEL = model
|
|
110
|
+
_TOKENIZER = tokenizer
|
|
111
|
+
return _MODEL, _TOKENIZER
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _now() -> int:
|
|
115
|
+
return int(time.time())
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def build_app() -> FastAPI:
|
|
119
|
+
app = FastAPI(
|
|
120
|
+
title="Drydock Deep Noir Steering Sidecar",
|
|
121
|
+
version="0.1.0-milestone1",
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
@app.get("/health")
|
|
125
|
+
async def health() -> dict[str, Any]:
|
|
126
|
+
return {
|
|
127
|
+
"status": "ok",
|
|
128
|
+
"model_loaded": _MODEL is not None,
|
|
129
|
+
"model_path": _MODEL_PATH,
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@app.get("/v1/models")
|
|
133
|
+
async def list_models() -> dict[str, Any]:
|
|
134
|
+
return {
|
|
135
|
+
"object": "list",
|
|
136
|
+
"data": [
|
|
137
|
+
{
|
|
138
|
+
"id": _REPORTED_MODEL_NAME,
|
|
139
|
+
"object": "model",
|
|
140
|
+
"created": _now(),
|
|
141
|
+
"owned_by": "drydock-steering-sidecar",
|
|
142
|
+
}
|
|
143
|
+
],
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
@app.post("/v1/chat/completions")
|
|
147
|
+
async def chat_completions(request: Request) -> JSONResponse:
|
|
148
|
+
try:
|
|
149
|
+
payload = await request.json()
|
|
150
|
+
except Exception as e:
|
|
151
|
+
raise HTTPException(status_code=400, detail=f"invalid json: {e}")
|
|
152
|
+
messages = payload.get("messages")
|
|
153
|
+
if not isinstance(messages, list) or not messages:
|
|
154
|
+
raise HTTPException(status_code=400, detail="missing messages[]")
|
|
155
|
+
|
|
156
|
+
# Milestone 1: ignore the steering header entirely. Just verify
|
|
157
|
+
# we can serve a completion. Hooks land in M2.
|
|
158
|
+
steering_header = request.headers.get("x-drydock-steering", "")
|
|
159
|
+
if steering_header:
|
|
160
|
+
logger.info(
|
|
161
|
+
"steering header received but no hooks active in M1: %r",
|
|
162
|
+
steering_header,
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
# Lazy load — pays the cost only on the first real request.
|
|
166
|
+
try:
|
|
167
|
+
model, tokenizer = _load_model()
|
|
168
|
+
except RuntimeError as e:
|
|
169
|
+
logger.error("model load failed: %s", e)
|
|
170
|
+
return JSONResponse(
|
|
171
|
+
status_code=503,
|
|
172
|
+
content={"error": {"message": str(e), "type": "model_load_failed"}},
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
# Apply the chat template — Gemma 4 has its own.
|
|
176
|
+
try:
|
|
177
|
+
prompt_ids = tokenizer.apply_chat_template(
|
|
178
|
+
messages,
|
|
179
|
+
add_generation_prompt=True,
|
|
180
|
+
return_tensors="pt",
|
|
181
|
+
)
|
|
182
|
+
except Exception as e:
|
|
183
|
+
raise HTTPException(
|
|
184
|
+
status_code=400, detail=f"chat template failed: {e}"
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
import torch
|
|
188
|
+
|
|
189
|
+
prompt_ids = prompt_ids.to(model.device)
|
|
190
|
+
max_new_tokens = int(payload.get("max_tokens") or 512)
|
|
191
|
+
# Gemma 4 anti-loop sampling defaults — match what we ship in
|
|
192
|
+
# DEFAULT_MODELS for the local model. Caller can override via
|
|
193
|
+
# the JSON payload.
|
|
194
|
+
temperature = float(payload.get("temperature", 1.0))
|
|
195
|
+
top_p = float(payload.get("top_p", 0.95))
|
|
196
|
+
top_k = int(payload.get("top_k", 40))
|
|
197
|
+
do_sample = temperature > 0
|
|
198
|
+
|
|
199
|
+
t0 = time.perf_counter()
|
|
200
|
+
with torch.no_grad():
|
|
201
|
+
output = model.generate(
|
|
202
|
+
prompt_ids,
|
|
203
|
+
max_new_tokens=max_new_tokens,
|
|
204
|
+
do_sample=do_sample,
|
|
205
|
+
temperature=temperature if do_sample else 1.0,
|
|
206
|
+
top_p=top_p if do_sample else 1.0,
|
|
207
|
+
top_k=top_k if do_sample else 0,
|
|
208
|
+
pad_token_id=tokenizer.eos_token_id,
|
|
209
|
+
)
|
|
210
|
+
gen_time = time.perf_counter() - t0
|
|
211
|
+
|
|
212
|
+
# Decode only the newly-generated portion.
|
|
213
|
+
new_tokens = output[0][prompt_ids.shape[-1]:]
|
|
214
|
+
completion = tokenizer.decode(new_tokens, skip_special_tokens=True)
|
|
215
|
+
prompt_token_count = int(prompt_ids.shape[-1])
|
|
216
|
+
completion_token_count = int(new_tokens.shape[-1])
|
|
217
|
+
|
|
218
|
+
logger.info(
|
|
219
|
+
"completion: prompt=%d completion=%d gen=%.2fs",
|
|
220
|
+
prompt_token_count, completion_token_count, gen_time,
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
return JSONResponse(
|
|
224
|
+
content={
|
|
225
|
+
"id": f"chatcmpl-{uuid.uuid4().hex[:24]}",
|
|
226
|
+
"object": "chat.completion",
|
|
227
|
+
"created": _now(),
|
|
228
|
+
"model": _REPORTED_MODEL_NAME,
|
|
229
|
+
"choices": [
|
|
230
|
+
{
|
|
231
|
+
"index": 0,
|
|
232
|
+
"message": {
|
|
233
|
+
"role": "assistant",
|
|
234
|
+
"content": completion,
|
|
235
|
+
},
|
|
236
|
+
"finish_reason": "stop",
|
|
237
|
+
}
|
|
238
|
+
],
|
|
239
|
+
"usage": {
|
|
240
|
+
"prompt_tokens": prompt_token_count,
|
|
241
|
+
"completion_tokens": completion_token_count,
|
|
242
|
+
"total_tokens": prompt_token_count + completion_token_count,
|
|
243
|
+
},
|
|
244
|
+
}
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
return app
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
# uvicorn looks for `app` by default
|
|
251
|
+
app = build_app()
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Start the Deep Noir activation-steering sidecar.
|
|
3
|
+
#
|
|
4
|
+
# Default port 8002. The model loads lazily on the first inference
|
|
5
|
+
# request, so this script returns quickly even though the actual
|
|
6
|
+
# Gemma 4 26B AWQ-4bit load takes ~30-60s of GPU time.
|
|
7
|
+
#
|
|
8
|
+
# Override defaults via env:
|
|
9
|
+
# DRYDOCK_STEERING_SIDECAR_MODEL_PATH=/data3/Models/<other>
|
|
10
|
+
# DRYDOCK_STEERING_SIDECAR_DEVICE_MAP=cuda:1 # pin to GPU 1
|
|
11
|
+
# DRYDOCK_STEERING_SIDECAR_MODEL_NAME=gemma4 # /v1/models id
|
|
12
|
+
#
|
|
13
|
+
# Usage:
|
|
14
|
+
# bash scripts/start_steering_sidecar.sh [--port 8002]
|
|
15
|
+
#
|
|
16
|
+
# The sidecar competes with llama.cpp for VRAM. Confirm
|
|
17
|
+
# `nvidia-smi` shows ≥16 GB free before starting.
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
PORT=8002
|
|
21
|
+
HOST=0.0.0.0
|
|
22
|
+
PYTHON=/home/bobef/miniconda3/bin/python3
|
|
23
|
+
|
|
24
|
+
while [[ $# -gt 0 ]]; do
|
|
25
|
+
case $1 in
|
|
26
|
+
--port) PORT=$2; shift 2 ;;
|
|
27
|
+
--host) HOST=$2; shift 2 ;;
|
|
28
|
+
*) echo "unknown arg: $1" >&2; exit 2 ;;
|
|
29
|
+
esac
|
|
30
|
+
done
|
|
31
|
+
|
|
32
|
+
cd /data3/drydock
|
|
33
|
+
|
|
34
|
+
LOGFILE=/data3/drydock/logs/steering_sidecar.log
|
|
35
|
+
PIDFILE=/tmp/steering_sidecar.pid
|
|
36
|
+
|
|
37
|
+
if [[ -f $PIDFILE ]] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then
|
|
38
|
+
echo "steering sidecar already running (pid $(cat "$PIDFILE"))"
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
echo "[$(date)] starting steering sidecar on $HOST:$PORT (log: $LOGFILE)"
|
|
43
|
+
nohup "$PYTHON" -m uvicorn \
|
|
44
|
+
drydock.steering.sidecar.server:app \
|
|
45
|
+
--host "$HOST" --port "$PORT" \
|
|
46
|
+
--log-level info \
|
|
47
|
+
>> "$LOGFILE" 2>&1 &
|
|
48
|
+
|
|
49
|
+
echo $! > "$PIDFILE"
|
|
50
|
+
echo "[$(date)] pid=$(cat "$PIDFILE")"
|
|
51
|
+
echo "Tail: tail -f $LOGFILE"
|
|
52
|
+
echo "Stop: kill \$(cat $PIDFILE)"
|