Found while reviewing the @tanstack/ai-octane port (#1000). Fixed there; ai-react has the same ordering.
Problem
packages/ai-react/src/use-generation.ts builds its devtools metadata with the hardcoded identity before the caller's spread:
devtools: {
hookName: 'useGeneration',
framework: 'react',
...opts.devtools, // <-- caller wins
},
useGeneration is documented as public API ("You can also use it directly for custom generation types"), so callers do pass devtools. A caller supplying devtools.framework or devtools.hookName silently overrides the identity, and the devtools then misattribute the activity.
Notably ai-vue and ai-solid already spread first and are not affected — ai-react is the odd one out.
Fix
Match the sibling adapters:
devtools: {
- hookName: 'useGeneration',
- framework: 'react',
- ...opts.devtools,
+ ...opts.devtools,
+ framework: 'react',
+ hookName: 'useGeneration',
},
Unrelated caller metadata (e.g. outputKind) still passes through; only the identity keys become non-overridable.
Test
packages/ai-octane/tests/conformance/devtools-identification.test.ts covers this by spying on the bridge factory and asserting the metadata survives a hostile devtools: { framework: 'react' }. It was verified to fail against the un-fixed ordering. The same approach ports directly to ai-react.
Affected
(ai-vue / ai-solid already correct; @tanstack/ai-octane fixed in #1000.)
Found while reviewing the
@tanstack/ai-octaneport (#1000). Fixed there;ai-reacthas the same ordering.Problem
packages/ai-react/src/use-generation.tsbuilds its devtools metadata with the hardcoded identity before the caller's spread:useGenerationis documented as public API ("You can also use it directly for custom generation types"), so callers do passdevtools. A caller supplyingdevtools.frameworkordevtools.hookNamesilently overrides the identity, and the devtools then misattribute the activity.Notably
ai-vueandai-solidalready spread first and are not affected —ai-reactis the odd one out.Fix
Match the sibling adapters:
devtools: { - hookName: 'useGeneration', - framework: 'react', - ...opts.devtools, + ...opts.devtools, + framework: 'react', + hookName: 'useGeneration', },Unrelated caller metadata (e.g.
outputKind) still passes through; only the identity keys become non-overridable.Test
packages/ai-octane/tests/conformance/devtools-identification.test.tscovers this by spying on the bridge factory and asserting the metadata survives a hostiledevtools: { framework: 'react' }. It was verified to fail against the un-fixed ordering. The same approach ports directly toai-react.Affected
@tanstack/ai-react(
ai-vue/ai-solidalready correct;@tanstack/ai-octanefixed in #1000.)