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 9 commits into
Conversation
…oses #619) Adds a separate `@tanstack/ai-schemas` package that ships per-endpoint JSON Schema + Zod definitions for every supported provider, generated nightly from upstream OpenAPI specs. Architecture ported from fal-ai/fal-js PR #212 and generalised to multi-provider. Pipeline: `fetch-schemas` (per-provider fetchers) → `generate-schemas` (`@hey-api/openapi-ts` with the Zod 4 plugin) → `generate-endpoint-maps` (bundles `$ref` closures under `$defs`, emits endpoint-id-keyed maps and namespaced top-level barrels). Providers wired up with working generation: - OpenAI: `github.com/openai/openai-openapi` raw YAML - Anthropic: Stainless OpenAPI resolved via anthropic-sdk-typescript/.stats.yml - Gemini: Google Discovery doc → OpenAPI converted in-pipeline - ElevenLabs: `api.elevenlabs.io/openapi.json` - FAL: per-model OpenAPI from `api.fal.ai/v1/models` (skips when FAL_KEY absent) .github/workflows/sync-schemas.yml runs daily and opens an automated PR when any upstream spec diff lands, following the same pattern as sync-models.yml. Per repo coupling rules: media-generation + adapter-configuration SKILL.md cross-reference the new package; new docs/advanced/ai-schemas.md page added under the Advanced section. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
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 Preview1 package(s) bumped directly, 0 bumped as dependents. 🟨 Minor bumps
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
View your CI Pipeline Execution ↗ for commit 192f1a8
☁️ Nx Cloud last updated this comment at |
Switches `@tanstack/ai-schemas` from format-first
(`@tanstack/ai-schemas/schemas/openai`, `/zod/gemini`) to provider-first
(`@tanstack/ai-schemas/openai/json-schema`, `/gemini/zod`) and drops the
namespaced aggregator barrels.
With provider-first subpaths and no aggregator, importing one provider's
schemas pulls only that provider's bytes. Importing
`@tanstack/ai-schemas/gemini/json-schema` carries no OpenAI, Anthropic,
ElevenLabs, or FAL code into the consumer's bundle.
The default `.` entry now only re-exports `toOpenAIStrict` (4 KB).
Wildcard exports in package.json:
"./*/json-schema" -> dist/esm/providers/*/schemas-index.{js,d.ts}
"./*/zod" -> dist/esm/providers/*/index.{js,d.ts}
Generator emits a flat layout — `providers/{providerId}` for single-
category providers, `providers/{providerId}-{category}` for FAL
(`fal-image`, `fal-video`, etc.) — so Node's single-segment `*` wildcard
resolves cleanly.
Vite discovers per-provider barrels at build time so the dist mirrors
the provider layout.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds Grok as a provider in the nightly OpenAPI sync. Source is xAI's first-party OpenAPI spec at docs.x.ai/openapi.json (OpenAPI 3.1.0, 32 endpoints, 168 schemas). Public, no auth required for the spec. Grok is API-compatible with OpenAI's chat completions at the wire level but ships an independent schema set (different names, slightly different shapes, plus xAI-specific endpoints: deferred-completion, documents/search, per-modality model lists, video edits/extensions, tokenize-text, etc.). Each provider stays isolated in the schemas package. Bumps the build script's heap to 8 GB. With six providers now in the single dts program, the default 4 GB limit was tight. Knip ignores `vite` for ai-schemas since the script invokes the binary directly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@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-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: |
…bles The earlier `/* eslint-disable */` and `// @ts-nocheck` headers on every generated file were holdovers from iterations before the spec-level transforms (`coerceDefaults`, discriminator rewrites) cleaned up the codegen. With those in place, the only real issues are: - One `no-control-regex` lint error in `elevenlabs/zod.gen.ts` (a literal `\x09` in a regex pattern, faithful to upstream). - One tsc error in `openai/zod.gen.ts` where the post-process rewrites `.extend()` on a discriminatedUnion to `z.intersection(...)` (runtime correct, but intersections aren't `$ZodTypeDiscriminable`). Replace the blanket suppressors with two surgical mechanisms: - `suppressControlRegexLines` injects `// eslint-disable-next-line no-control-regex` immediately above each regex literal containing a control-char escape. - The `.extend()` rewriter now reports whether it touched anything; only files where it did get a two-line header (`ban-ts-comment` disable followed by `@ts-nocheck`) so the workspace lint rule doesn't fire. Net effect: zero file-level disables, two line-level disables on the only file that needs them, ~100 `no-explicit-any` warnings (warn-level in the project config, do not fail CI). `pnpm test:eslint` and `pnpm test:types` both walk the generated files in full and pass clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rkflow `@hey-api/openapi-ts` runs with full code-execution privileges during nightly codegen, so an unintentional bump shouldn't be possible. Drop the caret on the version specifier (`^0.97.2` -> `0.97.2`) so future updates have to land via an explicit PR. The lockfile already pinned the resolved version; this just removes the wiggle room in the manifest. Add a `pnpm audit --audit-level=high` step to sync-schemas.yml. It's non-blocking (`continue-on-error: true`) because the workspace currently carries pre-existing transitive advisories (e.g. an old protobufjs via @google/genai used by ai-gemini) that aren't related to schemas codegen and shouldn't be allowed to break the nightly. The step's purpose is to surface any *new* advisory landing on the codegen dep tree so the human reviewing the automated PR can spot it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
We already have pnpm's trust-downgrade policy active (refuses installs where provenance attestation regressed), the heyapi version explicitly pinned without a caret, and an automated PR pattern that forces human review before any codegen change lands. A non-blocking audit step would just be log noise, and a blocking one needs scope work we don't want to take on right now. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Adds a separate
@tanstack/ai-schemaspackage that ships per-endpoint JSON Schema + Zod definitions for every supported provider, generated nightly from upstream OpenAPI specs. Resolves #619.Architecture ported from fal-ai/fal-js#212 and generalised to multi-provider.
Pipeline
fetch-schemas— per-provider fetchers underscripts/providers/.generate-schemas—@hey-api/openapi-tswith@hey-api/schemas+ Zod 4 plugin.generate-endpoint-maps— bundles each schema's$refclosure under$defs, emits endpoint-id-keyed maps + namespaced top-level barrels.Providers covered
github.com/openai/openai-openapiraw YAMLanthropic-sdk-typescript/.stats.ymlapi.elevenlabs.io/openapi.jsonapi.fal.ai/v1/models?status=active&expand=openapi-3.0(needsFAL_KEY)Spec-level fixes
To keep generator output type-clean, the merge step (
scripts/merge-openapi-specs.ts) drops/coerces malformed defaults:default: nullon non-nullable fields,default: "string"on enum/array/object fields, type/value mismatches. Post-process step rewrites.extend()calls on discriminated unions toz.intersection(...)so runtime Zod is valid.The auto-generated
*.gen.tsfiles carry/* eslint-disable */+// @ts-nocheck(standard codegen convention). All hand-written source still type-checks strictly.Automation
.github/workflows/sync-schemas.ymlruns daily at 05:00 UTC. On diff: bumps patch version, writes a changeset, opens an automated PR. Same pattern as the existingsync-models.yml.Repo setup: add
FAL_KEYto repo secrets so FAL schemas can sync in CI. Other four providers are public.Per-coupling updates
packages/typescript/ai/skills/ai-core/media-generation/SKILL.md— adds a "Validating inputs before submitting" section + cross-ref.packages/typescript/ai/skills/ai-core/adapter-configuration/SKILL.md— cross-references the new package.docs/advanced/ai-schemas.md+docs/config.json— new doc page under Advanced..changeset/initial-ai-schemas.md— minor release for@tanstack/ai-schemas@0.1.0.Test plan
pnpm install(lockfile updated for@hey-api/openapi-ts,tsx,yaml)pnpm --filter @tanstack/ai-schemas test:lib— 5 unit tests pass (toOpenAIStrict)pnpm --filter @tanstack/ai-schemas test:types— strict tsc, no errorspnpm --filter @tanstack/ai-schemas test:eslint— cleanpnpm --filter @tanstack/ai-schemas test:build— publint strict passespnpm test:sherif,pnpm test:knip,pnpm test:docs— cleanpnpm --filter @tanstack/ai-schemas update-schemasregenerates all 4 public providers end-to-end (~30s)FAL_KEYto repo secrets, manually dispatchsync-schemas.yml, confirm FAL category schemas land in the follow-up PRimport { openaiEndpointZodMap } from "@tanstack/ai-schemas/zod/openai", parse a sample request🤖 Generated with Claude Code