Skip to content

feat(providers): generate type-checked provider HTTP clients from modelschemas with Kubb - #2105

Draft
tombeckenham wants to merge 13 commits into
mainfrom
2104-generate-provider-http-clients-from-modelschemas-with-kubb
Draft

tombeckenham wants to merge 13 commits into
mainfrom
2104-generate-provider-http-clients-from-modelschemas-with-kubb

Conversation

@tombeckenham

@tombeckenham tombeckenham commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Review packages/openai-base/src/client/client.ts first. The other six clients copy its pattern. The provider clients now build their requests with code that Kubb generates from the modelschemas OpenAPI documents. TypeScript checks every request body against the generated types. pnpm generate:provider-clients:check fails when a live document would change the committed code.

🎯 Changes

  • Generator. scripts/provider-clients/ lists the providers on modelschemas, fetches each OpenAPI document, and runs Kubb and oxfmt.
    • It skips a provider that has no document (missing_connect, no_endpoints, unknown_provider).
    • --check compares the output with the committed files.
    • It removes format: byte before Kubb runs. Kubb types byte as Blob, but the APIs take a base64 string.
  • Generated clients. OpenAI (in openai-base), Anthropic, Gemini, Mistral, OpenRouter, ElevenLabs, Fal, Cohere, Ollama, World Labs, Ollaya, TypeSafe, and Reactor each get src/generated/client/{sdk,types}.ts. Groq, Grok, Azure, and the gateways use the OpenAI client.
    • World Labs drops its hey-api client and its copy of openapi.yaml.
    • Bedrock gets types.ts only. Its Converse bodies are checked against it, and the AWS SDK still sends them.
    • Muse gets Meta's types.ts only. It sends through the shared OpenAI Chat Completions path, and its request is checked against Meta's own body type.
    • Cohere rerank stays hand-written, because /v2/rerank is not in the document.
  • Fal types by activity. FalModelInput and FalModelOutput come from the per-activity fal documents (?activity=image|video|audio|chat), not from @fal-ai/client. The image field overrides and video durations are generated from the same documents. *_url fields still take a Blob to upload.
  • Type-checked bodies. Each adapter builds its body as the generated type, with no casts. A line where the document or a public SDK type does not fit has a @ts-expect-error that names the mismatch. The build fails when the document is fixed, so the marker cannot go stale.
  • One shared runtime. @tanstack/ai-utils/kubb holds the Kubb fetch runtime and sendWith(). sendWith() sends a generated request through the provider's own code (auth, retries, errors, SSE, audio).
  • Video durations. Sora (OPENAI_VIDEO_DURATIONS) and Grok Imagine (GROK_VIDEO_DURATIONS) are generated from each provider's video create operation, like fal's. Gemini, BytePlus and Lovable stay hand-written until modelschemas has the data.
  • Model lists from modelschemas. scripts/sync-provider-models.ts reads GET /v1/models?provider=…&pricing=1 for OpenAI, Anthropic, Gemini and Grok, not the OpenRouter catalogue. Ids are native (rawId), so the OpenRouter id mapping is gone.
  • Daily drift workflow. sync-provider-clients.yml runs the check, regenerates, and opens a PR.

Bugs fixed on the way:

  • Mistral. The streaming path sent a json_schema response format in camelCase. It now sends snake_case.
  • ElevenLabs. Transcription dropped a string entityDetection or entityRedaction. It now sends it.

Hand-written code that stays: calls that the documents do not have (files, job status, model lists, rerank), SigV4 signing, and the Vertex and Enterprise paths of Gemini.

Differences from the plan in the issue:

Document gaps found

These lines carry a modelschemas gap marker. Each one needs an upstream fix in TanStack/modelschemas.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested code changes locally with pnpm run test:pr, or these tests do not apply to this pull request.
  • I fully understand the code in this pull request, including any code generated with AI assistance.
  • Docs: I updated docs/ for this change, or this change is not user-facing.
  • Changeset: I added a changeset (pnpm changeset), or this PR does not change a published package.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Testing

