feat(ai): native Files API support across providers (upload adapters + file content source)#915
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🚀 Changeset Version Preview21 package(s) bumped directly, 25 bumped as dependents. 🟥 Major bumps
🟨 Minor bumps
🟩 Patch bumps
|
|
View your CI Pipeline Execution ↗ for commit 160e1d0
☁️ Nx Cloud last updated this comment at |
|
View your CI Pipeline Execution ↗ for commit 83e6d90
☁️ Nx Cloud last updated this comment at |
@tanstack/ai
@tanstack/ai-acp
@tanstack/ai-angular
@tanstack/ai-anthropic
@tanstack/ai-bedrock
@tanstack/ai-claude-code
@tanstack/ai-client
@tanstack/ai-code-mode
@tanstack/ai-code-mode-skills
@tanstack/ai-codex
@tanstack/ai-devtools-core
@tanstack/ai-elevenlabs
@tanstack/ai-event-client
@tanstack/ai-fal
@tanstack/ai-gemini
@tanstack/ai-grok
@tanstack/ai-grok-build
@tanstack/ai-groq
@tanstack/ai-isolate-cloudflare
@tanstack/ai-isolate-node
@tanstack/ai-isolate-quickjs
@tanstack/ai-mcp
@tanstack/ai-mistral
@tanstack/ai-ollama
@tanstack/ai-openai
@tanstack/ai-opencode
@tanstack/ai-openrouter
@tanstack/ai-preact
@tanstack/ai-react
@tanstack/ai-react-ui
@tanstack/ai-sandbox
@tanstack/ai-sandbox-cloudflare
@tanstack/ai-sandbox-daytona
@tanstack/ai-sandbox-docker
@tanstack/ai-sandbox-local-process
@tanstack/ai-sandbox-sprites
@tanstack/ai-sandbox-vercel
@tanstack/ai-solid
@tanstack/ai-solid-ui
@tanstack/ai-svelte
@tanstack/ai-utils
@tanstack/ai-vue
@tanstack/ai-vue-ui
@tanstack/openai-base
@tanstack/preact-ai-devtools
@tanstack/react-ai-devtools
@tanstack/solid-ai-devtools
commit: |
…+ `file` content source)
Add first-class support for provider Files / storage APIs so callers can
upload media once and reference it by a provider-issued handle instead of
re-sending base64 or a public URL each request.
- New tree-shakeable `files` adapter kind: openaiFiles(), anthropicFiles(),
geminiFiles(), falFiles() — each with upload(), plus get()/delete() where
the provider has a lifecycle API (fal is upload-only). Driven by the new
uploadFile()/getFile()/deleteFile() activity functions.
- New `{ type: 'file' }` arm on ContentPartSource. Adapters map it to the
provider's native reference: OpenAI (Responses) input_image/input_file
file_id, Anthropic file_id source (sends the files-api-2025-04-14 beta),
Gemini fileData.fileUri, fal storage URL. fileSourceFromHandle() builds
the source from an uploaded FileHandle.
- Runtime provider routing: a handle only routes to its issuing provider;
cross-provider handles and endpoints that require raw bytes (image edits,
Veo, Chat Completions images, Bedrock, Mistral, Grok, OpenRouter, Ollama)
throw a clear error instead of silently mis-mapping.
Closes #909
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… + Nitro note Upload reference images (Gemini) and image-to-video start frames (fal) once via the Files API (`geminiFiles()` / `falFiles()`) and reference them by handle, instead of re-sending the base64 payload inline on every generation request. Bump the example's `nitro` to `latest` (3.0.260610-beta) — older Nitro rejected `@google/genai`'s resumable upload (explicit `Content-Length` on a Blob body) with "invalid content-length header", surfaced as "fetch failed". Document that runtime requirement in the Files API guide. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
d440425 to
160e1d0
Compare
Closes #909.
Adds first-class support for provider Files / storage APIs so callers can upload media once and reference it by a provider-issued handle instead of re-sending base64 (or relying on the provider to re-fetch a public URL) each request — lower latency/bandwidth, no re-buffering of base64 on memory-constrained runtimes (the #907 OOM class), and access to provider-side file lifecycle.
What's included
1. Tree-shakeable
filesadapter kind (packages/ai/src/activities/files/)openaiFiles(),anthropicFiles(),geminiFiles(),falFiles()— each withupload(), plusget()/delete()where the provider has a lifecycle API. fal storage is upload-only (itsget/deletethrow a clear error).uploadFile()/getFile()/deleteFile()activity dispatchers +FileHandle/FileUploadInputtypes.2. New
{ type: 'file' }arm onContentPartSourcefileSourceFromHandle(handle)builds the source (uses the handle URL for Gemini/fal, the opaque id for OpenAI/Anthropic).input_image/input_filefile_id, Anthropicfile_idsource (sends thefiles-api-2025-04-14beta), GeminifileData.fileUri, fal storage URL.3. Runtime provider routing (chosen over compile-time — see below)
source.typediscrimination site was swept; a new arm would otherwise fall through to the URL/data branch.)4. Docs + a worked example
docs/advanced/files-api.mdguide + a "File Handle" section in the multimodal-content page.examples/ts-react-medianow uploads reference images (Gemini) and image-to-video start frames (fal) once via the Files API and references them by handle, instead of re-sending base64 each request.Notes / decisions
chat()'smessagesunion includes a deliberately-permissiveModelMessagearm (for AG-UI wire-forwarding) that structurally subsumes any well-formed content-parts array, so even the existing modality constraint doesn't hard-error at a call site. Runtime routing matches how modality is already validated. Narrowing that union is a larger, separate change.client.beta.messages.create, so consumingfile_idsources meant switching that adapter's message-content block types to the Beta param variants (a superset) and adding the Files beta when a file source is present — not a new client.@google/genai's resumable upload sets an explicitContent-Lengthon a Blob-body request, which older Nitro runtimes reject with "invalid content-length header" (surfaced as "fetch failed"). Verified fixed on current Nitro; the example bumpsnitroaccordingly anddocs/advanced/files-api.mddocuments the requirement. Native Node and the productionnode-serverbuild are unaffected.supports.filescapability typing.Testing
Green locally:
test:types(all touched packages and theexamples/**+testing/**call sites),test:lib,test:eslint,build,test:build,test:knip,test:sherif,test:docs. Rebased onto latestmain(which includes #919 / #920, fixing an unrelated pre-existingGeminiClientConfig/.d.tsresolution issue that had been failing the e2e type-check).🤖 Generated with Claude Code