Patch Changes
-
#1393
5aaf7c4Thanks @threepointone! - Migrate facet (sub-agent) bootstrap to the documented Cloudflare facet API: passid: parentNs.idFromName(name)toctx.facets.get()so the facet has its ownctx.id.name. Drops the__ps_namestorage write andsetName()bootstrap from_cf_initAsFacet.Why this matters. Facets spawned without an explicit
idinherit the parent DO'sctx.id, so on a facetctx.id.namewas the parent's name andthis.namesilently misreported as the parent's name. Anything that readthis.namefrom inside a sub-agent (includingselfPath,parentPath, and any user code) was getting the wrong value. With the explicitidpassed at facet creation time, the runtime gives the facet a realctx.id.name === nameand PartyServer's existing 0.5.xnamegetter resolvesthis.namecorrectly without any override mechanism, storage write, or cold-wake hydrate cost. Cold-wake recovery happens for free becauseidFromNameis deterministic and the factory re-runs on resume.This requires
partyserver≥ 0.5.3 (bumped in this release); 0.5.3 is byte-identical to 0.5.2 at runtime, only adds documentation and test coverage of the explicit-idfacet pattern.Other changes:
- New error path. If
subAgent()is called from a parent class that isn't bound as a Durable Object namespace, the framework now throws a descriptive error pointing atwrangler.jsonc. Ifthis.constructor.namelooks minified (e.g._a), the message includes a bundler-config hint about preserving class names. - Defensive runtime check.
_cf_initAsFacetnow assertsthis.name === nameso any future bug in the parent's id construction surfaces immediately instead of silently mis-identifying the facet. alarm()docstring clarified to reflect the new resolution path (this.namefromctx.id.name, not from a storage hydrate).- MCP test cleanup. Vestigial
setName("default")+ explicitonStart()call pairs inoauth2-mcp-client,wait-connections-e2e, andcreate-oauth-providertest files have been removed; they were originally needed for partyserver 0.4.x bootstrap but became actualctx.id.namemismatches under partyserver 0.5.x.
Backward-compatible for all public APIs:
subAgent(),parentAgent(),hasSubAgent(),listSubAgents(),deleteSubAgent(), andabortSubAgent()keep their signatures and semantics. The change is purely in the facet bootstrap internals; the user-facing effect is thatthis.nameinside a sub-agent now correctly reports the sub-agent's own name (was previously the parent's name when run against partyserver 0.5.x).See cloudflare/partykit#386 for the partyserver-side documentation companion.
- New error path. If
-
#1395
63cfae6Thanks @threepointone! - Share submit concurrency bookkeeping throughagents/chatand use it from both chat agents.This extracts the
latest/merge/drop/debounceadmission state machine into aSubmitConcurrencyControllerexported fromagents/chat.AIChatAgentsemantics (including merge persistence) are preserved.Thinknow picks up the same pending-enqueue protection, so an overlapping submit is still detected while an accepted request is between admission and turn queue registration.Additional fixes:
Thinknow captures the turn generation immediately after admission and threads it into_turnQueue.enqueue, so a clear that lands between admission and queue registration cannot run a stale turn.- Pending-enqueue tracking is now bound to a release function tied to the controller's reset epoch, so a release from a pre-reset submit can no longer erase a post-reset submit's marker and let a third submit slip through as non-overlapping.
- Debounce cancellation correctly resolves all in-flight waiters instead of overwriting a single timer slot.
-
#1396
fdf5a8aThanks @threepointone! - Fix Think persisting a duplicate orphan assistant row when a user submits during a streaming tool turn (#1381).When
useAgentChatposts an in-flight assistant snapshot it minted optimistically (client-generated ID,state: "input-available"), Session's INSERT-OR-IGNORE-by-ID would store it as a separate row alongside the eventual server-owned assistant for the sametoolCallId. The next turn'sconvertToModelMessagesthen produced a malformed Anthropic prompt and the provider rejected it.reconcileMessagesandresolveToolMergeIdnow live inagents/chatand Think runs them in_handleChatRequestbefore persistence. Staleinput-availablesnapshots pick up the server's tool output viamergeServerToolOutputs, and any incoming assistant whosetoolCallIdalready exists on a server row adopts the server's ID so persistence updates the existing row instead of inserting an orphan.@cloudflare/ai-chatkeeps its existing reconciler behavior; the only change is that it now importsreconcileMessages/resolveToolMergeIdfromagents/chatinstead of a local file.