Commands run

  • tsc --noEmit, oxlint src --type-aware, and vitest run in the 26 changed packages, and nx run-many -t test:types on all of them. All pass, and the SDK parity tests are green.
  • pnpm test:knip passes. pnpm generate:provider-clients:check exits 0.
  • pnpm test:kiira passes (2149 doc snippets).
  • vitest run scripts/provider-clients passes (12 tests).
  • Not run: pnpm test:pr and the E2E suite. CI runs them.

Manual test

  1. Run pnpm generate:provider-clients:check. It exits 0.
  2. Edit one line in packages/ai-fal/src/generated/client/sdk.ts. Run the check again. It names the file and exits 1.
  3. Run pnpm generate:provider-clients. The edit is gone.
  4. In packages/ai-mistral/src/adapters/text.ts, remove a @ts-expect-error modelschemas gap line. pnpm exec tsc --noEmit -p packages/ai-mistral fails on that line.

How this PR makes testing easy

Each migrated package has tests/generated-client.test.ts. It injects fetch and checks one JSON call and one streaming or audio call. scripts/provider-clients/files.test.ts covers the drift check and the byte fix.

Linked issues

Closes #2104

Risk / rollback

  • Request shape. A changed URL, header, or body key could break a call. The parity tests compare the wire with the real SDKs.
  • Breaking changes.
    • A custom adapter that passes new OpenAI() to an openai-base adapter no longer compiles. The runtime is the same.
    • Some Fal model input fields change type, because they now follow the live fal schemas.
  • Ollama. Requests built from adapter config no longer send the ollama-js User-Agent. In Node, an image string that is a file path is sent as is.
  • Repo size. The generated types add about 4 MB, plus about 6.5 MB of Fal types.
  • Rollback. Revert the PR.

Public API change

OpenAIClientLike in @tanstack/openai-base takes the generated body types, so an SDK instance no longer fits it. @tanstack/openai-base exports the generated body types. @tanstack/ai-utils has a new @tanstack/ai-utils/kubb entry point, and createElevenLabsClient() accepts an optional fetch.

Before

import OpenAI from 'openai'

new MyTextAdapter('my-model', 'my-provider', new OpenAI({ apiKey, baseURL }))

After

import { createOpenAIClient } from '@tanstack/openai-base'

new MyTextAdapter('my-model', 'my-provider', createOpenAIClient({ apiKey, baseURL }))

@tombeckenham
tombeckenham requested a review from a team as a code owner November 9, 2026 04:06
@tombeckenham tombeckenham linked an issue Nov 9, 2026 that may be closed by this pull request
@tombeckenham
tombeckenham marked this pull request as draft November 9, 2026 04:08
@nx-cloud

nx-cloud Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 80cb9c0

Command Status Duration Result
nx run-many --targets=test:coverage --projects=... ✅ Succeeded 6s View ↗
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 5m 41s View ↗
nx run-many --targets=build --exclude=examples/... ✅ Succeeded 2s View ↗

💡 With Ultracache enabled, Nx Cloud learns each task's file inputs in CI and uses them on later runs. Turn on Ultracache in workspace settings ↗ · Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-11-14 07:22:14 UTC

@coderabbitai

coderabbitai Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
Pre-merge checks: Inconclusive 2

Failed Failed checks: 2 inconclusive

Check name Status Explanation Resolution
Title check Pending This assessment has not completed. The check will be retried on the next pre-merge check run.
Description check Pending This assessment has not completed. The check will be retried on the next pre-merge check run.
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

Share

@changeset-bot

changeset-bot Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 80cb9c0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 18 packages
Name Type
@tanstack/ai-utils Minor
@tanstack/openai-base Minor
@tanstack/ai-anthropic Patch
@tanstack/ai-gemini Patch
@tanstack/ai-mistral Patch
@tanstack/ai-openrouter Patch
@tanstack/ai-elevenlabs Patch
@tanstack/ai-fal Minor
@tanstack/ai-cohere Patch
@tanstack/ai-ollama Patch
@tanstack/ai-worldlabs Patch
@tanstack/ai-ollaya Patch
@tanstack/ai-typesafe Patch
@tanstack/ai-reactor Patch
@tanstack/ai-muse Patch
@tanstack/ai-bedrock Patch
@tanstack/ai-openai Patch
@tanstack/ai-grok Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@socket-security

