Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
493 commits
Select commit Hold shift + click to select a range
f755c28
test(flutter): typed stream fixtures are JSON maps; the chat mock is …
claude Oct 14, 2026
5590fa3
Merge branch 'v4/12-vendor-streams-are-transformer-structs' into v4/1…
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
6bced34
docs(agents): update the differential probe for the new public JSON
claude Oct 14, 2026
e27c13c
Merge branch 'v4/8-public-json-equals-the-ai-sdk-json' into v4/9-rewr…
claude Oct 14, 2026
ba3f923
Merge branch 'v4/9-rewrite-json-repair-in-idiomatic-rust' into v4/10-…
claude Oct 14, 2026
fc67f42
Merge branch 'v4/10-tool-call-repair-is-a-trait' into v4/11-provider-…
claude Oct 14, 2026
defa5ab
Merge branch 'v4/12-vendor-streams-are-transformer-structs' into v4/1…
claude Oct 14, 2026
8656cd0
Merge branch 'v4/11-provider-config-is-plain-data' into v4/12-vendor-…
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
ee0b00e
Merge branch 'v4/8-public-json-equals-the-ai-sdk-json' into v4/9-rewr…
claude Oct 14, 2026
ecbfc3e
Merge branch 'v4/9-rewrite-json-repair-in-idiomatic-rust' into v4/10-…
claude Oct 14, 2026
c5c84f2
Merge branch 'v4/10-tool-call-repair-is-a-trait' into v4/11-provider-…
claude Oct 14, 2026
7a5c97e
Merge branch 'v4/12-vendor-streams-are-transformer-structs' into v4/1…
claude Oct 14, 2026
f371112
Merge branch 'v4/11-provider-config-is-plain-data' into v4/12-vendor-…
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
540fef5
Merge branch 'v4/8-public-json-equals-the-ai-sdk-json' into v4/9-rewr…
claude Oct 14, 2026
4166bf0
Merge branch 'v4/9-rewrite-json-repair-in-idiomatic-rust' into v4/10-…
claude Oct 14, 2026
cdf678a
Merge branch 'v4/10-tool-call-repair-is-a-trait' into v4/11-provider-…
claude Oct 14, 2026
70c8fff
Merge branch 'v4/12-vendor-streams-are-transformer-structs' into v4/1…
claude Oct 14, 2026
430eb5d
Merge branch 'v4/11-provider-config-is-plain-data' into v4/12-vendor-…
claude Oct 14, 2026
8ccd560
Merge branch 'master' into ci/optimize-ci-speed-and-cache
claude Oct 15, 2026
e084dc9
docs(agents): trim the native-Rust skills and profile to what stays true
claude Oct 14, 2026
7914f80
docs(agents): drop the preset count from the profile
claude Oct 15, 2026
ca886c1
ci: pin cargo-ndk and keep pull requests from saving two more caches
claude Oct 15, 2026
a057ba6
feat(ops)!: add the aimux-ops dispatch layer
cunninghamcard-bit Oct 15, 2026
d0d13c9
feat(ffi)!: replace the C exports with the RFC-0039 primitives
cunninghamcard-bit Oct 15, 2026
d6ec8b7
feat(node)!: move the node binding onto the ops layer
cunninghamcard-bit Oct 15, 2026
72c62cc
feat(python)!: move the python binding onto the ops layer
cunninghamcard-bit Oct 15, 2026
d636694
feat(go)!: move the go binding onto the ops layer
cunninghamcard-bit Oct 15, 2026
b3d7934
feat(java)!: move the java binding onto the ops layer
cunninghamcard-bit Oct 15, 2026
6d56d29
feat(kotlin)!: move the kotlin binding onto the ops layer
cunninghamcard-bit Oct 15, 2026
92ce920
feat(swift)!: move the swift binding onto the ops layer
cunninghamcard-bit Oct 15, 2026
bc1bcf4
feat(flutter)!: move the flutter binding onto the ops layer
cunninghamcard-bit Oct 15, 2026
d364eb2
docs(ops): list the registered operations
cunninghamcard-bit 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
7868308
refactor(ops): remove unused helpers and duplicated test scaffolding
cunninghamcard-bit Oct 15, 2026
188febd
refactor(ffi): trim the C ABI glue and generate the Flutter header fr…
cunninghamcard-bit Oct 15, 2026
a1c6841
refactor(go): remove code the ops layer made redundant
cunninghamcard-bit Oct 15, 2026
4f2fdd8
refactor(node): drop the legacy bench package and fix the stale trace…
cunninghamcard-bit Oct 15, 2026
47d5ca3
refactor(flutter): generate the FFI bindings from the codegen header
cunninghamcard-bit Oct 15, 2026
9e5c151
fix(kotlin): expect the abort as the cause of CancellationException
cunninghamcard-bit Oct 15, 2026
0721b11
fix(python): align the Responses fixture and remove the unused wrapper
cunninghamcard-bit Oct 15, 2026
7940fdd
refactor(java): remove the hand-written mock provider server
cunninghamcard-bit 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
36ad6f8
chore: satisfy the Rust 1.99 lints
cunninghamcard-bit Oct 15, 2026
6ae63e0
fix(ffi): include <cstring> in the C++ RAII test
cunninghamcard-bit Oct 15, 2026
d0580db
ci(flutter): build the ABI test fixtures and run the real-library tests
cunninghamcard-bit Oct 15, 2026
502f3cf
fix(python): make every GIL-release entry reach a blocking native wait
cunninghamcard-bit Oct 15, 2026
b828987
fix(swift): qualify the iterator's Failure so Swift 6 compiles Bounde…
cunninghamcard-bit Oct 15, 2026
da4dfed
fix(kotlin): assert on the root cause where coroutine stack-trace rec…
cunninghamcard-bit Oct 15, 2026
f05d945
fix(node): import the worker module by file URL so the test runs on W…
cunninghamcard-bit Oct 15, 2026
a4a0657
fix(go): link the C library statically on Linux again
cunninghamcard-bit Oct 15, 2026
e8948a7
chore(node): commit the napi-generated declarations
cunninghamcard-bit Oct 15, 2026
5c79870
test(flutter): check isolate responsiveness by ordering instead of ti…
cunninghamcard-bit 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
da02379
test(flutter): resume the fixture's native sleep after EINTR
cunninghamcard-bit Oct 15, 2026
97f3c2d
docs(ops): add the RFC-0039 design, coverage ledger, conformance matr…
cunninghamcard-bit 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
0e2ffc3
Merge branch 'v4/8-public-json-equals-the-ai-sdk-json' into v4/9-rewr…
claude Oct 16, 2026
1e60857
test(aimux-core): replace the in-test legacy json_repair port with re…
claude Oct 14, 2026
f0b17f6
docs(core): say why json_repair stays public
claude Oct 15, 2026
b1fd1b3
Merge branch 'v4/9-rewrite-json-repair-in-idiomatic-rust' into v4/10-…
claude Oct 16, 2026
0eeb671
refactor(providers): keep vendor endpoints out of shared and openai_c…
claude Oct 14, 2026
bd6c67e
test(searxng): the instance URL comes from SEARXNG_URL per request
claude Oct 15, 2026
2e08078
refactor(providers)!: remove the by-name provider shim the bindings n…
cunninghamcard-bit Oct 16, 2026
8676f29
Merge branch 'v4/10-tool-call-repair-is-a-trait' into v4/11-provider-…
claude Oct 16, 2026
b21d9ed
refactor(provider-utils): PipeThrough is a Stream over one reused queue
claude Oct 14, 2026
f04c217
refactor(providers): chat streams share ChatToolCalls, no tracker type
claude Oct 14, 2026
faf5c0f
refactor(providers): vendor streams share StreamContext and Emit
claude Oct 14, 2026
ae1437d
test(providers): drive chat and Anthropic stream transformers synchro…
claude Oct 14, 2026
a6d890c
Merge branch 'v4/11-provider-config-is-plain-data' into v4/12-vendor-…
claude Oct 16, 2026
70abded
chore(providers): let shared layers use the stream module in the boun…
claude Oct 14, 2026
da607da
docs: say where the chat streams keep their tool-call state
claude Oct 15, 2026
0c69d2e
Merge branch 'v4/12-vendor-streams-are-transformer-structs' into v4/1…
claude Oct 16, 2026
8e6a597
test(provider-utils): nothing is emitted after a transform stream ended
claude Oct 15, 2026
2b40886
fix(ops): terminate and drop an operation safely after its runtime sh…
cunninghamcard-bit Oct 16, 2026
ec546ed
test(ops): error envelopes never carry a missing or invalid secret
cunninghamcard-bit Oct 16, 2026
4da9798
docs(rfc-0039): record the accepted D8 and schema-2 order, the new am…
cunninghamcard-bit Oct 16, 2026
9fc5d01
fix(ops)!: one schema per control object, poll mode for operation.nex…
cunninghamcard-bit Oct 16, 2026
b8ce765
fix(codegen): write the Dart constants under lib/ so package imports …
cunninghamcard-bit Oct 16, 2026
9c97b5b
fix(bindings): pin opsVersion and manifest digest exactly, name ops b…
cunninghamcard-bit Oct 16, 2026
d673715
fix(node,python): replay the shared vectors, reject a full push queue…
cunninghamcard-bit Oct 16, 2026
522f427
ci: drop steps that claimed shared-vector checks, one iOS symbol list…
cunninghamcard-bit Oct 16, 2026
9874095
docs(rfc-0039): every binding now pins the manifest digest
cunninghamcard-bit Oct 16, 2026
70767ec
fix(ops,node): one handle-id rule shared by DTO decoding, the registr…
cunninghamcard-bit Oct 16, 2026
e5aacef
docs(rfc-0039): the series' last PR removes schema-2 and older record…
cunninghamcard-bit Oct 16, 2026
2574772
fix(core): fix_json steps through UTF-16 code units like upstream
claude Oct 16, 2026
563d65c
test(dataforseo): the login comes from DATAFORSEO_LOGIN per request
cunninghamcard-bit Oct 16, 2026
8f90ad6
feat(core): the recording context has an operation scope
claude Oct 16, 2026
aa050b0
docs(contributing): say what .agents/ holds and in which language
cunninghamcard-bit 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
43e012c
refactor(node,python): derive handle bookkeeping from the registry, n…
cunninghamcard-bit Oct 16, 2026
cf9aca6
refactor(flutter): use generated ABI, ops and symbol names everywhere
cunninghamcard-bit Oct 16, 2026
c7b814e
refactor(bindings): drive Swift contract tests from generated ops con…
cunninghamcard-bit Oct 16, 2026
30233a0
refactor(bindings): use generated Go op and ABI constants
cunninghamcard-bit Oct 16, 2026
e06bb55
refactor(bindings): use generated protocol constants in JVM tests
cunninghamcard-bit Oct 16, 2026
bae2683
refactor(bindings): use generated Node operation constants
cunninghamcard-bit Oct 16, 2026
d4d8add
refactor(bindings): use generated Python operation constants
cunninghamcard-bit 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
b4ef67a
fix(ci): regenerate the providers doc, tolerate Windows addon locks, …
cunninghamcard-bit Oct 16, 2026
560709f
feat(ops): list the provider packages in the manifest and runtime.des…
cunninghamcard-bit 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
f390ff4
Merge branch 'v4/8-public-json-equals-the-ai-sdk-json' into v4/9-rewr…
claude Oct 16, 2026
adec25f
Merge branch 'v4/9-rewrite-json-repair-in-idiomatic-rust' into v4/10-…
claude Oct 16, 2026
5330a48
Merge branch 'v4/10-tool-call-repair-is-a-trait' into v4/11-provider-…
claude Oct 16, 2026
e2f2e46
Merge branch 'v4/11-provider-config-is-plain-data' into v4/12-vendor-…
claude Oct 16, 2026
bd5418b
Merge branch 'v4/12-vendor-streams-are-transformer-structs' into v4/1…
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
f89c989
Merge branch 'v4/8-public-json-equals-the-ai-sdk-json' into v4/9-rewr…
claude Oct 16, 2026
27901f1
Merge branch 'v4/9-rewrite-json-repair-in-idiomatic-rust' into v4/10-…
claude Oct 16, 2026
6e2b132
Merge branch 'v4/10-tool-call-repair-is-a-trait' into v4/11-provider-…
claude Oct 16, 2026
a4e5267
Merge branch 'v4/11-provider-config-is-plain-data' into v4/12-vendor-…
claude Oct 16, 2026
b88f3a2
Merge branch 'v4/12-vendor-streams-are-transformer-structs' into v4/1…
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
2db6c74
Merge branch 'v4/13-add-the-native-rust-porting-skills' into v4/14-op…
cunninghamcard-bit Oct 16, 2026
f1e2277
fix(python): reject unknown request options
cunninghamcard-bit Oct 16, 2026
55c54cd
test(python): a successful stream ends iteration without yielding End
cunninghamcard-bit 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
8c8eb61
Merge branch 'v4/8-public-json-equals-the-ai-sdk-json' into v4/9-rewr…
claude Oct 17, 2026
50a6fb7
Merge branch 'v4/9-rewrite-json-repair-in-idiomatic-rust' into v4/10-…
claude Oct 17, 2026
4e7afd8
Merge branch 'v4/10-tool-call-repair-is-a-trait' into v4/11-provider-…
claude Oct 17, 2026
a510dda
Merge branch 'v4/11-provider-config-is-plain-data' into v4/12-vendor-…
claude Oct 17, 2026
5641211
Merge branch 'v4/12-vendor-streams-are-transformer-structs' into v4/1…
claude Oct 17, 2026
133b0f1
Merge branch 'v4/13-add-the-native-rust-porting-skills' into v4/14-op…
cunninghamcard-bit Oct 17, 2026
c346d18
Merge master into [14/14]: 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
  •  
  •  
  •  
102 changes: 82 additions & 20 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ concurrency:

env:
CARGO_TERM_COLOR: always
# Node and Python replay the shared vectors from this checkout.
AIMUX_CONTRACT_VECTORS: ${{ github.workspace }}/contract-tests/ops
# Test-only jobs do not ship binaries: skip single-threaded fat LTO and -Oz
# size optimization. ffi-build uploads release artifacts and restores
# Cargo.toml's release profile in its job env.
# opt-level 1, not 0: aimux_stream_text drives the whole stream future on
# opt-level 1, not 0: aimux_stream drives the whole stream future on
# the caller's thread, and at opt-level 0 that needs more than the 512 KB
# stack of a Swift cooperative thread (SIGBUS in the async Swift tests).
# Measured for one stream through the C ABI: ~530 KB at 0, ~110 KB at 1,
Expand Down Expand Up @@ -212,6 +214,8 @@ jobs:
CARGO_PROFILE_DEV_DEBUG: "0"
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
Expand All @@ -224,6 +228,8 @@ jobs:
run: cargo doc --workspace --no-deps
env:
RUSTDOCFLAGS: -D warnings
- name: Ops contract tests (matrix, lifecycle, streams, envelopes, manifest)
run: cargo test -p aimux-ops
- name: Test workspace
run: cargo test --workspace

