drydock-cli 3.1.6__tar.gz → 3.1.7__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-3.1.6/drydock_cli.egg-info → drydock_cli-3.1.7}/PKG-INFO +54 -1
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/README.md +53 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/providers.py +11 -0
- drydock_cli-3.1.7/drydock/ratchet.py +522 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/tui/app.py +135 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7/drydock_cli.egg-info}/PKG-INFO +54 -1
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock_cli.egg-info/SOURCES.txt +2 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/pyproject.toml +1 -1
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_doccanvas.py +45 -0
- drydock_cli-3.1.7/tests/test_ratchet.py +324 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/LICENSE +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/NOTICE +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/__init__.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/__main__.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/advisor.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/agent.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/bash_safety.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/budget.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/__init__.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/document-canvas.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/fiar-assess.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/fiar-cap.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/fiar-evidence.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/fiar-readiness.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/ml-data.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/ml-debug.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/ml-finetune.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/ml-metrics.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/ml-rl.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/ml-train.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/nist-ai-rmf.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/nist-csf.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/rmf-categorize.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/rmf-control.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/rmf-poam.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/rmf-review.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/stig-assess.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/builtin_skills/stig-remediate.md +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/cci.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/cli.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/compaction.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/config.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/detect.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/doccanvas.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/events.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/extract.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/fiar.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/gittools.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/graphrag.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/guards.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/loop_detect.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/mcp.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/phases.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/poam.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/progress.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/recipes.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/recovery.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/resume.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/rmf.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/rmf_graph.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/skills.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/stig.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/subagents.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/suggest.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/task_state.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/tool_policy.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/tool_registry.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/tool_result.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/tool_select.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/tool_validate.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/tools/__init__.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/trajectory.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/tui/__init__.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/tui/approval.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/tui/messages.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/tui/widgets.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/tuning.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/verification.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock/web.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock_cli.egg-info/dependency_links.txt +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock_cli.egg-info/entry_points.txt +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock_cli.egg-info/requires.txt +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/drydock_cli.egg-info/top_level.txt +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/setup.cfg +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_advisor.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_approval.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_back_command.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_bash_background.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_bash_binary_output.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_bash_crossplatform.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_bash_output_bounding.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_bash_process_group.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_bash_safety.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_bash_sanitize.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_bash_shell.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_bash_stdin.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_bash_stop_partial.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_bash_timeout_network.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_bash_timeout_param.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_budget.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_cci.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_cli_agents.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_compact_command.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_compaction.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_config.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_config_migration.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_context_limit_config.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_context_limit_issue25.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_criteria_coverage.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_cycling_detection.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_degenerate_argument.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_detect.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_dispatch.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_e2e_connected.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_edit_replace_all.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_effort_governor.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_empty_response.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_events.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_extract.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_failure_loop.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_fiar.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_first_run_setup.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_gittools.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_glob_edit_edges.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_graphify_example.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_graphrag.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_graphrag_quoted_path.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_graphrag_sqlite.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_grep_and_read_robust.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_guards_and_tools.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_hallucinated_tools.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_leaked_tool_call.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_loop_detect.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_mcp.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_model_registry.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_oneshot_unreachable.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_overthink_interrupt.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_phases.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_plan_autocontinue.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_poam.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_progress.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_providers_unreachable.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_read_index.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_recipes.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_recovery.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_recovery_config.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_recovery_integration.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_repeated_outcome.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_repetition_interrupt.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_resume_events.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_resume_restore.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_resume_snapshot.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_rmf.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_rmf_graph.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_rmf_stig_graph.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_rolling_plan.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_runaway_repetition.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_screenshot.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_server_probe.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_skills.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_sqlite_events.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_stall_retry.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_stig.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_stop.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_streaming_newlines.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_subagent.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_subagents.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_suggest.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_system_prompt_help.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_task_state.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_timeline.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_todo.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_tool_arg_coercion.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_tool_arg_coercion_more.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_tool_arg_parsing.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_tool_canonical.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_tool_policy.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_tool_result.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_tool_select.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_tool_validate.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_tools_undo.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_trajectory.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_tui.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_tuning.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_verification_gate.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_viewimage.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_vision_input.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_web_tools.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_windows_shell.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_worker_subagent.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_write_content_coerce.py +0 -0
- {drydock_cli-3.1.6 → drydock_cli-3.1.7}/tests/test_xccdf.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: drydock-cli
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.7
|
|
4
4
|
Summary: Drydock — a local, provider-agnostic terminal coding agent for local LLMs
|
|
5
5
|
Author: Frank Bobe III
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -112,6 +112,10 @@ A full agentic CLI harness — every tool below is clean-room and dependency-fre
|
|
|
112
112
|
- **Cross-platform** — runs natively on Linux, macOS, and **Windows via PowerShell/cmd**
|
|
113
113
|
(no WSL or Git-Bash required); `/shell` shows which shell your commands run in.
|
|
114
114
|
- **Loops** — `/loop <count> <prompt>` runs a prompt iteratively (Esc stops).
|
|
115
|
+
- **Ratchet** — `/ratchet <goal>` keeps solving across rounds, snapshotting the
|
|
116
|
+
workspace whenever more tests pass and rolling back regressions, until it goes
|
|
117
|
+
green. The verifier auto-detects (pytest/cargo/go/npm/make); `--verify "<cmd>"`
|
|
118
|
+
overrides. Progress can't slip backward.
|
|
115
119
|
|
|
116
120
|
## Slash commands
|
|
117
121
|
|
|
@@ -129,6 +133,7 @@ Typed into the prompt. The agent also knows these, so you can just **ask it**
|
|
|
129
133
|
| `/skills new <name> <prompt>` | Create a reusable `/<name>` skill (use `$ARGS` for input) |
|
|
130
134
|
| `/<name>` | Run a skill |
|
|
131
135
|
| `/loop <count> <prompt>` | Repeat a prompt N times (Esc stops) |
|
|
136
|
+
| `/ratchet <goal>` | Solve across rounds, snapshotting on verifier gains, rolling back regressions. Verifier auto-detects; override with `--verify "<cmd>"` (`--rounds N`, `--fitness auto\|exitcode\|<regex>`) |
|
|
132
137
|
| `/mcp` | List connected MCP servers + their tools |
|
|
133
138
|
| `/rmf bootstrap [families]` | Ingest the NIST SP 800-53 catalog (RMF automation) |
|
|
134
139
|
| `/rmf-control` · `/rmf-categorize` · `/rmf-review` · `/rmf-poam` | Bundled RMF skills |
|
|
@@ -367,6 +372,54 @@ docker run -it --add-host=host.docker.internal:host-gateway \
|
|
|
367
372
|
`-v "$PWD:/work"` mounts your project so the agent can read/edit it. Tags:
|
|
368
373
|
`fbobe3/drydock:latest` and `fbobe3/drydock:<version>` (e.g. `:3.0.135`).
|
|
369
374
|
|
|
375
|
+
### Serving Gemma-4-31B
|
|
376
|
+
|
|
377
|
+
Drydock is provider-agnostic, but its primary target is dense **Gemma-4-31B**.
|
|
378
|
+
Two proven ways to serve it on a 2×GPU box, both exposing an OpenAI-compatible
|
|
379
|
+
API on `:8000` as model `gemma4`:
|
|
380
|
+
|
|
381
|
+
**llama.cpp** — QAT GGUF, flexible concurrency (more slots if you need them):
|
|
382
|
+
|
|
383
|
+
```
|
|
384
|
+
llama-server -m gemma-4-31B-it-qat-UD-Q4_K_XL.gguf \
|
|
385
|
+
-c 65536 -np 2 --host 0.0.0.0 --port 8000 --alias gemma4
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**vLLM** — w4a16 QAT, ~2× faster per request, 128K context:
|
|
389
|
+
|
|
390
|
+
```
|
|
391
|
+
docker run -d --name vllm-prod --gpus all --ipc=host --restart unless-stopped \
|
|
392
|
+
-v /data3/Models:/models -p 8000:8000 \
|
|
393
|
+
-e NCCL_P2P_DISABLE=1 \
|
|
394
|
+
vllm/vllm-openai:v0.26.0 \
|
|
395
|
+
--model /models/gemma-4-31B-it-qat-w4a16-ct \
|
|
396
|
+
--served-model-name gemma4 \
|
|
397
|
+
--tensor-parallel-size 2 \
|
|
398
|
+
--max-model-len 131072 \
|
|
399
|
+
--max-num-seqs 2 \
|
|
400
|
+
--gpu-memory-utilization 0.97 \
|
|
401
|
+
--kv-cache-dtype fp8 \
|
|
402
|
+
--tool-call-parser gemma4 \
|
|
403
|
+
--enable-auto-tool-choice
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
Point drydock at either with
|
|
407
|
+
`--provider vllm --base-url http://<host>:8000/v1 --model gemma4`.
|
|
408
|
+
|
|
409
|
+
**vLLM-on-Gemma-4 notes** (drydock handles these for you as of **3.1.7**):
|
|
410
|
+
|
|
411
|
+
- **`skip_special_tokens: false`** is sent on every request — without it, a turn
|
|
412
|
+
truncated at `max_tokens` (tool-call / reasoning tails) comes back with *empty*
|
|
413
|
+
content, which looks like a refusal. If `finish_reason == "length"`, retry with
|
|
414
|
+
a larger `max_tokens` (≥ 2000 for reasoning-heavy calls).
|
|
415
|
+
- **Reasoning is off by default.** Enable per-request via
|
|
416
|
+
`chat_template_kwargs.enable_thinking`; the vLLM reasoning parser is disabled,
|
|
417
|
+
so `<|channel>thought …` markers arrive inside `content` (stripped client-side).
|
|
418
|
+
- **`--max-num-seqs 2`** caps concurrency at 2 — the cost of fitting 128K context
|
|
419
|
+
into the VRAM. Use llama.cpp if you need more concurrent sessions than context.
|
|
420
|
+
- Tool-calling is the standard OpenAI format; `/props` is llama.cpp-only (vLLM
|
|
421
|
+
404s it — drydock falls back to `/v1/models` for the context length).
|
|
422
|
+
|
|
370
423
|
## Using it
|
|
371
424
|
|
|
372
425
|
Type a task and press **Enter**. Drydock reads/writes/edits files and runs
|
|
@@ -88,6 +88,10 @@ A full agentic CLI harness — every tool below is clean-room and dependency-fre
|
|
|
88
88
|
- **Cross-platform** — runs natively on Linux, macOS, and **Windows via PowerShell/cmd**
|
|
89
89
|
(no WSL or Git-Bash required); `/shell` shows which shell your commands run in.
|
|
90
90
|
- **Loops** — `/loop <count> <prompt>` runs a prompt iteratively (Esc stops).
|
|
91
|
+
- **Ratchet** — `/ratchet <goal>` keeps solving across rounds, snapshotting the
|
|
92
|
+
workspace whenever more tests pass and rolling back regressions, until it goes
|
|
93
|
+
green. The verifier auto-detects (pytest/cargo/go/npm/make); `--verify "<cmd>"`
|
|
94
|
+
overrides. Progress can't slip backward.
|
|
91
95
|
|
|
92
96
|
## Slash commands
|
|
93
97
|
|
|
@@ -105,6 +109,7 @@ Typed into the prompt. The agent also knows these, so you can just **ask it**
|
|
|
105
109
|
| `/skills new <name> <prompt>` | Create a reusable `/<name>` skill (use `$ARGS` for input) |
|
|
106
110
|
| `/<name>` | Run a skill |
|
|
107
111
|
| `/loop <count> <prompt>` | Repeat a prompt N times (Esc stops) |
|
|
112
|
+
| `/ratchet <goal>` | Solve across rounds, snapshotting on verifier gains, rolling back regressions. Verifier auto-detects; override with `--verify "<cmd>"` (`--rounds N`, `--fitness auto\|exitcode\|<regex>`) |
|
|
108
113
|
| `/mcp` | List connected MCP servers + their tools |
|
|
109
114
|
| `/rmf bootstrap [families]` | Ingest the NIST SP 800-53 catalog (RMF automation) |
|
|
110
115
|
| `/rmf-control` · `/rmf-categorize` · `/rmf-review` · `/rmf-poam` | Bundled RMF skills |
|
|
@@ -343,6 +348,54 @@ docker run -it --add-host=host.docker.internal:host-gateway \
|
|
|
343
348
|
`-v "$PWD:/work"` mounts your project so the agent can read/edit it. Tags:
|
|
344
349
|
`fbobe3/drydock:latest` and `fbobe3/drydock:<version>` (e.g. `:3.0.135`).
|
|
345
350
|
|
|
351
|
+
### Serving Gemma-4-31B
|
|
352
|
+
|
|
353
|
+
Drydock is provider-agnostic, but its primary target is dense **Gemma-4-31B**.
|
|
354
|
+
Two proven ways to serve it on a 2×GPU box, both exposing an OpenAI-compatible
|
|
355
|
+
API on `:8000` as model `gemma4`:
|
|
356
|
+
|
|
357
|
+
**llama.cpp** — QAT GGUF, flexible concurrency (more slots if you need them):
|
|
358
|
+
|
|
359
|
+
```
|
|
360
|
+
llama-server -m gemma-4-31B-it-qat-UD-Q4_K_XL.gguf \
|
|
361
|
+
-c 65536 -np 2 --host 0.0.0.0 --port 8000 --alias gemma4
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
**vLLM** — w4a16 QAT, ~2× faster per request, 128K context:
|
|
365
|
+
|
|
366
|
+
```
|
|
367
|
+
docker run -d --name vllm-prod --gpus all --ipc=host --restart unless-stopped \
|
|
368
|
+
-v /data3/Models:/models -p 8000:8000 \
|
|
369
|
+
-e NCCL_P2P_DISABLE=1 \
|
|
370
|
+
vllm/vllm-openai:v0.26.0 \
|
|
371
|
+
--model /models/gemma-4-31B-it-qat-w4a16-ct \
|
|
372
|
+
--served-model-name gemma4 \
|
|
373
|
+
--tensor-parallel-size 2 \
|
|
374
|
+
--max-model-len 131072 \
|
|
375
|
+
--max-num-seqs 2 \
|
|
376
|
+
--gpu-memory-utilization 0.97 \
|
|
377
|
+
--kv-cache-dtype fp8 \
|
|
378
|
+
--tool-call-parser gemma4 \
|
|
379
|
+
--enable-auto-tool-choice
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Point drydock at either with
|
|
383
|
+
`--provider vllm --base-url http://<host>:8000/v1 --model gemma4`.
|
|
384
|
+
|
|
385
|
+
**vLLM-on-Gemma-4 notes** (drydock handles these for you as of **3.1.7**):
|
|
386
|
+
|
|
387
|
+
- **`skip_special_tokens: false`** is sent on every request — without it, a turn
|
|
388
|
+
truncated at `max_tokens` (tool-call / reasoning tails) comes back with *empty*
|
|
389
|
+
content, which looks like a refusal. If `finish_reason == "length"`, retry with
|
|
390
|
+
a larger `max_tokens` (≥ 2000 for reasoning-heavy calls).
|
|
391
|
+
- **Reasoning is off by default.** Enable per-request via
|
|
392
|
+
`chat_template_kwargs.enable_thinking`; the vLLM reasoning parser is disabled,
|
|
393
|
+
so `<|channel>thought …` markers arrive inside `content` (stripped client-side).
|
|
394
|
+
- **`--max-num-seqs 2`** caps concurrency at 2 — the cost of fitting 128K context
|
|
395
|
+
into the VRAM. Use llama.cpp if you need more concurrent sessions than context.
|
|
396
|
+
- Tool-calling is the standard OpenAI format; `/props` is llama.cpp-only (vLLM
|
|
397
|
+
404s it — drydock falls back to `/v1/models` for the context length).
|
|
398
|
+
|
|
346
399
|
## Using it
|
|
347
400
|
|
|
348
401
|
Type a task and press **Enter**. Drydock reads/writes/edits files and runs
|
|
@@ -584,6 +584,17 @@ def stream(
|
|
|
584
584
|
if config.get("temperature") is not None:
|
|
585
585
|
kwargs["temperature"] = config["temperature"]
|
|
586
586
|
|
|
587
|
+
# vLLM-Gemma quirk: a turn truncated at max_tokens (esp. tool-call / reasoning
|
|
588
|
+
# turns, whose tail is special tokens) comes back with EMPTY content unless we
|
|
589
|
+
# send skip_special_tokens=false — and a checker-scored harness reads an empty
|
|
590
|
+
# turn as a FAILURE. Always send it for vLLM (harmless / ignored on llama.cpp),
|
|
591
|
+
# and floor an already-configured-but-tiny budget so reasoning turns don't
|
|
592
|
+
# truncate to nothing. We never impose a cap where none was set.
|
|
593
|
+
if provider == "vllm":
|
|
594
|
+
kwargs.setdefault("extra_body", {})["skip_special_tokens"] = False
|
|
595
|
+
if kwargs.get("max_tokens") and kwargs["max_tokens"] < 2000:
|
|
596
|
+
kwargs["max_tokens"] = 2000
|
|
597
|
+
|
|
587
598
|
# Adaptive reasoning budget (harmony/gpt-oss style models accept this;
|
|
588
599
|
# endpoints without the knob ignore the extra field). Set per turn by the
|
|
589
600
|
# agent loop: high for planning, low for routine continuation.
|