Loading workspace insights... Statistics interval
7 days30 daysLatest CI Pipeline Executions
714d35be fix(ai-octane): fix three defects inherited from the React adapter
Review of the port surfaced real defects rather than style nits. Treating
this as new code rather than an untouchable move, they are fixed here and
tracked upstream (#1001, #1002, #1003) so the other adapters can follow.
- useAudioRecorder's transforming overload now requires `onComplete`.
Without that constraint an options object carrying only unrelated keys
(`useAudioRecorder({ onError })`) still matched it, `TOnComplete`
inferred as `unknown`, and `recording`/`stop()` collapsed to `unknown` —
so passing any option silently cost you the AudioRecording type.
Confirmed to reproduce in @tanstack/ai-react.
- useGeneration spreads caller `devtools` metadata before the hardcoded
`framework`/`hookName`, so a caller can no longer misattribute this
binding in the devtools. The port was internally inconsistent here:
useChat and useGenerateVideo already ordered it this way. Upstream, only
ai-react is affected — ai-vue and ai-solid are already correct.
- UseGenerationReturn is now `<TInput, TOutput>` and types `generate` as
`(input: TInput)` rather than casting it to `(input: Record<string,
any>)`, so required and narrow input fields are checked at the call
site. This is the one place the public type surface differs in shape
from ai-react; the runtime surface is unchanged, and no other module
referenced the type (the media hooks declare their own).
Also hardens the renderUseChat test helper to default its options instead
of asserting `options!`, which would have passed `undefined` into a hook
that reads options eagerly.
typetests/ is now wired into CI via `test:types`. It previously could not
be: the upstream tool-input-inference case failed because its hand-rolled
StandardJSONSchemaLike stand-in doesn't thread through @tanstack/ai's
inference. That stand-in existed only because @standard-schema/spec wasn't
directly resolvable in the Octane repo — it is here, so tool inputs now
use real Zod, matching @tanstack/ai-client's own type tests. The
outputSchema tests keep a structural stand-in deliberately, to prove
inference works for any spec-conforming validator rather than one library.
Each fix is covered by a test that was verified to fail when the fix is
reverted: 5 type errors for the TInput widening, 3 for the audio-recorder
overload, and a failing devtools assertion (`framework: 'react'` leaking
through) for the spread order.
147 tests pass (was 143); src and typetests both type-check.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> 714d35be fix(ai-octane): fix three defects inherited from the React adapter
Review of the port surfaced real defects rather than style nits. Treating
this as new code rather than an untouchable move, they are fixed here and
tracked upstream (#1001, #1002, #1003) so the other adapters can follow.
- useAudioRecorder's transforming overload now requires `onComplete`.
Without that constraint an options object carrying only unrelated keys
(`useAudioRecorder({ onError })`) still matched it, `TOnComplete`
inferred as `unknown`, and `recording`/`stop()` collapsed to `unknown` —
so passing any option silently cost you the AudioRecording type.
Confirmed to reproduce in @tanstack/ai-react.
- useGeneration spreads caller `devtools` metadata before the hardcoded
`framework`/`hookName`, so a caller can no longer misattribute this
binding in the devtools. The port was internally inconsistent here:
useChat and useGenerateVideo already ordered it this way. Upstream, only
ai-react is affected — ai-vue and ai-solid are already correct.
- UseGenerationReturn is now `<TInput, TOutput>` and types `generate` as
`(input: TInput)` rather than casting it to `(input: Record<string,
any>)`, so required and narrow input fields are checked at the call
site. This is the one place the public type surface differs in shape
from ai-react; the runtime surface is unchanged, and no other module
referenced the type (the media hooks declare their own).
Also hardens the renderUseChat test helper to default its options instead
of asserting `options!`, which would have passed `undefined` into a hook
that reads options eagerly.
typetests/ is now wired into CI via `test:types`. It previously could not
be: the upstream tool-input-inference case failed because its hand-rolled
StandardJSONSchemaLike stand-in doesn't thread through @tanstack/ai's
inference. That stand-in existed only because @standard-schema/spec wasn't
directly resolvable in the Octane repo — it is here, so tool inputs now
use real Zod, matching @tanstack/ai-client's own type tests. The
outputSchema tests keep a structural stand-in deliberately, to prove
inference works for any spec-conforming validator rather than one library.
Each fix is covered by a test that was verified to fail when the fix is
reverted: 5 type errors for the TInput widening, 3 for the audio-recorder
overload, and a failing devtools assertion (`framework: 'react'` leaking
through) for the spread order.
147 tests pass (was 143); src and typetests both type-check.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> b7d58ae5 feat(ai-octane): port Octane bindings from @octanejs/tanstack-ai
Adds `@tanstack/ai-octane`, an Octane binding for TanStack AI. This is a
port of `@octanejs/tanstack-ai@0.0.11`, which lived in the octanejs/octane
repo as a temporary stopgap; the code moves here essentially unchanged
apart from the rename.
Covers the `@tanstack/ai-react` hook surface (useChat, useRealtimeChat,
useMcpAppBridge, useGeneration, useGenerateImage/Audio/Speech/Video,
useTranscription, useSummarize, useAudioRecorder) plus the 30
`@tanstack/ai-client` convenience re-exports, reusing `@tanstack/ai` and
`@tanstack/ai-client` unchanged. SSR through `octane/server` is tested.
Packaging: like Svelte packages shipping `.svelte`, this one publishes
uncompiled source. The hook modules are `.tsrx`, compiled by the
consumer's Octane plugin, so there is no `dist`/`build` target and no
publint `test:build`; `octane` is a required peer. The `.tsrx.d.ts`
companions are checked declaration emits, so `tsc` still verifies the
full public generic surface.
Deviations from a byte-for-byte move, all recorded in status.json:
- Conformance runs on happy-dom rather than jsdom. This repo pins jsdom
^27, whose `Blob` has no `arrayBuffer()` (Octane pins ^29, which does)
and the useAudioRecorder cases need it. Bumping jsdom for one package
would break sherif's cross-package version consistency.
- Two useChat cases asserted that a second concurrent sendMessage is
dropped. #900 made client-side queueing the default, so both now
assert queue-and-deliver-in-order, mirroring the current ai-react
tests. The hook needed no change — queueing lives in ChatClient.
- The differential parity test stays in the Octane repo: it byte-compares
streamed output against real @tanstack/ai-react, which would make a
sibling workspace package a pinned test dependency.
- Unused vendored test helpers were dropped rather than carried as dead
code (knip).
- The generated .tsrx.d.ts companions are excluded from lint; a
regeneration would undo any hand-fix.
Known gap: the port is baselined against @tanstack/ai-react 0.17.0 while
this repo is at 0.18.1. The interrupts overhaul (#970) and server
persistence / browser-refresh durability (#984) are not yet reflected in
the Octane hooks, and `typetests/` is therefore not wired into CI — its 4
errors are confined to one tool-input-inference case that fails
identically against @tanstack/ai-react, so it is not a port defect.
status.json lists the exact type-surface delta. Parity catch-up is
follow-up work.
pnpm-workspace.yaml excludes octane@0.1.17 and
@octanejs/testing-library@0.1.14 from minimumReleaseAge: Octane publishes
the pair in lockstep (testing-library pins an exact octane peer) and
releases roughly daily, so the newest pair is essentially always inside
the 24h window.
143 tests pass (142 conformance + 1 SSR), no skips or todos.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>