Repository navigation
fix(inference): a stream that fails ends its inference/lifecycle failed - #537
Merged
Merged
Conversation
…led` driveStream emits `started` for each stream and one terminal in its `finally`, whose phase the exit paths decide. The catch and the `error` case's two provider holds set `failed`. The `error` case's other failure paths (the exhausted end, a retry, and a retry that `stop()` cancels) and the `aborted` case's failure branch (a reason other than `user`, such as `timeout`) left the default `completed` standing. So an MCPL server granted `inferenceLifecycle` was told that a failed inference completed. The `error` case now sets `failed` once, where the failure is established: after its two cancel checks, beside `inference:failed`. That covers each path the case takes after it, the provider holds included, so their own lines go. The `aborted` case's failure branch sets it too. The endings a stop or the framework's own cancel accounts for still end `aborted`, as before: an `aborted` event with reason `user`, an `error` event after a caller's stop, and an `aborted` or `error` event after the framework's cancel. The comments at the `let` and in the `finally` now say which path sets which phase. test/inference-lifecycle-failed.test.ts drives a turn through each ending and reads what the lifecycle grant is sent: a completion (control), an error with no retry, an error retried (the retry has its own `started` and terminal), an error whose retry `stop()` cancels, a 429 that holds the turn, a `timeout` abort, and a `user` abort (control). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Required label not found on this PR. |
nissa-seru
pushed a commit
to nissa-seru/agent-framework
that referenced
this pull request
Oct 18, 2026
One conflict, in driveStream's error case: main now sets the stream's lifecycle phase to `failed` before reporting inference:failed (anima-research#537), and this branch resets the agent there before the report. Both stay, the phase first.
nissa-seru
pushed a commit
to nissa-seru/agent-framework
that referenced
this pull request
Oct 18, 2026
… inference failed With main's lifecycle phases (anima-research#537), a stream that fails ends `failed`, and a stop() that cancels its retry leaves that failure standing. The check after driveStream's wait to retry set the phase to `aborted` when a caller's stop or an abandon ended the turn there. It now leaves the phase as the failure set it, and the turn still ends as the stop. Test: a stream that fails, whose retry a caller's stop cancels during its wait, ends failed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nissa-seru
pushed a commit
to nissa-seru/agent-framework
that referenced
this pull request
Oct 18, 2026
One conflict, in driveStream's error case: main now sets the stream's lifecycle phase to `failed` before reporting inference:failed (anima-research#537), and this branch resets the agent there before the report. Both stay, the phase first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nissa-seru
pushed a commit
to nissa-seru/agent-framework
that referenced
this pull request
Oct 18, 2026
… inference failed With main's lifecycle phases (anima-research#537), a stream that fails ends `failed`, and a stop() that cancels its retry leaves that failure standing. The check after driveStream's wait to retry set the phase to `aborted` when a caller's stop or an abandon ended the turn there. It now leaves the phase as the failure set it, and the turn still ends as the stop. Test: a stream that fails, whose retry a caller's stop cancels during its wait, ends failed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 task done
nissa-seru
pushed a commit
to nissa-seru/agent-framework
that referenced
this pull request
Oct 19, 2026
main brings anima-research#533, whose disk reads check the mount's root and read a file beneath it through the root they checked (viewOf, openBeneathRoot), anima-research#262's MCP client, and anima-research#537. Resolved, in index.ts only: - The imports take both sides' names. - WorkspaceReadErrorCode's doc keeps the include's rewrite of the codes and adds anima-research#533's sentence on a root whose realpath or stat fails. - readFileFromDisk's doc keeps the include's list of codes, with anima-research#533's "missing or non-regular file". - The runtime view is anima-research#533's viewOf, which now carries the mount's include, as the view the include built in its place did. viewOf also gives the view a disk read checks the mount's root with, where the include changes nothing. Merged without a conflict: the rule for a place in a nested mount's directory, in openContainedFile, which anima-research#533 moved into openBeneathRoot, and the rest of anima-research#533's index.ts, observe.ts and disk-agreement.ts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nissa-seru
pushed a commit
to nissa-seru/agent-framework
that referenced
this pull request
Oct 19, 2026
main brings anima-research#533, whose disk reads check the mount's root and read a file beneath it through the root they checked (viewOf, openBeneathRoot), anima-research#262's MCP client, and anima-research#537. Resolved, in index.ts only: - The imports take both sides' names. - WorkspaceReadErrorCode's doc keeps the include's rewrite of the codes and adds anima-research#533's sentence on a root whose realpath or stat fails. - readFileFromDisk's doc keeps the include's list of codes, with anima-research#533's "missing or non-regular file". - The runtime view is anima-research#533's viewOf, which now carries the mount's include, as the view the include built in its place did. viewOf also gives the view a disk read checks the mount's root with, where the include changes nothing. Merged without a conflict: the rule for a place in a nested mount's directory, in openContainedFile, which anima-research#533 moved into openBeneathRoot, and the rest of anima-research#533's index.ts, observe.ts and disk-agreement.ts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nissa-seru
pushed a commit
to nissa-seru/agent-framework
that referenced
this pull request
Oct 19, 2026
…anima-research#506's words and F240 main moved 331 commits on from 9e3e407, among them anima-research#262 (the modern MCP client and the legacy engine's protocol boundary), anima-research#506 (the agent's words for failed requests), anima-research#532, anima-research#537, anima-research#210 and anima-research#542 (F240: a redaction that can't read its configuration withholds the text). What anima-research#250 removes stays removed, and what main added keeps working beside it. Conflicts: - src/framework.ts, imports: main's new imports, with anima-research#250's McplRequestError beside McplProtocolVersionError and McplUnreapedLaunchError. - src/framework.ts, the barrier: main changed failMcplDataPlaneGate's recycle (a connection it couldn't close takes its tools off the list). anima-research#250 removes the gate and its recycle, so that change has nowhere to go; the close for good it rests on (closeMcplServerForGood) is main's and stays, and a runtime connect whose policy registration throws still goes through it. - src/framework.ts, the connect: main split connectMcplServerInternal into the id hold and connectHeldMcplServer, with a modern family, a stop check and an abort. That structure is main's. anima-research#250's parts go into it: the parameter is `staged`, the ledger is read first only by a legacy connect that derives the protective default (anima-research#542's sentence about a ledger that breaks after that read stays), listeners are wired before any plane opens, a runtime connect whose policy registration throws closes for good, and a staged startup connect returns its connection while a runtime one opens its planes and starts delivery in the background before returning it. - src/framework.ts, the restart: main's restart (its in-flight, claim, id and prefix checks, and its claims) with anima-research#250's rule for the ledger read: only a legacy server that derives the default reads it before disconnecting. - src/mcpl/server-connection.ts: main's file, which moved the reconnect into reconnectOnce, with anima-research#250's five rewrites of comments that named the awareness barrier. - test/failed-create-releases: main's two-engine test, with anima-research#250's legacy server (`chat`, the reregistering fixture) and no ledger options. - test/mcpl-reconnect-reregistration, test/stop-with-host-operations: wireMcplEvents takes the config now. - test/stop-ends-awareness-drains: anima-research#250's assertions, with anima-research#506's words for a request the close ended. - test/placed-reaction-baseline: anima-research#542's two tests go in ahead of anima-research#250's restart tests. The reconnect one breaks the ledger with breakLedger, since version 3 reads the file only when it has no document in memory. - test/mcpl-awareness-barrier.test.ts and its fixture stay deleted. Of main's changes to them, the deadline wording and the generation tests' signatures go with the file; the relist after a failed close is anima-research#459's test, which anima-research#250 keeps in mcpl-runtime-connect-failure.test.ts, so that assertion moves there. Outside the conflicts: - test/fixtures/reregistering-mcpl-server.mjs, anima-research#250's own fixture, answers initialize with protocolVersion 2024-11-05: main's legacy engine refuses an initialize answer without it (anima-research#262), and main gave its own fixtures the field. - test/discord-awareness-delivery's inbound test passes a config to wireMcplEvents, which records through that server's redactor now. - main's modern-MCP connect and restart read no ledger and install no gate, so they meet nothing anima-research#250 removed. Two of main's comments, and the modern client's pending fragment, named an awareness gate as MCPL surface a modern server lacks; with no gate left, they no longer name it. - main's modern test in placed-reaction-baseline breaks the ledger with breakLedger too, for the same reason. - anima-research#506's words reach anima-research#250's own assertions: a hung reaction's recorded error says the server didn't answer within its deadline, and a request the connection's loss ended says the connection closed before it answered. anima-research#250's test of a request the host's close ends goes: main's "closing the connection while a request awaits its answer" pins the same outcome, and stop-ends-awareness-drains pins its words. - test/mcp-server-ownership: main's two tests of the gate's recycle (an accounting failure recycling a server whose child can't be reaped, with and without reconnect) call installMcplDataPlaneGate and failMcplDataPlaneGate, which anima-research#250 removes, so they go with the gate. The close for good they lead to is still pinned for a runtime connect's failure, in mcpl-runtime-connect-failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nissa-seru
pushed a commit
to nissa-seru/agent-framework
that referenced
this pull request
Oct 19, 2026
…arch#506's words and anima-research#542 main moved 331 commits on from 9e3e407, among them anima-research#262 (the modern MCP client and the legacy engine's protocol boundary), anima-research#506 (the agent's words for failed requests), anima-research#532, anima-research#537, anima-research#210 and anima-research#542 (a redaction that can't read its configuration withholds the text). What anima-research#250 removes stays removed, and what main added keeps working beside it. Conflicts: - src/framework.ts, imports: main's new imports, with anima-research#250's McplRequestError beside McplProtocolVersionError and McplUnreapedLaunchError. - src/framework.ts, the barrier: main changed failMcplDataPlaneGate's recycle (a connection it couldn't close takes its tools off the list). anima-research#250 removes the gate and its recycle, so that change has nowhere to go; the close for good it rests on (closeMcplServerForGood) is main's and stays, and a runtime connect whose policy registration throws still goes through it. - src/framework.ts, the connect: main split connectMcplServerInternal into the id hold and connectHeldMcplServer, with a modern family, a stop check and an abort. That structure is main's. anima-research#250's parts go into it: the parameter is `staged`, the ledger is read first only by a legacy connect that derives the protective default (anima-research#542's sentence about a ledger that breaks after that read stays), listeners are wired before any plane opens, a runtime connect whose policy registration throws closes for good, and a staged startup connect returns its connection while a runtime one opens its planes and starts delivery in the background before returning it. - src/framework.ts, the restart: main's restart (its in-flight, claim, id and prefix checks, and its claims) with anima-research#250's rule for the ledger read: only a legacy server that derives the default reads it before disconnecting. - src/mcpl/server-connection.ts: main's file, which moved the reconnect into reconnectOnce, with anima-research#250's five rewrites of comments that named the awareness barrier. - test/failed-create-releases: main's two-engine test, with anima-research#250's legacy server (`chat`, the reregistering fixture) and no ledger options. - test/mcpl-reconnect-reregistration, test/stop-with-host-operations: wireMcplEvents takes the config now. - test/stop-ends-awareness-drains: anima-research#250's assertions, with anima-research#506's words for a request the close ended. - test/placed-reaction-baseline: anima-research#542's two tests go in ahead of anima-research#250's restart tests. The reconnect one breaks the ledger with breakLedger, since version 3 reads the file only when it has no document in memory. - test/mcpl-awareness-barrier.test.ts and its fixture stay deleted. Of main's changes to them, the deadline wording and the generation tests' signatures go with the file; the relist after a failed close is anima-research#459's test, which anima-research#250 keeps in mcpl-runtime-connect-failure.test.ts, so that assertion moves there. Outside the conflicts: - test/fixtures/reregistering-mcpl-server.mjs, anima-research#250's own fixture, answers initialize with protocolVersion 2024-11-05: main's legacy engine refuses an initialize answer without it (anima-research#262), and main gave its own fixtures the field. - test/discord-awareness-delivery's inbound test passes a config to wireMcplEvents, which records through that server's redactor now. - main's modern-MCP connect and restart read no ledger and install no gate, so they meet nothing anima-research#250 removed. Two of main's comments, and the modern client's pending fragment, named an awareness gate as MCPL surface a modern server lacks; with no gate left, they no longer name it. - main's modern test in placed-reaction-baseline breaks the ledger with breakLedger too, for the same reason. - anima-research#506's words reach anima-research#250's own assertions: a hung reaction's recorded error says the server didn't answer within its deadline, and a request the connection's loss ended says the connection closed before it answered. anima-research#250's test of a request the host's close ends goes: main's "closing the connection while a request awaits its answer" pins the same outcome, and stop-ends-awareness-drains pins its words. - test/mcp-server-ownership: main's two tests of the gate's recycle (an accounting failure recycling a server whose child can't be reaped, with and without reconnect) call installMcplDataPlaneGate and failMcplDataPlaneGate, which anima-research#250 removes, so they go with the gate. The close for good they lead to is still pinned for a runtime connect's failure, in mcpl-runtime-connect-failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nissa-seru
pushed a commit
to nissa-seru/agent-framework
that referenced
this pull request
Oct 19, 2026
…arch#506's words and anima-research#542 main moved 331 commits on from 9e3e407, among them anima-research#262 (the modern MCP client and the legacy engine's protocol boundary), anima-research#506 (the agent's words for failed requests), anima-research#532, anima-research#537, anima-research#210 and anima-research#542 (a redaction that can't read its configuration withholds the text). What anima-research#250 removes stays removed, and what main added keeps working beside it. Conflicts: - src/framework.ts, imports: main's new imports, with anima-research#250's McplRequestError beside McplProtocolVersionError and McplUnreapedLaunchError. - src/framework.ts, the barrier: main changed failMcplDataPlaneGate's recycle (a connection it couldn't close takes its tools off the list). anima-research#250 removes the gate and its recycle, so that change has nowhere to go; the close for good it rests on (closeMcplServerForGood) is main's and stays, and a runtime connect whose policy registration throws still goes through it. - src/framework.ts, the connect: main split connectMcplServerInternal into the id hold and connectHeldMcplServer, with a modern family, a stop check and an abort. That structure is main's. anima-research#250's parts go into it: the parameter is `staged`, the ledger is read first only by a legacy connect that derives the protective default (anima-research#542's sentence about a ledger that breaks after that read stays), listeners are wired before any plane opens, a runtime connect whose policy registration throws closes for good, and a staged startup connect returns its connection while a runtime one opens its planes and starts delivery in the background before returning it. - src/framework.ts, the restart: main's restart (its in-flight, claim, id and prefix checks, and its claims) with anima-research#250's rule for the ledger read: only a legacy server that derives the default reads it before disconnecting. - src/mcpl/server-connection.ts: main's file, which moved the reconnect into reconnectOnce, with anima-research#250's five rewrites of comments that named the awareness barrier. - test/failed-create-releases: main's two-engine test, with anima-research#250's legacy server (`chat`, the reregistering fixture) and no ledger options. - test/mcpl-reconnect-reregistration, test/stop-with-host-operations: wireMcplEvents takes the config now. - test/stop-ends-awareness-drains: anima-research#250's assertions, with anima-research#506's words for a request the close ended. - test/placed-reaction-baseline: anima-research#542's two tests go in ahead of anima-research#250's restart tests. The reconnect one breaks the ledger with breakLedger, since version 3 reads the file only when it has no document in memory. - test/mcpl-awareness-barrier.test.ts and its fixture stay deleted. Of main's changes to them, the deadline wording and the generation tests' signatures go with the file; the relist after a failed close is anima-research#459's test, which anima-research#250 keeps in mcpl-runtime-connect-failure.test.ts, so that assertion moves there. Outside the conflicts: - test/fixtures/reregistering-mcpl-server.mjs, anima-research#250's own fixture, answers initialize with protocolVersion 2024-11-05: main's legacy engine refuses an initialize answer without it (anima-research#262), and main gave its own fixtures the field. - test/discord-awareness-delivery's inbound test passes a config to wireMcplEvents, which records through that server's redactor now. - main's modern-MCP connect and restart read no ledger and install no gate, so they meet nothing anima-research#250 removed. Two of main's comments, and the modern client's pending fragment, named an awareness gate as MCPL surface a modern server lacks; with no gate left, they no longer name it. - main's modern test in placed-reaction-baseline breaks the ledger with breakLedger too, for the same reason. - anima-research#506's words reach anima-research#250's own assertions: a hung reaction's recorded error says the server didn't answer within its deadline, and a request the connection's loss ended says the connection closed before it answered. anima-research#250's test of a request the host's close ends goes: main's "closing the connection while a request awaits its answer" pins the same outcome, and stop-ends-awareness-drains pins its words. - test/mcp-server-ownership: main's two tests of the gate's recycle (an accounting failure recycling a server whose child can't be reaped, with and without reconnect) call installMcplDataPlaneGate and failMcplDataPlaneGate, which anima-research#250 removes, so they go with the gate. The close for good they lead to is still pinned for a runtime connect's failure, in mcpl-runtime-connect-failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nissa-seru
pushed a commit
that referenced
this pull request
Oct 19, 2026
…laces it main brought, among others, #533 (the mount root's identity and bounds), #535 (mount roots placed where disk has them: readNesting replaces spellNestedDirs, and a nested mount's directory has a place per way it lies there, each with its spellings), #262, #537, #543 and the 0.22.3 release. F194's changelog fragment and its edit of #525's are both still unreleased. The five conflicts were all in src/modules/workspace/index.ts: - the ./observe.js import: main's names, with F194's foldsCase and WorkspaceEntries; - the nested mounts' field: main's NestedMountEntry[], with F194's rootFoldsCase beside it; - three in start, around what it reads before it sets anything: main's readNesting, and F194's root folding read after it, both assigned after the check for a stop begun meanwhile. As Ada-1017 set for this merge, start reads each root's folding from the root #535 places, where disk has it: readNesting now returns its real roots (reals) beside the nesting, and start calls foldsCase on each. Before, F194 read it at the root as configured, so a root configured through a link was judged by the directory holding the link rather than by the one holding the directory the files are in. F194's step asks holderOf, which now reads every place and spelling #535 gives a nested mount's directory, so the step needs no change for it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR: an inference whose stream fails now ends its
inference/lifecyclewithfailed. Three endings left the defaultcompletedstanding: anerrorevent that ends the turn, one that is retried, and anabortedevent whose reason isn'tuser, such astimeout. So an MCPL server grantedinferenceLifecyclewas told that a failed inference completed.Problem
driveStreamsendsstartedfor each stream, and one terminal in itsfinally(src/framework.ts:17491–17496at124edb46). The terminal's phase is theletat:15903:completedunless a path sets another. The catch setsfailed(:17374,:17388,:17418), and so do theerrorcase's two provider holds (:17037,:17043). Three endings set nothing:errorcase's exhausted end (:17070–17072), which settles the turn as exhausted;:17049–17054), including a retry thatstop()cancels while it waits (:17055–17069). The retry is an inference of its own, with its ownstarted;abortedcase's branch for a reason other thanuser(:17146–17152), which also settles the turn as exhausted.SPEC §10.5 gives
inference/lifecyclethe terminal phasescompleted,abortedandfailed, and says the explicitabortedandfailedmean that "an observer usually learns of a dead turn instead of inferring it from silence".Changes
errorcase setsfailedonce, where the failure is established: after its two cancel checks, besideinference:failed. Each path the case takes after it endsfailed, the provider holds included, so their own lines go.abortedcase's branch for a reason other thanusersetsfailedtoo. That branch already counts such an event as a failure even after a caller's stop, since the stream's own word decides, and the lifecycle now agrees with it.letand in thefinallynow name the paths that set each phase. Before, they named only the catch as settingfailed. Each new assignment has a comment saying why.What a server newly sees: a server granted
inferenceLifecycleis sentfailedwhere it was sentcompleted, for those three endings. Nothing else on the wire changes: the same notifications, with the sameinferenceIds. The endings a stop or the framework's own cancel accounts for still endaborted, as before: anabortedevent with reasonuser, anerrorevent after a caller's stop, and anabortedorerrorevent after the framework's cancel.What each part is for
errorcase, after its cancel checks. It gives each failure path the case takes after itfailed: the exhausted end, the retry, a retry thatstop()cancels, and the two provider holds. A path added there later gets it too. Setting it in each branch would take four lines, and a branch added later could miss it, as these three did. A stop or a framework cancel still endsaborted, since each of those branches sets it and returns before the assignment.failed. The hold for a turn that doesn't own it comes after that one, so the same placement covers it.abortedcase's failure branch. The framework already counts that branch as a failure: it settles the turn as exhausted and logs a failed row.mainand pin the fix. The 429 test pins the holds. The completion anduser-abort controls pin two endings the fix leaves alone. The endings a stop or the framework's cancel accounts for are pinned intest/cancel-surfaces-as-error.test.ts, below.Left out:
failed, withcompletedset on a completion. It would also change the silent end below, and every success path would have to setcompleted.complete,abortedorerrorevent, which nobody cancelled. It still endscompleted, as the comment there says (:17288–17309), and nothing in the framework counts it as a failure.Tests
test/inference-lifecycle-failed.test.tsdrives one turn through each ending, with a membrane whose streams end as scripted, and reads what the framework sends to the lifecycle grant:completed(control);error, not retried →failed;error, retried →failed, and the retry has its ownstartedandcompleted;errorwhose retrystop()cancels →failed, with the trace'sinference:abortedsaying the retry was dropped, and one request sent;errorcarrying a 429 →failed, with the turn held for the provider's stated wait (the health snapshot lists it), one request sent, and noinference:exhausted;abortedwith reasontimeout→failed;abortedwith reasonuser, a stop as the stream reports it →aborted(control).At this head, on Linux with Node 24.22.0,
tsc --noEmitis clean, the file passes 7 of 7, andtest/cancel-surfaces-as-error.test.tspasses 23 of 23. GitHub's CI run passes all four Build & Test legs, Ubuntu and macOS on Node 20 and 24, each runningnpm test, and its packed release installs on its own.Against
main'ssrc/framework.ts(124edb46), with these tests, 4 fail: not retried, retried, the cancelled retry andtimeout. The 429 test and the two controls pass, sincemain's holds already setfailed.Each piece removed or moved alone fails at least one test:
errorcase's assignment removed: 4 fail (not retried, retried, the cancelled retry, the 429);abortedcase's assignment removed: thetimeouttest fails;errorcase's assignment moved into its exhausted branch only: 3 fail (retried, the cancelled retry, the 429);The endings this change leaves
abortedare pinned intest/cancel-surfaces-as-error.test.ts. Removing theabortedthat the framework's cancel sets (endFrameworkCancel) fails 10 of its 23 tests. Removing the one theerrorcase sets after a caller's stop fails 1, and so does removing the one the catch sets after a caller's stop.Not verified
YieldingStreamImplsendserrorand then ends (src/yielding-stream.ts:335–344, and its iterator at:208–227), the shape the tests script.Out of scope
aborted, as onmain, since the loop's head (:16052–16058) and the catch (:17327–17334) take it as a replaced stream. membrane's stream sends nothing aftererror, and a retry whose start fails is taken bybeginAgentTurn's own catch (:15543–15634). So only another stream implementation, or a throw that escapes that catch, reaches it.:16112), and the terminal is sent under that id, so the inference'sstartedgets no terminal. That is so onmainas well, and this change leaves it as it is.Other open pull requests
errorcase's retry. After the retry's wait, a caller's stop or a quiesce abandon now ends the turn there and setsaborted. The two merge cleanly. By our reading of the two merged, that path would end the inference that failedaborted, while astop()that cancels the same retry leaves itfailed.changelog.d/inference-lifecycle-failed.fixed.md.Written by Nigel-2654 (Claude Opus 5.5). Paloma-2644 found the defect, beside the one #380 fixed, and Ada-1017 made the design calls. An internal review read the change before its last round, and this head answers it. Abigail-2676 reviewed the code at this head and ran the full suite there.
Description checked and posted by Lottie-2661 (Claude Opus 5.5).
🤖 Written using Anthropic's Claude Opus 5.5 through the Rookery's Pi tooling, and posted from the shared
nissa-seruaccount.