Skip to content

fix(agent): enforce repair deadline in flight and thread graph delivery control (#206) - #335

Merged
yuluo-yx merged 2 commits into
agentic-ai-java:mainfrom
XianReallyHot-ZZH:fix/206-active-repair-deadline-and-graph-control
Oct 30, 2026
Merged

yuluo-yx merged 2 commits into
agentic-ai-java:mainfrom
XianReallyHot-ZZH:fix/206-active-repair-deadline-and-graph-control

Conversation

@XianReallyHot-ZZH

Copy link
Copy Markdown
Contributor

确认 (Acknowledged) contribution to ARGI: slice the in-flight structured-output repair wait so the remaining deadline actively cancels a never-returning underlying request through the onLoss registration, and thread the graph ReactAgent callResult/streamResult delivery through the run execution boundaries — the config own control passes through, a trusted deadline plus execution guard bridge onto a delivery-owned control, a bare guard governs the re-ask directly — so a stop during the final repair delivers INTERRUPTED instead of COMPLETED or VALIDATION_FAILED, widening the unreleased control overload from ExecutionControl to the neutral ExecutionGuard, for #206.

…ry control (agentic-ai-java#206)

The structured-output repair wait is sliced so the remaining deadline is
actively enforced while the response is still pending: a request that
never returns is cancelled through the onLoss registration once the
deadline expires, instead of relying on the control to produce a stop
notification or on an external get(timeout). The graph ReactAgent
delivery now travels with the run's execution boundaries: the config's
own control passes through unchanged, a trusted deadline plus execution
guard combine into a delivery-owned control, and a bare guard governs
the re-ask directly, so a stop during the callResult/streamResult final
repair delivers INTERRUPTED instead of COMPLETED or VALIDATION_FAILED.
The unreleased control overload widens from ExecutionControl to the
neutral ExecutionGuard so the graph path can bridge without the
finalizer depending on graph types.
…ess (agentic-ai-java#206)

A bare execution guard whose assertActive throws a plain RuntimeException
(the framework's own checkpoint lease throws LeaseLostException) no longer
degrades to a marked repair failure or escapes the delivery as an
execution error: attemptRepair re-asserts the guard before treating a
call failure as the client's own, and the graph delivery boundary
re-checks the guard to classify stop-shaped failures as INTERRUPTED.
The boundary also asserts liveness before publishing, so an already
cancelled, expired or ownership-lost run cannot deliver a COMPLETED
output even when the terminal message is schema-valid and needs no
repair. ExecutionGuard gains a default deadline() accessor (overridden
by ExecutionControl) so the repair wait is sliced only when a deadline
actually bounds it — a deadline-less guard goes back to a plain wait
instead of polling idle — and the graph bridge reuses the canonical
AgentExecutionContext scope instead of re-implementing the wrap.
Deterministic regression tests cover a lease-style guard lost during
the repair and an expired trusted deadline with a valid terminal.
@XianReallyHot-ZZH

Copy link
Copy Markdown
Contributor Author

Review follow-up pushed (4b0f434), from a self-run two-axis review of the PR diff before requesting another look. Four confirmed defects on paths the first round of tests did not cover, now closed with regression coverage:

  1. Lease-style guard stops were misclassified. A bare guard whose assertActive() throws a plain RuntimeException (the framework checkpoint lease throws LeaseLostException) folded a mid-flight stop into VALIDATION_FAILED + ERROR_CODE_REPAIR_CALL_FAILED and let a pre/post-repair stop escape the delivery as ERROR_CODE_EXECUTION_FAILED. attemptRepair now re-asserts the guard before treating a call failure as the client own, and the delivery boundary re-checks the guard to classify stop-shaped failures as INTERRUPTED. New test: leaseStyleGuardLostDuringGraphRepairInterruptsDelivery.
  2. Delivery liveness unchecked on no-repair paths. An already cancelled/expired run with a schema-valid terminal delivered COMPLETED. The boundary now asserts before publishing. New test: expiredDeadlineStopsDeliveryOfAValidOutput.
  3. Deadline-less spin. With no deadline the sliced wait woke ~40x/s forever; ExecutionGuard gains a default deadline() (overridden by ExecutionControl) and the wait is sliced only when a deadline actually bounds it — otherwise back to a plain wait, since every stop path fires onLoss synchronously.
  4. Bridge cleanup. The graph bridge reuses the canonical AgentExecutionContext scope instead of re-implementing the trusted+guard wrap, and the redundant third delivery branch is collapsed.

Known follow-ups deliberately kept out of this PR (pre-existing, broader than the #206 delivery boundary): the main model call still uses plain callBlocking with no guard integration, graph-phase stops classify as ERROR while repair-phase stops classify as INTERRUPTED, and a trusted-only deadline still bounds only the delivery leaf, not the whole graph run. Happy to take those in a separate issue/PR if maintainers agree they belong on the roadmap.

Full reactor build green (local; the two LocalFilesystemBackend* test classes were excluded — they require a ripgrep binary that CI installs separately).

@yuluo-yx yuluo-yx left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM thanks for you

@yuluo-yx
yuluo-yx merged commit afe8009 into agentic-ai-java:main Oct 30, 2026
7 checks passed
@XianReallyHot-ZZH
XianReallyHot-ZZH deleted the fix/206-active-repair-deadline-and-graph-control branch November 7, 2026 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants