feat(schemas): @tanstack/ai-schemas with nightly OpenAPI sync (closes #619)#622
feat(schemas): @tanstack/ai-schemas with nightly OpenAPI sync (closes #619)#622tombeckenham wants to merge 7 commits into
Conversation
|
Important Review skippedToo many files! This PR contains 228 files, which is 78 over the limit of 150. To get a review, narrow the scope: ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (228)
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 Preview7 package(s) bumped directly, 25 bumped as dependents. 🟥 Major bumps
🟨 Minor bumps
🟩 Patch bumps
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
View your CI Pipeline Execution ↗ for commit e625a4a
☁️ Nx Cloud last updated this comment at |
@tanstack/ai
@tanstack/ai-anthropic
@tanstack/ai-client
@tanstack/ai-code-mode
@tanstack/ai-code-mode-skills
@tanstack/ai-devtools-core
@tanstack/ai-elevenlabs
@tanstack/ai-event-client
@tanstack/ai-fal
@tanstack/ai-gemini
@tanstack/ai-grok
@tanstack/ai-groq
@tanstack/ai-isolate-cloudflare
@tanstack/ai-isolate-node
@tanstack/ai-isolate-quickjs
@tanstack/ai-mcp
@tanstack/ai-ollama
@tanstack/ai-openai
@tanstack/ai-openrouter
@tanstack/ai-preact
@tanstack/ai-react
@tanstack/ai-react-ui
@tanstack/ai-schemas
@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: |
Adds a fifth generic `TModelDurationByName` to `VideoAdapter` plus two
introspection methods on the base class:
- `availableDurations()` returns a `DurationOptions` tagged union
(`discrete | range | mixed | none`) describing the durations the
current model accepts.
- `snapDuration(seconds)` coerces raw seconds to the closest valid
duration for the current model.
`generateVideo({ duration })` is now typed via
`VideoDurationForAdapter<TAdapter>`. The FAL adapter derives its
per-model duration type from the SDK's `EndpointTypeMap`, so e.g.
`falVideo('fal-ai/kling-video/v1.6/standard/text-to-video')` types
`duration` as `'5' | '10'`; `falVideo('fal-ai/veo3')` types it as
`'4s' | '6s' | '8s'`; `falVideo('fal-ai/minimax/video-01')` rejects
the field entirely.
Adapters that have not yet declared their per-model duration map get
sensible defaults (`{ kind: 'none' }`, `undefined`) so existing video
adapters keep working without changes.
Built on top of #622 (`@tanstack/ai-schemas`); once that PR's FAL
pipeline syncs runtime constraint data, the hand-curated map in
`packages/typescript/ai-fal/src/video/video-provider-options.ts` can
be replaced with schema-derived lookups. Follow-up issue #634 covers
building the Gemini Veo adapter directly on this contract.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7a05fca to
d9904cf
Compare
|
I've got some other ideas around how to do this. Converting to a draft for now |
…oses #619) JSON Schema + Zod definitions for AI provider generation endpoints, generated from each provider's official OpenAPI spec (or equivalent): OpenAI, Anthropic, Gemini, ElevenLabs, xAI Grok, and FAL (600+ models). Endpoints are grouped per provider by activity, aligned with the core library's activities — chat, image, video, audio (TTS, transcription, music, SFX in one group), embeddings, moderation — behind @tanstack/ai-schemas/{provider}/{activity}/{json-schema,zod} subpaths. Platform/admin endpoints (projects, invites, certificates, fine-tuning, file stores, workspaces) are excluded from generation. JSON Schemas ship self-contained with their $ref closures bundled under $defs; binary- response media endpoints map input-only entries. Pipeline (ported from fal-ai/fal-js#212, generalised multi-provider): fetch-schemas (per-provider fetchers) → @hey-api/openapi-ts (pinned, JSON Schema + Zod 4 plugins, per-activity spec splits with orphan pruning) → generate-endpoint-maps ($defs bundling, endpoint-id-keyed maps). Post-processing strips hey-api's schema-name discriminator grafts (which made discriminated unions reject every valid payload), accepts multipart/form-data bodies, and resolves dedup-renamed schema refs. .github/workflows/sync-schemas.yml refreshes specs daily and opens an automated PR on diff, following the sync-models.yml pattern. FAL specs are committed like the other providers'; the fetcher needs FAL_KEY (repo secret) and the plain `expand=openapi-3.0` query param. Squashed and rebased onto the flattened packages/* monorepo layout; the package lives at packages/ai-schemas. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pulls the public OpenAPI 3.1 spec from openrouter.ai/openapi.json and classifies into chat (chat/completions, messages, responses), audio (speech, transcriptions), and video (/videos — including the frame_images / input_references image-conditioning shape). Account management, preset-scoped variants, and rerank drop out of generation. /embeddings is intentionally unclassified: OpenRouter declares its schemas inline rather than via $ref, so it can't be mapped to named exports. Per-model video constraints (supported_durations, resolutions, aspect ratios from GET /api/v1/videos/models) are a candidate follow-up — noted in the provider module. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ecc6fac to
bd3a917
Compare
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
…chemas
Two gaps noted in the OpenRouter provider land here:
/embeddings was unclassified because OpenRouter declares its request/
response schemas inline rather than via $ref, and the endpoint-map
generator can only map named component schemas. The loader now lifts the
inline shapes into components.schemas as EmbeddingsRequest /
EmbeddingsResponse and re-points the operation, so the endpoint
classifies into a new openrouter/embeddings activity unit.
Per-model video constraints: the fetcher now also caches the public
GET /api/v1/videos/models metadata (supported durations, resolutions,
aspect ratios, sizes, frame images, audio/seed capability, passthrough
allow-lists) as openrouter.video-models.json, sorted by id for stable
nightly diffs. The loader synthesises one constrained
VideoGenerationRequest variant per video model (currently 14), mounted
at synthetic /videos/{model-id} POSTs marked with
x-tanstack-synthetic-video-model so classification never catches real
upstream paths. Constraints become enums; capabilities a model lacks
drop out of its variant; frame-type and passthrough rules land in field
descriptions. The maps expose them as videos/{model-id} entries
alongside the generic videos entry.
Also: the endpoint extractor now falls back 200 → 201 → 202 for JSON
success responses, giving the OpenRouter video job ack (202,
VideoGenerationResponse) and two ElevenLabs dubbing endpoints (201)
real output schemas.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Equivalent of one nightly sync-schemas.yml run, executed locally with FAL_KEY: refetched all 7 providers' upstream specs (OpenAI, Anthropic, Gemini, ElevenLabs, xAI Grok, OpenRouter incl. video-models metadata, FAL with 600+ per-model specs) and regenerated schemas, zod, and endpoint maps. Endpoint surface changes are FAL model additions (e.g. bria/genfill/v2, ideogram/v4/lora); everything else is within-schema drift. No endpoint-map warnings; tests, types, lint, build, and publint green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fetchers write plain JSON.stringify output, but the repo's autofix bot runs `pnpm format` on every PR — so each nightly sync PR earned a formatting follow-up commit (and a misleading double diff). Normalise the specs dir with the repo's Prettier at the end of fetch-schemas so committed specs land in their final form. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The nightly schema sync feeds third-party-controlled OpenAPI specs (notably per-model FAL metadata) through codegen into modules that execute on import and ship to npm. Add two mechanical guards so the sync PR is safe to merge without reading the multi-MB generated diff: - scripts/verify-generated.ts: AST check that every module under src/providers/ is data-only TypeScript — literals, zod builder chains, and same-directory imports only. Blocks template substitutions, element access, constructor/prototype pivots, new, spreads, arbitrary functions, and undeclared identifiers. Runs in the sync workflow, as a vitest test in normal CI, and via a new verify-generated package script. - .github/workflows/verify-sync-schemas.yml: PR-side gate for automated/sync-schemas PRs that enforces the diff stays within sync-owned paths and re-runs the data-only check. Also tighten sync-schemas.yml (fail on out-of-allowlist changes, detect untracked files, narrow git add) and correct the README's claim that the workflow bumps the package version. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
🎯 Changes
Closes #619.
Adds
@tanstack/ai-schemas— per-endpoint JSON Schema + Zod definitions for every supported provider's generation endpoints, generated nightly from upstream OpenAPI specs. Architecture ported from fal-ai/fal-js#212 and generalised to multi-provider.Why:
model-meta.tscovers coarse per-model facts (context window, modalities, pricing) but not the per-endpoint constraint surface — which durations Veo3 accepts, which image sizes Flux2 takes, valid ElevenLabs voice IDs, prompt-length caps. Schemas give runtime code and LLMs a way to shape and validate requests before they hit the network.Providers: OpenAI, Anthropic, Gemini (Discovery doc → OpenAPI in-pipeline), ElevenLabs, xAI Grok, OpenRouter (incl. async video generation with frame/reference image conditioning), FAL (600+ models, specs committed; CI fetch needs
FAL_KEY).Activity grouping: endpoints are grouped per provider by activity, aligned with the core library's activities —
chat,image,video,audio(TTS, transcription, music, SFX in one group),embeddings,moderation:Platform/admin endpoints (projects, invites, certificates, fine-tuning, file stores, workspaces) are excluded from generation. JSON Schemas ship self-contained (
$refclosures bundled under$defs); binary-response media endpoints (e.g. TTS) map input-only entries. No aggregator barrel — bundlers tree-shake by file.Pipeline:
fetch-schemas→@hey-api/openapi-ts(pinned 0.97.2, JSON Schema + Zod 4 plugins, per-activity spec splits with orphan pruning) →generate-endpoint-maps($defs bundling, endpoint-id-keyed maps). Post-processing fixes three generator/spec issues: hey-api's schema-name discriminator grafts (discriminated unions rejected every valid payload at runtime), multipart/form-data request bodies (transcription/dubbing endpoints were silently missing), and dedup-renamed schema refs dangling in$defs.Automation:
.github/workflows/sync-schemas.ymlruns daily at 05:00 UTC and opens an automated PR on diff, following thesync-models.ymlpattern. Repo setup: addFAL_KEYto repo secrets (the fetcher must use the plainexpand=openapi-3.0param — the bracketed form is silently ignored upstream).Coupled updates:
docs/advanced/ai-schemas.md(+docs/config.json), media-generation and adapter-configuration skills, changeset for the initial minor release.✅ Checklist
pnpm run test:pr.🚀 Release Impact
🤖 Generated with Claude Code