Version Packages#1828
Open
github-actions[bot] wants to merge 1 commit into
Open
Conversation
8c3dc0a to
e8bef13
Compare
e8bef13 to
28bb53b
Compare
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.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@cloudflare/think@0.12.0
Minor Changes
#1832
51ec433Thanks @threepointone! -getModel()now accepts a model id string, resolved through a built-inworkers-ai-providerinstance — no separate provider package to install, import, or wire up for the common case.Think now depends on
workers-ai-provider(plus the@ai-sdk/openaiand@ai-sdk/anthropicwire-format plugins) directly. WhengetModel()returns a string, Think resolves it off yourAIbinding:@cf/...id hits Workers AI directly (withsessionAffinitywired in automatically for prefix-cache hits)."<provider>/<model>"slug — e.g."openai/gpt-5.5","anthropic/claude-sonnet-4-5","google/gemini-2.5-pro","xai/grok-4","groq/..."— is routed through AI Gateway.Returning a fully-constructed AI SDK
LanguageModelfromgetModel()still works unchanged for any other provider or for full control over provider/gateway options. A newgetAIBinding()override (defaultthis.env.AI) controls which binding the string resolver uses.Because
getModel()may now return a bare string, a new publicresolveModel(model?)method (defaults to resolvinggetModel()) returns a concreteLanguageModel. Use it for side inference calls — e.g. summarization/compactiongenerateText— instead of passinggetModel()straight to the AI SDK.The per-turn override
TurnConfig.model(returned frombeforeTurn) also accepts aThinkModelnow, so you can switch models for a turn with a plain string (e.g. a cheaper model for continuations). The per-step overrideStepConfig.model(returned frombeforeStep) accepts aThinkModeltoo — Think resolves a string back into aLanguageModelbefore handing the step to the AI SDK.getModel()is typed to returnThinkModel(a newly exported alias forLanguageModel | ThinkModelId).ThinkModelId(also exported) gives editor autocomplete for the Workers AI text-generation catalog (@cf/..., derived from the installed@cloudflare/workers-types) while still accepting any string — gateway catalog slugs like"openai/gpt-5.5"are validated at runtime, since the catalog lives server-side and is not knowable from types.Patch Changes
#1827
e5e6b57Thanks @threepointone! - Fix sub-agent tool events getting stuck atinput-availablewhen an agent-tool child proxies a remotetoUIMessageStreamResponse()(#1589).tailAgentToolRun(in bothAIChatAgentandThink) drained the stored chunk backlog and only afterwards attached its live forwarder, withawaitboundaries in between. Any chunk the child stored and broadcast in that window was neither in the drained snapshot nor live-forwarded, so it silently vanished from the parent's stream — leaving tool parts (notablytool-output-available) stuck atinput-availableinuseAgentToolEvents. A network-paced proxied remote stream hits this window constantly, while a fast local child mostly avoids it. The forwarder is now registered before the backlog is drained, with live chunks buffered and replayed in order and deduped by sequence, closing the gap.Both
AIChatAgentandThinkalso realign the in-memory live sequence to the stored high-water mark after draining. Without this, a re-attach after the child's Durable Object restarts or wakes from hibernation (where the live counter is cold but the durable backlog sits at N) would hand the recovered turn's new chunks sequences from 0, which the high-water dedupe silently drops — leaving the parent permanently stuck with no post-restart chunks.agents@0.17.2
Patch Changes
#1836
0544aa2Thanks @threepointone! - FixuseAgentToolEventsdoubling streamed text in React StrictMode / SSR frameworks (#1835).The agent-tool-event reducer (
applyAgentToolEvent→applyToRun) shallow-copied a run'spartsarray with[...seeded.parts]and then handed it toapplyChunkToParts, which mutates part objects in place (e.g.lastTextPart.text += delta). Because the copied array still shared its element references with the previous state, those in-place mutations leaked back intoprev. React double-invokessetStateupdaters in StrictMode and during dev hydration, so eachtext-deltachunk was applied twice against the same already-mutatedprev, doubling every word. Affected Next.js, TanStack Start, Remix, and any<React.StrictMode>app. The reducer now clones each part before mutating, keeping it pure.#1838
cc21f09Thanks @threepointone! - Fix reconnect-driven resume overlap throwingCannot read properties of undefined (reading 'state')inuseAgentChat(#1837).With
resume: true(the default), the hook re-probes the stream from its WebSocketonAgentOpenhandler on every reconnect. The AI SDK'sChat.makeRequesthas no concurrency guard — every resume shares the single mutablethis.activeResponse, and itsfinallyfinalizer readsthis.activeResponse.state.messagewith a bare (unguarded) read before clearing it. Under a reconnect storm (flaky mobile link, or a Durable Object bounce on redeploy), a second resume could overwrite + clearactiveResponsebefore an earlier resume's finalizer ran, so the earlier finalizer readundefinedand threw. The old guard didn't close the window:isAwaitingResume()only covers the handshake (it flips false the instantSTREAM_RESUMINGresolves, before the AI SDK sets status tosubmittedin a later microtask) andstatusRefis lagging React state. Resumes are now serialized via an in-flight flag, so a re-proberesumeStream()is never issued while one is still outstanding.@cloudflare/ai-chat@0.9.2
Patch Changes
#1827
e5e6b57Thanks @threepointone! - Fix sub-agent tool events getting stuck atinput-availablewhen an agent-tool child proxies a remotetoUIMessageStreamResponse()(#1589).tailAgentToolRun(in bothAIChatAgentandThink) drained the stored chunk backlog and only afterwards attached its live forwarder, withawaitboundaries in between. Any chunk the child stored and broadcast in that window was neither in the drained snapshot nor live-forwarded, so it silently vanished from the parent's stream — leaving tool parts (notablytool-output-available) stuck atinput-availableinuseAgentToolEvents. A network-paced proxied remote stream hits this window constantly, while a fast local child mostly avoids it. The forwarder is now registered before the backlog is drained, with live chunks buffered and replayed in order and deduped by sequence, closing the gap.Both
AIChatAgentandThinkalso realign the in-memory live sequence to the stored high-water mark after draining. Without this, a re-attach after the child's Durable Object restarts or wakes from hibernation (where the live counter is cold but the durable backlog sits at N) would hand the recovered turn's new chunks sequences from 0, which the high-water dedupe silently drops — leaving the parent permanently stuck with no post-restart chunks.