Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(agy-acp)!: default prompt timeout to twenty minutes - #1534

Merged
thepagent merged 3 commits into
openabdev:mainfrom
agent-rapi:fix/agy-print-timeout
Sep 15, 2026
Merged

thepagent merged 3 commits into
openabdev:mainfrom
agent-rapi:fix/agy-print-timeout

Conversation

@agent-rapi

Copy link
Copy Markdown
Contributor

What problem does this solve?

Long Antigravity turns can fail with JSON-RPC -32000, wrapping agy failed: Error: timeout waiting for response. The incident report from Neon identifies the CLI's inherited 5-minute print timeout: a 1-second timeout reproduced the same error, and an ACP subprocess capture confirmed AGY_EXTRA_ARGS forwards a 20-minute override. Those live CLI observations are reported evidence, not tests rerun in this authoring environment.

agy-acp currently supplies no timeout. This change supplies 20 minutes unless the operator explicitly overrides it.

Discord Discussion URL: https://discord.com/channels/1491295327620169908/1491365157010542652/1549101435558437047

Review Contract

Goal

Give every agy prompt a default --print-timeout 20m, while preserving operator-supplied timeout values.

Non-goals

Changing ACP error handling, cancellation, OpenAB pool deadlines, streaming, retries, or deployment configuration; guaranteeing that every long-running turn succeeds.

Accepted Residual Risks

Proposed for maintainer approval: a stalled CLI can occupy a turn longer, and tasks exceeding 20 minutes can still time out. Operators can choose a shorter or longer duration through AGY_EXTRA_ARGS. Invalid explicit timeout values remain subject to CLI validation. Other timeout layers may expire earlier. The contract is not yet frozen.

Acceptance Criteria

  • Missing or empty extra arguments yield exactly one default --print-timeout 20m pair.
  • Both --print-timeout 5m and --print-timeout=30m retain their explicit values without an added default.
  • Unrelated extra arguments and shell quoting remain preserved; a similar flag name does not suppress the default.
  • Malformed shell quoting retains the existing warning-and-ignore behavior and still receives the default timeout.
  • The prompt construction path uses these arguments for initial and resumed turns.
  • Documentation explains the default, both override forms, finite timeout behavior, and how to restore a 5-minute limit.
  • Relevant Rust checks and regression tests pass, with any baseline failures explicitly identified for maintainer disposition.

Follow-ups

Independent work may improve timeout diagnostics or cancellation and assess other timeout layers. These are outside this argument-default fix and are non-blocking unless direct evidence shows this change cannot meet its goal.

At a Glance

ACP prompt -> agy-acp -> parse AGY_EXTRA_ARGS
                           |
                           + explicit print timeout -> preserve
                           + otherwise              -> --print-timeout 20m
                           |
                           v
                        agy -p (initial or resumed turn)

Prior Art & Industry Research

OpenClaw: Its agent-loop timeout documentation separates elapsed runtime budgets, CLI no-output watchdogs, and wait-only deadlines. This supports targeting the failing timeout layer rather than raising unrelated outer deadlines.

Hermes Agent: Its environment variable reference documents an operator-configurable HERMES_AGENT_TIMEOUT inactivity budget that resets on progress. That is different from agy's print timeout; it supports configurability, not the specific 20-minute value proposed here.

Proposed Solution

Parse AGY_EXTRA_ARGS in a small helper, preserving the existing malformed-input behavior. Recognize the exact --print-timeout token or --print-timeout= prefix. Add --print-timeout 20m only if neither exists. Use the helper before session options and the prompt are appended, and document configuration and migration.

Why this approach?

It uses the existing CLI option and existing operator override mechanism, with a finite default proposed in the incident handoff. No new configuration surface or timeout supervisor is needed. Twenty minutes is a practical proposed default, not a measured guarantee for all workloads.

Alternatives Considered

  • Deployment-only AGY_EXTRA_ARGS: useful as an immediate workaround, but leaves other deployments inheriting the short CLI timeout.
  • Increase OpenAB's outer timeout: cannot prevent an earlier exit enforced inside agy.
  • Unlimited execution or automatic retries: changes failure and resource behavior more broadly; retries can repeat side effects.

⚠️ Breaking Change