socket-security Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​@​kubb/​plugin-client@​5.10.01001007896100
Addednpm/​@​kubb/​plugin-fetch@​5.13.01001009396100
Addednpm/​@​kubb/​plugin-ts@​5.4.11001009396100
Addednpm/​kubb@​5.16.19910010096100

View full report

@github-actions

github-actions Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Coverage

❌ Coverage fell under 60% in 1 package(s).

Each package is measured twice in this job — on this PR and on its merge-base with main — and compared. A metric fails only when it is at or above 60% on the merge-base and under 60% on this PR. Other drops are listed but do not fail. Packages your PR doesn't affect are not measured and not listed.

package statements branches functions lines
ai 92.33% (0.00) 86.07% (0.00) 92.20% (0.00) 93.88% (0.00) ok
ai-acp 83.40% (0.00) 72.32% (0.00) 79.01% (0.00) 85.05% (0.00) ok
ai-angular 73.83% (0.00) 60.89% (0.00) 61.83% (0.00) 75.40% (0.00) ok
ai-anthropic 92.97% (+0.02) 87.88% (0.00) 95.15% (+0.06) 94.16% (+0.02) ok
ai-bedrock 92.56% (+0.03) 85.51% (0.00) 96.29% (+0.02) 93.95% (+0.02) ok
ai-byteplus 97.15% (0.00) 92.41% (0.00) 98.26% (0.00) 98.61% (0.00) ok
ai-claude-code 88.95% (0.00) 77.47% (0.00) 86.66% (0.00) 90.42% (0.00) ok
ai-client 88.21% (0.00) 80.30% (0.00) 87.46% (0.00) 90.47% (0.00) ok
ai-cloudflare 87.54% (0.00) 78.12% (0.00) 85.48% (0.00) 88.76% (0.00) ok
ai-code-mode 93.83% (0.00) 86.33% (0.00) 91.48% (0.00) 94.73% (0.00) ok
ai-code-mode-snippets 87.13% (0.00) 75.67% (0.00) 91.11% (0.00) 88.39% (0.00) ok
ai-codex 94.59% (0.00) 85.41% (0.00) 89.09% (0.00) 95.58% (0.00) ok
ai-cohere 84.75% (-6.73) 74.38% (-13.37) 76.31% (-15.69) 87.17% (-6.90) ok
ai-compaction 97.41% (0.00) 92.89% (0.00) 100.00% (0.00) 98.89% (0.00) ok
ai-computer-local 97.29% (0.00) 85.71% (0.00) 88.00% (0.00) 96.84% (0.00) ok
ai-computer-playwright 92.85% (0.00) 96.55% (0.00) 92.59% (0.00) 93.44% (0.00) ok
ai-computer-sandbox 96.25% (0.00) 87.50% (0.00) 100.00% (0.00) 96.05% (0.00) ok
ai-computer-use 96.08% (0.00) 92.22% (0.00) 95.53% (0.00) 98.28% (0.00) ok
ai-devtools 83.13% (0.00) 72.77% (0.00) 87.07% (0.00) 85.22% (0.00) ok
ai-durable-stream 86.70% (0.00) 82.25% (0.00) 92.30% (0.00) 88.72% (0.00) ok
ai-effect 100.00% (0.00) 80.00% (0.00) 96.96% (0.00) 100.00% (0.00) ok
ai-elevenlabs 80.70% (+0.42) 73.12% (+0.24) 78.01% (+2.05) 81.22% (+0.45) ok
ai-event-client 60.13% (0.00) 52.50% (0.00) 70.00% (0.00) 61.76% (0.00) ok
ai-fal 90.89% (-0.31) 80.88% (-0.83) 89.68% (+0.43) 91.34% (-0.21) ok
ai-gemini 74.10% (-0.30) 70.53% (-0.77) 71.33% (-1.63) 74.88% (-0.31) ok
ai-grok 51.97% (-0.08) 54.86% (0.00) 62.83% (0.00) 52.74% (-0.08) ok
ai-grok-build 81.12% (0.00) 66.61% (0.00) 77.87% (0.00) 83.12% (0.00) ok
ai-groq 74.53% (0.00) 68.02% (0.00) 83.72% (0.00) 76.19% (0.00) ok
ai-harness 93.80% (0.00) 88.14% (0.00) 93.62% (0.00) 95.58% (0.00) ok
ai-harness-cli 91.08% (0.00) 83.24% (0.00) 83.85% (0.00) 92.12% (0.00) ok
ai-isolate-cloudflare 94.30% (0.00) 71.60% (0.00) 100.00% (0.00) 94.16% (0.00) ok
ai-isolate-daytona 90.99% (0.00) 81.50% (+0.68) 100.00% (0.00) 90.64% (0.00) ok
ai-isolate-e2b 92.38% (0.00) 81.75% (0.00) 97.43% (0.00) 95.21% (0.00) ok
ai-isolate-node 86.04% (0.00) 48.33% (0.00) 100.00% (0.00) 85.36% (0.00) ok
ai-isolate-quickjs 88.84% (0.00) 76.92% (0.00) 91.66% (0.00) 89.87% (0.00) ok
ai-isolate-quickjs-bun 7.36% (0.00) 7.53% (0.00) 4.76% (0.00) 7.94% (0.00) ok
ai-llmgateway 97.82% (0.00) 100.00% (0.00) 88.88% (0.00) 97.82% (0.00) ok
ai-lovable 76.33% (0.00) 59.85% (-0.29) 88.05% (0.00) 77.19% (0.00) FAIL
ai-mcp 94.79% (0.00) 89.59% (0.00) 96.85% (0.00) 96.86% (0.00) ok
ai-memory 77.44% (0.00) 58.40% (0.00) 81.70% (0.00) 79.80% (0.00) ok
ai-mistral 87.95% (-0.02) 82.62% (+0.14) 93.20% (-0.49) 88.57% (-0.10) ok
ai-muse 87.09% (-6.01) 100.00% (0.00) 71.42% (-11.91) 87.09% (-6.01) ok
ai-neon 96.51% (0.00) 90.00% (0.00) 94.73% (0.00) 98.11% (0.00) ok
ai-octane 91.19% (0.00) 68.26% (0.00) 87.44% (0.00) 91.47% (0.00) ok
ai-ollama 92.85% (-1.56) 76.81% (-5.57) 87.80% (-3.37) 93.40% (-0.94) ok
ai-ollaya 92.30% (+5.46) 90.32% (+1.04) 88.88% (+3.17) 97.29% (+5.63) ok
ai-openai 75.12% (-0.02) 71.03% (-0.13) 74.75% (0.00) 76.07% (-0.02) ok
ai-opencode 79.07% (0.00) 71.30% (0.00) 75.23% (0.00) 81.21% (0.00) ok
ai-openrouter 89.22% (+0.02) 77.12% (-0.02) 91.36% (+0.18) 91.27% (+0.05) ok
ai-perplexity 91.34% (0.00) 90.43% (0.00) 100.00% (0.00) 93.87% (0.00) ok
ai-persistence 94.38% (0.00) 82.64% (0.00) 97.81% (0.00) 96.11% (0.00) ok
ai-preact 86.50% (0.00) 71.00% (0.00) 87.50% (0.00) 87.98% (0.00) ok
ai-react 82.20% (0.00) 66.01% (0.00) 80.82% (0.00) 82.91% (0.00) ok
ai-reactor 95.23% (+0.32) 84.84% (+1.51) 94.11% (+0.78) 96.77% (+0.22) ok
ai-remix 43.02% (0.00) 30.35% (0.00) 39.02% (0.00) 46.23% (0.00) ok
ai-sandbox 79.53% (0.00) 83.99% (0.00) 76.68% (0.00) 80.19% (0.00) ok
ai-sandbox-blaxel 87.66% (0.00) 77.18% (0.00) 82.26% (0.00) 89.69% (0.00) ok
ai-sandbox-boxd 95.40% (0.00) 86.42% (0.00) 93.42% (0.00) 98.05% (0.00) ok
ai-sandbox-cloudflare 70.61% (0.00) 59.86% (0.00) 75.32% (0.00) 71.89% (0.00) ok
ai-sandbox-daytona 81.25% (0.00) 82.20% (0.00) 67.12% (0.00) 83.62% (0.00) ok
ai-sandbox-docker 82.89% (0.00) 73.57% (0.00) 81.16% (0.00) 84.67% (0.00) ok
ai-sandbox-e2b 94.84% (0.00) 90.71% (0.00) 93.24% (0.00) 98.64% (0.00) ok
ai-sandbox-local-process 69.27% (0.00) 53.59% (0.00) 77.01% (0.00) 70.30% (0.00) ok
ai-sandbox-railway 94.87% (0.00) 92.68% (0.00) 90.90% (0.00) 97.65% (0.00) ok
ai-sandbox-sprites 73.10% (0.00) 60.00% (0.00) 73.83% (0.00) 75.95% (0.00) ok
ai-sandbox-upstash-box 94.61% (0.00) 91.52% (0.00) 91.04% (0.00) 97.42% (0.00) ok
ai-sandbox-vercel 54.20% (0.00) 54.46% (0.00) 46.42% (0.00) 54.68% (0.00) ok
ai-skills 83.94% (0.00) 67.95% (0.00) 88.00% (0.00) 86.03% (0.00) ok
ai-solid 75.81% (0.00) 57.63% (0.00) 71.28% (0.00) 78.11% (0.00) ok
ai-svelte 74.05% (0.00) 50.99% (0.00) 70.05% (0.00) 78.64% (0.00) ok
ai-typesafe 83.33% (+5.29) 86.20% (+1.59) 72.72% (+6.06) 87.50% (+5.45) ok
ai-utils 88.78% (+0.08) 85.01% (+0.10) 84.12% (+0.52) 90.00% (+0.09) ok
ai-vercel-gateway 78.84% (0.00) 67.72% (0.00) 84.90% (0.00) 82.16% (0.00) ok
ai-vertex 96.77% (0.00) 97.22% (0.00) 100.00% (0.00) 96.77% (0.00) ok
ai-vue 73.33% (0.00) 48.73% (0.00) 73.28% (0.00) 74.66% (0.00) ok
ai-worldlabs 81.81% (+2.19) 72.10% (+0.60) 92.10% (+0.68) 84.04% (+1.38) ok
openai-base 92.28% (+0.17) 82.23% (+0.05) 96.74% (+0.50) 94.49% (+0.12) ok

@pkg-pr-new

pkg-pr-new Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@tanstack/ai

npm i https://pkg.pr.new/@tanstack/ai@2105

@tanstack/ai-acp

npm i https://pkg.pr.new/@tanstack/ai-acp@2105

@tanstack/ai-angular

npm i https://pkg.pr.new/@tanstack/ai-angular@2105

@tanstack/ai-anthropic

npm i https://pkg.pr.new/@tanstack/ai-anthropic@2105

@tanstack/ai-bedrock

npm i https://pkg.pr.new/@tanstack/ai-bedrock@2105

@tanstack/ai-byteplus

npm i https://pkg.pr.new/@tanstack/ai-byteplus@2105

@tanstack/ai-claude-code

npm i https://pkg.pr.new/@tanstack/ai-claude-code@2105

@tanstack/ai-client

npm i https://pkg.pr.new/@tanstack/ai-client@2105

@tanstack/ai-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-cloudflare@2105

@tanstack/ai-code-mode

npm i https://pkg.pr.new/@tanstack/ai-code-mode@2105

@tanstack/ai-code-mode-snippets

npm i https://pkg.pr.new/@tanstack/ai-code-mode-snippets@2105

@tanstack/ai-codex

npm i https://pkg.pr.new/@tanstack/ai-codex@2105

