Sourced from @assistant-ui/react's releases.
@assistant-ui/react@0.14.13Patch Changes
#4176
27ae936- feat: add theToolkitDeclaration/ToolkitDeclarationDefinitiontypes for authoring a toolkit permissively (a backend tool may declaredescription/parameters/execute); the canonicalToolkitkeeps those fields erased. Author withdefineToolkit()from@assistant-ui/react, which the"use generative"compiler strips per build. (@Yonom)#4176
27ae936- feat: move thedefineToolkitandhitluse-generative markers from@assistant-ui/nextinto@assistant-ui/core/react, so they ship once from every distribution (@assistant-ui/react,@assistant-ui/react-native,@assistant-ui/react-ink) and stay portable across build targets. Import them from@assistant-ui/reactinstead of@assistant-ui/next; they remain no-op markers stripped at build time by a"use generative"compiler. (@Yonom)Updated dependencies [
27ae936,27ae936]:
- assistant-stream@0.3.19
@assistant-ui/core@0.2.9
@assistant-ui/react-langgraph@0.14.4Patch Changes
- #4125
e639a11- chore: drop tracker-behaviour explainer comments left behind in satellite runtimes (@Yonom)
@assistant-ui/react@0.14.11Patch Changes
- #4125
e639a11- chore: drop tracker-behaviour explainer comments left behind in satellite runtimes (@Yonom)
@assistant-ui/react@0.14.9Patch Changes
#4120
372d4f0- feat: simplifyMessagePrimitive.GroupedPartsAPI and addgroupPartByTypehelper. (@Yonom)
- New
groupPartByType({ ... })helper builds agroupByfrom apart.type → group-key pathlookup. The map keys are typed againstPartState["type"](autocomplete + typo rejection), missing keys leave the part ungrouped, and the returned function carries an internal memo fingerprint so the tree survives unrelated re-renders even when reconstructed inline.- Special map key
"mcp-app"matches tool-call parts that point at an assistant-ui MCP app resource (ui://...). It takes precedence over the"tool-call"entry for those parts, so MCP apps can be routed separately (e.g. rendered outside a chain-of-thought wrapper).groupBysignature simplified from(part, index, parts) => string | string[] | null | undefinedto(part) => readonly \group-${string}`[] | null. The 2nd/3rd args were unused in practice. Arrays are required (no bare-string shorthand);nullis accepted as an alias for[]` to soften the migration.- Internal memoization now uses the helper's memo fingerprint when present, otherwise rebuilds the tree per render (O(n), cheap). The previous "pass a stable reference" advice is dropped — inline
groupByis fine.- Docs and examples updated to lead with
groupPartByType. ThegetMcpAppFromToolPartbranch inpackages/uiswitches to"mcp-app": []via the helper.#4107
32ae846- feat: surface AI SDK v6 tool approvals as a first-classrespondToApprovalprop on tool components. tool-call parts in theapproval-requestedstate now carrypart.approval = { id, isAutomatic? }; tool components callrespondToApproval({ approved, reason? })to ack the gate without threadingchatHelpersthrough application context. also fixes a transientrequires-actionflicker for theapproval-respondedstate and tightens the external-message converter so interrupt vs pending tool calls are distinguished by an actualinterrupt/approvalfield rather than byresult === undefined. (@okisdev)Updated dependencies [
372d4f0,d4f1db4,32ae846]:
@assistant-ui/core@0.2.6- assistant-stream@0.3.17
@assistant-ui/react-syntax-highlighter@0.14.1Patch Changes
@assistant-ui/react-langgraph@0.14.2Patch Changes
- #3967
0a0c306- feat(core, react): addMessagePrimitive.GenerativeUIprimitive (@samdickson22)
... (truncated)
Sourced from @assistant-ui/react's changelog.
0.14.13
Patch Changes
#4176
27ae936- feat: add theToolkitDeclaration/ToolkitDeclarationDefinitiontypes for authoring a toolkit permissively (a backend tool may declaredescription/parameters/execute); the canonicalToolkitkeeps those fields erased. Author withdefineToolkit()from@assistant-ui/react, which the"use generative"compiler strips per build. (@Yonom)#4176
27ae936- feat: move thedefineToolkitandhitluse-generative markers from@assistant-ui/nextinto@assistant-ui/core/react, so they ship once from every distribution (@assistant-ui/react,@assistant-ui/react-native,@assistant-ui/react-ink) and stay portable across build targets. Import them from@assistant-ui/reactinstead of@assistant-ui/next; they remain no-op markers stripped at build time by a"use generative"compiler. (@Yonom)Updated dependencies [
27ae936,27ae936]:
- assistant-stream@0.3.19
@assistant-ui/core@0.2.90.14.12
Patch Changes
#4172
1315789- feat: add theToolkitDeclaration/ToolkitDeclarationDefinitiontypes for authoring a toolkit permissively (a backend tool may declaredescription/parameters/execute); the canonicalToolkitkeeps those fields erased. Author withdefineToolkit()from@assistant-ui/next, which the"use generative"compiler strips per build. (@Yonom)#4151
299d448- chore: drop stalebiome-ignorepragmas now that the repo lints with oxlint (@okisdev)#4136
4429aa3- centralize thread-level shared options forwarding across runtime wrapper hooks. follow-up to #4135. (@okisdev)new public exports from
@assistant-ui/core(re-exported from@assistant-ui/react):
ExternalStoreSharedOptions, a typedPickoverExternalStoreAdaptercovering the four thread-level optional fields every wrapper forwards:isDisabled,isSendDisabled,unstable_capabilities,suggestions.pickExternalStoreSharedOptions(options), plucks those four fields from a wider options object. the body usessatisfies Required<...>so adding a key to the type without copying it in the function is a compile error rather than a silent missing-field bug.useExternalStoreSharedOptions(options)(from@assistant-ui/core/react), a memoized variant for wrappers that wrap their store inuseMemo. lets the wrapper list a single stablesharedreference as a dep instead of enumerating the four fields. samesatisfiesguard internally so the destructure stays in sync with the type.internal: every runtime wrapper hook (
useChatRuntime,useAISDKRuntime,useLangGraphRuntime,useA2ARuntime,useAgUiRuntime,useAdkRuntime,useStreamRuntime,useOpenCodeRuntime) now uses these helpers instead of inlining the conditional spreads added in #4135. each wrapper sheds 20 to 40 lines of duplicated declarations and conditional spreads; future additions to the shared option set propagate through a single edit inpickExternalStoreSharedOptionsinstead of touching every wrapper. no user-facing behavior change.#4141
0b99959- fix(react): stop subtree mutations from snapping a scrolled-up viewport back to bottom; loosen at-bottom threshold for high-DPR displays (@vaniyokk)
useThreadViewportAutoScrollhad two related bugs surfaced on Chrome macOS atdevicePixelRatio: 2:
- subtree mutations snapped the viewport back to bottom after the user scrolled away.
scrollingToBottomBehaviorRefwas planted onthread.runStart/useOnScrollToBottom/ initialize / thread switch and only cleared inhandleScrolloncenewIsAtBottombecame true. while the ref stayed set, every non-style subtree mutation (a Radixdata-stateflip, a markdown re-render, an image lazy-load, an attribute toggle on a child) re-entereduseOnResizeContent's callback and calledscrollToBottom(scrollBehavior), locking the viewport to the bottom until reload.isAtBottomnever registered astrueon high-DPR displays.Math.abs(scrollHeight - scrollTop - clientHeight) < 1is strict-less-than, and Chrome macOS atdevicePixelRatio: 2clipsscrollTopone pixel short ofscrollHeight - clientHeight(Math.abs(1) < 1 === false), so the store never updated andScrollToBottomnever moved into its disabled state.the fix combines two layers.
handleScrollnow trackslastScrollHeightalongsidelastScrollTopand releases the auto-stick intent when the user scrolls up with content size unchanged, ruling out content-driven scrollTop shifts. the resize callback also bails when neitherscrollHeightnorclientHeighthas changed since the last fire, so mutations that don't move layout never re-enter the snap path. at-bottom auto-follow during streaming is preserved (verified by appending a synthetic 600px child while scrolled to bottom; viewport follows to new bottom). the threshold becomes<= 1to absorb the 1px sub-pixel clip.closes #4140.
#4160
e76611f- feat: addindicatorsupport toMessagePrimitive.GroupedParts. (@Yonom)Restores loading-state handling that was dropped from the grouped renderer.
GroupedPartsnow emits a synthetic{ part: { type: "indicator" } }render call you handle withcase "indicator"in yourswitch (part.type)— render a "thinking…" dot or any loading affordance.
- The indicator is only ever emitted while the message is running, so its presence alone means "render loading UI here" — there's no
statusto branch on.- New
indicatorprop restricts which running states qualify:"never","empty"(no parts yet),"no-text"(default — last part isn'ttext/reasoning, e.g. the model ended on a tool call), or"always"(any running state).#4162
eef724e- fix: drop phantom sibling messages when an external store swaps an optimistic message id mid-run (#4037). (@Yonom)Messages can now be flagged
metadata.isOptimistic. Optimistic messages are treated as ephemeral: they only ever live on the current head branch (the repository evicts off-branch optimistic messages whenever the head moves) and they are never written to persisted state (export()omits them). The AI SDK v6 adapter flags the streaming assistant message as optimistic, so when its client-generated id is replaced by a server-provided one mid-run, the stale placeholder no longer lingers as a phantom branch (e.g.BranchPickershowing2/2on a turn the user never branched). Unlike the reverted blanket id-diff (#4040), only explicitly-optimistic messages are affected, so legitimateonEdit/onReload/switchToBranchbranches are preserved.
... (truncated)
426c4ac
chore: update versions (#4177)27ae936
feat: move use-generative markers to core/react, extract the compiler,
add @a...275aef6
chore: update versions (#4129)2dec3ae
chore: update dependencies (#4175)eef724e
fix: drop phantom siblings on optimistic message id swap (#4037)
(#4162)1315789
feat: add @assistant-ui/next + "use generative"
toolkit support (#4172)fcb6baf
feat(core): tool display hint +
standalone-tool-call grouping (#4167)299d448
chore: drop stale biome-ignore pragmas after migrating to oxlint (#4151)0b99959
fix(react): release auto-stick intent on user scroll-up; fix retina
at-bottom...4429aa3
refactor: centralize thread-level shared options helper (#4136)