Expand All @@ -241,6 +247,8 @@ jobs:
settings: ${{ fromJSON(needs.changes.outputs.node-legs) }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.settings.target }}
Expand Down Expand Up @@ -310,7 +318,7 @@ jobs:
- name: Rust unit tests
if: matrix.settings.test && runner.os == 'Linux'
run: cargo test --lib --manifest-path bindings/node/Cargo.toml
- name: Test
- name: Test Node binding and shared contract vectors
if: matrix.settings.test
working-directory: bindings/node
run: npm test
Expand Down Expand Up @@ -343,6 +351,8 @@ jobs:
if: fromJSON(needs.changes.outputs.run)['python-binding']
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
Expand All @@ -365,7 +375,7 @@ jobs:
run: |
maturin build --release
pip install --force-reinstall target/wheels/*.whl
- name: Test
- name: Test Python binding and shared contract vectors
working-directory: bindings/python
run: |
pip install pytest pydantic
Expand All @@ -387,6 +397,8 @@ jobs:
include: ${{ fromJSON(needs.changes.outputs.ffi-legs) }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
Expand All @@ -395,13 +407,20 @@ jobs:
save-if: ${{ github.ref == 'refs/heads/master' }}
- name: Build cdylib
run: cargo build -p aimux-ffi --release --target ${{ matrix.target }}
- name: C11 and C++17 ABI contract tests
if: runner.os == 'Linux'
shell: bash
env:
AIMUX_C_LIB_DIR: ${{ github.workspace }}/target/${{ matrix.target }}/release
LD_LIBRARY_PATH: ${{ github.workspace }}/target/${{ matrix.target }}/release
run: bash scripts/test-c-abi.sh
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ffi-${{ matrix.target }}
path: |
target/${{ matrix.target }}/release/${{ matrix.artifact }}
aimux-ffi/aimux-ffi.h
aimux-ffi/include/aimux.h
# The Go binding links against the library this build produced. On
# Linux the cgo LDFLAGS force the static archive; on macOS ld64 picks
# the .dylib next to it (see bindings/go/aimux.go). macOS is covered
Expand All @@ -426,6 +445,43 @@ jobs:
export CGO_LDFLAGS="-L${{ github.workspace }}/target/${{ matrix.target }}/release"
go test -race ./...

ffi-sanitizers:
name: C ABI (ASan + LSan)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
shared-key: "ffi-test"
save-if: ${{ github.ref == 'refs/heads/master' }}
- name: Build FFI library
run: cargo rustc -p aimux-ffi --release --crate-type cdylib
- name: Run C11 and C++17 ABI tests with ASan and LSan
env:
CC: clang
CXX: clang++
AIMUX_C_LIB_DIR: ${{ github.workspace }}/target/release
run: bash scripts/test-c-abi.sh --asan-lsan

ffi-linux-arm:
name: aimux-ffi (aarch64-unknown-linux-gnu)
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-unknown-linux-gnu
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/master' }}
- name: Build Linux ARM64 FFI library
run: cargo build -p aimux-ffi --release --target aarch64-unknown-linux-gnu

# ── Java + Kotlin bindings: one FFI build, every JDK in turn ─────────────
# Gradle 8.14.3 runs on JDK 8+; the Java build script only sets --release on
# JDK 9+, so JDK 8 compiles with plain source/target compatibility. The
Expand All @@ -439,6 +495,8 @@ jobs:
LD_LIBRARY_PATH: ${{ github.workspace }}/target/release
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
Expand Down Expand Up @@ -497,6 +555,8 @@ jobs:
if: fromJSON(needs.changes.outputs.run)['flutter-binding']
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
Expand Down Expand Up @@ -528,10 +588,18 @@ jobs:
- name: Get dependencies
working-directory: bindings/flutter
run: flutter pub get
- name: Test
- name: Build the ABI test fixtures and the Dart bridge
working-directory: bindings/flutter
run: |
python3 tool/build_test_fixture.py
cc -std=c11 -Wall -Wextra -Werror -fPIC -shared -pthread native/aimux_dart.c \
-o .dart_tool/native/libaimux_dart.so
- name: Test Flutter binding
working-directory: bindings/flutter
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/target/release
AIMUX_NATIVE_LIBRARY: ${{ github.workspace }}/target/release/libaimux_ffi.so
AIMUX_DART_BRIDGE: ${{ github.workspace }}/bindings/flutter/.dart_tool/native/libaimux_dart.so
run: flutter test
- name: Analyze
working-directory: bindings/flutter
Expand All @@ -557,6 +625,8 @@ jobs:
include: ${{ fromJSON(needs.changes.outputs.example-legs) }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.targets }}
Expand Down Expand Up @@ -610,21 +680,7 @@ jobs:
run: |
flutter config --no-enable-swift-package-manager
flutter build ios --debug --no-codesign --simulator
# Debug builds link the app code into Runner.debug.dylib; the
# Runner stub carries no symbols — scan every executable in the app.
FOUND=""
while IFS= read -r f; do
if nm -g "$f" 2>/dev/null | grep -q 'aimux_openai_new'; then
echo "FOUND aimux_openai_new in: $f"
FOUND=yes
fi
done < <(find build/ios/iphonesimulator/Runner.app -type f -perm -111 2>/dev/null)
if [ -n "$FOUND" ]; then
echo 'OK: aimux symbols present'
else
echo 'FAIL: aimux_openai_new missing from all app binaries'
exit 1
fi
bash ../tool/check_symbols.sh build/ios/iphonesimulator/Runner.app
- name: Build example (Android)
if: matrix.platform == 'android'
working-directory: bindings/flutter/example
Expand All @@ -650,6 +706,8 @@ jobs:
if: fromJSON(needs.changes.outputs.run)['contract-tests']
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- name: Providers doc generator drift (docs/api/providers.md must match generator output)
run: python3 scripts/gen_providers_doc.py --check
- name: Provider boundaries (no call-level reads or provider-name branches in providers, removed names stay removed)
Expand All @@ -658,6 +716,8 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/master' }}
- name: Ops manifest and generated artifact drift
run: cargo run -p aimux-codegen -- --check
- name: ts-rs export drift (checked-in types must match generator output)
run: python3 scripts/gen_ts_types.py --check
# The AI SDK pin tooling: VERSIONS.json format and integrity rules, and
Expand All @@ -677,6 +737,8 @@ jobs:
if: fromJSON(needs.changes.outputs.run)['swift-contract-tests']
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
Expand Down
16 changes: 15 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,17 @@ jobs:
fi
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- name: Publish aimux-ops
run: |
sleep 30
VERSION=$(grep -m1 '^version = ' Cargo.toml | sed 's/version = "\(.*\)"/\1/')
if curl -sf -A "aimux-ci" "https://crates.io/api/v1/crates/aimux-ops/${VERSION}" > /dev/null 2>&1; then
echo "aimux-ops@${VERSION} already published, skipping"
else
cargo publish -p aimux-ops
fi
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- name: Publish aimux-ffi
run: |
sleep 30
Expand Down Expand Up @@ -334,6 +345,7 @@ jobs:
shell: bash
run: |
mkdir -p staging
cp aimux-ffi/include/aimux.h staging/aimux.h
case "${{ matrix.target }}" in
*linux*) cp target/${{ matrix.target }}/release/libaimux_ffi.so staging/${{ matrix.artifact }} ;;
*darwin*) cp target/${{ matrix.target }}/release/libaimux_ffi.dylib staging/${{ matrix.artifact }} ;;
Expand All @@ -343,7 +355,9 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
path: staging/${{ matrix.artifact }}
path: |
staging/${{ matrix.artifact }}
staging/aimux.h

# ── aimux-web console + CLI: self-contained binaries with the embedded
# frontend, shipped on the GitHub Release so users download one file and
Expand Down
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
[workspace]
members = [
"aimux-ops",
"aimux-core",
"aimux-ffi",
"aimux-provider-utils",
"aimux-providers",
"aimux-stream",
"tools/aimux-codegen",
"tools/aimux-cli",
"tools/aimux-replay",
"tools/aimux-web",
Expand Down
81 changes: 50 additions & 31 deletions aimux-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,54 @@ use serde::{Deserialize, Serialize};
use thiserror::Error;
use ts_rs::TS;

/// Projects response retry headers to milliseconds using a caller-supplied clock.
///
/// A numeric `retry-after-ms` takes precedence, even when negative or out of
/// range. An absent or malformed millisecond value falls back to
/// `retry-after` seconds, then an HTTP date. Only finite, non-negative delays
/// fitting in `u64` are returned; fractional milliseconds are truncated.
#[must_use]
pub fn retry_after_ms_from_headers(
headers: &HashMap<String, String>,
now: SystemTime,
) -> Option<u64> {
fn header<'a>(headers: &'a HashMap<String, String>, name: &str) -> Option<&'a str> {
headers
.get(name)
.or_else(|| {
headers
.iter()
.find(|(key, _)| key.eq_ignore_ascii_case(name))
.map(|(_, value)| value)
})
.map(|value| value.trim())
}

fn milliseconds(value: f64) -> Option<u64> {
// u64::MAX rounds up to 2^64 as f64, so the upper bound is exclusive.
if value.is_finite() && (0.0..u64::MAX as f64).contains(&value) {
Some(value.trunc() as u64)
} else {
None
}
}

if let Some(value) =
header(headers, "retry-after-ms").and_then(|value| value.parse::<f64>().ok())
{
return milliseconds(value);
}

let value = header(headers, "retry-after")?;
if let Ok(seconds) = value.parse::<f64>() {
return milliseconds(seconds * 1_000.0);
}

let date = httpdate::parse_http_date(value).ok()?;
let delay = date.duration_since(now).ok()?;
u64::try_from(delay.as_millis()).ok()
}

/// What a failed API call observed — the field set of the AI SDK's
/// `APICallError` (`statusCode` / `responseBody`), which this project's error
/// taxonomy mirrors (docs/internal/vercel-research/07-kernel-infrastructure.md).
Expand Down Expand Up @@ -672,37 +720,8 @@ impl AiMuxError {
return None;
};
let headers = detail.response_headers.as_ref()?;
// Rust's float parser accepts `inf`, `Infinity` and `NaN`. A
// non-finite value is no hint: `as i64` would saturate it to
// `i64::MAX`, and upstream never uses it either (it fails the
// `ms < 60000 || ms < backoff` window).
headers
.get("retry-after-ms")
.and_then(|value| value.parse::<f64>().ok())
.filter(|value| value.is_finite())
.map(|value| value as i64)
.or_else(|| {
headers.get("retry-after").and_then(|value| {
value
.parse::<f64>()
.ok()
.map(|seconds| seconds * 1_000.0)
.filter(|milliseconds| milliseconds.is_finite())
.map(|milliseconds| milliseconds as i64)
.or_else(|| {
httpdate::parse_http_date(value).ok().map(|date| {
match date.duration_since(SystemTime::now()) {
Ok(duration) => duration.as_millis() as i64,
Err(error) => -(error.duration().as_millis() as i64),
}
})
})
})
})
// Upstream's `0 <= ms` check: a hint in the past is no hint. It
// also keeps the value clear of the C ABI's -1 = absent sentinel
// (`aimux_error_retry_ms`).
.filter(|milliseconds| *milliseconds >= 0)
retry_after_ms_from_headers(headers, SystemTime::now())
.and_then(|ms| i64::try_from(ms).ok())
}

/// Returns the HTTP status code carried by this error, if any.
Expand Down
Loading
Loading