v0.12.0
·
176 commits
to 1.x
since this release
Immutable
release. Only release title and notes can be modified.
What's Changed
Lifecycle correctness on both peers: close/drain ordering, in-flight caps that hold under pressure, subscription accounting, and task expiry and stall guarantees. The schema side now honours the spec's open capability set and the empty {} sub-schemas the decoder collapses to []. Seven breaking changes are listed in BREAKING_CHANGES.md.
Added
ClientBuilder::setMaxInFlightDispatches()caps how many inbound messages a client processes at once.RequestStateSigner::sign()andverify()take an optional binding, so a state minted for one caller does not verify for another.
Changed
Core\Transport\SubscriptionInterfaceis renamedListenerHandleInterface(see BREAKING_CHANGES.md).- The in-flight dispatch cap is on by default on both peers, at
DEFAULT_MAX_IN_FLIGHT(1024). See BREAKING_CHANGES.md. RequestStateSignersignatures changed shape, so a state minted before this release no longer verifies.VerifiedAccessToken::$subjectand$clientIdarenon-empty-string, and an empty or non-string identity claim reads as absent rather than reaching a handler or masking a later one. See BREAKING_CHANGES.md.
Fixed
- A
close()racing an in-progress close on the stdio transports now blocks until that close settles, instead of returning early whilesend()was still accepted. - An empty
{}sub-schema, whichjson_decode(..., true)renders as PHP[], no longer fails everytools/callwith a bare internal error: the default validator restores it in every sub-schema position. #[InputSchema(definition: [])]is refused at construction instead of being read differently per level.- A completion answering more than the spec's 100-value cap is truncated with
hasMore: trueand atotal, instead of shipping an over-long list. Icondecodes any RFC 3986 URIsrcinstead of aborting a whole listing on an unusual scheme. The http/data restriction moved to the authoring surfaces (stores and builders). See BREAKING_CHANGES.md.ServerCapabilitiesnow keeps unknown capabilities (top level in a newextrasslot, nested keys in place) and models the deprecatedloggingmember, honouring the spec's open-set rule. See BREAKING_CHANGES.md.awaitTask()'s stall ceiling now counts polls that sent no answers, so a resolver answering outside the offered set can no longer defeat it, and a key re-issued after aworkinground is offered again.InMemoryTaskStorenow fails a task that has not settled bycreatedAt + ttlMsand sweeps it, instead of retaining a parked task forever.HeaderMismatchErrornow carriesdatalike its sibling errors, instead of silently dropping it on construction and decode.- Building a
-32021or-32022error without itsdatapayload now fails with a message naming the code and the keys it requires, instead of a generic decode error. - A prompt or template completion registered under an all-digit name no longer fails
build(). - A discovered tool's nullable parameter now accepts the
nullits advertised schema permits, at the top level and inside an expanded object, instead of answering-32602. - A method-level
#[InputSchema(...)]withoutdefinitionnow merges its constraints over the inferred schema instead of being silently discarded. ResourceStorerefuses an entry whose key differs from its resource's URI at construction, the same check its three sibling stores already run.- A
subscriptions/listenacknowledgement no longer promises alistChangedtype no registered store can produce, matching whatserver/discoveradvertises. - A stdio transport closed from the main context before its read loop's first turn now drains that loop before
close()returns, the same as every other close path. - A resource reader's own
ResourceNotFoundExceptionends the read instead of being answered by an overlapping resource template. A registry miss still falls through, signalled by the newResourceNotRegisteredException(see BREAKING_CHANGES.md). - An authorization caller that stops waiting for the coordinator's lock now returns the permit it is eventually handed, so later token operations no longer depend on collection timing to proceed.
SubscriptionStorecounts a stream whose acknowledgement is still in flight againstmaxSubscriptions, so the limit holds against a peer that stops reading.subscriptions/listenno longer occupies an in-flight dispatch slot on a server that serves it, and listens arriving faster than the loop starts them are shed with-32000.- The first
notifications/cancellednaming a request in flight is no longer shed by the in-flight dispatch cap, and is cancelled on admission when the cap is reached. StreamableHttpServerTransportno longer leaks a request's sink when anonMessagelistener throws.StreamableHttpServerTransportno longer strands an in-flight request whose response or notification cannot be encoded or built, and settles those still in flight whenclose()runs.
Full Changelog: v0.11.0...v0.12.0