drydock-cli 2.8.10__tar.gz → 2.8.12__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.12/.auto_release.lock +1 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/PKG-INFO +1 -1
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/agent_loop.py +66 -7
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/classifier/rules.py +21 -1
- drydock_cli-2.8.12/drydock/steering/sidecar/hooks.py +372 -0
- drydock_cli-2.8.12/drydock/steering/sidecar/loader.py +98 -0
- drydock_cli-2.8.12/drydock/steering/sidecar/server.py +345 -0
- drydock_cli-2.8.12/drydock/steering/train/__init__.py +12 -0
- drydock_cli-2.8.12/drydock/steering/train/capture.py +247 -0
- drydock_cli-2.8.12/drydock/steering/train/compute_vector.py +375 -0
- drydock_cli-2.8.12/drydock/steering/train/extract_pairs.py +371 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/pyproject.toml +1 -1
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_classifier.py +27 -0
- drydock_cli-2.8.12/tests/test_steering_capture.py +292 -0
- drydock_cli-2.8.12/tests/test_steering_compute_vector.py +326 -0
- drydock_cli-2.8.12/tests/test_steering_extract_pairs.py +264 -0
- drydock_cli-2.8.12/tests/test_steering_sidecar_hooks.py +324 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/trip_log.md +223 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/uv.lock +1 -1
- drydock_cli-2.8.10/.auto_release.lock +0 -1
- drydock_cli-2.8.10/drydock/steering/sidecar/server.py +0 -251
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/.github/CODEOWNERS +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/.github/workflows/build-and-upload.yml +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/.github/workflows/ci.yml +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/.github/workflows/issue-labeler.yml +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/.github/workflows/release.yml +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/.gitignore +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/.pre-commit-config.yaml +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/.python-version +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/.typos.toml +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/.vscode/extensions.json +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/.vscode/launch.json +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/.vscode/settings.json +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/AGENTS.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/Admiral.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/CHANGELOG.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/CLAUDE.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/CONTRIBUTING.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/DEEP_NOIR_PRD.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/DEPLOYMENT.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/HLE_PRD.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/JETSON_BENCH.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/LICENSE +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/MODEL_SHORTCOMINGS.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/NOTICE +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/README.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/SOVEREIGN_PRD.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/TRIAGE_v1.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/action.yml +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/README.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results1.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results13.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results14.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results15.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results16.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results17.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results18.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results19.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results2.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results20.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results3.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results4.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results5.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results6.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results7.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results8.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results9.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/baseline_history/results_evolved_v1.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/distribution/zed/LICENSE +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/distribution/zed/extension.toml +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/distribution/zed/icons/mistral_vibe.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/docs/README.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/docs/acp-setup.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/docs/archive/BASELINE_412.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/docs/archive/Drydock_rebrand.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/docs/archive/OVERNIGHT_PROGRESS.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/docs/archive/OVERNIGHT_REPORT_2026_04_13.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/docs/archive/PERF_SWEEP_PLAN.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/docs/archive/PRD.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/docs/archive/drydock_terms.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/docs/archive/resume.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/docs/proxy-setup.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/__main__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/acp/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/acp/acp_agent_loop.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/acp/acp_logger.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/acp/entrypoint.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/acp/tools/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/acp/tools/base.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/acp/tools/builtins/bash.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/acp/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/acp/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/acp/tools/builtins/todo.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/acp/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/acp/tools/session_update.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/acp/utils.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/detectors.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/detectors_proposed.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/history.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/interventions.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/llm_analyzer.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/metrics.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/opus_escalator.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/persistence.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/policy.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/proposer.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/stager.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/task_classifier.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/tuning.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/validator.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/admiral/worker.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/autocompletion/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/autocompletion/base.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/autocompletion/path_completion.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/autocompletion/slash_command.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/cli.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/clipboard.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/commands.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/entrypoint.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/fix_windows_path.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/history_manager.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/plan_offer/adapters/http_whoami_gateway.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/plan_offer/decide_plan_offer.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/plan_offer/ports/whoami_gateway.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/terminal_setup.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/ansi_markdown.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/app.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/app.tcss +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/external_editor.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/handlers/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/handlers/event_handler.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/notifications/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/notifications/adapters/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/notifications/adapters/textual_notification_adapter.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/notifications/ports/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/notifications/ports/notification_port.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/approval_app.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/banner/banner.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/banner/petit_chat.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/braille_renderer.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/chat_input/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/chat_input/body.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/chat_input/completion_manager.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/chat_input/completion_popup.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/chat_input/container.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/chat_input/text_area.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/checkpoint_picker.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/compact.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/config_app.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/context_progress.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/load_more.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/loading.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/messages.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/no_markup_static.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/path_display.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/proxy_setup_app.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/question_app.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/session_picker.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/spinner.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/status_message.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/teleport_message.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/tool_widgets.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/tools.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/widgets/vscode_compat.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/windowing/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/windowing/history.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/windowing/history_windowing.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/textual_ui/windowing/state.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/update_notifier/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/update_notifier/adapters/filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/update_notifier/adapters/github_update_gateway.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/update_notifier/adapters/pypi_update_gateway.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/update_notifier/ports/update_cache_repository.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/update_notifier/ports/update_gateway.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/update_notifier/update.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/cli/update_notifier/whats_new.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/agents/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/agents/manager.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/agents/models.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/auth/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/auth/crypto.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/auth/github.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/autocompletion/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/autocompletion/completers.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/autocompletion/file_indexer/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/autocompletion/file_indexer/ignore_rules.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/autocompletion/file_indexer/indexer.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/autocompletion/file_indexer/store.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/autocompletion/file_indexer/watcher.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/autocompletion/fuzzy.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/autocompletion/path_prompt.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/autocompletion/path_prompt_adapter.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/build_orchestrator.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/checkpoint.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/classifier/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/classifier/__main__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/classifier/classifier.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/classifier/dispatcher.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/classifier/signal.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/config/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/config/_dotenv.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/config/_settings.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/config/doctor.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/config/harness_files/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/config/harness_files/_harness_manager.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/config/harness_files/_paths.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/config/local_detect.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/config/migrate.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/consultant.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/context_recovery.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/drydock_states.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/hooks.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/llm/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/llm/backend/anthropic.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/llm/backend/base.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/llm/backend/factory.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/llm/backend/generic.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/llm/backend/mistral.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/llm/backend/reasoning_adapter.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/llm/backend/vertex.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/llm/exceptions.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/llm/format.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/llm/message_utils.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/llm/types.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/logger.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/middleware.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/output_formatters.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/paths/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/paths/_drydock_home.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/paths/_local_config_walk.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/paths/conventions.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/plan_session.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/plugins.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/programmatic.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/prompts/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/prompts/builder.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/prompts/cli.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/prompts/compact.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/prompts/dangerous_directory.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/prompts/diagnostic.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/prompts/explore.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/prompts/gemma4.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/prompts/planner.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/prompts/project_context.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/prompts/tests.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/proxy_setup.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/session/agent_memory.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/session/checkpoints.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/session/session_loader.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/session/session_logger.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/session/session_migration.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/session/state_file.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/session_checker.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/skills/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/skills/manager.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/skills/models.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/skills/parser.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/slug.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/steering_hook.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/system_prompt.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/telemetry/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/telemetry/send.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/teleport/errors.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/teleport/git.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/teleport/nuage.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/teleport/teleport.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/teleport/types.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/base.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/_task_manager.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/ask_user_question.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/bash.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/cron.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/exit_plan_mode.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/glob_tool.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/grep.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/invoke_skill.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/lsp.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/mcp_resources.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/notebook_edit.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/powershell.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/ask_user_question.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/bash.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/cron.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/glob.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/grep.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/invoke_skill.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/lsp.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/mcp_resources.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/notebook_edit.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/powershell.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/read_file.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/retrieve.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/search_replace.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/swe_bench.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/task.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/task_manager.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/todo.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/tool_search.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/webfetch.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/websearch.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/worktree.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/prompts/write_file.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/read_file.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/retrieve.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/search_replace.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/task.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/todo.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/tool_search.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/webfetch.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/websearch.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/worktree.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/builtins/write_file.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/injection_guard.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/manager.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/mcp/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/mcp/registry.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/mcp/tools.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/mcp_sampling.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/ui.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/tools/utils.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/trusted_folders.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/types.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/core/utils.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/graphrag/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/graphrag/__main__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/graphrag/code_indexer.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/graphrag/retriever.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/graphrag/storage.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/graphrag/text_indexer.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/setup/onboarding/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/setup/onboarding/base.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/setup/onboarding/onboarding.tcss +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/setup/onboarding/screens/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/setup/onboarding/screens/api_key.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/setup/onboarding/screens/choice.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/setup/onboarding/screens/local_model.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/setup/onboarding/screens/welcome.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/setup/trusted_folders/trust_folder_dialog.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/setup/trusted_folders/trust_folder_dialog.tcss +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/api-design/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/audit-tests/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/batch/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/commit-code/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/context-summary/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/create-presentation/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/deep-research/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/deploy/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/diff-review/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/doc-gen/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/explain-code/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/explore-code/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/fix-issue/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/git-ops/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/init-project/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/investigate/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/loop/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/migrate/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/perf-analyze/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/plan-impl/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/pr-review/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/refactor/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/regex-help/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/review/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/security-review/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/ship/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/simplify/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/strong-tests/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/skills/test-verify/SKILL.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/steering/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/steering/__main__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/steering/applier.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/steering/config.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/steering/registry.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/steering/sandbox.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/steering/sidecar/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/steering/sidecar/header_parser.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/steering/vectors.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock/whats_new.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/drydock-acp.spec +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/flake.lock +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/flake.nix +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/research/README.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/research/config_base.toml +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/research/config_best.toml +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/research/domain_spec.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/research/experimenter.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/research/kernel.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/research/mini_prd.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/research/mini_prompts.txt +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/research/proposer.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/research/results.tsv +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/README.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/admiral_probe.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/archive/auto_test_loop.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/archive/monitor_test_battery.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/archive/overnight_agents_test.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/archive/test_bank.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/archive/test_full.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/archive/test_smoke.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/archive/tui_test.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/audit_sampler.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/auto_generate_tests.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/auto_release.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/autonomous_review.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/autonomous_review_prompt.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/backup.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/bump_version.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/classify_pulse.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/consume_retrieval_queue.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/deploy_to_github.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/fetch_arxiv_abstracts.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/gen_2000_prompts.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/hle_eval.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/hle_eval_seed.jsonl +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/llm_balancer.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/notify_release.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/perf_baseline_when_idle.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/perf_sweep.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/poll_issues.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/publish_to_pypi.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/queue_top.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/ralph_loop.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/research_babysitter.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/shakedown.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/shakedown_interactive.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/shakedown_suite.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/shakedown_variance.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/start_steering_sidecar.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/stress_babysitter.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/stress_prompts_50.txt +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/stress_prompts_realuser.txt +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/stress_prompts_tool_agent.txt +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/stress_prompts_tool_agent_2000.txt +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/stress_shakedown.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/stress_telegram_status.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/stress_watcher.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/telegram_bot.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/scripts/vllm_failover.sh +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/conftest.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_acp.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_agent_thought.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_bash.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_compact_session_updates.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_content.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_initialize.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_list_sessions.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_load_session.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_multi_session.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_new_session.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_proxy_setup_acp.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_read_file.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_search_replace.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_set_config_option.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_set_mode.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_set_model.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_tool_call_session_update.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_utils.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/acp/test_write_file.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/autocompletion/test_file_indexer.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/autocompletion/test_fuzzy.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/autocompletion/test_path_completer_fuzzy.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/autocompletion/test_path_completer_recursive.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/autocompletion/test_path_completion_controller.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/autocompletion/test_path_prompt_transformer.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/autocompletion/test_slash_command_controller.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/autocompletion/test_ui_chat_autocompletion.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/backend/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/backend/data/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/backend/data/fireworks.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/backend/data/mistral.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/backend/test_anthropic_adapter.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/backend/test_backend.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/backend/test_generic_adapter_sanitize.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/backend/test_reasoning_adapter.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/backend/test_vertex_anthropic_adapter.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/plan_offer/adapters/fake_whoami_gateway.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/plan_offer/test_decide_plan_offer.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/plan_offer/test_http_whoami_gateway.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/test_bell_notifications.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/test_braille_renderer.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/test_clipboard.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/test_commands.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/test_copy_shortcuts.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/test_external_editor.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/test_no_markup_static.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/test_question_app.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/test_spinner.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/test_switching_mode.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/test_ui_clipboard_notifications.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/test_ui_session_incremental_renderer.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/test_ui_session_resume.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/test_ui_skill_dispatch.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/textual_ui/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/cli/textual_ui/test_session_picker.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/conftest.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_agents.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_auth_crypto.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_auth_github.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_circuit_breaker_count_escalation.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_circuit_breaker_readonly_threshold.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_config_load_dotenv.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_config_paths.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_config_resolution.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_file_logging.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_plan_session.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_proxy_setup.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_slug.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_telemetry_send.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_teleport_git.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_teleport_nuage.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_teleport_service.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_trusted_folders.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/core/test_utils.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/e2e/common.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/e2e/conftest.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/e2e/mock_server.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/e2e/test_cli_tui_onboarding.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/e2e/test_cli_tui_streaming.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/e2e/test_cli_tui_tool_approval.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/fixtures/doc_qa_system_prd.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/mock/__init__.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/mock/mock_backend_factory.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/mock/mock_entrypoint.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/mock/utils.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/onboarding/test_run_onboarding.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/onboarding/test_ui_onboarding.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/session/test_session_loader.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/session/test_session_logger.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/session/test_session_migration.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/skills/conftest.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/skills/test_manager.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/skills/test_models.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/skills/test_parser.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_collapsed.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_ask_user_question/test_snapshot_ask_user_question_expanded.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_basic_conversation/test_snapshot_shows_basic_conversation.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/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.10 → drydock_cli-2.8.12}/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.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_accept_edits_mode.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_auto_approve_mode.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_to_plan_mode.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_cycle_wraps_to_default.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_modes/test_snapshot_default_mode.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_pending.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_parallel_tool_calls/test_snapshot_parallel_tool_calls_resolved.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_cancel_discards_changes.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_edit_existing_values.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_empty.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_initial_with_values.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_error.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_proxy_setup/test_snapshot_proxy_setup_save_new_values.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_answer_first_advance.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_first_answered_checkmark.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_initial.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_left_wraps.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_navigate_right.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_question_tab_to_second.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_initial.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_mixed_selection.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_navigate_to_submit.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_other_with_text.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_first.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_toggle_multiple.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_multi_select_untoggle.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_initial.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_down.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_other.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_to_third_option.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_navigate_up_wraps.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_question_app/test_snapshot_question_app_other_typing.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_buffered_reasoning_yields_before_content.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_interleaved_reasoning.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_reasoning_content/test_snapshot_shows_reasoning_content_expanded.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_session_resume/test_snapshot_shows_resumed_session_messages.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_partial.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_streaming_tool_call/test_snapshot_tool_call_updated.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_cancel_selected.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_multiple_commits.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_push_confirmation_single_commit.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_complete.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_auth_required.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_checking_git.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_complete.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_error.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_pushing.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_sending_token.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_teleport/test_snapshot_teleport_status_starting_workflow.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_no_plan_message.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_switch_message.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_upgrade_message.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/__snapshots__/test_ui_snapshot_whats_new/test_snapshot_shows_whats_new_message.svg +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/base_snapshot_test_app.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/conftest.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/snap_compare.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/test_ui_snapshot_ask_user_question.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/test_ui_snapshot_basic_conversation.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/test_ui_snapshot_code_block_horizontal_scrolling.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/test_ui_snapshot_empty_assistant_before_reasoning.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/test_ui_snapshot_modes.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/test_ui_snapshot_parallel_tool_calls.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/test_ui_snapshot_proxy_setup.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/test_ui_snapshot_question_app.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/test_ui_snapshot_reasoning_content.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/test_ui_snapshot_release_update_notification.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/test_ui_snapshot_session_resume.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/test_ui_snapshot_streaming_tool_call.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/test_ui_snapshot_teleport.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/snapshots/test_ui_snapshot_whats_new.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/stubs/fake_backend.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/stubs/fake_client.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/stubs/fake_tool.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_admiral.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_admiral_phase3.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_admiral_proposed.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_admiral_struggle_dedup.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_agent_auto_compact.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_agent_backend.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_agent_observer_streaming.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_agent_stats.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_agent_tasks.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_agent_tool_call.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_agents.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_bank_build.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_bank_debug.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_bank_multiagent.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_bank_prd.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_bank_prd_extended.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_bank_tools.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_bank_update.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_build_projects.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_checkpoint.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_cli_programmatic_preload.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_config_migration.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_context_recovery.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_current_bugs.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_dispatcher.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_drydock_regression.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_drydock_tasks.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_fake_tool_call_paren_syntax.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_full_regression.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_graphrag.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_hallucinated_tool_suppression.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_history_manager.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_integration.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_issue_fixes.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_local_detect.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_loop_detection.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_message_id.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_message_merging.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_middleware.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_multi_agent.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_read_file_not_found_listing.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_real_failures.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_real_issues.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_real_workflow.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_reasoning_content.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_retrieval_consumer.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_retrieve_tool.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_search_replace_args_not_truncated.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_smoke.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_steering.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_steering_hook.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_system_prompt.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_tagged_text.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_task_complete_nudge.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_tool_args.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_truncate_args_valid_json.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_truncated_arg_path_hint.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_truncated_search_replace_escalation.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_truncated_write_escalation.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_ui_external_editor.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_ui_input_history.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_user_issues.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_wall_of_text_rescue.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_workloads.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/test_write_file_missing_path.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/testbank_helpers.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_ask_user_question.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_bash.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_bash_binary_grep_hint.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_bash_consec_empty_search.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_bash_echo_escape_loop_breaker.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_bash_empty_search_loop_breaker.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_bash_error_loop_breaker.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_bash_exact_cmd_loop_breaker.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_bash_heredoc_confirmation.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_bash_kill_exit1_annotation.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_bash_python_c_syntaxerr_loop_breaker.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_exit_plan_mode.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_grep.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_hallucinated_retrieval_redirect.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_invoke_context.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_manager_gemma_derived_models.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_manager_get_tool_config.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_mcp.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_mcp_sampling.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_read_file_dedup_alternating_offset.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_read_file_dedup_reembed.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_read_file_directory.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_read_file_limit_truncation.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_search_replace_append_fallback.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_search_replace_dir_path.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_search_replace_empty_content.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_search_replace_file_not_found.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_search_replace_first_failure_hint.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_search_replace_hard_stop.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_search_replace_malformed_block.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_search_replace_no_op_loop_breaker.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_search_replace_placeholder.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_search_replace_refused_loop_breaker.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_task.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_ui_bash_execution.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_webfetch.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_websearch.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_write_file_dedup_missing_imports.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/tools/test_write_file_missing_path_hint.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/update_notifier/adapters/fake_update_cache_repository.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/update_notifier/adapters/fake_update_gateway.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/update_notifier/test_do_update.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/update_notifier/test_filesystem_update_cache_repository.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/update_notifier/test_github_update_gateway.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/update_notifier/test_pypi_update_gateway.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/update_notifier/test_ui_update_notification.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/update_notifier/test_update_use_case.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/tests/update_notifier/test_whats_new.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/worked_examples/README.md +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/worked_examples/cli_subcommand_dispatch.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/worked_examples/lookup.json +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/worked_examples/sql_parser.py +0 -0
- {drydock_cli-2.8.10 → drydock_cli-2.8.12}/worked_examples/tree_walking_interpreter.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
271649
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: drydock-cli
|
|
3
|
-
Version: 2.8.
|
|
3
|
+
Version: 2.8.12
|
|
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
|
|
@@ -1081,7 +1081,7 @@ class AgentLoop:
|
|
|
1081
1081
|
prev_tool_name = assistant_msg.tool_calls[-1].function.name if assistant_msg.tool_calls[-1].function else None
|
|
1082
1082
|
_readonly_tools = {"read_file", "grep", "glob", "ls", "pwd",
|
|
1083
1083
|
"ralph_repo_index", "ralph_file_summary",
|
|
1084
|
-
"retrieve", "search_files"}
|
|
1084
|
+
"retrieve", "search_files", "lsp"}
|
|
1085
1085
|
_write_tools = {"write_file", "search_replace"}
|
|
1086
1086
|
_prev_was_read = prev_tool_name in _readonly_tools
|
|
1087
1087
|
_prev_was_write = prev_tool_name in _write_tools
|
|
@@ -1230,6 +1230,27 @@ class AgentLoop:
|
|
|
1230
1230
|
f"what you read — OR state in one sentence why you "
|
|
1231
1231
|
f"cannot proceed. Do NOT call {_tool_name_str} again."
|
|
1232
1232
|
)
|
|
1233
|
+
elif _prev_was_write:
|
|
1234
|
+
_tool_name_str = prev_tool_name or "write_file"
|
|
1235
|
+
note = (
|
|
1236
|
+
f"You sent an empty response after {_tool_name_str}. "
|
|
1237
|
+
"Write the NEXT file in your plan NOW with write_file, "
|
|
1238
|
+
"or run bash to test what you have built. "
|
|
1239
|
+
"Do NOT send another empty response."
|
|
1240
|
+
)
|
|
1241
|
+
elif _prev_bash_had_error:
|
|
1242
|
+
note = (
|
|
1243
|
+
"Second empty response after a bash error. "
|
|
1244
|
+
"Fix the error NOW with search_replace or write_file. "
|
|
1245
|
+
"Do NOT re-run the same failing command."
|
|
1246
|
+
)
|
|
1247
|
+
elif _prev_bash_had_output:
|
|
1248
|
+
note = (
|
|
1249
|
+
"Second empty response after bash output. "
|
|
1250
|
+
"Use the output now — write code with write_file, "
|
|
1251
|
+
"fix issues with search_replace, or respond to the user. "
|
|
1252
|
+
"Do NOT re-run the same command."
|
|
1253
|
+
)
|
|
1233
1254
|
else:
|
|
1234
1255
|
note = (
|
|
1235
1256
|
"You sent an empty response. Call a tool now "
|
|
@@ -1237,12 +1258,50 @@ class AgentLoop:
|
|
|
1237
1258
|
"OR explicitly say you are done with this task."
|
|
1238
1259
|
)
|
|
1239
1260
|
else:
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1261
|
+
if prev_tool_name == "ralph_repo_index":
|
|
1262
|
+
note = (
|
|
1263
|
+
"THIRD empty response after ralph_repo_index. "
|
|
1264
|
+
"Stop — write a text reply to the user RIGHT NOW. "
|
|
1265
|
+
"If you cannot answer, say 'I was unable to find that information' "
|
|
1266
|
+
"and stop. Do NOT call ralph_repo_index or any other tool."
|
|
1267
|
+
)
|
|
1268
|
+
elif prev_tool_name in _readonly_tools:
|
|
1269
|
+
_tool_name_str = prev_tool_name or "read_file"
|
|
1270
|
+
note = (
|
|
1271
|
+
f"THIRD empty response after {_tool_name_str}. "
|
|
1272
|
+
"Stop reading — call write_file or search_replace NOW to apply "
|
|
1273
|
+
"the change, or respond in text explaining why you cannot proceed. "
|
|
1274
|
+
f"Do NOT call {_tool_name_str} again."
|
|
1275
|
+
)
|
|
1276
|
+
elif _prev_was_write:
|
|
1277
|
+
_tool_name_str = prev_tool_name or "write_file"
|
|
1278
|
+
note = (
|
|
1279
|
+
f"THIRD empty response after {_tool_name_str}. "
|
|
1280
|
+
"Call bash NOW to run the tests or verify what you built, "
|
|
1281
|
+
"or write the next required file. "
|
|
1282
|
+
"Do NOT send another empty response."
|
|
1283
|
+
)
|
|
1284
|
+
elif _prev_bash_had_error:
|
|
1285
|
+
note = (
|
|
1286
|
+
"THIRD empty response after a bash error. "
|
|
1287
|
+
"Fix the error NOW — call search_replace or write_file to "
|
|
1288
|
+
"correct the broken code, or respond in text with what went wrong. "
|
|
1289
|
+
"Do NOT run the same failing command again."
|
|
1290
|
+
)
|
|
1291
|
+
elif _prev_bash_had_output:
|
|
1292
|
+
note = (
|
|
1293
|
+
"THIRD empty response after bash output. "
|
|
1294
|
+
"Act on the output NOW — write or fix code with write_file "
|
|
1295
|
+
"or search_replace, or respond in one sentence. "
|
|
1296
|
+
"Do NOT re-run the same command."
|
|
1297
|
+
)
|
|
1298
|
+
else:
|
|
1299
|
+
note = (
|
|
1300
|
+
"You have sent 3 empty responses in a row for "
|
|
1301
|
+
"this user request. Respond with either (a) a "
|
|
1302
|
+
"tool call to make progress, or (b) one "
|
|
1303
|
+
"sentence explaining why you cannot proceed."
|
|
1304
|
+
)
|
|
1246
1305
|
self._inject_system_note(note)
|
|
1247
1306
|
logger.info(
|
|
1248
1307
|
"Empty-response stall (inline retry %d/%d, prev=%s)",
|
|
@@ -63,9 +63,29 @@ RULES: tuple[ClassificationRule, ...] = (
|
|
|
63
63
|
bucket=Bucket.HARNESS,
|
|
64
64
|
suggested_action="Add escape-sequence-loop detection in bash hint generator.",
|
|
65
65
|
),
|
|
66
|
+
# ORDER MATTERS: the repeated-call loop has to match BEFORE the
|
|
67
|
+
# invalid-regex rule below, because admiral's loop intervention
|
|
68
|
+
# text contains the substring "retry_after_error:grep" too —
|
|
69
|
+
# without this split, valid greps that just looped were getting
|
|
70
|
+
# mis-classified as unescaped_pattern (4k+ false positives in
|
|
71
|
+
# the dispatch queue, observed 2026-05-10).
|
|
72
|
+
ClassificationRule(
|
|
73
|
+
pattern_id="harness:grep:repeated_call_loop",
|
|
74
|
+
regex=_r(
|
|
75
|
+
r"retry_after_error[:\s]*grep[:\s]*"
|
|
76
|
+
r".*\b(this\s+exact\s+call\s+to\s+`?grep`?\s+has\s+been\s+made"
|
|
77
|
+
r"|matches[:\s]|same\s+arguments\s+that\s+errored)"
|
|
78
|
+
),
|
|
79
|
+
bucket=Bucket.HARNESS,
|
|
80
|
+
suggested_action="Add per-call dedup hint to grep tool result on Nth identical call; reuse search_replace dedup pattern.",
|
|
81
|
+
confidence=0.85,
|
|
82
|
+
),
|
|
66
83
|
ClassificationRule(
|
|
67
84
|
pattern_id="harness:grep:unescaped_pattern",
|
|
68
|
-
|
|
85
|
+
# Only true invalid-regex signals — the engine error text or an
|
|
86
|
+
# explicit "invalid regex" mention. Bare `retry_after_error:grep`
|
|
87
|
+
# without one of those signals goes to the loop rule above.
|
|
88
|
+
regex=_r(r"(grep:\s+Unmatched|grep.*invalid\s+regex|grep:.*Unbalanced|grep:.*Trailing\s+backslash)"),
|
|
69
89
|
bucket=Bucket.HARNESS,
|
|
70
90
|
suggested_action="Validate regex in grep tool early; suggest re.escape() literal.",
|
|
71
91
|
),
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
"""Forward-hook scaffolding for activation-steering on Gemma 4.
|
|
2
|
+
|
|
3
|
+
Milestone 2 deliverable per DEEP_NOIR_PRD.md. The hook layer is the
|
|
4
|
+
load-bearing piece that turns the sidecar from "an OpenAI-compat
|
|
5
|
+
wrapper around transformers" into "an OpenAI-compat wrapper that can
|
|
6
|
+
inject per-layer residual-stream offsets per-request."
|
|
7
|
+
|
|
8
|
+
Architecture:
|
|
9
|
+
|
|
10
|
+
- Hooks are registered ONCE at manager construction. Every forward
|
|
11
|
+
pass through every decoder layer goes through them. Cost when
|
|
12
|
+
inactive: one ContextVar.get() returning None and an early return
|
|
13
|
+
— negligible relative to a transformer forward pass.
|
|
14
|
+
- Per-request directives are dispatched via a `contextvars.ContextVar`.
|
|
15
|
+
This is the right primitive for FastAPI: it propagates correctly
|
|
16
|
+
across `await` boundaries and threadpool dispatch, so concurrent
|
|
17
|
+
requests don't clobber each other's steering state.
|
|
18
|
+
- `model.generate()` is GPU-serialised by torch (one generate at a
|
|
19
|
+
time per model), so contention happens at the CUDA layer regardless
|
|
20
|
+
of how many requests arrive. The ContextVar still matters for
|
|
21
|
+
correctness across the asyncio→threadpool hop FastAPI does for
|
|
22
|
+
sync handlers.
|
|
23
|
+
|
|
24
|
+
M2 acceptance test:
|
|
25
|
+
|
|
26
|
+
A request with no `X-Drydock-Steering` header and a request with
|
|
27
|
+
`show_work@18×0.5` (and ANY mode/layer/scale) must return
|
|
28
|
+
bit-identical completions on a deterministic seed, BECAUSE the
|
|
29
|
+
M2 vector lookup returns a zero tensor. Proves the wiring works.
|
|
30
|
+
|
|
31
|
+
M3+ replaces the zero-vector lookup with a real one that pulls from
|
|
32
|
+
the registry; behavior changes only at that point.
|
|
33
|
+
"""
|
|
34
|
+
from __future__ import annotations
|
|
35
|
+
|
|
36
|
+
import contextvars
|
|
37
|
+
import logging
|
|
38
|
+
from contextlib import contextmanager
|
|
39
|
+
from dataclasses import dataclass, field
|
|
40
|
+
from typing import Any, Callable, Iterator, Optional
|
|
41
|
+
|
|
42
|
+
from drydock.steering.sidecar.header_parser import SteeringDirective
|
|
43
|
+
|
|
44
|
+
logger = logging.getLogger(__name__)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# Module-level ContextVar so a request handler's `activate()` block
|
|
48
|
+
# is visible to the model.generate it wraps, even when generate dips
|
|
49
|
+
# into torch C++ that calls back into our Python hook.
|
|
50
|
+
_active_directives: contextvars.ContextVar[Optional["ActiveSteering"]] = (
|
|
51
|
+
contextvars.ContextVar("drydock_steering_active", default=None)
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# Vectors must be a torch.Tensor of shape (hidden_dim,). We type it as
|
|
56
|
+
# Any here to keep `import torch` out of this module's import path —
|
|
57
|
+
# the manager is constructed with a real model and torch is already
|
|
58
|
+
# imported by then.
|
|
59
|
+
VectorLookup = Callable[[str, int], Optional[Any]]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass(frozen=True)
|
|
63
|
+
class ActiveSteering:
|
|
64
|
+
"""Resolved per-layer steering for one in-flight request.
|
|
65
|
+
|
|
66
|
+
`by_layer[idx]` is the list of `(scale, vector)` pairs to add to
|
|
67
|
+
layer `idx`'s residual output. Multiple directives can target the
|
|
68
|
+
same layer (the PRD allows comma-separated modes); they sum.
|
|
69
|
+
"""
|
|
70
|
+
by_layer: dict[int, list[tuple[float, Any]]]
|
|
71
|
+
|
|
72
|
+
def fired_layers(self) -> list[int]:
|
|
73
|
+
return sorted(self.by_layer.keys())
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def get_active_steering() -> Optional[ActiveSteering]:
|
|
77
|
+
"""Read the current ContextVar. Exposed for tests."""
|
|
78
|
+
return _active_directives.get()
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class SteeringHookManager:
|
|
82
|
+
"""Owns the lifecycle of per-layer forward hooks on a loaded model.
|
|
83
|
+
|
|
84
|
+
Construct ONCE per model. The `vector_lookup` callable is invoked
|
|
85
|
+
at directive-activation time, not per-forward — so the lookup can
|
|
86
|
+
do non-trivial work (file reads, sha256 verification) without
|
|
87
|
+
blocking inference.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
def __init__(self, model: Any, vector_lookup: VectorLookup):
|
|
91
|
+
self._model = model
|
|
92
|
+
self._vector_lookup = vector_lookup
|
|
93
|
+
self._handles: list[Any] = []
|
|
94
|
+
self._layers = self._discover_layers(model)
|
|
95
|
+
self._n_layers = len(self._layers)
|
|
96
|
+
self._register_hooks()
|
|
97
|
+
|
|
98
|
+
@staticmethod
|
|
99
|
+
def _discover_layers(model: Any) -> Any:
|
|
100
|
+
# transformers convention: decoder blocks live at
|
|
101
|
+
# `model.model.layers` (Gemma, Llama, Mistral, …). Some legacy
|
|
102
|
+
# archs put them at `model.layers` directly. Accept both.
|
|
103
|
+
candidates = [
|
|
104
|
+
getattr(getattr(model, "model", None), "layers", None),
|
|
105
|
+
getattr(model, "layers", None),
|
|
106
|
+
]
|
|
107
|
+
for c in candidates:
|
|
108
|
+
if c is not None and hasattr(c, "__len__") and len(c) > 0:
|
|
109
|
+
return c
|
|
110
|
+
raise RuntimeError(
|
|
111
|
+
"steering: cannot locate decoder layers — expected "
|
|
112
|
+
f"model.model.layers or model.layers (got {type(model).__name__})"
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
@property
|
|
116
|
+
def n_layers(self) -> int:
|
|
117
|
+
return self._n_layers
|
|
118
|
+
|
|
119
|
+
def _make_hook(self, layer_idx: int) -> Callable[..., Any]:
|
|
120
|
+
def hook(_module: Any, _inputs: Any, output: Any) -> Any:
|
|
121
|
+
active = _active_directives.get()
|
|
122
|
+
if active is None:
|
|
123
|
+
return output
|
|
124
|
+
entries = active.by_layer.get(layer_idx)
|
|
125
|
+
if not entries:
|
|
126
|
+
return output
|
|
127
|
+
|
|
128
|
+
# Decoder-layer outputs in transformers are typically a
|
|
129
|
+
# tuple (hidden_states, present_kv, attn_weights, ...).
|
|
130
|
+
# We only ever modify the hidden_states; everything else
|
|
131
|
+
# rides through unchanged.
|
|
132
|
+
if isinstance(output, tuple):
|
|
133
|
+
hidden = output[0]
|
|
134
|
+
rest: tuple[Any, ...] = output[1:]
|
|
135
|
+
else:
|
|
136
|
+
hidden = output
|
|
137
|
+
rest = ()
|
|
138
|
+
|
|
139
|
+
for scale, vector in entries:
|
|
140
|
+
if vector is None or scale == 0.0:
|
|
141
|
+
continue
|
|
142
|
+
# Match dtype/device of the residual stream — vectors
|
|
143
|
+
# live on CPU as fp32 in the registry, residuals are
|
|
144
|
+
# whatever the model picked (fp16/bf16 typically).
|
|
145
|
+
v = vector.to(dtype=hidden.dtype, device=hidden.device)
|
|
146
|
+
hidden = hidden + scale * v
|
|
147
|
+
|
|
148
|
+
if rest:
|
|
149
|
+
return (hidden,) + rest
|
|
150
|
+
return hidden
|
|
151
|
+
|
|
152
|
+
return hook
|
|
153
|
+
|
|
154
|
+
def _register_hooks(self) -> None:
|
|
155
|
+
for i, layer in enumerate(self._layers):
|
|
156
|
+
handle = layer.register_forward_hook(self._make_hook(i))
|
|
157
|
+
self._handles.append(handle)
|
|
158
|
+
logger.info(
|
|
159
|
+
"steering: registered %d forward hooks (one per decoder layer)",
|
|
160
|
+
len(self._handles),
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
@contextmanager
|
|
164
|
+
def activate(
|
|
165
|
+
self, directives: list[SteeringDirective]
|
|
166
|
+
) -> Iterator[Optional[ActiveSteering]]:
|
|
167
|
+
"""Set the ContextVar for the duration of one generate() call.
|
|
168
|
+
|
|
169
|
+
Resolves each directive's vector NOW (not in the hook hot
|
|
170
|
+
path). Out-of-range layers and missing vectors are dropped
|
|
171
|
+
with a warning, never raised — a malformed request should
|
|
172
|
+
still serve a completion, just unsteered.
|
|
173
|
+
"""
|
|
174
|
+
if not directives:
|
|
175
|
+
yield None
|
|
176
|
+
return
|
|
177
|
+
|
|
178
|
+
by_layer: dict[int, list[tuple[float, Any]]] = {}
|
|
179
|
+
for d in directives:
|
|
180
|
+
if d.layer < 0 or d.layer >= self._n_layers:
|
|
181
|
+
logger.warning(
|
|
182
|
+
"steering: directive %s layer out of range (0..%d), skipping",
|
|
183
|
+
d, self._n_layers - 1,
|
|
184
|
+
)
|
|
185
|
+
continue
|
|
186
|
+
try:
|
|
187
|
+
vec = self._vector_lookup(d.mode, d.layer)
|
|
188
|
+
except Exception as e:
|
|
189
|
+
logger.warning(
|
|
190
|
+
"steering: vector lookup raised for %s: %s — skipping", d, e
|
|
191
|
+
)
|
|
192
|
+
continue
|
|
193
|
+
if vec is None:
|
|
194
|
+
logger.warning(
|
|
195
|
+
"steering: no vector for mode=%r layer=%d — skipping",
|
|
196
|
+
d.mode, d.layer,
|
|
197
|
+
)
|
|
198
|
+
continue
|
|
199
|
+
by_layer.setdefault(d.layer, []).append((d.scale, vec))
|
|
200
|
+
|
|
201
|
+
if not by_layer:
|
|
202
|
+
yield None
|
|
203
|
+
return
|
|
204
|
+
|
|
205
|
+
active = ActiveSteering(by_layer=by_layer)
|
|
206
|
+
token = _active_directives.set(active)
|
|
207
|
+
try:
|
|
208
|
+
yield active
|
|
209
|
+
finally:
|
|
210
|
+
_active_directives.reset(token)
|
|
211
|
+
|
|
212
|
+
def close(self) -> None:
|
|
213
|
+
"""Remove every hook. After close(), the manager is unusable."""
|
|
214
|
+
for h in self._handles:
|
|
215
|
+
try:
|
|
216
|
+
h.remove()
|
|
217
|
+
except Exception:
|
|
218
|
+
pass
|
|
219
|
+
self._handles.clear()
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
# --- Capture-mode hooks (Milestone 3) --------------------------------------
|
|
223
|
+
#
|
|
224
|
+
# The capture path is the read-only complement to SteeringHookManager: the
|
|
225
|
+
# hooks observe each layer's residual stream and record the chosen token
|
|
226
|
+
# position into a per-pass buffer, but they do not modify the output. This
|
|
227
|
+
# is what `drydock/steering/train/capture.py` uses to gather the
|
|
228
|
+
# (good_residuals, derailed_residuals) pairs M4 will turn into vectors.
|
|
229
|
+
#
|
|
230
|
+
# Same ContextVar pattern as the inject path so the same model can serve
|
|
231
|
+
# both modes (in different processes — capture is offline, inject is
|
|
232
|
+
# online — but the abstraction stays uniform).
|
|
233
|
+
|
|
234
|
+
_active_capture: contextvars.ContextVar[Optional["CaptureBuffer"]] = (
|
|
235
|
+
contextvars.ContextVar("drydock_steering_capture", default=None)
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
@dataclass
|
|
240
|
+
class CaptureBuffer:
|
|
241
|
+
"""Per-forward-pass buffer holding one residual vector per layer.
|
|
242
|
+
|
|
243
|
+
`position` is the token index to capture. -1 = last token (the
|
|
244
|
+
most common pattern for steering-vector training: the model has
|
|
245
|
+
seen the whole prompt+completion and the LAST hidden state is the
|
|
246
|
+
cleanest read on whether it's currently in the "good" or
|
|
247
|
+
"derailed" trajectory). 0 = first token, etc.
|
|
248
|
+
|
|
249
|
+
Residuals land on CPU as fp32 — the hook eagerly detaches and
|
|
250
|
+
casts so the per-pass buffer doesn't hold CUDA refs after the
|
|
251
|
+
forward pass returns. That keeps GPU memory bounded across long
|
|
252
|
+
capture runs.
|
|
253
|
+
"""
|
|
254
|
+
position: int = -1
|
|
255
|
+
residuals: dict[int, Any] = field(default_factory=dict)
|
|
256
|
+
batch_index: int = 0 # which row of the batch to capture (default 0)
|
|
257
|
+
|
|
258
|
+
def stack(self, n_layers: int) -> Any:
|
|
259
|
+
"""Stack into a (n_layers, hidden_dim) array. Missing layers
|
|
260
|
+
are filled with zeros at the inferred hidden_dim. Returns a
|
|
261
|
+
torch.Tensor; callers convert to numpy as needed."""
|
|
262
|
+
import torch
|
|
263
|
+
if not self.residuals:
|
|
264
|
+
raise RuntimeError(
|
|
265
|
+
"capture buffer is empty — did the forward pass run "
|
|
266
|
+
"inside the `with mgr.capture():` block?"
|
|
267
|
+
)
|
|
268
|
+
sample = next(iter(self.residuals.values()))
|
|
269
|
+
hidden_dim = sample.shape[-1]
|
|
270
|
+
out = torch.zeros((n_layers, hidden_dim), dtype=torch.float32)
|
|
271
|
+
for idx, vec in self.residuals.items():
|
|
272
|
+
if 0 <= idx < n_layers:
|
|
273
|
+
out[idx] = vec
|
|
274
|
+
return out
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def get_active_capture() -> Optional[CaptureBuffer]:
|
|
278
|
+
"""Read the current capture ContextVar. Exposed for tests."""
|
|
279
|
+
return _active_capture.get()
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
class CaptureHookManager:
|
|
283
|
+
"""Owns per-layer forward hooks that record (do not modify) residuals.
|
|
284
|
+
|
|
285
|
+
Concurrency: identical to SteeringHookManager — register once,
|
|
286
|
+
dispatch per-pass via a ContextVar. Capture and steering can be
|
|
287
|
+
used on the same process by constructing both managers; their
|
|
288
|
+
hooks are independent.
|
|
289
|
+
"""
|
|
290
|
+
|
|
291
|
+
def __init__(self, model: Any):
|
|
292
|
+
self._model = model
|
|
293
|
+
self._handles: list[Any] = []
|
|
294
|
+
self._layers = SteeringHookManager._discover_layers(model)
|
|
295
|
+
self._n_layers = len(self._layers)
|
|
296
|
+
self._register_hooks()
|
|
297
|
+
|
|
298
|
+
@property
|
|
299
|
+
def n_layers(self) -> int:
|
|
300
|
+
return self._n_layers
|
|
301
|
+
|
|
302
|
+
def _make_hook(self, layer_idx: int) -> Callable[..., Any]:
|
|
303
|
+
# Capture fires inside a torch forward pass, so torch is
|
|
304
|
+
# already in sys.modules by then. Importing here keeps the
|
|
305
|
+
# module-import path torch-free.
|
|
306
|
+
import torch
|
|
307
|
+
|
|
308
|
+
def hook(_module: Any, _inputs: Any, output: Any) -> Any:
|
|
309
|
+
buf = _active_capture.get()
|
|
310
|
+
if buf is None:
|
|
311
|
+
return output
|
|
312
|
+
hidden = output[0] if isinstance(output, tuple) else output
|
|
313
|
+
# hidden: (batch, seq, hidden_dim). Pick the configured
|
|
314
|
+
# batch row and token position. Detach + cast on the GPU
|
|
315
|
+
# side, then move to CPU — minimizes the data crossing
|
|
316
|
+
# the bus and avoids holding CUDA refs after the pass.
|
|
317
|
+
if buf.batch_index >= hidden.shape[0]:
|
|
318
|
+
logger.warning(
|
|
319
|
+
"capture: batch_index=%d out of range for shape %s",
|
|
320
|
+
buf.batch_index, tuple(hidden.shape),
|
|
321
|
+
)
|
|
322
|
+
return output
|
|
323
|
+
row = hidden[buf.batch_index]
|
|
324
|
+
seq_len = row.shape[0]
|
|
325
|
+
pos = buf.position
|
|
326
|
+
if pos < 0:
|
|
327
|
+
pos = seq_len + pos
|
|
328
|
+
if pos < 0 or pos >= seq_len:
|
|
329
|
+
logger.warning(
|
|
330
|
+
"capture: position=%d out of range for seq_len=%d (layer=%d)",
|
|
331
|
+
buf.position, seq_len, layer_idx,
|
|
332
|
+
)
|
|
333
|
+
return output
|
|
334
|
+
buf.residuals[layer_idx] = (
|
|
335
|
+
row[pos].detach().to(dtype=torch.float32).cpu()
|
|
336
|
+
)
|
|
337
|
+
return output
|
|
338
|
+
|
|
339
|
+
return hook
|
|
340
|
+
|
|
341
|
+
def _register_hooks(self) -> None:
|
|
342
|
+
for i, layer in enumerate(self._layers):
|
|
343
|
+
handle = layer.register_forward_hook(self._make_hook(i))
|
|
344
|
+
self._handles.append(handle)
|
|
345
|
+
logger.info(
|
|
346
|
+
"capture: registered %d forward hooks (read-only)",
|
|
347
|
+
len(self._handles),
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
@contextmanager
|
|
351
|
+
def capture(
|
|
352
|
+
self, position: int = -1, batch_index: int = 0
|
|
353
|
+
) -> Iterator[CaptureBuffer]:
|
|
354
|
+
"""Activate the capture ContextVar for one forward pass.
|
|
355
|
+
|
|
356
|
+
Returns the buffer; after the block exits, `buf.residuals`
|
|
357
|
+
holds one tensor per layer that was reached during the pass.
|
|
358
|
+
"""
|
|
359
|
+
buf = CaptureBuffer(position=position, batch_index=batch_index)
|
|
360
|
+
token = _active_capture.set(buf)
|
|
361
|
+
try:
|
|
362
|
+
yield buf
|
|
363
|
+
finally:
|
|
364
|
+
_active_capture.reset(token)
|
|
365
|
+
|
|
366
|
+
def close(self) -> None:
|
|
367
|
+
for h in self._handles:
|
|
368
|
+
try:
|
|
369
|
+
h.remove()
|
|
370
|
+
except Exception:
|
|
371
|
+
pass
|
|
372
|
+
self._handles.clear()
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"""Lazy model + tokenizer loader for the steering sidecar.
|
|
2
|
+
|
|
3
|
+
Lifted out of `server.py` so non-HTTP callers (e.g. the offline
|
|
4
|
+
capture pipeline in `drydock.steering.train.capture`) can reuse the
|
|
5
|
+
same load path without dragging in FastAPI/uvicorn.
|
|
6
|
+
|
|
7
|
+
The cache is module-level — calling `load_model()` from anywhere in
|
|
8
|
+
the process returns the same `(model, tokenizer)` pair after the
|
|
9
|
+
first hit. Thread-safe via a single lock around the load.
|
|
10
|
+
"""
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import logging
|
|
14
|
+
import os
|
|
15
|
+
import threading
|
|
16
|
+
import time
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
_DEFAULT_MODEL_PATH = "/data3/Models/Gemma-4-26B-A4B-it-AWQ-4bit"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _model_path() -> str:
|
|
26
|
+
return os.environ.get(
|
|
27
|
+
"DRYDOCK_STEERING_SIDECAR_MODEL_PATH", _DEFAULT_MODEL_PATH
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _device_map() -> str:
|
|
32
|
+
return os.environ.get("DRYDOCK_STEERING_SIDECAR_DEVICE_MAP", "auto")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
_MODEL_LOCK = threading.Lock()
|
|
36
|
+
_MODEL: Any = None
|
|
37
|
+
_TOKENIZER: Any = None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def is_loaded() -> bool:
|
|
41
|
+
return _MODEL is not None and _TOKENIZER is not None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def load_model() -> tuple[Any, Any]:
|
|
45
|
+
"""Lazy + thread-safe model load. Cached after the first call.
|
|
46
|
+
|
|
47
|
+
Raises RuntimeError on any underlying transformers/torch failure —
|
|
48
|
+
callers convert that into whatever error shape they want (HTTP
|
|
49
|
+
503 in the FastAPI handler, sys.exit in CLIs).
|
|
50
|
+
"""
|
|
51
|
+
global _MODEL, _TOKENIZER
|
|
52
|
+
if _MODEL is not None and _TOKENIZER is not None:
|
|
53
|
+
return _MODEL, _TOKENIZER
|
|
54
|
+
with _MODEL_LOCK:
|
|
55
|
+
if _MODEL is not None and _TOKENIZER is not None:
|
|
56
|
+
return _MODEL, _TOKENIZER
|
|
57
|
+
path = _model_path()
|
|
58
|
+
device_map = _device_map()
|
|
59
|
+
logger.info(
|
|
60
|
+
"steering sidecar: loading model from %s (device_map=%s)",
|
|
61
|
+
path, device_map,
|
|
62
|
+
)
|
|
63
|
+
t0 = time.perf_counter()
|
|
64
|
+
try:
|
|
65
|
+
import torch # noqa: F401 (used below)
|
|
66
|
+
from transformers import AutoModelForCausalLM, AutoTokenizer
|
|
67
|
+
except ImportError as e:
|
|
68
|
+
raise RuntimeError(
|
|
69
|
+
f"steering sidecar: missing dependency ({e}). Install "
|
|
70
|
+
"transformers + torch (CUDA build) to use the sidecar."
|
|
71
|
+
) from e
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
tokenizer = AutoTokenizer.from_pretrained(path, trust_remote_code=True)
|
|
75
|
+
model = AutoModelForCausalLM.from_pretrained(
|
|
76
|
+
path,
|
|
77
|
+
device_map=device_map,
|
|
78
|
+
torch_dtype="auto",
|
|
79
|
+
trust_remote_code=True,
|
|
80
|
+
)
|
|
81
|
+
model.eval()
|
|
82
|
+
except Exception as e:
|
|
83
|
+
raise RuntimeError(
|
|
84
|
+
f"steering sidecar: model load failed: {type(e).__name__}: {e}"
|
|
85
|
+
) from e
|
|
86
|
+
|
|
87
|
+
elapsed = time.perf_counter() - t0
|
|
88
|
+
try:
|
|
89
|
+
param_dtype = next(iter(model.parameters())).dtype
|
|
90
|
+
except StopIteration:
|
|
91
|
+
param_dtype = "?"
|
|
92
|
+
logger.info(
|
|
93
|
+
"steering sidecar: model loaded in %.1fs (param dtype=%s)",
|
|
94
|
+
elapsed, param_dtype,
|
|
95
|
+
)
|
|
96
|
+
_MODEL = model
|
|
97
|
+
_TOKENIZER = tokenizer
|
|
98
|
+
return _MODEL, _TOKENIZER
|