Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
376 commits
Select commit Hold shift + click to select a range
cdc01fa
feat(openai,azure): provider tools on the provider instance
claude Oct 13, 2026
3630471
test(openai): pin raw chunks on the Responses stream
claude Oct 13, 2026
a437aee
docs(api): list the Vertex MaaS and xAI factories
claude Oct 13, 2026
f5ce5a2
fix(core): redact the Prodia and Azure subscription key headers
claude Oct 13, 2026
406f8aa
chore(types): regenerate the ApiCallError status_code doc
claude Oct 13, 2026
a7150bb
Merge [6/8] into [7/8]: vendor alignment and the lower layers' fixes
claude Oct 13, 2026
2e8b3e4
fix(flutter): give the NativeFinalizer a pointer-sized drop entry point
claude Oct 13, 2026
fe9136c
fix(python): release the GIL around every blocking native call
claude Oct 13, 2026
0b85e7e
fix(core): an approval request replays input_schema_input only when i…
claude Oct 13, 2026
20d7458
fix(core)!: a provider tool result without its call is an error unles…
claude Oct 13, 2026
9a94b17
fix(web): accept env:VAR only for the provider's registered key variable
claude Oct 13, 2026
f0ced8e
chore(fixtures): pin @ai-sdk/provider 4.0.22, the first DecisionModel…
claude Oct 13, 2026
9111473
refactor(core)!: stream tool results are the AI SDK's typed tool resu…
claude Oct 13, 2026
e01a6c6
feat(core): an invalid tool call in the stream is followed by a tool …
claude Oct 13, 2026
7384b47
fix(providers): each package names its own provider-utils in the user…
claude Oct 13, 2026
1a9c60a
feat(core): the stream's part set includes tool-output-denied and too…
claude Oct 13, 2026
124dd49
fix(web): send no stored or env key to a caller-supplied base_url
claude Oct 13, 2026
f7c9177
fix(openai-compatible): chat stream errors carry no inferred status
claude Oct 13, 2026
75865e3
test(core): restore RFC-0031's stream timeout and pipeline tests (#23…
claude Oct 13, 2026
e131a55
fix(vertex): partner provider headers win over per-call headers
claude Oct 13, 2026
f9a31f4
test(core): acceptance tests for the stream part set, stream state an…
claude Oct 13, 2026
9505486
fix(core): never mark a recording complete after a lost or inconsiste…
claude Oct 13, 2026
6ed88c1
refactor(core)!: realtime transcription streaming is an optional method
claude Oct 13, 2026
96e96fa
fix(anthropic): stream error data is the frame's data or the error
claude Oct 13, 2026
ced1a9b
fix(replay): replay decision recordings of any provider live
claude Oct 13, 2026
c4b089f
docs: RFC-0031 states where the AI SDK request pipeline differs (U2, …
claude Oct 13, 2026
2198aab
feat(core): custom_provider forwards discovery to its fallback
claude Oct 13, 2026
f745459
fix(core): OpenAI output logprobs in the Chat Completions wire shape
claude Oct 13, 2026
90945bb
docs(alignment): register Bedrock Mantle and AWS GET signing as known…
claude Oct 13, 2026
555630b
fix(web): give each custom endpoint its own trace scope
claude Oct 13, 2026
21f1457
docs(rfc): add the RFC-0023 revision line for the V4 recording layer
claude Oct 13, 2026
73012b0
feat(core)!: speech results carry the provider's usage
claude Oct 13, 2026
907393f
refactor(core)!: decision recordings carry no capability snapshot
claude Oct 13, 2026
37255a7
Merge [6/8] into [7/8]: per-package user-agents and upstream error/he…
claude Oct 13, 2026
3386ec5
fix(open-responses): send the ai-sdk-open-responses user-agent part
claude Oct 13, 2026
96a6a4f
fix(openai): chat logprobs metadata drops bytes as upstream
claude Oct 13, 2026
4c00266
Merge [3/8] into [4/8]: core ContentPart steps, prompt and tool-choic…
claude Oct 13, 2026
ee18247
fix(vertex): a partner provider user-agent header replaces the whole one
claude Oct 13, 2026
8520201
docs: the alignment document follows ai 7.0.127 for results, jobs and…
claude Oct 13, 2026
dcaf474
fix(provider-utils): URL downloads send no user-agent, as downloadBlob
claude Oct 13, 2026
fb416f9
fix(openai): image edits download URL files through the download guard
claude Oct 13, 2026
a87b9ca
fix(google): files upload sends no provider-utils user-agent part
claude Oct 13, 2026
822def8
refactor(core)!: the retry count, timeout and session id are operatio…
claude Oct 13, 2026
e0996ce
Merge [6/8] into [8/8]: vendor alignment and the lower layers' fixes
claude Oct 13, 2026
e6f88ba
Merge [4/8] into [5/8]: AI SDK steps, stream parts and operation sett…
claude Oct 13, 2026
92e86a9
fix(core): tests and comments follow the merged retry and error sets
claude Oct 13, 2026
4b662a5
fix(providers): layer 5 provider code takes layers 2 to 4 types
claude Oct 13, 2026
9bfa1e9
chore(fixtures): the recorder pins provider-utils 5.0.55 as VERSIONS.…
claude Oct 13, 2026
bbbc72a
refactor(core)!: decisions follow DecisionModelV4
claude Oct 13, 2026
ed192ea
docs: video polling, retry comments and generated types after the merge
claude Oct 13, 2026
b647fb8
fix(core)!: bytes are base64 strings in the public JSON (#232 C33)
claude Oct 13, 2026
8f9bcca
fix(decision): decision image bytes are a base64 string (#232 C33a)
claude Oct 13, 2026
06bb478
feat(core)!: the operations take an injectable download, as the AI SD…
claude Oct 13, 2026
52bd723
fix(core)!: JSON null is kept apart from a missing value (#232 C34)
claude Oct 13, 2026
0b1908d
docs(changelog): note that JSON null is kept apart from missing (#232…
claude Oct 13, 2026
d2c82df
Merge [5/8] into [6/8]: providers are AI SDK factories
claude Oct 13, 2026
8b23a16
fix(providers): layer 6 provider code takes layer 5's types
claude Oct 13, 2026
f4c5fe0
fix(providers): the layer 6 transcription models refuse URL audio
claude Oct 13, 2026
87544a5
fix(core)!: file content parts are the AI SDK FilePart (#232 C35)
claude Oct 13, 2026
c3846ba
test(anthropic): an unparsable stream chunk is an error part
claude Oct 13, 2026
ac0d061
fix(providers): Cohere, Open Responses and xAI Responses declare thei…
claude Oct 13, 2026
19a9a3c
fix(core)!: generated files are {base64, mediaType} (#232 C46)
claude Oct 13, 2026
317ebcd
test: restore the hand-written unit tests 48a92aaf deleted that still…
claude Oct 13, 2026
d062be3
fix(codex): Codex models declare the OpenAI Responses supported URLs
claude Oct 13, 2026
3f389ba
fix(huggingface): pin @ai-sdk/huggingface 2.0.62 and declare its supp…
claude Oct 13, 2026
97c6fbc
fix(core)!: timestamps are toISOString() strings (#232 C48)
claude Oct 13, 2026
bc013ad
chore(node): export the generated Timestamp type (#232 C48)
claude Oct 13, 2026
c71fae0
Merge [6/8] into [7/8]: layer 6 with layers 2-5 (V4 types, operation …
claude Oct 13, 2026
21719b5
fix(core)!: text and reasoning stream deltas carry text (#229 B9)
claude Oct 13, 2026
e8279c4
fix: layer 7 code takes layers 2-6's types
claude Oct 13, 2026
635a3f4
test(providers): the layer 7 transcription models refuse URL audio
claude Oct 13, 2026
f94eadb
fix(core): decide runs its model call in the operation settings
claude Oct 13, 2026
3d78123
refactor(core)!: provider namespace maps keep insertion order (#229 N…
claude Oct 13, 2026
efd10d6
test(kotlin): the OpenAI decision test sends the fixture's options in…
claude Oct 13, 2026
6aa327d
docs(node): regenerate index.d.ts for applyToolCallRepair's doc
claude Oct 13, 2026
35711cb
test(node): the reasoning replay test gives its tool call a result
claude Oct 13, 2026
dcc11f8
Merge [3/8] into [4/8]: the reasoning replay test gives its tool call…
claude Oct 13, 2026
18e3e0e
test(bindings): the DeepSeek usage.raw tests read the step usage
claude Oct 13, 2026
4ce9aa0
docs(node): regenerate index.d.ts for applyToolCallRepair's doc
claude Oct 13, 2026
cfe290a
Merge [4/8] into [5/8]: binding tests follow layers 3 and 4
claude Oct 13, 2026
8bef2c9
Merge [5/8] into [6/8]: binding tests follow layers 3 and 4
claude Oct 13, 2026
1602ed8
Merge [6/8] into [7/8]: binding tests follow layers 3 and 4
claude Oct 13, 2026
5415fea
test(swift): the OpenAI decision test sends the fixture's options in …
claude Oct 13, 2026
f69a33f
fix(core)!: standalone tool calls and sources carry their type tag (#…
claude Oct 13, 2026
af252bb
fix(core)!: integral tool input numbers are written as JavaScript wri…
claude Oct 13, 2026
f42526b
docs(rfc): RFC-0035 shows the final repair wire and upstream's contro…
claude Oct 13, 2026
4b200a5
test(node,python): decision usage omits unknown totals, never null
claude Oct 13, 2026
38770b5
fix(core): keep recording schema 2 and read the recordings master writes
claude Oct 13, 2026
9d01eb5
chore(core): keep the removed key-source field name out of code
claude Oct 13, 2026
a382242
Merge [5/8] into [6/8]: recording schema 2, master recordings load
claude Oct 13, 2026
7294e13
Merge [6/8] into [7/8]: recording schema 2, master recordings load
claude Oct 13, 2026
370f077
docs(changelog): legacy vertex and bedrock keys are still read and wr…
claude Oct 13, 2026
4cb1e53
Merge [5/8] into [6/8]: CHANGELOG wording for legacy namespace keys
claude Oct 13, 2026
9fcc401
Merge [6/8] into [7/8]: CHANGELOG wording for legacy namespace keys
claude Oct 13, 2026
3bae669
docs(changelog): decision recordings carry no capability snapshot
claude Oct 13, 2026
3949042
Merge [7/8] into [8/8]: layer 7 (decisions, speech usage, layers 2-6)…
claude Oct 13, 2026
2da6fa9
fix(go)!: Error.Data keeps a null API call error data apart from none
claude Oct 13, 2026
7a9a4e7
docs: RFC-0035 names the tests that pin repair; RFC-0026 deltas carry…
claude Oct 13, 2026
c9d99c9
refactor!: text results' usage, steps, tool outputs and Output follow…
claude Oct 13, 2026
1f6d61e
docs(rfc): RFC-0036's stream example writes the public JSON
claude Oct 13, 2026
a8fb12f
Merge [7/8] into [8/8]: recording schema 2, master recordings load
claude Oct 13, 2026
6b214ac
refactor!: decisions follow the public JSON
claude Oct 13, 2026
87e652c
docs: fix two rustdoc links that fail cargo doc -D warnings
claude Oct 13, 2026
ee60e4e
Merge [6/8] into [7/8]: rustdoc link fixes
claude Oct 13, 2026
58572b3
Merge [5/8] into [6/8]: rustdoc link fixes
claude Oct 13, 2026
48083ff
docs: plain code spans for the private stream_transcription methods
claude Oct 13, 2026
6d51fe7
Merge [7/8] into [8/8]: rustdoc link fixes
claude Oct 13, 2026
03b43b7
ci: speed up test builds, deduplicate caches, and use prebuilt cargo-ndk
Oct 14, 2026
f755c28
test(flutter): typed stream fixtures are JSON maps; the chat mock is …
claude Oct 14, 2026
9ab9dff
ci: keep uploaded artifacts unchanged and stop PR runs from evicting …
claude Oct 14, 2026
c75e37f
test(swift): the plain-text result's content part is type-tagged
claude Oct 14, 2026
c9ade5f
ci: fewer jobs per run so pull requests stop queueing for runners
claude Oct 14, 2026
2e746cd
docs(alignment): the first-chunk timer start is a registered difference
claude Oct 14, 2026
df7a67c
Merge the CI speed-up (#262) into [1/8]
claude Oct 14, 2026
4e0bfe2
Merge [1/8] into [2/8]: the CI speed-up (#262)
claude Oct 14, 2026
0fe1a89
Merge [2/8] into [3/8]: the CI speed-up (#262)
claude Oct 14, 2026
2af8255
Merge [3/8] into [4/8]: the CI speed-up (#262)
claude Oct 14, 2026
8ecea4e
Merge [4/8] into [5/8]: the CI speed-up (#262)
claude Oct 14, 2026
777e358
Merge [5/8] into [6/8]: the CI speed-up (#262)
claude Oct 14, 2026
008859c
Merge [7/8] into [8/8]: the CI speed-up (#262)
claude Oct 14, 2026
f80fff2
Merge [6/8] into [7/8]: the CI speed-up (#262)
claude Oct 14, 2026
8ab9abb
ci: restore the Flutter SDK cache everywhere, save it from master only
claude Oct 14, 2026
753b61b
ci: build test-only FFI libraries at opt-level 1, not 0
claude Oct 14, 2026
19b9e9f
Merge the CI fix (#262) into [1/8]: test libraries at opt-level 1
claude Oct 14, 2026
824f948
Merge [1/8] into [2/8]: the CI fix (#262)
claude Oct 14, 2026
515fb3d
Merge [2/8] into [3/8]: the CI fix (#262)
claude Oct 14, 2026
75e96c2
Merge [3/8] into [4/8]: the CI fix (#262)
claude Oct 14, 2026
5aadb1c
Merge [4/8] into [5/8]: the CI fix (#262)
claude Oct 14, 2026
dd13b04
Merge [5/8] into [6/8]: the CI fix (#262)
claude Oct 14, 2026
ca181dd
Merge [7/8] into [8/8]: the CI fix (#262)
claude Oct 14, 2026
22db086
Merge [6/8] into [7/8]: the CI fix (#262)
claude Oct 14, 2026
8ccd560
Merge branch 'master' into ci/optimize-ci-speed-and-cache
claude Oct 15, 2026
ca886c1
ci: pin cargo-ndk and keep pull requests from saving two more caches
claude Oct 15, 2026
7c5ded7
Merge branch 'master' into ci/optimize-ci-speed-and-cache
claude Oct 15, 2026
3fcf1da
Merge master into the ProviderName removal: Bedrock SigV4 and secret …
claude Oct 15, 2026
ec7ab7c
chore: delete the web console's generated ProviderName copy
claude Oct 15, 2026
ea0384a
Merge master into the web wire types: tiered CI (#263), Bedrock SigV4…
claude Oct 15, 2026
1bd6a55
ci: type-check the web console against the generated types
claude Oct 15, 2026
d1005cf
Merge the CI speed-up branch (with master) into [1/8]: tiered CI (#26…
claude Oct 15, 2026
d482975
docs: size and performance gates follow RFC-0043
claude Oct 15, 2026
c1d10b5
docs: the alignment doc links back to RFC-0036 §12.2 and names the me…
claude Oct 15, 2026
b32dc0a
ci: run the AI SDK pin script tests
claude Oct 15, 2026
710fcd7
docs: note the retired contract fixtures in the RFCs and the changelog
claude Oct 15, 2026
be87f81
docs(web): note that cargo test rewrites the tracked node types
claude Oct 15, 2026
d30833d
Merge [1/8] into [2/8]: master (#205-#212, #248, #263), the RFC-0043 …
claude Oct 15, 2026
d005871
test(openai): tool calls are flushed after an error frame
claude Oct 15, 2026
f0ee302
refactor(provider-utils): bound the tracker's id suffix search
claude Oct 15, 2026
fb2f23f
Merge [2/8] into [3/8]: master (#205-#212, #248, #263), the RFC-0043 …
claude Oct 15, 2026
7a726e3
test(core): restore the OpenAI output tool-argument tests
claude Oct 15, 2026
88ce267
test(core): part metadata replays whole into providerOptions
claude Oct 15, 2026
750f9a0
test(ffi): restore the composite, frame-error and session-input tests
claude Oct 15, 2026
4b21206
fix(core): a stream that ends with Finish is traced as completed
claude Oct 15, 2026
bfd9fdd
test(core): restore the TraceLayer suite
claude Oct 15, 2026
6faea33
test(core): a traced call keeps the id of its recording
claude Oct 15, 2026
62e2967
test(google): restore the inlineData-to-file tests
claude Oct 15, 2026
9fd8905
test(core): restore the replay_with_model tests
claude Oct 15, 2026
95d9a3a
Merge [3/8] into [4/8]: master (#205-#212, #248, #263), the RFC-0043 …
claude Oct 15, 2026
a7efac0
test(core): pin an abort after a finished step and repeated tool-call…
claude Oct 15, 2026
d989330
docs(alignment): register recording_context and deferred provider res…
claude Oct 15, 2026
1aead53
refactor(stream_text): the chunk loop has no arm that cannot run
claude Oct 16, 2026
73626fe
Merge [4/8] into [5/8]: master (#205-#212, #248, #263), #262's CI fol…
claude Oct 16, 2026
5fa4045
test(provider-utils): the default-transport test keeps 127.0.0.1 off …
claude Oct 15, 2026
e03b5f1
docs(web): a blank key at a custom base_url goes out as an empty key
claude Oct 15, 2026
20a0ee5
test(provider-utils): pin the redirect cap and re-signing on a same-o…
claude Oct 15, 2026
b7f1b7f
docs(rfc): RFC-0040 §3.2 follows the implemented redirect rule
claude Oct 15, 2026
a2ba419
test(providers): a preset's base-URL and optional-key variables
claude Oct 15, 2026
636b4ca
Merge [5/8] into [6/8]: master (#205-#212, #248, #263), #262's CI fol…
claude Oct 16, 2026
a693548
test(mistral): model_length is a length finish
claude Oct 15, 2026
bd2d041
test(providers): non-object input of a past tool call
claude Oct 15, 2026
007ad30
fix(anthropic): toolset member calls go back as upstream sends them
claude Oct 16, 2026
ed69b7e
test(preset): the registry checks run on any input
claude Oct 16, 2026
a9a97fd
fix(anthropic): provider tool args are checked as upstream checks them
claude Oct 16, 2026
78d7b90
Merge [7/8] into [8/8]: master (#205-#212, #248, #263), #262's CI fol…
claude Oct 16, 2026
13845e1
test(provider-utils): say how the botocore SigV4 pins were made
claude Oct 15, 2026
9db6427
Merge [6/8] into [7/8]: master (#205-#212, #248, #263), #262's CI fol…
claude Oct 16, 2026
272a70b
docs(core): a tool result carries only output
claude Oct 15, 2026
e899de9
feat(anthropic): decision_model is upstream's evaluationModel
claude Oct 15, 2026
8f1eaf4
test(google): restore the thought-signature replay tests
claude Oct 15, 2026
7511ff4
test(providers): a failed decision is recorded and replays as the fai…
claude Oct 15, 2026
f275cdf
fix(core): request options reject unknown keys
claude Oct 15, 2026
7c3bb6a
docs(core): replay's question types and the video status key
claude Oct 15, 2026
d365388
fix(core): a prompt part with an unknown type names it
claude Oct 15, 2026
72e4fb9
docs(core): cite upstream for the snake_case video frame type
claude Oct 15, 2026
586235f
test(anthropic): compare usage JSON with what the AI SDK wrote
claude Oct 15, 2026
8f90ad6
feat(core): the recording context has an operation scope
claude Oct 16, 2026
13131b8
refactor(core)!: the recording context is an operation value, not a c…
claude Oct 16, 2026
2c86792
Merge the ProviderName removal (#246) into the web wire types
claude Oct 16, 2026
c749bf5
fix(core)!: a deferred tool result needs a provider tool that support…
claude Oct 16, 2026
9432c71
docs(core): the replay key and input record no longer name a recordin…
claude Oct 16, 2026
36b91bc
Merge [4/8] into [5/8]: deferred tool results and the recording scope
claude Oct 16, 2026
46e974a
Merge [5/8] into [6/8]: deferred tool results and the recording scope
claude Oct 16, 2026
aad72e8
Merge [6/8] into [7/8]: deferred tool results and the recording scope
claude Oct 16, 2026
67c7f1d
Merge [7/8] into [8/8]: deferred tool results and the recording scope
claude Oct 16, 2026
0b78344
build(core): ts-rs exports run only from the generator
claude Oct 16, 2026
e4104aa
fix(provider-utils): the tool call tracker generates ids as upstream
claude Oct 16, 2026
2f51e47
feat(bindings): typed provider tools carry supportsDeferredResults
claude Oct 16, 2026
79ea814
chore(node): regenerate InputRecord.ts for the corrected options comment
claude Oct 16, 2026
af67cb8
Merge [2/8] into [3/8]: the tracker generates ids as upstream
claude Oct 16, 2026
1e0a04d
Merge [3/8] into [4/8]: the tracker generates ids as upstream
claude Oct 16, 2026
85e65d8
Merge [4/8] into [5/8]: tracker ids, binding provider tools, InputRec…
claude Oct 16, 2026
2eef03b
Merge [5/8] into [6/8]: tracker ids, binding provider tools, InputRec…
claude Oct 16, 2026
31fb8fe
Merge [6/8] into [7/8]: tracker ids, binding provider tools, InputRec…
claude Oct 16, 2026
eb24c62
Merge [7/8] into [8/8]: tracker ids, binding provider tools, InputRec…
claude Oct 16, 2026
c6382f1
fix(core)!: MoA failMode and the recording operation are kebab-case
claude Oct 16, 2026
c525525
Merge #247 into [1/8]: gated ts-rs exports and the ProviderName removal
claude Oct 16, 2026
020688d
Merge [1/8] into [2/8]: gated ts-rs exports and the ProviderName removal
claude Oct 16, 2026
21a4b2f
Merge [2/8] into [3/8]: gated ts-rs exports and the ProviderName removal
claude Oct 16, 2026
36a9e5c
Merge [3/8] into [4/8]: gated ts-rs exports and the ProviderName removal
claude Oct 16, 2026
2c477ce
Merge [4/8] into [5/8]: gated ts-rs exports and the ProviderName removal
claude Oct 16, 2026
4ba56b0
Merge [5/8] into [6/8]: gated ts-rs exports and the ProviderName removal
claude Oct 16, 2026
e661f11
Merge [6/8] into [7/8]: gated ts-rs exports and the ProviderName removal
claude Oct 16, 2026
564cfff
Merge [7/8] into [8/8]: gated ts-rs exports and the ProviderName removal
claude Oct 16, 2026
b0dc009
docs(changelog): the deferred tool result rule is generate_text's
claude Oct 16, 2026
e347e8c
feat(go): provider tools carry supportsDeferredResults
claude Oct 16, 2026
6422a37
Merge [4/8] into [5/8]: the deferred tool result rule is generate_text's
claude Oct 16, 2026
7da96b4
Merge [5/8] into [6/8]: the deferred tool result rule is generate_text's
claude Oct 16, 2026
de9e9a0
Merge [6/8] into [7/8]: the deferred tool result rule is generate_text's
claude Oct 16, 2026
095ee27
Merge [7/8] into [8/8]: the deferred tool result rule is generate_text's
claude Oct 16, 2026
7a4b023
Merge master into #246: the #266 docs wording
claude Oct 16, 2026
453f611
Merge #246 into #247: master's #266 docs wording
claude Oct 16, 2026
796bd99
Merge #247 into [1/8]: master's #266 docs wording
claude Oct 16, 2026
36c8823
Merge [1/8] into [2/8]: master's #266 docs wording
claude Oct 16, 2026
59d9005
Merge [2/8] into [3/8]: master's #266 docs wording
claude Oct 16, 2026
2997346
Merge [3/8] into [4/8]: master's #266 docs wording
claude Oct 16, 2026
857b29d
Merge [4/8] into [5/8]: master's #266 docs wording
claude Oct 16, 2026
bed5ca7
Merge [5/8] into [6/8]: master's #266 docs wording
claude Oct 16, 2026
cd55182
Merge [6/8] into [7/8]: master's #266 docs wording
claude Oct 16, 2026
8eaa63d
Merge [7/8] into [8/8]: master's #266 docs wording
claude Oct 16, 2026
6ca248e
test(scripts): give the pin fetch test its own user and global npmrc
claude Oct 16, 2026
e572504
Merge [3/8] into [4/8]: the pin fetch test fix
claude Oct 16, 2026
7790a2b
Merge [1/8] into [2/8]: the pin fetch test fix
claude Oct 16, 2026
be39004
Merge [2/8] into [3/8]: the pin fetch test fix
claude Oct 16, 2026
9a9056c
Merge [4/8] into [5/8]: the pin fetch test fix
claude Oct 16, 2026
f88bd61
Merge [5/8] into [6/8]: the pin fetch test fix
claude Oct 16, 2026
dc656f8
Merge [6/8] into [7/8]: the pin fetch test fix
claude Oct 16, 2026
5ee53e2
Merge [7/8] into [8/8]: the pin fetch test fix
claude Oct 16, 2026
38b6cde
docs(rfc): the retry count, timeout and session id are operation sett…
claude Oct 16, 2026
f039e50
Merge [4/8] into [5/8]: RFC text for the operation settings
claude Oct 16, 2026
7be67e6
Merge [5/8] into [6/8]: RFC text for the operation settings
claude Oct 16, 2026
593b5e5
Merge [6/8] into [7/8]: RFC text for the operation settings
claude Oct 16, 2026
9cef9bf
Merge [7/8] into [8/8]: RFC text for the operation settings
claude Oct 16, 2026
2a0b02b
Merge master into [1/8]: keep this layer ci.yml/CHANGELOG/local-ci
eric8810 Oct 17, 2026
057453e
Merge [1/8] into [2/8]: #262, #246 and #247 as eric merged them
claude Oct 17, 2026
bdeebad
Merge [2/8] into [3/8]: #262, #246 and #247 as eric merged them
claude Oct 17, 2026
6fec783
Merge [3/8] into [4/8]: #262, #246 and #247 as eric merged them
claude Oct 17, 2026
79c2efc
Merge [4/8] into [5/8]: #262, #246 and #247 as eric merged them
claude Oct 17, 2026
dbf852f
Merge [5/8] into [6/8]: #262, #246 and #247 as eric merged them
claude Oct 17, 2026
fa3d877
Merge [6/8] into [7/8]: #262, #246 and #247 as eric merged them
claude Oct 17, 2026
f8a4287
Merge [7/8] into [8/8]: #262, #246 and #247 as eric merged them
claude Oct 17, 2026
544117a
Merge master into [8/8]: converge to the layer tree
eric8810 Oct 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,12 @@ jobs:
if ($dependencies -match '(?im)^\s*(?:VCRUNTIME|MSVCP|UCRTBASE|api-ms-win-crt)[^\s]*\.dll\s*$') {
throw "Dynamic MSVC runtime dependency found:`n$dependencies"
}
# The binding crate's own Rust unit tests (JSON parsing, no Node
# runtime). The crate is not a member of the main workspace, so
# rust-test does not run them; one leg suffices.
- name: Rust unit tests
if: matrix.settings.test && runner.os == 'Linux'
run: cargo test --lib --manifest-path bindings/node/Cargo.toml
- name: Test
if: matrix.settings.test
working-directory: bindings/node
Expand Down Expand Up @@ -349,6 +355,10 @@ jobs:
cache-dependency-path: bindings/python/pyproject.toml
- name: Install maturin
run: pip install "maturin[patchelf]"
# The binding crate's own Rust unit tests (JSON parsing); the crate is
# not a member of the main workspace, so rust-test does not run them.
- name: Rust unit tests
run: cargo test --lib --manifest-path bindings/python/Cargo.toml
- name: Build
working-directory: bindings/python
shell: bash
Expand Down
186 changes: 175 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,163 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Breaking

- aimux's public JSON equals the AI SDK's JSON. Struct fields serialize
camelCase (`toolCallId`, `providerOptions`, `inputTokens`); unions carry the
AI SDK's tag and strings (`{"type":"text-delta"}`, `"tool-call"`,
`"reasoning-file"`, Source `sourceType`, Warning/FileData/ResponseFormat/
stream parts no longer externally tagged); bytes are base64 strings;
optional fields are omitted instead of `null` and generate as `field?: T`;
`AiMuxError` is tagged by `name`
(`AI_APICallError`, `AI_RetryError`, ...). Vendor request and response types
and the OpenAI chat-completion output keep their vendor wire formats.
Persisted recordings and trace records change with the same rule;
recordings stay schema 2 and still read the snake_case envelope keys
aimux 0.5 writes (`call_id`, `recorded_at`, `model_id`, ...).

- MoA `failMode` values (`"best-effort"`, `"fail-fast"`) and the recording
operation value `"language-model"` use kebab-case.

- Bytes are base64 strings in the public JSON, as the AI SDK writes a
`Uint8Array`: image part `image`, file part `data`, `FileBytes`, speech
`audio`, image outputs, video `binary` data and audio/image/video inputs. An
array of numbers is no longer read. Bindings keep their byte-valued APIs
(`Binary` variants, Python `bytes`) and encode them at the JSON boundary
(#232 C33). Decision images (`images[].data` in a provider's options)
follow the same rule; Python `decide` encodes `bytes` image data there
(C33a).

- JSON `null` is kept apart from a missing value where the AI SDK's type is
`unknown`: response and request `body` (language, speech, transcription,
embedding, reranking and search results), `APICallError.data` and the tool
approval request's `inputSchemaInput` read `"body": null` as a present null
and write it back, and omit the field only when it was missing. Python
serializes without `exclude_none` and keeps a set `None` of an `Any` field;
Go reads these bodies as `json.RawMessage`, and `Error.Data` changes from
`any` to `json.RawMessage` (`nil` when missing, `null` when null); Dart
gains `hasBody` / `hasInputSchemaInput` (#232 C34).

- File content parts are the AI SDK's `FilePart`: one `file` tag whose `data`
is a tagged `FileData` (`{type:"data"|"url"|"reference"|"text"}`), a string
(base64 or a URL) or a bare `{provider: id}` reference. The `file-base64`,
`file-url` and `file-reference` parts are removed; write
`{type:"file", data:{type:"url", url}}` and so on. A `reasoning-file`
part's `data` also takes a bare string. A `data:` URL's media type wins over
the part's `mediaType`, and response messages carry files as bare base64
strings. Bindings replace the three part classes with a typed `FilePartData`
(#232 C35).

- Generated files are the AI SDK's `GeneratedFile`: `files[]` holds
`{base64, mediaType, providerMetadata?}` instead of
`{type:"data"|"url", ...}`, and the text results' and stream's `file` /
`reasoning-file` parts are `{type, file: GeneratedFile, providerMetadata?}`.
`ReasoningFileOutput` is replaced by `GeneratedFileOutput`; the
provider-level `raw.content` keeps the V4 file
(`LanguageModelFile`: `{mediaType, data}`). Bindings gain a `GeneratedFile`
type with a bytes accessor (#232 C46).

- Response timestamps are written as JavaScript's `Date.toISOString()`
(`"2025-03-06T13:50:19.000Z"`: UTC, milliseconds) instead of each
provider's own form (`+00:00` offsets, nanoseconds, Bedrock's HTTP date,
Open Responses' Unix seconds). Reading one requires an RFC 3339 date-time;
other text is an error, so stored results or recordings with another form
no longer parse. In Rust the fields are `Option<Timestamp>`
(`aimux_core::Timestamp`) instead of `Option<String>`. Binding types stay
strings (#232 C48).

- The text stream's `text-delta` and `reasoning-delta` parts carry their
text under `text`, as the AI SDK's `TextStreamPart` does, instead of
`delta`. `tool-input-delta` keeps `delta`, and so does the provider-level
`StreamPart`. Rust matches `TextStreamPart::TextDelta { text, .. }`; the
bindings' typed parts rename `delta` to `text` (Go `TextDeltaPayload.Text`,
Java `getText()`, Kotlin/Swift/Dart `text`) (#229 B9).

- Provider options, provider metadata and provider references keep their
keys in insertion order end to end, as the AI SDK's JS objects do: Rust
holds them as `IndexMap` (see the provider options entry below) and the
bindings no longer sort them. Go: `Tool.ProviderOptions` and
`TranscriptionSessionOpts.ProviderOptions` are `json.RawMessage` instead of
`map[string]json.RawMessage`, and `UploadFileResult.ProviderReference` is a
`ProviderReference` (raw JSON, read with `Get(provider)`) instead of
`map[string]string`. Java's `UploadFileResult` defaults to a
`LinkedHashMap`. Swift's typed dictionaries remain unordered (#229 NP2-1).

- A tool call or source outside `content` carries its AI SDK `type` tag: the
text results' `toolCalls[]` and an approval request's `toolCall` are
`{"type": "tool-call", ...}` (the AI SDK's `TypedToolCall`), and their
`sources[]` are `{"type": "source", "sourceType", ...}`. So are the repair
context's `toolCall` and the call `apply_tool_call_repair` returns (a
`LanguageModelV4ToolCall`). Reading accepts JSON without the tag and rejects
a different one. Rust keeps `ToolCall` and `Source` untagged and writes the
tag through `wire::typed` / `wire::typed_vec` / `wire::Tagged`; TypeScript
types the fields as the new `TypedToolCall` and `TypedSource`. Every
binding's standalone `ToolCall`, `RawToolCall` and `Source` writes the tag
(Go through `MarshalJSON`; Java, Kotlin, Swift, Dart and Python as a fixed
`type` field) (#229 NP2-7).

- Tool-call input parsed from the model's argument text writes an integral
number as JavaScript does: `1e2` and `100.0` become `100`, `-0.0` becomes
`0`, as `JSON.stringify(JSON.parse(text))` writes them, instead of
serde_json's `100.0`. Other numbers are unchanged. Bindings that tell
integers from floats (Python `int`, Go raw JSON, Jackson `IntNode`) now see
integers (#229).

- The text results' usage, steps and typed tool outputs follow the same JSON
rules. `LanguageModelUsage` (`usage`, `totalUsage`, each step's and the
`finish` / `finish-step` parts' usage) is camelCase: `inputTokens`,
`inputTokenDetails {noCacheTokens, cacheReadTokens, cacheWriteTokens}`,
`outputTokens`, `outputTokenDetails {textTokens, reasoningTokens}`,
`totalTokens`, `raw?`; an unknown count is omitted instead of `null`, the
two detail objects are always written. `steps[]` are camelCase (`callId`,
`stepNumber`, `model {provider, modelId}`, `rawFinishReason?`,
`performance {stepTimeMs, responseTimeMs, timeToFirstOutputMs?, ...}`,
`response {id, timestamp, modelId, headers?, body?, messages}`). Tool
results, tool errors, `tool-output-denied` and `tool-approval-response`
parts write `toolCallId`, `toolName`, `providerExecuted`, `approvalId`; an
approval response's `toolCall` carries `type: "tool-call"`, and the
results' `toolResults[]` are `{"type": "tool-result", ...}` (the AI SDK's
`TypedToolResult`; TypeScript `TaggedToolResult`). Recordings write the
outcome's usage the same way. Go, Java, Kotlin, Swift and Dart read and
write the camelCase keys with unchanged field names; Python dicts and Node
objects carry the new keys. Kotlin, Swift and Dart keep a parsed JSON
`null` output apart from no output (Kotlin `JsonNull`, Swift `.null`, Dart
`hasOutput`).

- `Output` (the `output` option of `generateText` / `streamText` and
`generate_object`) is tagged by `type`, as the AI SDK names its output
modes: `{"type": "text"}`, `{"type": "object", "schema", "name?",
"description?"}`, `{"type": "array", "element", "minItems?", "maxItems?",
...}`, `{"type": "choice", "options"}`, `{"type": "json"}`. The externally
tagged `{"Object": {...}}` form is no longer read.

- Decisions follow the same JSON rules. `DecideOptions` and
`DecisionCallOptions` write `maxRetries` and `providerOptions`;
`DecisionResult` and `DecideResult` write `rounding {probabilityDecimals,
scoreDecimals}`, `providerMetadata` and `usage {inputTokens, outputTokens,
totalTokens}`, an unknown count omitted instead of `null`
(`decision-result.ts:27-31`). The model description of
`aimux_decision_capabilities` and every binding's `describe` is
`{specificationVersion, provider, modelId, supportedQuestionTypes}`. The
options and metadata aimux defines in a provider's namespace are camelCase
too: `images[].mediaType`, OpenAI `choiceValues` and `safetyIdentifier`,
candidate scoring's `modelRevision`, `tokenizerRevision`,
`promptFormatVersion` and `encoded.<id>.{promptTokenIds, labelTokenIds}`,
and the metadata's `probabilitySource` and `latencyMs`; options a runtime
receives as given keep the runtime's names (`keep_alive`,
`chat_template_kwargs`, ...). Python's `decide` takes the JSON keys as
keyword arguments (`maxRetries=0`). Decision recordings write the options
and result this way, and replay refuses recorded options with snake_case
keys instead of ignoring them.

- Request options reject keys they do not have (RFC-0042 §7.2):
`GenerateTextOptions` and its `timeout`, the options of the other
operations (embedding, speech, image, transcription, reranking, video and
its `poll`, search, file upload, `decide`), the MoA config, and the router
and transcription-session configs of the C ABI, Node and Python. aimux
0.5's snake_case keys (`max_retries`, `timeout.total_ms`, `fail_mode`,
`provider_name`) and typos fail naming the key instead of falling back to
the default. The Node and Python router and transcription-session configs
are camelCase, as the C ABI's are.

- Middleware wraps generation and streaming with callbacks for both operations,
parameter transforms and provider/model/supported-URL overrides. Explicit
model and provider ids take precedence over middleware overrides.
Expand Down Expand Up @@ -200,10 +357,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
`tool_approval_response { approval_id, approved, reason, provider_executed }`,
which reaches the provider only for a provider-executed tool, as upstream;
a tool message left empty is dropped. Wire format: the role and part tags
are unchanged; a tool result still reads the earlier `result` (or untyped
`output`) value with `is_error` and writes `text` / `json` / error outputs
that way, while `output` holding an AI SDK output object is read as typed;
a part its role does not allow (an `image` in an assistant message, a
are unchanged; a tool result carries only `output`, an AI SDK output
object, and the earlier `result` / `is_error` fields are no longer read or
written; a part its role does not allow (an `image` in an assistant message, a
non-text system message, a string or text part in a tool message) is now
rejected when the prompt is parsed instead of when it is converted.

Expand Down Expand Up @@ -662,7 +818,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
replay time with an error that names it: its empty `provider_id`
(`ProviderRecord::registry_id`) for a rebuild from a registry, a prompt in
the older format (`InputRecord::unreadable_prompt`, loaded as empty),
older call options, or the pre-V4 decision options and results.
older call options (snake_case keys the camelCase options would ignore are
refused), or the pre-V4 decision options and results.
`rebuild_provider(record, registry)` resolves `provider_id` through the
caller-supplied registry, retaining its settings.
If the default model method differs from the recorded one, pass the model
Expand Down Expand Up @@ -796,7 +953,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
levels). Answers are `{choice, probabilities?}`, `{score, probabilities?}`
(keyed `"0"`, `"1"`, …) and `{probability}`. `decide` takes `DecideOptions`
(the call options plus `max_retries`, default 2, and `timeout`) and returns
`DecideResult` (answers, usage with `total_tokens`, warnings, rounding,
`DecideResult` (answers, usage with `totalTokens`, warnings, rounding,
provider metadata, response). It validates the input, rejects unsupported
question types before any I/O and validates the answers once after the
retries, with the upstream messages. The model call runs inside
Expand All @@ -806,9 +963,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
`supported_question_types` and `do_decide(&DecisionCallOptions)`;
`capabilities()` and `DecisionCapabilities` are removed, and provider limits
are checked in `do_decide` before HTTP. Images and OpenAI typed choice
values move to `provider_options.<provider>`; the probability source,
confidence, OpenAI typed values, Laya abstentions and `latency_ms` move to
`provider_metadata.<provider>`. An OpenAI refusal or a vLLM skipped question
values move to `providerOptions.<provider>`; the probability source,
confidence, OpenAI typed values, Laya abstentions and `latencyMs` move to
`providerMetadata.<provider>`. An OpenAI refusal or a vLLM skipped question
fails the decision instead of returning a partial answer. Decision
recordings hold the `DecideOptions` and the `DecideResult`; recordings made
before this change load but do not replay.
Expand All @@ -831,7 +988,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
failures used to surface as `AIMUX_E_INVALID_ARGUMENT`.
- `aimux_decide` takes `DecideOptions` JSON and returns `DecideResult` JSON.
`aimux_decision_capabilities` keeps its name and signature but returns
`{specification_version, provider, model_id, supported_question_types}`.
`{specificationVersion, provider, modelId, supportedQuestionTypes}`.
`aimux_provider_decision_model` on a provider without decision models
returns `AIMUX_E_NO_SUCH_MODEL` (was `AIMUX_E_UNSUPPORTED_FUNCTIONALITY`).
- `aimux_provider_new`, `aimux_provider_handle_new` and `config_json` resolve
Expand Down Expand Up @@ -883,7 +1040,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

**All bindings**

- Typed provider tools in Java, Kotlin, Swift, Python and Flutter carry
- Typed provider tools in Java, Kotlin, Swift, Python, Flutter and Go carry
optional `supportsDeferredResults`, omitted from JSON when absent
(provider-utils@5.0.55 src/types/tool.ts:316-326).

Expand Down Expand Up @@ -1038,6 +1195,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
timeout's start, `additionalRetryableError` and per-batch idempotency
keys.

- RFC-0035 shows the repair context, reply and result patch in the final
JSON (`toolCall` tagged `tool-call`, errors tagged by `name`, camelCase
keys). It says that a repaired call failing re-validation is returned as an
invalid call, not wrapped in `AI_ToolCallRepairError`, as upstream does, and
registers the pre-evaluated `inputSchema` and Swift's delayed abort as
differences from upstream.

## [0.5.0] - 2026-09-27

**Breaking release.** 13 PRs since 0.3.0: the cross-language error model
Expand Down
2 changes: 2 additions & 0 deletions aimux-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ tokio-util = "0.7"
httpdate = { workspace = true }
rand = { workspace = true }
base64 = "0.22"
# `Timestamp`: RFC 3339 parsing and `toISOString` formatting.
chrono = { version = "0.4", default-features = false, features = ["std", "clock"] }
jsonschema = { workspace = true }
regex = "1"

Expand Down
Loading
Loading