Skip to content

fix(tools): abort retries on cancel#52

Merged
mudler merged 1 commit into
mainfrom
fix/sinkstate-and-cancel
Jun 2, 2026
Merged

fix(tools): abort retries on cancel#52
mudler merged 1 commit into
mainfrom
fix/sinkstate-and-cancel

Conversation

@mudler

@mudler mudler commented Jun 2, 2026

Copy link
Copy Markdown
Owner

Cancellation responsiveness: the decision()/decisionWithStreaming() retry loops retried on any error (including context.Canceled) and slept the backoff non-cancellably between attempts. Bail out the moment the context is cancelled (check ctx.Err() each attempt + context-aware backoffOrCancel), so a cancelled in-flight LLM call surfaces context.Canceled promptly instead of sleeping through the full backoff.

Adds a unit test asserting ExecuteTools aborts an in-flight call on cancel. Branched off the commit wiz pins (67811fa) so it is testable end-to-end with wiz.

ExecuteTools' retry loops slept on a non-cancellable
time.Sleep(attempts+1 seconds) backoff and re-issued the LLM call even
after the caller's context was cancelled. A Ctrl+C therefore took up to
several seconds to take effect because an in-flight/retrying call kept
running through the backoff before noticing cancellation.

Add a backoffOrCancel(ctx, attempt) helper that waits the backoff but
returns ctx.Err() immediately when the context is done, and check
ctx.Err() at the top of each retry loop. The interrupt now propagates in
~0.3s.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mudler mudler merged commit d7c169e into main Jun 2, 2026
mudler added a commit that referenced this pull request Jun 2, 2026
Go 1.25's gofmt expands a single-line function body that earlier versions
left inline, so the repo-wide `go fmt ./...` CI check failed on this file
(inherited from #52). No behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mudler added a commit that referenced this pull request Jun 2, 2026
…rn ends (#53)

* fix(agent): keep detached/background sub-agents alive after parent turn ends

A sub-agent's context was a child of the parent turn context (r.ctx), so
when an embedder cancelled its per-turn context right after ExecuteTools
returned — the normal end-of-turn cleanup — a just-detached (or
background) agent was cancelled too, defeating the whole point of
detaching.

Parent the sub-agent context off context.WithoutCancel(r.ctx): it keeps
the context's values but no longer propagates the parent's cancellation.
Foreground cancellation is unaffected because the foreground select
already watches r.ctx.Done() and calls cancel() explicitly; detached and
background agents now run to completion independently and remain
cancellable via AgentState.Cancel.

Add TestDetachedAgentSurvivesParentCancel, which fails on the old
behavior (agent cancelled after parent cancel) and passes now.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore: gofmt cancel_inflight_test.go under Go 1.25

Go 1.25's gofmt expands a single-line function body that earlier versions
left inline, so the repo-wide `go fmt ./...` CI check failed on this file
(inherited from #52). No behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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.

1 participant