Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### Fixed

- **Agent executor documentation describes the existing interactive lease.** The request and resume comments explain the shared failure result and distinguish approval-bound write continuations from remote writes that can execute in the initial leased segment.

- **Invalid retrieval provenance follows the public exception contract (ADR-053).** Constructor validation implements `NrLlmExceptionInterface` while preserving native `InvalidArgumentException` catch compatibility, reason codes and messages.

- **Retrieval details preserve legacy byte ids at full privacy (ADR-215).** Invalid UTF-8 question ids, hard classes and measured document ids use a versioned lossless field representation after filtering their original bytes. Ordinary UTF-8 and prompt snapshots remain compatible; redacted and metadata policies cannot be bypassed through encoding.
Expand Down
19 changes: 10 additions & 9 deletions Classes/Service/Agent/AgentRunExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,10 @@ public function __construct(
*
* A queued run passes its worker identity as $leaseOwner (so each step
* boundary renews the lease and detects a reaper reclaim, ADR-104) and a
* $recover closure that decides retry-vs-dead-letter for a failure. An
* interactive run() passes neither: it holds no lease and surfaces failures
* to its caller unchanged.
* $recover closure that decides retry-vs-dead-letter for a failure.
* An interactive run() passes its own lease when the run was persisted
* (ADR-141). It passes no recovery closure; loop failures use the shared
* lifecycle's default failure result.
*
* @param (Closure(RunStep): void)|null $onStep
* @param (Closure(Throwable, list<RunStep>): ?AgentRunResult)|null $recover
Expand Down Expand Up @@ -131,12 +132,12 @@ public function executeRequest(
* factory over the context and the trace keeps the ordering here, where it
* is stated once, instead of in each caller.
*
* A resume carries no recovery: it is the continuation of a suspended run
* driven by a request, so a failure surfaces to its caller exactly as an
* interactive run's does. It DOES hold a lease (ADR-141). This is the
* segment a writing tool executes in — a write suspends before it runs
* (ADR-134), so the first pass never reaches the tool — and an unleased
* segment cannot arm the ADR-111 fence around it.
* A resume carries no queued recovery and uses the shared lifecycle's
* default failure result, like an interactive run. It holds a lease
* (ADR-141), so an approval-bound write can execute fenced in this
* continuation. A remote write that requires no approval can execute in
* the initial segment, which also holds a lease (ADR-134/141). An unleased
* segment cannot arm the ADR-111 fence around a write.
*
* @param (Closure(RunStep): void)|null $onStep
* @param Closure(ToolExecutionContext, RunTrace): ToolLoopResult $loopCall
Expand Down
Loading