delegate-agent-cli 0.21.0__tar.gz → 0.23.0__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.
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/CHANGELOG.md +23 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/PKG-INFO +2 -1
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/README.md +1 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/docs/cli-reference.md +3 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/docs/delegate-workflows.md +2 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/pyproject.toml +1 -1
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/__init__.py +1 -1
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/capability_commands.py +1 -2
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/cli.py +9 -16
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/cli_parser.py +43 -25
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/command_errors.py +2 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/command_help.py +30 -1
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/config.py +3 -5
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/config_commands.py +7 -3
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/constants.py +24 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/describe_payload.py +5 -14
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/harness_discovery.py +8 -4
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/inspection_commands.py +31 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/profiles.py +1 -6
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/prompt_transport.py +18 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/reasoning.py +2 -31
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/redaction.py +5 -5
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/rendering.py +18 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/request_build.py +33 -82
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/run_registry.py +155 -5
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/run_status.py +6 -10
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/runner.py +42 -111
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/safe_workspace.py +0 -4
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/setup_commands.py +3 -12
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/snapshot_view.py +2 -2
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/structured_output.py +8 -7
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/workflows/commands.py +12 -12
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/workflows/registry.py +3 -4
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/workflows/runtime.py +53 -45
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/workflows/schema.py +5 -4
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/workflows/script.py +8 -4
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/worktree_records.py +1 -3
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent_cli.egg-info/PKG-INFO +2 -1
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_delegate_help_cli.py +1 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_delegate_parser.py +24 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_execution_worktree_failure_cleanup.py +0 -3
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_inspection_commands.py +170 -1
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_retention.py +0 -3
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/CONTRIBUTING.md +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/LICENSE +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/MANIFEST.in +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/SECURITY.md +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/bin/delegate-profile-shim +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/bin/delegate.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/config.example.json +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/docs/agent-setup.md +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/docs/assets/delegate-agent-header.png +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/docs/configuration.md +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/docs/development.md +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/docs/live-runtime.md +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/docs/publishing-checklist.md +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/docs/security-model.md +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/docs/troubleshooting.md +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/docs/worktrees.md +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/examples/task.claude.json +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/examples/task.codex.json +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/examples/task.cursor.json +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/examples/task.droid.json +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/examples/task.grok.json +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/examples/task.judge.json +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/examples/task.kimi.json +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/setup.cfg +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/archived_logs.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/argv_builders.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/argv_utils.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/bundled_models.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/child_failures.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/errors.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/git_utils.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/harness_events.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/isolation.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/json_types.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/log_output.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/model_discovery.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/private_io.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/profile_commands.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/profile_guard.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/prompt_instructions.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/request_models.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/retention.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/run_metadata.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/run_output_commands.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/seatbelt.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/wait_cancel_commands.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/workflows/__init__.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/worktree_commands.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/worktree_execution.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/worktree_gc.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/worktree_mgmt.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/worktree_remove.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/worktree_summary.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/wsl.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent_cli.egg-info/SOURCES.txt +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent_cli.egg-info/dependency_links.txt +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent_cli.egg-info/entry_points.txt +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent_cli.egg-info/requires.txt +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent_cli.egg-info/top_level.txt +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_capability_commands.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_child_failures.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_codex_pure_sandbox.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_codex_thread_resilience.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_command_help.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_config_commands.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_delegate_isolation.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_delegate_validation.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_end_to_end_tracking.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_engine_argv.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_execution_argv_and_prompt.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_execution_dry_run.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_execution_worktree_preflight.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_execution_worktree_run.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_harness_discovery.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_harness_events.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_kimi_commands.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_model_discovery.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_model_selection_wave1a.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_model_selection_wave1b.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_omp_read_only_behavior.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_packaging.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_profiles.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_pure_call.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_reasoning_capabilities.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_run_registry.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_runner_capture.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_safe_workspace_isolation.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_setup_commands.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_slash_passthrough.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_snapshot_redaction.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_snapshot_rendering.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_snapshot_run_output.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_snapshot_view.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_structured_output.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_tracked_timeout.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_utility_modules.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_wait_cancel_commands.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_wave4_launch_features.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_workflow_commands.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_worktree_list_show.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_worktree_prune_gc.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_worktree_remove.py +0 -0
- {delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/tests/test_wsl_guardrails.py +0 -0
|
@@ -5,6 +5,27 @@ All notable changes to this project are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.23.0] - 2026-07-30
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Added `delegate runs prune` with a 30-day default age threshold, an explicit `--older-than` override, and `--dry-run` preview output. It prunes terminal Run records and their associated Registry artifacts (per-Run directory, logs, Completion Report, retained raw-log archive) without touching genuinely running Runs. Persistent-worktree Runs are skipped unless their worktree is recorded as removed or missing — unknown or unrecorded worktree status is treated as possibly present, mirroring `worktree gc` — so live worktrees never lose their Registry records. The ambient retention pass is bypassed on the prune command path so a dry run never mutates state.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- Focused unittest invocations (`python3 -m unittest tests.<module>`) no longer fail on the src layout import: `tests/__init__.py` now puts `src` on `sys.path` before any test module import runs.
|
|
17
|
+
|
|
18
|
+
## [0.22.0] - 2026-07-26
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Consolidated pure-call validation in `constants.validate_pure_call`, collapsed repeated `attempt`/`call` invocations in `runner.py` into local closures, eliminated `typing.Any` from `src`, and removed defensive `getattr`/`isinstance` hedges where the contract guarantees the type.
|
|
23
|
+
|
|
24
|
+
### Removed
|
|
25
|
+
|
|
26
|
+
- Removed the write-only `ReasoningCapability.supported_efforts` field and unused `STATUS_FILTER_ACTIVE`/`STATUS_FILTER_RECENT` constants.
|
|
27
|
+
- Removed dead back-compat re-exports from `delegate_agent.cli`: `build_kimi_argv`, `build_opencode_argv`, `build_pi_argv`, `prefix_droid_safe_prompt`, `redacted_prompt_argv`, `KIMI_PROMPT_REDACTION`, `_grok_harness_bypass_enabled`, `_resolve_default_model`, and `block_external_symlinks`. These had no known consumers; the supported import surface is the CLI and `delegate --json` contracts.
|
|
28
|
+
|
|
8
29
|
## [0.21.0] - 2026-07-26
|
|
9
30
|
|
|
10
31
|
### Added
|
|
@@ -748,6 +769,8 @@ Usage-audit fix wave: 82 sessions and 1,241 delegate invocations from one week o
|
|
|
748
769
|
|
|
749
770
|
- Releases before 0.1.3 predate this changelog.
|
|
750
771
|
|
|
772
|
+
[0.23.0]: https://github.com/treygoff24/delegate-agent/compare/v0.22.0...v0.23.0
|
|
773
|
+
[0.22.0]: https://github.com/treygoff24/delegate-agent/compare/v0.21.0...v0.22.0
|
|
751
774
|
[0.21.0]: https://github.com/treygoff24/delegate-agent/compare/v0.20.0...v0.21.0
|
|
752
775
|
[0.20.0]: https://github.com/treygoff24/delegate-agent/compare/v0.19.0...v0.20.0
|
|
753
776
|
[0.19.0]: https://github.com/treygoff24/delegate-agent/compare/v0.18.0...v0.19.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: delegate-agent-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.23.0
|
|
4
4
|
Summary: A tiny CLI for delegating bounded agent tasks across coding-agent runtimes.
|
|
5
5
|
Author: Trey Goff
|
|
6
6
|
License-Expression: MIT
|
|
@@ -332,6 +332,7 @@ delegate runs --recent
|
|
|
332
332
|
delegate ps # active and stale tracked runs
|
|
333
333
|
delegate snapshot <alias-or-runId>
|
|
334
334
|
delegate run-output <alias-or-runId>
|
|
335
|
+
delegate runs prune --dry-run # preview GC of terminal run records older than 30 days
|
|
335
336
|
```
|
|
336
337
|
|
|
337
338
|
Aliases are always numbered (`codex-1`, `cursor-2`); a **bare harness name
|
|
@@ -299,6 +299,7 @@ delegate runs --recent
|
|
|
299
299
|
delegate ps # active and stale tracked runs
|
|
300
300
|
delegate snapshot <alias-or-runId>
|
|
301
301
|
delegate run-output <alias-or-runId>
|
|
302
|
+
delegate runs prune --dry-run # preview GC of terminal run records older than 30 days
|
|
302
303
|
```
|
|
303
304
|
|
|
304
305
|
Aliases are always numbered (`codex-1`, `cursor-2`); a **bare harness name
|
|
@@ -931,6 +931,7 @@ Tracked runs return bounded parent-facing output and store local metadata under
|
|
|
931
931
|
|
|
932
932
|
```bash
|
|
933
933
|
delegate runs [--active|--running|--stale|--recent] [--harness HARNESS] [--group NAME] [--limit N]
|
|
934
|
+
delegate runs prune [--older-than DAYS] [--dry-run]
|
|
934
935
|
delegate ps [--harness HARNESS] [--group NAME] [--limit N]
|
|
935
936
|
delegate snapshot [--latest HARNESS] [--no-redact] <handle>
|
|
936
937
|
delegate run-output [--latest HARNESS] <handle> [--completion-report] [--stdout] [--stderr] [--tail N] [--max-chars N] [--raw] [--no-redact]
|
|
@@ -942,6 +943,8 @@ delegate cancel <handle>...
|
|
|
942
943
|
`delegate ps` is the shorter first-class form of `delegate runs --active` and
|
|
943
944
|
accepts the same harness, group, and limit selectors.
|
|
944
945
|
|
|
946
|
+
`delegate runs prune` removes old terminal Run records from the workspace Registry so they stop accumulating forever. Only runs whose effective status is terminal (`succeeded`, `failed`, `cancelled`, or `stale` from a dead child) and whose last Registry activity is older than the threshold (default 30 days; override with `--older-than DAYS`) are eligible. Effectively running runs are always skipped, and persistent-worktree runs are skipped unless their worktree is recorded as removed or missing — pruning the record of a live worktree would orphan it from `worktree list`/`show`/`remove`. Pruning deletes the per-Run directory (Snapshot, Manifest, logs, events, Completion Report) and the retained raw-log archive; worktree paths on disk are never touched. `--dry-run` reports what would be removed without changing anything. JSON output uses schema `delegate.runs-prune.v1` with `planned`, `removed`, `skipped` (each entry carries a `reason`), and `errors` sections.
|
|
947
|
+
|
|
945
948
|
Run-scoped handles (`snapshot`, `run-output`, `wait`, and `cancel`)
|
|
946
949
|
resolve exact run IDs and numbered aliases first. A bare harness name such as
|
|
947
950
|
`codex` resolves to that harness's latest run, and `harness:modelAlias` (for
|
|
@@ -175,6 +175,7 @@ engines = args.get("engines", ["codex", "claude", "cursor"])
|
|
|
175
175
|
models = args.get("models", {})
|
|
176
176
|
prompt = args["prompt"]
|
|
177
177
|
|
|
178
|
+
|
|
178
179
|
def reviewer(engine):
|
|
179
180
|
return lambda: agent(
|
|
180
181
|
prompt,
|
|
@@ -184,6 +185,7 @@ def reviewer(engine):
|
|
|
184
185
|
phase=f"Review ({engine})",
|
|
185
186
|
)
|
|
186
187
|
|
|
188
|
+
|
|
187
189
|
reviews = parallel([reviewer(engine) for engine in engines])
|
|
188
190
|
return {"reviews": dict(zip(engines, reviews))}
|
|
189
191
|
```
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "delegate-agent-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.23.0"
|
|
8
8
|
description = "A tiny CLI for delegating bounded agent tasks across coding-agent runtimes."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
{delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/capability_commands.py
RENAMED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from collections.abc import Callable
|
|
4
3
|
from dataclasses import dataclass
|
|
5
4
|
from pathlib import Path
|
|
6
5
|
from typing import TextIO
|
|
@@ -139,7 +138,7 @@ def _refresh_payload(
|
|
|
139
138
|
*,
|
|
140
139
|
profile: profiles.ProfileResolution,
|
|
141
140
|
engines: tuple[str, ...] | None = None,
|
|
142
|
-
progress:
|
|
141
|
+
progress: harness_discovery.ProgressCallback | None = None,
|
|
143
142
|
) -> JsonObject:
|
|
144
143
|
try:
|
|
145
144
|
result = harness_discovery.refresh_discovery(
|
|
@@ -40,20 +40,14 @@ from delegate_agent import runner as delegate_runner
|
|
|
40
40
|
from delegate_agent.argv_builders import ( # noqa: F401 # re-exported for tests / back-compat
|
|
41
41
|
SAFE_REVIEW_PREFIX_BY_ENGINE,
|
|
42
42
|
_claude_harness_bypass_enabled,
|
|
43
|
-
_grok_harness_bypass_enabled,
|
|
44
43
|
build_claude_argv,
|
|
45
44
|
build_codex_argv,
|
|
46
45
|
build_cursor_argv,
|
|
47
46
|
build_devin_argv,
|
|
48
47
|
build_droid_argv,
|
|
49
48
|
build_grok_argv,
|
|
50
|
-
build_kimi_argv,
|
|
51
49
|
build_omp_argv,
|
|
52
|
-
build_opencode_argv,
|
|
53
|
-
build_pi_argv,
|
|
54
50
|
prefix_cursor_safe_prompt,
|
|
55
|
-
prefix_droid_safe_prompt,
|
|
56
|
-
redacted_prompt_argv,
|
|
57
51
|
)
|
|
58
52
|
from delegate_agent.argv_utils import public_argv
|
|
59
53
|
from delegate_agent.cli_parser import ( # noqa: F401 # re-exported for tests / back-compat
|
|
@@ -98,7 +92,6 @@ from delegate_agent.prompt_transport import ( # noqa: F401 # CURSOR_PROMPT_RED
|
|
|
98
92
|
DEVIN_AGENT_CONFIG_DISPLAY,
|
|
99
93
|
DROID_PROMPT_FILE_ARG_PLACEHOLDER,
|
|
100
94
|
DROID_PROMPT_FILE_DISPLAY,
|
|
101
|
-
KIMI_PROMPT_REDACTION,
|
|
102
95
|
PROMPT_FILE_ARG_PLACEHOLDER,
|
|
103
96
|
PROMPT_FILE_DISPLAY,
|
|
104
97
|
PROMPT_TRANSPORT_ARGV,
|
|
@@ -109,7 +102,6 @@ from delegate_agent.request_build import ( # noqa: F401 # re-exported for test
|
|
|
109
102
|
CALL_TEMP_CWD_PLACEHOLDER,
|
|
110
103
|
RUN_INPUT_KEYS,
|
|
111
104
|
_load_input_json_object,
|
|
112
|
-
_resolve_default_model,
|
|
113
105
|
build_request,
|
|
114
106
|
effective_prompt,
|
|
115
107
|
load_config,
|
|
@@ -136,7 +128,6 @@ from delegate_agent.safe_workspace import ( # noqa: F401 # re-exported for tes
|
|
|
136
128
|
SAFE_BLOCKED_SYMLINK_PLACEHOLDER,
|
|
137
129
|
SAFE_EXTERNAL_SYMLINK_WARNING_PREFIX,
|
|
138
130
|
SAFE_UNBORN_GIT_WARNING,
|
|
139
|
-
block_external_symlinks,
|
|
140
131
|
cleanup_safe_isolated_workspace,
|
|
141
132
|
create_directory_safe_workspace,
|
|
142
133
|
create_git_safe_workspace,
|
|
@@ -332,7 +323,6 @@ def dry_run_payload(request: Request) -> JsonObject:
|
|
|
332
323
|
if request.profile_resolution.name is not None:
|
|
333
324
|
payload["profileEnv"] = redaction.redact_env_map(request.profile_resolution.env)
|
|
334
325
|
|
|
335
|
-
# Structured isolation fields from the isolation context.
|
|
336
326
|
if request.isolation_context is not None:
|
|
337
327
|
ctx = request.isolation_context
|
|
338
328
|
|
|
@@ -515,7 +505,6 @@ def make_run_context(
|
|
|
515
505
|
if request.isolation_context is not None
|
|
516
506
|
else False
|
|
517
507
|
)
|
|
518
|
-
# Extract isolation metadata from the isolation context.
|
|
519
508
|
iso_ctx = request.isolation_context
|
|
520
509
|
if iso_ctx is not None:
|
|
521
510
|
isolation_mode = iso_ctx.isolation_mode
|
|
@@ -860,7 +849,7 @@ def execute_request(
|
|
|
860
849
|
profiles.preflight_codex_request(request, config.get("codex", {}))
|
|
861
850
|
ctx = request.isolation_context
|
|
862
851
|
|
|
863
|
-
#
|
|
852
|
+
# Persistent worktree runs (work + worktree) hand off to worktree_execution.
|
|
864
853
|
if ctx is not None and ctx.isolation_lifecycle == "persistent":
|
|
865
854
|
try:
|
|
866
855
|
return worktree_execution.execute_persistent_worktree(
|
|
@@ -1022,7 +1011,6 @@ def pre_read_run_json_for_config(
|
|
|
1022
1011
|
if json_cwd is not None and not isinstance(json_cwd, str):
|
|
1023
1012
|
raise DelegateError("invalid_cwd", "cwd must be a string.")
|
|
1024
1013
|
|
|
1025
|
-
# Reject explicit null isolation in the JSON pre-read.
|
|
1026
1014
|
if "isolation" in raw and raw["isolation"] is None:
|
|
1027
1015
|
raise DelegateError(
|
|
1028
1016
|
"invalid_isolation",
|
|
@@ -1192,7 +1180,12 @@ def main(
|
|
|
1192
1180
|
"workflow",
|
|
1193
1181
|
}:
|
|
1194
1182
|
existing_registry = run_registry.registry_root_if_exists(Path(workspace.path))
|
|
1195
|
-
|
|
1183
|
+
pruning_runs = (
|
|
1184
|
+
parsed.subcommand == "runs"
|
|
1185
|
+
and parsed.runs is not None
|
|
1186
|
+
and parsed.runs.action == "prune"
|
|
1187
|
+
)
|
|
1188
|
+
if existing_registry is not None and not pruning_runs:
|
|
1196
1189
|
maybe_run_retention_pass(existing_registry, config)
|
|
1197
1190
|
if parsed.subcommand == "snapshot":
|
|
1198
1191
|
return emit_snapshot(parsed, workspace, stdout)
|
|
@@ -1280,8 +1273,8 @@ def main(
|
|
|
1280
1273
|
DelegateError(
|
|
1281
1274
|
exc.error,
|
|
1282
1275
|
exc.message,
|
|
1283
|
-
diagnostics=
|
|
1284
|
-
next_actions=
|
|
1276
|
+
diagnostics=exc.diagnostics,
|
|
1277
|
+
next_actions=exc.next_actions,
|
|
1285
1278
|
),
|
|
1286
1279
|
json_mode,
|
|
1287
1280
|
stdout,
|
|
@@ -32,10 +32,9 @@ from delegate_agent.constants import (
|
|
|
32
32
|
ENGINES_PROSE,
|
|
33
33
|
KNOWN_ENGINES,
|
|
34
34
|
MODELESS_ENGINES,
|
|
35
|
-
PURE_CALL_ENGINES,
|
|
36
35
|
VALID_MODES,
|
|
37
|
-
pure_call_supported,
|
|
38
36
|
validate_mode,
|
|
37
|
+
validate_pure_call,
|
|
39
38
|
)
|
|
40
39
|
from delegate_agent.errors import DelegateError
|
|
41
40
|
from delegate_agent.request_models import (
|
|
@@ -647,10 +646,6 @@ def corrected_global_argv(argv: list[str]) -> list[str]:
|
|
|
647
646
|
return [*globals_out, *rest]
|
|
648
647
|
|
|
649
648
|
|
|
650
|
-
def corrected_global_command(argv: list[str]) -> str:
|
|
651
|
-
return _shell_command(corrected_global_argv(argv))
|
|
652
|
-
|
|
653
|
-
|
|
654
649
|
def raise_misplaced_global_option(message: str, argv: list[str] | None = None) -> NoReturn:
|
|
655
650
|
guidance = (
|
|
656
651
|
"Move global options before the subcommand "
|
|
@@ -1320,22 +1315,7 @@ def _validate_pure_options(
|
|
|
1320
1315
|
return
|
|
1321
1316
|
if mode != "call":
|
|
1322
1317
|
raise DelegateError("unsupported_pure_call", "--pure only applies to call mode.")
|
|
1323
|
-
|
|
1324
|
-
raise DelegateError(
|
|
1325
|
-
"pure_conflicts_group",
|
|
1326
|
-
"--pure cannot be combined with --group; pure call is a stateless one-hop completion.",
|
|
1327
|
-
)
|
|
1328
|
-
if read_only:
|
|
1329
|
-
raise DelegateError(
|
|
1330
|
-
"pure_conflicts_read_only", "--pure cannot be combined with --read-only."
|
|
1331
|
-
)
|
|
1332
|
-
if not pure_call_supported(engine):
|
|
1333
|
-
supported = ", ".join(PURE_CALL_ENGINES)
|
|
1334
|
-
raise DelegateError(
|
|
1335
|
-
"unsupported_pure_call",
|
|
1336
|
-
f"{engine} does not support pure call mode.",
|
|
1337
|
-
next_actions=[f"Use --pure with one of: {supported}."],
|
|
1338
|
-
)
|
|
1318
|
+
validate_pure_call(engine, pure=pure, read_only=read_only, group=group)
|
|
1339
1319
|
|
|
1340
1320
|
|
|
1341
1321
|
def parse_snapshot(rest: list[str], json_mode: bool, cwd: str | None) -> ParsedCommand:
|
|
@@ -1400,7 +1380,10 @@ def parse_runs(
|
|
|
1400
1380
|
# front-ends (ps) do not report errors against flags nobody entered.
|
|
1401
1381
|
rest, json_mode = consume_json_option(rest, json_mode)
|
|
1402
1382
|
if any(command_help.is_help_token(token) for token in rest):
|
|
1403
|
-
|
|
1383
|
+
topic = "runs prune" if rest and rest[0] == "prune" else "runs"
|
|
1384
|
+
return help_command(json_mode, topic)
|
|
1385
|
+
if rest and rest[0] == "prune":
|
|
1386
|
+
return parse_runs_prune(rest[1:], json_mode, cwd)
|
|
1404
1387
|
active = False
|
|
1405
1388
|
recent = False
|
|
1406
1389
|
running = False
|
|
@@ -1488,6 +1471,37 @@ def parse_runs(
|
|
|
1488
1471
|
)
|
|
1489
1472
|
|
|
1490
1473
|
|
|
1474
|
+
def parse_runs_prune(rest: list[str], json_mode: bool, cwd: str | None) -> ParsedCommand:
|
|
1475
|
+
rest, json_mode = consume_json_option(rest, json_mode)
|
|
1476
|
+
if any(command_help.is_help_token(token) for token in rest):
|
|
1477
|
+
return help_command(json_mode, "runs prune")
|
|
1478
|
+
older_than_days = None
|
|
1479
|
+
dry_run = False
|
|
1480
|
+
i = 0
|
|
1481
|
+
while i < len(rest):
|
|
1482
|
+
token = rest[i]
|
|
1483
|
+
if token == "--older-than":
|
|
1484
|
+
value = _require_option_value(rest, i, token)
|
|
1485
|
+
older_than_days = parse_non_negative_int(value, option="runs prune --older-than")
|
|
1486
|
+
i += 2
|
|
1487
|
+
continue
|
|
1488
|
+
if token == "--dry-run":
|
|
1489
|
+
dry_run = True
|
|
1490
|
+
i += 1
|
|
1491
|
+
continue
|
|
1492
|
+
raise DelegateError("unknown_option", f"runs prune does not support option: {token}")
|
|
1493
|
+
return ParsedCommand(
|
|
1494
|
+
"runs",
|
|
1495
|
+
global_options=GlobalOptions(json_mode=json_mode, cwd=cwd),
|
|
1496
|
+
runs=inspection_commands.RunsCommand(
|
|
1497
|
+
action="prune",
|
|
1498
|
+
older_than_days=older_than_days,
|
|
1499
|
+
dry_run=dry_run,
|
|
1500
|
+
json_mode=json_mode,
|
|
1501
|
+
),
|
|
1502
|
+
)
|
|
1503
|
+
|
|
1504
|
+
|
|
1491
1505
|
def parse_ps(rest: list[str], json_mode: bool, cwd: str | None) -> ParsedCommand:
|
|
1492
1506
|
rest, json_mode = consume_json_option(rest, json_mode)
|
|
1493
1507
|
if any(command_help.is_help_token(token) for token in rest):
|
|
@@ -1982,6 +1996,10 @@ def _require_option_value(rest: list[str], index: int, option: str) -> str:
|
|
|
1982
1996
|
|
|
1983
1997
|
WorktreeOptionSpec = tuple[str, str]
|
|
1984
1998
|
|
|
1999
|
+
# Parsed worktree option values: flags store True, "str"/"group"/"status" kinds
|
|
2000
|
+
# store the validated string, and the int kinds store a parsed int.
|
|
2001
|
+
WorktreeOptionValue = str | int | bool
|
|
2002
|
+
|
|
1985
2003
|
WORKTREE_OPTION_SPECS: dict[str, dict[str, WorktreeOptionSpec]] = {
|
|
1986
2004
|
"list": {
|
|
1987
2005
|
"--harness": ("str", "harness"),
|
|
@@ -2020,7 +2038,7 @@ WORKTREE_OPTION_SPECS: dict[str, dict[str, WorktreeOptionSpec]] = {
|
|
|
2020
2038
|
|
|
2021
2039
|
|
|
2022
2040
|
def _apply_worktree_option(
|
|
2023
|
-
options: dict[str,
|
|
2041
|
+
options: dict[str, WorktreeOptionValue],
|
|
2024
2042
|
args: list[str],
|
|
2025
2043
|
index: int,
|
|
2026
2044
|
option: str,
|
|
@@ -2069,7 +2087,7 @@ def parse_worktree(rest: list[str], json_mode: bool, cwd: str | None) -> ParsedC
|
|
|
2069
2087
|
return help_command(json_mode, topic)
|
|
2070
2088
|
if action not in WORKTREE_OPTION_SPECS:
|
|
2071
2089
|
raise DelegateError("unknown_worktree_action", f"Unknown worktree action: {action}")
|
|
2072
|
-
options: dict[str,
|
|
2090
|
+
options: dict[str, WorktreeOptionValue] = {}
|
|
2073
2091
|
positional: list[str] = []
|
|
2074
2092
|
i = 0
|
|
2075
2093
|
action_specs = WORKTREE_OPTION_SPECS[action]
|
|
@@ -16,6 +16,7 @@ from dataclasses import dataclass, field
|
|
|
16
16
|
from delegate_agent import VERSION
|
|
17
17
|
from delegate_agent.constants import ENGINES_PROSE
|
|
18
18
|
from delegate_agent.json_types import JsonObject
|
|
19
|
+
from delegate_agent.run_registry import DEFAULT_RUN_PRUNE_DAYS
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
@dataclass(frozen=True)
|
|
@@ -818,7 +819,34 @@ COMMAND_SPECS: dict[str, CommandSpec] = {
|
|
|
818
819
|
"delegate runs --group wave4",
|
|
819
820
|
),
|
|
820
821
|
notes=("--active, --running, --stale, and --recent are mutually exclusive.",),
|
|
821
|
-
see_also=("ps", "snapshot", "run-output"),
|
|
822
|
+
see_also=("ps", "runs prune", "snapshot", "run-output"),
|
|
823
|
+
unsupported_global_options=("--auth-profile",),
|
|
824
|
+
),
|
|
825
|
+
"runs prune": CommandSpec(
|
|
826
|
+
name="runs prune",
|
|
827
|
+
summary="Prune old terminal Run records from the workspace Registry.",
|
|
828
|
+
usage=("delegate [--cwd PATH] [--json] runs prune [--older-than DAYS] [--dry-run]",),
|
|
829
|
+
options=(
|
|
830
|
+
OptionSpec(
|
|
831
|
+
"--older-than",
|
|
832
|
+
"DAYS",
|
|
833
|
+
f"Prune Runs older than DAYS by Registry activity time (defaults to {DEFAULT_RUN_PRUNE_DAYS}; non-negative integer).",
|
|
834
|
+
),
|
|
835
|
+
OptionSpec(
|
|
836
|
+
"--dry-run",
|
|
837
|
+
None,
|
|
838
|
+
"Report planned removals without changing the Registry, logs, or artifacts.",
|
|
839
|
+
),
|
|
840
|
+
),
|
|
841
|
+
examples=(
|
|
842
|
+
"delegate runs prune --dry-run",
|
|
843
|
+
"delegate runs prune --older-than 14",
|
|
844
|
+
),
|
|
845
|
+
notes=(
|
|
846
|
+
"Only terminal effective statuses are eligible: succeeded, failed, cancelled, and stale from a dead child; effective running Runs are always skipped.",
|
|
847
|
+
"Runs with a registered present persistent worktree are skipped, so their worktree remains manageable. Pruning removes the per-Run directory, including its Snapshot, Manifest, logs, events, and Completion Report, plus the retained raw-log archive.",
|
|
848
|
+
),
|
|
849
|
+
see_also=("runs", "snapshot", "run-output"),
|
|
822
850
|
unsupported_global_options=("--auth-profile",),
|
|
823
851
|
),
|
|
824
852
|
"ps": CommandSpec(
|
|
@@ -1745,6 +1773,7 @@ def render_overview_text() -> str:
|
|
|
1745
1773
|
"delegate [--cwd PATH] [--json] snapshot [--latest HARNESS] [--no-redact] <handle>",
|
|
1746
1774
|
"delegate [--cwd PATH] [--json] runs "
|
|
1747
1775
|
"[--active|--running|--stale|--recent] [--harness HARNESS] [--limit N]",
|
|
1776
|
+
"delegate [--cwd PATH] [--json] runs prune [--older-than DAYS] [--dry-run]",
|
|
1748
1777
|
"delegate [--cwd PATH] [--json] ps [--harness HARNESS] [--group NAME] [--limit N]",
|
|
1749
1778
|
"delegate [--cwd PATH] [--json] run-output <handle> "
|
|
1750
1779
|
"[--completion-report] [--stdout] [--stderr] [--tail N] [--max-chars N] "
|
|
@@ -821,11 +821,9 @@ def _reject_opencode_flag_like_value(
|
|
|
821
821
|
def _reject_pi_family_flag_like_value(value: JsonValue, *, path: str, error: str) -> None:
|
|
822
822
|
if value is None:
|
|
823
823
|
return
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
f"{path} must be a non-empty string that does not start with '-'.",
|
|
828
|
-
)
|
|
824
|
+
_reject_opencode_flag_like_value(value, path=path, error=error)
|
|
825
|
+
if not isinstance(value, str):
|
|
826
|
+
return
|
|
829
827
|
if ":" in value:
|
|
830
828
|
raise ConfigError(
|
|
831
829
|
error,
|
{delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/config_commands.py
RENAMED
|
@@ -23,10 +23,14 @@ class ConfigCommand:
|
|
|
23
23
|
PROFILE_CONFIG_NAMES = delegate_config.PROFILE_CONFIG_NAMES
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
def
|
|
26
|
+
def target_config_path() -> Path:
|
|
27
|
+
"""Resolve the config path, rejecting Windows-style paths under WSL."""
|
|
27
28
|
raw = delegate_config.config_path()
|
|
28
29
|
if wsl.should_reject_windows_path(str(raw)):
|
|
29
|
-
raise DelegateError(
|
|
30
|
+
raise DelegateError(
|
|
31
|
+
"windows_path",
|
|
32
|
+
wsl.windows_path_message(delegate_config.CONFIG_ENV, str(raw)),
|
|
33
|
+
)
|
|
30
34
|
return raw
|
|
31
35
|
|
|
32
36
|
|
|
@@ -94,7 +98,7 @@ def _validated_effective_config(config: JsonObject) -> JsonObject:
|
|
|
94
98
|
def emit(command: ConfigCommand, stdout: TextIO) -> int:
|
|
95
99
|
if command.action not in {"init", "sync-profiles"}:
|
|
96
100
|
raise DelegateError("invalid_config_command", f"Unknown config action: {command.action}")
|
|
97
|
-
path =
|
|
101
|
+
path = target_config_path()
|
|
98
102
|
if command.action == "sync-profiles":
|
|
99
103
|
if not path.exists():
|
|
100
104
|
raise DelegateError(
|
|
@@ -53,6 +53,30 @@ def pure_call_supported(engine: str) -> bool:
|
|
|
53
53
|
return engine == "claude"
|
|
54
54
|
|
|
55
55
|
|
|
56
|
+
def validate_pure_call(
|
|
57
|
+
engine: str, *, pure: bool, read_only: bool, group: str | None = None
|
|
58
|
+
) -> None:
|
|
59
|
+
"""Reject --pure combinations that conflict with its stateless one-hop contract."""
|
|
60
|
+
if not pure:
|
|
61
|
+
return
|
|
62
|
+
if group is not None:
|
|
63
|
+
raise DelegateError(
|
|
64
|
+
"pure_conflicts_group",
|
|
65
|
+
"--pure cannot be combined with --group; pure call is a stateless one-hop completion.",
|
|
66
|
+
)
|
|
67
|
+
if read_only:
|
|
68
|
+
raise DelegateError(
|
|
69
|
+
"pure_conflicts_read_only", "--pure cannot be combined with --read-only."
|
|
70
|
+
)
|
|
71
|
+
if not pure_call_supported(engine):
|
|
72
|
+
supported = ", ".join(PURE_CALL_ENGINES)
|
|
73
|
+
raise DelegateError(
|
|
74
|
+
"unsupported_pure_call",
|
|
75
|
+
f"{engine} does not support pure call mode.",
|
|
76
|
+
next_actions=[f"Use --pure with one of: {supported}."],
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
|
|
56
80
|
# Public harness capability contract. Request validation and describe output both
|
|
57
81
|
# derive from this map so enabling a capability cannot drift between the two.
|
|
58
82
|
ENGINE_CAPABILITIES = {
|
{delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/describe_payload.py
RENAMED
|
@@ -48,14 +48,12 @@ from delegate_agent.constants import (
|
|
|
48
48
|
from delegate_agent.errors import EXIT_OK, DelegateError
|
|
49
49
|
from delegate_agent.json_types import JsonObject
|
|
50
50
|
from delegate_agent.prompt_transport import (
|
|
51
|
-
DEVIN_AGENT_CONFIG_ARG_PLACEHOLDER,
|
|
52
|
-
DEVIN_AGENT_CONFIG_DISPLAY,
|
|
53
51
|
DROID_PROMPT_FILE_DISPLAY,
|
|
54
|
-
PROMPT_FILE_ARG_PLACEHOLDER,
|
|
55
|
-
PROMPT_FILE_DISPLAY,
|
|
56
52
|
PROMPT_TRANSPORT_ARGV,
|
|
57
53
|
PROMPT_TRANSPORT_FILE,
|
|
58
54
|
PROMPT_TRANSPORT_STDIN,
|
|
55
|
+
devin_display_argv,
|
|
56
|
+
prompt_file_display_argv,
|
|
59
57
|
)
|
|
60
58
|
from delegate_agent.request_build import OPENCODE_SAFE_AGENT, _resolve_default_model
|
|
61
59
|
|
|
@@ -718,7 +716,7 @@ def _grok_describe_argv(
|
|
|
718
716
|
policy,
|
|
719
717
|
allow_bypass_permissions=_grok_harness_bypass_enabled(config, mode),
|
|
720
718
|
)
|
|
721
|
-
return
|
|
719
|
+
return prompt_file_display_argv(argv)
|
|
722
720
|
|
|
723
721
|
|
|
724
722
|
def _devin_describe_argv(
|
|
@@ -730,14 +728,7 @@ def _devin_describe_argv(
|
|
|
730
728
|
_resolve_default_model(devin),
|
|
731
729
|
call_read_only=call_read_only,
|
|
732
730
|
)
|
|
733
|
-
return
|
|
734
|
-
DEVIN_AGENT_CONFIG_DISPLAY
|
|
735
|
-
if item == DEVIN_AGENT_CONFIG_ARG_PLACEHOLDER
|
|
736
|
-
else PROMPT_FILE_DISPLAY
|
|
737
|
-
if item == PROMPT_FILE_ARG_PLACEHOLDER
|
|
738
|
-
else item
|
|
739
|
-
for item in argv
|
|
740
|
-
]
|
|
731
|
+
return devin_display_argv(argv)
|
|
741
732
|
|
|
742
733
|
|
|
743
734
|
def _kimi_describe_argv(kimi: JsonObject, *, mode: str) -> list[str]:
|
|
@@ -774,7 +765,7 @@ def _opencode_describe_argv(
|
|
|
774
765
|
if isinstance(opencode.get("defaultReasoningEffort"), str)
|
|
775
766
|
else None,
|
|
776
767
|
)
|
|
777
|
-
return
|
|
768
|
+
return prompt_file_display_argv(argv)
|
|
778
769
|
|
|
779
770
|
|
|
780
771
|
def _pi_family_describe_argv(section: JsonObject, engine: str, *, mode: str) -> list[str]:
|
{delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/harness_discovery.py
RENAMED
|
@@ -19,13 +19,17 @@ from collections.abc import Callable, Collection, Mapping
|
|
|
19
19
|
from dataclasses import dataclass
|
|
20
20
|
from datetime import UTC, datetime
|
|
21
21
|
from pathlib import Path
|
|
22
|
-
from typing import BinaryIO, TextIO
|
|
22
|
+
from typing import BinaryIO, TextIO, TypeAlias
|
|
23
23
|
|
|
24
24
|
from delegate_agent import config as delegate_config
|
|
25
25
|
from delegate_agent import private_io, profiles, redaction
|
|
26
26
|
from delegate_agent.constants import KNOWN_ENGINES
|
|
27
27
|
from delegate_agent.json_types import JsonObject
|
|
28
28
|
|
|
29
|
+
# A refresh-progress callback: called with each harness name before its probe
|
|
30
|
+
# spawns. Shared by every caller that threads a progress hook into discovery.
|
|
31
|
+
ProgressCallback: TypeAlias = Callable[[str], None]
|
|
32
|
+
|
|
29
33
|
DISCOVERY_SCHEMA = 1
|
|
30
34
|
PROBE_STATUSES = frozenset({"ok", "partial", "missing", "error"})
|
|
31
35
|
MODEL_SCOPES = frozenset({"account", "configured", "catalog", "unknown"})
|
|
@@ -1364,7 +1368,7 @@ def probe_harness(
|
|
|
1364
1368
|
)
|
|
1365
1369
|
|
|
1366
1370
|
|
|
1367
|
-
def stderr_probe_progress(stream: TextIO | None = None) ->
|
|
1371
|
+
def stderr_probe_progress(stream: TextIO | None = None) -> ProgressCallback:
|
|
1368
1372
|
"""Return a progress callback that names each harness as probing starts.
|
|
1369
1373
|
|
|
1370
1374
|
Every probe is bounded by ``METADATA_PROBE_TIMEOUT_SEC``, so a wedged
|
|
@@ -1384,7 +1388,7 @@ def probe_all_harnesses(
|
|
|
1384
1388
|
*,
|
|
1385
1389
|
env: Mapping[str, str],
|
|
1386
1390
|
factory_settings_path: Path | None = None,
|
|
1387
|
-
progress:
|
|
1391
|
+
progress: ProgressCallback | None = None,
|
|
1388
1392
|
) -> JsonObject:
|
|
1389
1393
|
records: JsonObject = {}
|
|
1390
1394
|
for harness in KNOWN_ENGINES:
|
|
@@ -1603,7 +1607,7 @@ def refresh_discovery(
|
|
|
1603
1607
|
home: Path | None = None,
|
|
1604
1608
|
factory_settings_path: Path | None = None,
|
|
1605
1609
|
persist: bool = True,
|
|
1606
|
-
progress:
|
|
1610
|
+
progress: ProgressCallback | None = None,
|
|
1607
1611
|
) -> JsonObject:
|
|
1608
1612
|
"""Probe harnesses, optionally persisting successful last-known-good records."""
|
|
1609
1613
|
if isinstance(engines, str):
|
{delegate_agent_cli-0.21.0 → delegate_agent_cli-0.23.0}/src/delegate_agent/inspection_commands.py
RENAMED
|
@@ -19,12 +19,15 @@ class SnapshotCommand:
|
|
|
19
19
|
|
|
20
20
|
@dataclass(frozen=True)
|
|
21
21
|
class RunsCommand:
|
|
22
|
+
action: str | None = None
|
|
22
23
|
active: bool = False
|
|
23
24
|
running: bool = False
|
|
24
25
|
stale: bool = False
|
|
25
26
|
harness: str | None = None
|
|
26
27
|
group: str | None = None
|
|
27
28
|
limit: int | None = None
|
|
29
|
+
older_than_days: int | None = None
|
|
30
|
+
dry_run: bool = False
|
|
28
31
|
json_mode: bool = False
|
|
29
32
|
|
|
30
33
|
|
|
@@ -64,6 +67,34 @@ def emit_snapshot(command: SnapshotCommand, *, workspace_path: str, stdout: Text
|
|
|
64
67
|
|
|
65
68
|
def emit_runs(command: RunsCommand, *, workspace_path: str, stdout: TextIO) -> int:
|
|
66
69
|
registry_root = run_registry.registry_root_if_exists(Path(workspace_path))
|
|
70
|
+
if command.action == "prune":
|
|
71
|
+
older_than_days = (
|
|
72
|
+
command.older_than_days
|
|
73
|
+
if command.older_than_days is not None
|
|
74
|
+
else run_registry.DEFAULT_RUN_PRUNE_DAYS
|
|
75
|
+
)
|
|
76
|
+
payload = (
|
|
77
|
+
run_registry.prune_runs(
|
|
78
|
+
registry_root,
|
|
79
|
+
older_than_days=older_than_days,
|
|
80
|
+
dry_run=command.dry_run,
|
|
81
|
+
)
|
|
82
|
+
if registry_root is not None
|
|
83
|
+
else run_registry.empty_run_prune_payload(
|
|
84
|
+
older_than_days=older_than_days,
|
|
85
|
+
dry_run=command.dry_run,
|
|
86
|
+
)
|
|
87
|
+
)
|
|
88
|
+
if command.json_mode:
|
|
89
|
+
delegate_rendering.print_json(payload, stdout)
|
|
90
|
+
else:
|
|
91
|
+
delegate_rendering.render_runs_prune_text(payload, stdout)
|
|
92
|
+
if payload.get("ok") is False:
|
|
93
|
+
exit_code = payload.get("exitCode")
|
|
94
|
+
return exit_code if isinstance(exit_code, int) else 1
|
|
95
|
+
return 0
|
|
96
|
+
if command.action is not None:
|
|
97
|
+
raise InspectionError("unknown_runs_action", f"Unknown runs action: {command.action}")
|
|
67
98
|
limit = command.limit or run_registry.DEFAULT_RUNS_LIMIT
|
|
68
99
|
if command.running:
|
|
69
100
|
mode = "running"
|
|
@@ -275,13 +275,8 @@ def preflight_codex_home(codex_home: str, *, codex: JsonObject) -> None:
|
|
|
275
275
|
)
|
|
276
276
|
|
|
277
277
|
|
|
278
|
-
def _request_resolution(request: object) -> ProfileResolution:
|
|
279
|
-
resolution = getattr(request, "profile_resolution", None)
|
|
280
|
-
return resolution if resolution is not None else empty_profile_resolution()
|
|
281
|
-
|
|
282
|
-
|
|
283
278
|
def preflight_codex_request(request: object, codex_config: JsonObject) -> None:
|
|
284
|
-
resolution =
|
|
279
|
+
resolution: ProfileResolution = request.profile_resolution # type: ignore[attr-defined]
|
|
285
280
|
if resolution.name is not None and resolution.codex_home is None:
|
|
286
281
|
raise DelegateError(
|
|
287
282
|
"profile_missing_codex_home",
|