@tanstack/ai-cohere

npm i https://pkg.pr.new/@tanstack/ai-cohere@2105

@tanstack/ai-compaction

npm i https://pkg.pr.new/@tanstack/ai-compaction@2105

@tanstack/ai-computer-local

npm i https://pkg.pr.new/@tanstack/ai-computer-local@2105

@tanstack/ai-computer-playwright

npm i https://pkg.pr.new/@tanstack/ai-computer-playwright@2105

@tanstack/ai-computer-sandbox

npm i https://pkg.pr.new/@tanstack/ai-computer-sandbox@2105

@tanstack/ai-computer-use

npm i https://pkg.pr.new/@tanstack/ai-computer-use@2105

@tanstack/ai-devtools-core

npm i https://pkg.pr.new/@tanstack/ai-devtools-core@2105

@tanstack/ai-durable-stream

npm i https://pkg.pr.new/@tanstack/ai-durable-stream@2105

@tanstack/ai-effect

npm i https://pkg.pr.new/@tanstack/ai-effect@2105

@tanstack/ai-elevenlabs

npm i https://pkg.pr.new/@tanstack/ai-elevenlabs@2105

@tanstack/ai-event-client

npm i https://pkg.pr.new/@tanstack/ai-event-client@2105

@tanstack/ai-fal

