release v0.2.1 - #23
Merged
Merged
Conversation
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.
Release 0.2.1
Generated by the Release prep workflow. Merging this PR creates annotated tag
v0.2.1and runs the Release workflow: verify -> GitHub Release -> crates.io publish (Trusted Publishing OIDC, tokenless).Changelog
[0.2.1] - 2026-09-14
Changed
-spawn-helper).Fixed
RunResult::final_responsenow falls back to an earlier rootassistant/messagewhen the last one is malformed (non-object
dataor non-arraycontent),matching the Python SDK's
final_responsereversed-scan algorithm. Theprevious implementation returned
""instead of trying an earlier event.RunResult::final_responseand the normativespec §6.2, which both incorrectly claimed
final_response"never falls backto an earlier event" while citing the Python source that does fall back.
The behavior is unreachable from a conformant runtime (which always emits
message.contentas a JSON array) but the algorithm and docs now agree.RunResult::final_responsetreats a non-stringtextblock (includingnull) as"". That is a recorded divergence from the Python SDK, whichcoerces a truthy non-string via
str()(42→"42",true→"True").There is no runtime behavior change.
HarnessClientdropped without an explicitclose()now closes its notification channel, so a subscription awaiting the next notification returnsError::TransportClosedpromptly instead of only when the aborted background reader task happens to be torn down. That error reports the closed reason, plus the runtime's exit code and captured stderr tail when they were observed.Config::dsh_binis the current runtime-binary override name (renamed fromConfig::runtime_bin; theDSH_RUNTIME_BINenvironment route is preserved).runtime — Linux x64, Linux arm64, macOS arm64, macOS x64, and Windows
x64 — and no longer states that macOS x64 has no wheel. A macOS x64 wheel
is published, so Route B (the self-contained wheel) works there; Route C
(build from source) remains the route that reproduces the exact contract
basis this crate was verified against, and the fallback for any platform with
no published wheel.
Session::runno longer wedges indefinitely when the runtime dies mid-turn (stdout EOF aftersession/promptsucceeds but before the inbox receipt or root-idle notification arrives). The high-level API surfacesError::TransportClosedwith the closed reason and the stderr tail the end-of-stream path captured, plus the exit code when the best-effort poll of the exiting child observed it, as its doc contract always promised ("once the channel (or the client) is closed,Error::TransportClosedis returned").NotificationSubscription::recvparked inbroadcast::Receiver::recv().awaitnow wakes withTransportClosedwhen the runtime dies spontaneously (stdout EOF without an explicitclose), instead of hanging forever. The fix shares the original broadcastSenderbetweenHarnessClientand the read loop and drops it on the read loop's EOF path, so the channel closes and a parkedrecvresolves withRecvError::Closed. Subscriptions created after runtime death remain born-failed.