Repository navigation
Conversation
… unions
Replace the open AiReasoningEffortHint types (any string type-checks) with
closed per-model unions: the efforts every model accepted before
("low" | "medium" | "high", plus "minimal" for Responses) and the model's
supported efforts from Workers AI ConfigAPI metadata. Types widen only by
what a model actually supports, and still accept every value that compiled
against main. Aliases are documented in hover text, not typed.
The shared reasoning_effort and Responses reasoning types return to their
main definitions; AiReasoningEffortHint, ChatCompletionsReasoningEffort and
ResponsesInputReasoning are removed. Snapshots are generated with bazel.
Regenerated from the Workers AI SDK type generator, which now compares with the latest published @cloudflare/workers-types: - New models get exact types. GLM-5.3 accepts exactly "max" | "high" | "low" and its mandatory reasoning cannot be disabled (enable_thinking?: true). Adds Nemotron Speech Streaming (@cf/nvidia/nemotron-speech-streaming-en-0.6b). - Nemotron 3 (@cf/nvidia/nemotron-3-120b-a12b) publishes its own schema: no top-level reasoning_effort (the model never supported it), and chat_template_kwargs gains low_effort and force_nonempty_content. This is a one-time approved breaking change for object literals passing reasoning_effort. - Removes @cf/runwayml/stable-diffusion-v1-5-img2img, which is no longer offered. - Published models keep their closed, non-narrowing effort unions.
GLM-5.3's exact type rejects its compatibility aliases, so its hover docs no longer list them. Regenerated from cloudflare/ai/sdk!1782.
Owner
Author
|
Closing: we're going with exact per-model reasoning types for every model instead, now in cloudflare#7437 (2501936). |
KastanDay
pushed a commit
that referenced
this pull request
Oct 16, 2026
The TypeScript constructors read a source's, sink's or transformer's members in their own order, checking type first, where WebIDL converts the whole dictionary before the constructor checks type. Pin both implementations as they are, ahead of the change to WebIDL conversion: - every member's read, through getters, on a default and a byte source, a sink and a transformer; - which error wins when a bad callback meets an invalid type, an invalid highWaterMark or a byte stream's size function; - autoAllocateChunkSize and expectedLength on a default source, which TypeScript does not read and C++ converts; - autoAllocateChunkSize on a byte source: C++ converts an int, so a fraction truncates and 2 ** 31 and up throw; TypeScript requires a positive integer and sets no upper bound. The ledgers record each divergence: readable #2, cloudflare#32 and cloudflare#34; readable-byte #2, cloudflare#39 and cloudflare#40; writable cloudflare#3 and cloudflare#18; transform cloudflare#24 and cloudflare#27.
KastanDay
pushed a commit
that referenced
this pull request
Oct 16, 2026
Decision D-10, which fixes finding F-3. A byte source's autoAllocateChunkSize had to be a positive integer, so a fraction threw, and no upper bound applied, so a value above 2^53 - 1 failed only when a read allocated it. The member now converts as WebIDL converts an [EnforceRange] unsigned long long, and the byte controller then rejects zero, as the spec's setup step does. Under the TypeScript streams: - A fraction truncates (1.5 gives 1-byte views), as under C++. - 2^53 and up throw TypeError at construction. C++ throws from 2^31, the end of its int. - Zero throws 'autoAllocateChunkSize cannot be zero'; every other value the conversion refuses names the range. The conversion lives in common.ts, beside normalizeExpectedLength. The readable-byte ledger #2 pin flips its TypeScript side, and fractionalAutoAllocateChunkSize is now parity.
KastanDay
pushed a commit
that referenced
this pull request
Oct 16, 2026
Decision D-10, which also closes the validation half of finding F-1. The ReadableStream constructor checked the source's type, then a byte stream's size function and the strategy's highWaterMark, and only then did a controller read the callbacks; a default source's autoAllocateChunkSize and expectedLength were not read at all. WebIDL converts the whole UnderlyingSource dictionary, in lexicographic order, type last as an enum, before the constructor checks anything. common.ts now converts it that way, into a null-prototype record (convertUnderlyingSource), and the controllers take the record and the source, which stays the hooks' receiver. Under the TypeScript streams: - A non-callable pull, or a throwing pull getter, now beats an invalid type, as under C++. - A non-callable pull now beats an invalid highWaterMark and a byte stream's size function (RangeError until now) and a zero autoAllocateChunkSize (TypeError 'cannot be zero'), as under C++. - A default source converts autoAllocateChunkSize and expectedLength as a byte source does, with no zero check, although it uses neither. For autoAllocateChunkSize, -1, 'abc', NaN and Infinity now throw TypeError, where C++, which converts an int, accepts them; for expectedLength, 'abc' and -1 throw TypeError, as under C++. The members are read in lexicographic order, as the spec reads them; C++ reads them in its own order. Readable ledger #2, cloudflare#32 and cloudflare#34 and readable-byte ledger cloudflare#39 and cloudflare#40 flip their TypeScript side; the new cases of cloudflare#32 and cloudflare#40 are now parity, and cloudflare#40 gains a zero autoAllocateChunkSize against a non-callable pull. The webstreams AGENTS.md file map lists the three converters.
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.
Stacked on cloudflare#7437 (base:
kastan/workers-ai-reasoning-types). Merge this PR into that branch to adopt Design 1; leave it unmerged to keep cloudflare#7437's open-string hint types.Why
cloudflare#7437 publishes reasoning efforts as
AiReasoningEffortHint<...>: suggested values, but any string type-checks. Once shipped, that can never be narrowed again without breaking user code. This PR loosens the types the minimum amount instead.What changes
"low" | "medium" | "high", plus"minimal"for the Responses API) plus the efforts that model supports (from Workers AI ConfigAPI metadata).reasoning_effortand Responsesreasoningtypes go back tomain.AiReasoningEffortHint,ChatCompletionsReasoningEffortandResponsesInputReasoningare removed.enable_thinking?: truereasoning_effort; ownchat_template_kwargsNew models get exact types; published models only widen
The generator (cloudflare/ai/sdk!1782) compares with the latest published
@cloudflare/workers-types@5.20260923.1:"max" | "high" | "low", andenable_thinking?: true(its reasoning is mandatory). GLM-5.3's hover docs omit compatibility aliases, since its type rejects them. Adds Nemotron Speech Streaming (@cf/nvidia/nemotron-speech-streaming-en-0.6b) with its own schema.@cf/nvidia/nemotron-3-120b-a12b) publishes its own schema: no top-levelreasoning_effort(the model never supported it), andchat_template_kwargsgainslow_effortandforce_nonempty_content. Inputs remain structurally assignable frommain; only object literals passingreasoning_effortstop compiling.@cf/runwayml/stable-diffusion-v1-5-img2imgis no longer offered, so itsAiModelsentry is removed. It used the sharedBaseAiTextToImage, so no export is removed.Compatibility with
mainAiModelskey removed is img2img (checked by diffingkeyof AiModels).inputstype is assignable frommain's (checked for all shared models); outputs are unchanged.stringvalues are rejected, as onmain.Validation
bazel build //types;types/generated-snapshot/is exactlybazel-bin/types/definitions/.bazel test //types/...: 29/29 pass, including the rewrittentypes/test/types/ai-reasoning.ts(exact per-model unions, legacy values accepted for published models, exact types for new models, Nemotron's controls, img2img removed, unsupported/alias/arbitrary values rejected).