npm i https://pkg.pr.new/@tanstack/ai-fal@2105

@tanstack/ai-gemini

npm i https://pkg.pr.new/@tanstack/ai-gemini@2105

@tanstack/ai-grok

npm i https://pkg.pr.new/@tanstack/ai-grok@2105

@tanstack/ai-grok-build

npm i https://pkg.pr.new/@tanstack/ai-grok-build@2105

@tanstack/ai-groq

npm i https://pkg.pr.new/@tanstack/ai-groq@2105

@tanstack/ai-harness

npm i https://pkg.pr.new/@tanstack/ai-harness@2105

@tanstack/ai-harness-cli

npm i https://pkg.pr.new/@tanstack/ai-harness-cli@2105

@tanstack/ai-isolate-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-isolate-cloudflare@2105

@tanstack/ai-isolate-daytona

npm i https://pkg.pr.new/@tanstack/ai-isolate-daytona@2105

@tanstack/ai-isolate-e2b

npm i https://pkg.pr.new/@tanstack/ai-isolate-e2b@2105

@tanstack/ai-isolate-node

npm i https://pkg.pr.new/@tanstack/ai-isolate-node@2105

@tanstack/ai-isolate-quickjs

npm i https://pkg.pr.new/@tanstack/ai-isolate-quickjs@2105

@tanstack/ai-isolate-quickjs-bun

npm i https://pkg.pr.new/@tanstack/ai-isolate-quickjs-bun@2105

@tanstack/ai-llmgateway

npm i https://pkg.pr.new/@tanstack/ai-llmgateway@2105

@tanstack/ai-lovable

npm i https://pkg.pr.new/@tanstack/ai-lovable@2105

@tanstack/ai-mcp

npm i https://pkg.pr.new/@tanstack/ai-mcp@2105

@tanstack/ai-memory

npm i https://pkg.pr.new/@tanstack/ai-memory@2105

@tanstack/ai-mistral

npm i https://pkg.pr.new/@tanstack/ai-mistral@2105

@tanstack/ai-muse

npm i https://pkg.pr.new/@tanstack/ai-muse@2105

@tanstack/ai-neon

npm i https://pkg.pr.new/@tanstack/ai-neon@2105

@tanstack/ai-octane

npm i https://pkg.pr.new/@tanstack/ai-octane@2105

@tanstack/ai-ollama

npm i https://pkg.pr.new/@tanstack/ai-ollama@2105

@tanstack/ai-ollaya

npm i https://pkg.pr.new/@tanstack/ai-ollaya@2105

@tanstack/ai-openai

npm i https://pkg.pr.new/@tanstack/ai-openai@2105

@tanstack/ai-opencode

npm i https://pkg.pr.new/@tanstack/ai-opencode@2105

@tanstack/ai-openrouter

npm i https://pkg.pr.new/@tanstack/ai-openrouter@2105

@tanstack/ai-perplexity

npm i https://pkg.pr.new/@tanstack/ai-perplexity@2105

@tanstack/ai-persistence

npm i https://pkg.pr.new/@tanstack/ai-persistence@2105

@tanstack/ai-preact

npm i https://pkg.pr.new/@tanstack/ai-preact@2105

@tanstack/ai-react

npm i https://pkg.pr.new/@tanstack/ai-react@2105

@tanstack/ai-reactor

npm i https://pkg.pr.new/@tanstack/ai-reactor@2105

@tanstack/ai-remix

npm i https://pkg.pr.new/@tanstack/ai-remix@2105

@tanstack/ai-sandbox

npm i https://pkg.pr.new/@tanstack/ai-sandbox@2105

@tanstack/ai-sandbox-blaxel

npm i https://pkg.pr.new/@tanstack/ai-sandbox-blaxel@2105

@tanstack/ai-sandbox-boxd

npm i https://pkg.pr.new/@tanstack/ai-sandbox-boxd@2105

@tanstack/ai-sandbox-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-sandbox-cloudflare@2105

@tanstack/ai-sandbox-daytona

npm i https://pkg.pr.new/@tanstack/ai-sandbox-daytona@2105

@tanstack/ai-sandbox-docker

npm i https://pkg.pr.new/@tanstack/ai-sandbox-docker@2105

@tanstack/ai-sandbox-e2b

npm i https://pkg.pr.new/@tanstack/ai-sandbox-e2b@2105

@tanstack/ai-sandbox-local-process

npm i https://pkg.pr.new/@tanstack/ai-sandbox-local-process@2105

@tanstack/ai-sandbox-railway

npm i https://pkg.pr.new/@tanstack/ai-sandbox-railway@2105

@tanstack/ai-sandbox-sprites

npm i https://pkg.pr.new/@tanstack/ai-sandbox-sprites@2105

@tanstack/ai-sandbox-upstash-box

npm i https://pkg.pr.new/@tanstack/ai-sandbox-upstash-box@2105

@tanstack/ai-sandbox-vercel

npm i https://pkg.pr.new/@tanstack/ai-sandbox-vercel@2105

@tanstack/ai-skills

npm i https://pkg.pr.new/@tanstack/ai-skills@2105

@tanstack/ai-solid

npm i https://pkg.pr.new/@tanstack/ai-solid@2105

@tanstack/ai-svelte

npm i https://pkg.pr.new/@tanstack/ai-svelte@2105

@tanstack/ai-typesafe

npm i https://pkg.pr.new/@tanstack/ai-typesafe@2105

@tanstack/ai-utils

npm i https://pkg.pr.new/@tanstack/ai-utils@2105

@tanstack/ai-vercel-gateway

npm i https://pkg.pr.new/@tanstack/ai-vercel-gateway@2105

@tanstack/ai-vertex

npm i https://pkg.pr.new/@tanstack/ai-vertex@2105

@tanstack/ai-vue

npm i https://pkg.pr.new/@tanstack/ai-vue@2105

@tanstack/ai-worldlabs

npm i https://pkg.pr.new/@tanstack/ai-worldlabs@2105

@tanstack/openai-base

npm i https://pkg.pr.new/@tanstack/openai-base@2105

@tanstack/preact-ai-devtools

npm i https://pkg.pr.new/@tanstack/preact-ai-devtools@2105

@tanstack/react-ai-devtools

npm i https://pkg.pr.new/@tanstack/react-ai-devtools@2105

@tanstack/solid-ai-devtools

npm i https://pkg.pr.new/@tanstack/solid-ai-devtools@2105