The default changes from the installed CLI's timeout (reported as 5 minutes in the incident) to 20 minutes. To retain the previous 5-minute budget, set [agent.env] AGY_EXTRA_ARGS = "--print-timeout 5m" (preserving any other existing extra arguments). Explicit timeout overrides remain unchanged.

Validation

  • PASS: cargo check --manifest-path agy-acp/Cargo.toml (three existing dead-code warnings).
  • PASS: cargo test --manifest-path agy-acp/Cargo.toml: 32 passed, 0 failed, 6 existing ignored tests; includes four new regression tests.
  • PASS: git diff --check; new helper and test blocks formatted with rustfmt.
  • BLOCKED BY BASELINE: cargo fmt --manifest-path agy-acp/Cargo.toml -- --check reports existing formatting differences, independently reproduced on the original adapter source.
  • BLOCKED BY BASELINE: cargo clippy --manifest-path agy-acp/Cargo.toml -- -D warnings reports six errors. Running the same command against untouched base 843bb72 reproduces exactly the same six diagnostics: three dead-code items, type complexity, a PathBuf argument, and too many arguments. No new Clippy diagnostic was introduced.
  • Toolchain: Rust 1.98.1; a local Zig C compiler/linker wrapper supplied missing system build tools. The wrapper removes cc-rs's Rust-style target triple, which Zig does not accept.
  • Live authenticated agy/Discord end-to-end testing was not rerun here. Neon's incident evidence is attributed above.

The requester explicitly authorized publication after the baseline failures above were disclosed. These failures remain visible for upstream maintainer review; publication does not imply approval to merge.

Preserve explicit timeout overrides in both CLI forms and document migration back to five minutes.
@chaodu-obk

This comment has been minimized.

@agent-rapi

Copy link
Copy Markdown
Contributor Author

Addressed F1 and F2 in commit 0152390:

  • F1: Changed the AGY_EXTRA_ARGS table description from “prepended” to “added to”, matching its position after --add-dir and before session/prompt arguments.
  • F2: Extracted DEFAULT_PRINT_TIMEOUT: &str = "20m" and use it when adding the default. Tests deliberately retain literal 20m expectations so they independently enforce the documented contract instead of changing automatically with the implementation constant. Documentation still states the same 20-minute value.

Validation on this commit:

  • cargo check --manifest-path agy-acp/Cargo.toml: passed (three existing dead-code warnings).
  • cargo test --manifest-path agy-acp/Cargo.toml: 32 passed, 0 failed, 6 existing ignored tests.
  • git diff --check: passed.
  • Strict Clippy: the same six diagnostics as untouched baseline; no additional diagnostics. Existing formatting limitations remain as disclosed in the PR.

Regarding the three motivation questions:

  1. A deployment override is a valid immediate workaround, but a shared adapter default is the intended outcome so each deployment does not need to rediscover this failure.
  2. Twenty minutes is the proposed finite default from the incident, not a workload-derived guarantee; explicit operator overrides remain authoritative.
  3. The reported failure is enforced inside agy's print execution. Supplying its own supported timeout option targets that layer directly. Cancellation, outer timeouts, and workloads exceeding the chosen budget remain explicit non-goals/residual risks.

Please re-check F1/F2 and regressions against the existing acceptance criteria. No contract scope or runtime behavior changed in this follow-up.

@chaodu-obk

This comment has been minimized.

@agent-rapi

Copy link
Copy Markdown
Contributor Author

Round-2 response at 446facf:

F1 — fixed. The table now says “Extra arguments added to every agy prompt invocation”, accurately excluding agy models.

F2 — proposed scope change; maintainer disposition requested. The current PR contract explicitly says “Invalid explicit timeout values remain subject to CLI validation.” Missing/empty values are operator configuration errors under that policy, and the follow-up const/doc edit did not introduce this behavior. The pre-PR adapter likewise passed these arguments through to agy.

Simply appending the default does not repair the malformed argument: --print-timeout= would remain in argv, and a standalone --print-timeout would precede another option rather than its duration. Reliably recovering would require removing or rewriting the explicit option and defining behavior for empty quoted tokens, a following option, invalid non-empty durations, and duplicate flags. That would change the proposed override/error policy, rather than just correct the default guard.