@tanstack/svelte-ai-devtools

npm i https://pkg.pr.new/@tanstack/svelte-ai-devtools@2105

commit: 80cb9c0

…h Kubb

Adds scripts/provider-clients (generate + --check drift mode), the shared
Kubb fetch runtime at @tanstack/ai-utils/kubb with sendWith(), the
generated clients for openai, anthropic, gemini, mistral, openrouter,
elevenlabs and fal, and routes the openai-base client through the
generated OpenAI operations.
…labs and fal through the generated clients

Each client sends the operations that its modelschemas OpenAPI document
describes through the generated Kubb functions. Auth, retries, errors,
SSE parsing and audio bytes stay hand-written, as do calls the documents
do not have. The shared runtime now merges every provider's Kubb runtime,
so the SSE helpers that ElevenLabs needs are exported.
The generator fetches each provider's ?activity= documents. An activity
with per-model schemas gets a types-only src/generated/{activity} with a
{Provider}{Activity}Endpoints map of model id to { input, output }.
Only fal has per-model schemas today.
…types

Adapters and clients build each body as the generated modelschemas type, with
no casts. Lines where the document or a public SDK type does not fit carry a
@ts-expect-error that names the gap, so the build fails once it is fixed.

- openai-base: OpenAIClientLike takes the generated bodies (breaking: an SDK
  instance no longer fits; use createOpenAIClient).
- generator: drop format: byte, which Kubb types as Blob instead of base64.
- mistral: stream json_schema response format in snake_case.
- elevenlabs: send string entityDetection/entityRedaction.
model-meta's EndpointTypeMap now extends the generated image, video,
audio and chat maps instead of @fal-ai/client's single map. The image
field overrides and the video duration table are generated from the same
activity documents, replacing scripts/generate-fal-image-field-map.ts and
the hand-curated duration list.

Blocked on TanStack/schemas#605: the activity documents drop ~235
indexed endpoints (veo3.1, kling v1.6/v2.6, sora-2), so 4 tests fail.
…e a Blob

The fal activity documents now hold every indexed endpoint, so the typed
endpoint map covers veo3.1, kling and whisper. FalModelInput lets *_url and
*_urls fields take a Blob, which the fal client uploads, as @fal-ai/client did.
…e and Bedrock clients

- cohere: embed goes through the generated client; rerank stays hand-written.
- ollama: chat and embed go through the generated client with an NDJSON reader.
- worldlabs: the Kubb client replaces hey-api and the copied openapi.yaml.
- ollaya, typesafe: /v1/systemone goes through the generated client.
- bedrock: Converse bodies are checked against the generated types (types
  only; the AWS SDK still sends).
- generator: typesOnly providers; knip ignores generated types in any folder.
- fal: drop the unused per-activity model id types.
modelschemas#643 added POST /tokens to the Reactor document and marked
the model commands as realtime-only. Also picks up upstream Fal, Gemini
and OpenRouter document changes.
@tombeckenham
tombeckenham force-pushed the 2104-generate-provider-http-clients-from-modelschemas-with-kubb branch from 4b90839 to b68b154 Compare November 13, 2026 01:35
…ed types

Also fixes a test from main that passes an OpenAI SDK instance as the
client, and picks up upstream Fal, OpenRouter and OpenAI document changes.
…ra and Grok video durations

sync-provider-models.ts reads GET /v1/models?provider=…&pricing=1 for
OpenAI, Anthropic, Gemini and Grok instead of the OpenRouter catalogue.
Native ids come from rawId, so the OpenRouter id mapping is gone. Models
with no price are skipped for OpenAI and Anthropic, whose ModelMeta needs one.

The video duration step of generate.ts now also writes OPENAI_VIDEO_DURATIONS
and GROK_VIDEO_DURATIONS from each provider's create operation. Gemini,
BytePlus and Lovable stay hand-written until TanStack/schemas#657, #658
and #659 land.

Refs #2104
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generate provider HTTP clients from modelschemas with Kubb

1 participant