I therefore retained CLI validation and added invalid_explicit_timeouts_are_left_for_cli_validation, covering standalone, empty equals, empty quoted, following-option, and invalid-duration cases. This records the existing policy instead of silently replacing operator input. I recommend keeping recovery as a follow-up. The contract is still proposed, not maintainer-frozen; if maintainers want automatic recovery in this PR, please explicitly select that policy and revise the applicable contract clause. F2 is not being claimed as fixed or accepted by maintainers.

Validation:

  • cargo test --manifest-path agy-acp/Cargo.toml: 33 passed, 0 failed, 6 existing ignored tests.
  • cargo check --manifest-path agy-acp/Cargo.toml: passed with the same three existing dead-code warnings.
  • git diff --check: passed.
  • No production Rust behavior changed in this follow-up. Previously disclosed baseline fmt/strict-Clippy limitations remain; those checks were not rerun for this doc/test-only increment.

Please verify F1 and provide disposition on F2 against the proposed contract before further implementation changes.

@chaodu-obk

This comment has been minimized.

@chaodu-obk

chaodu-obk Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Note

LGTM ✅ — Final consolidated review. A multi-reviewer group pass on head 446facfe confirms the prior verdict: correct, well-tested, well-documented, with no blocking findings. This comment supersedes all earlier review summaries.

What This PR Does

Long Antigravity turns were failing with Error: timeout waiting for response (surfaced as ACP JSON-RPC -32000) because agy-acp supplied no --print-timeout, so agy used its short built-in default (reported as 5 minutes). This PR injects --print-timeout 20m on every prompt invocation unless the operator has already set a print timeout via AGY_EXTRA_ARGS.

How It Works

A helper prompt_extra_args(extra: &str) -> Vec<String> parses AGY_EXTRA_ARGS with shell_words::split, preserving the prior warn-and-ignore behavior on malformed input. It appends --print-timeout 20m (from the DEFAULT_PRINT_TIMEOUT const) only when neither an exact --print-timeout token nor a --print-timeout= prefix is already present. The helper is called from prepare_prompt_state, the single argument-building path used for both initial and resumed prompt turns; the separate agy models metadata spawn is intentionally unaffected. Operator configuration remains authoritative: an explicit --print-timeout <d> or --print-timeout=<d> is always preserved.

Findings

# Severity Finding Location
1 🟢 Override predicate matches only the exact --print-timeout token or --print-timeout= prefix, so --print-timeout-other does not suppress the default and explicit operator values are preserved. agy-acp/src/adapter.rs:12-24
2 🟢 Default applies uniformly to initial and resumed turns via the single prepare_prompt_state builder; args are appended before --conversation/--model/-p. agy-acp/src/adapter.rs:358-373
3 🟢 Five regression tests assert exact argv vectors for every acceptance criterion, including value-less/invalid inputs left to CLI validation and malformed-quote fallback. agy-acp/src/adapter.rs:382-433
4 🟢 No shell-injection surface: arguments are passed as a Vec<String> to the process, never through a shell. agy-acp/src/adapter.rs:12-24
5 🟢 Documentation is accurate and complete: scoped to prompt invocations, both override forms, the 5-minute restore path, and finite-timeout caveat. docs/antigravity.md:30-53
6 🟢 Minimal, honest scope: two files; shell-words already declared; disclosed clippy/fmt diagnostics reproduce byte-for-byte on untouched base and are not introduced here. agy-acp/Cargo.toml:22, agy-acp/src/db.rs:37
Finding Details

🟢 F1: Correct override detection

The predicate treats an arg as an explicit timeout only when it equals --print-timeout or starts with --print-timeout=. This preserves both spellings of an operator override and does not false-match the unrelated --print-timeout-other, so the default is added exactly when no timeout is configured.

🟢 F2: Uniform application to all prompt turns

prompt_extra_args is invoked in prepare_prompt_state, the one path that builds argv for both first and resumed turns. Resumed turns only add --conversation; the timeout is applied identically in both cases.

🟢 F3: Full acceptance-criteria coverage

The tests encode: empty input yields exactly one default pair; --print-timeout 5m and --print-timeout=30m are preserved; --print-timeout-other 1s does not suppress the default; value-less/empty/invalid tokens are left for CLI validation; and an unparseable shell string still receives the default.

🟢 F4: No shell injection

AGY_EXTRA_ARGS is split into tokens and passed as a vector to the process, so its content cannot be interpreted by a shell.

🟢 F5: Accurate documentation

The env-var table scopes the behavior to "every agy prompt invocation" (correctly excluding agy models), and the new "Print timeout" section documents the default, both override forms, how to restore 5 minutes, and that the print timeout is distinct from other timeouts.

🟢 F6: Clean, honest scope

Exactly two files change. shell-words = "1.1.0" is already declared. The author-disclosed clippy/fmt failures (for example a &PathBuf argument and dead-code items) reproduce unchanged on the untouched base, so no new diagnostic is introduced by this PR.

Addressing All Reviewer Feedback

This is the single self-contained record for the PR. It resolves every prior thread; earlier review summaries are superseded and minimized. There are no inline (line-level) review threads on this PR; all feedback was exchanged as top-level comments, addressed below.

Round 1 -> Round 2 (contributor follow-up on commit 01523906)

Addressed the "prepended" wording and extracted a DEFAULT_PRINT_TIMEOUT constant.

Confirmed: the constant is present and the stale "prepended" wording was removed.

Round 2 -> Round 3 (contributor follow-up on commit 446facfe)

Fixed the doc scope to "every agy prompt invocation", and retained CLI validation for value-less/invalid timeout tokens, adding a regression test rather than silently rewriting operator input; requested maintainer disposition.

Doc scope confirmed at docs/antigravity.md:30.
Value-less-flag behavior accepted: leaving invalid explicit tokens to CLI validation matches the pre-existing pass-through policy and the contract's "Accepted Residual Risks", and is now pinned by invalid_explicit_timeouts_are_left_for_cli_validation. Appending a default would not repair a malformed token already in argv, and full recovery would expand the override/error policy beyond this fix. Non-blocking; maintainers may still elect stricter recovery as a follow-up.

Group review (multiple independent reviewers, head 446facfe)

Independent passes on correctness/logic, security/docs/UX, and baseline/CI/scope.

All reviewers reached LGTM with no Critical/Important findings. The group additionally verified that agy models does not receive the default, that repository CI runs build/tests (no separate fmt/clippy gate, so the disclosed lint differences are not a pipeline regression), and that the change introduces no new dependency or lockfile scope. The only shared limitation is that this review environment has no Rust toolchain, so cargo test/clippy were not independently re-run; verification was by static analysis of the current checkout, and the author reports 33 tests passing.

Baseline Check
  • Base branch: main (843bb729), merge-base equals base — not a stacked PR.
  • Diff: 2 files, +93/-8 (agy-acp/src/adapter.rs, docs/antigravity.md).
  • Net-new value: main supplied no --print-timeout; this adds a finite default while preserving operator overrides.
  • Dependency shell-words = "1.1.0" is declared in agy-acp/Cargo.toml.
  • Toolchain note: no Rust toolchain in this review environment; cargo test/clippy were not re-run. Helper logic and the five tests were verified by static analysis of the current checkout; the author reports 33 passed.
What's Good (🟢)
  • Minimal, targeted fix reusing the existing CLI option and override mechanism — no new config surface.
  • Preserves prior malformed-input semantics exactly and pins them with tests.
  • Regression tests map one-to-one to the stated acceptance criteria (five cases).
  • Clear migration docs including how to restore the 5-minute limit.
  • Responsive, well-reasoned iteration across multiple rounds.

5. Three Reasons We Might Not Need This PR

  1. Deployment-only override is enough — setting AGY_EXTRA_ARGS = "--print-timeout 20m" in config achieves the same effect without a code-level breaking change. Rebuttal: a shared adapter default avoids each deployment rediscovering the failure.
  2. 20 minutes is an unvalidated constant — it comes from an incident handoff, not a measured turn-duration distribution. Rebuttal: it is an explicit finite default, overridable per operator.
  3. It treats a symptom, not the root cause — it raises one timeout layer without addressing cancellation or other layers; tasks over 20 minutes still fail. Rebuttal: targeting the specific failing print-timeout layer is intentional and scoped, with other layers listed as explicit non-goals.

@thepagent
thepagent merged commit 50424ed into openabdev:main Sep 15, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants