TypeScript SDK Providers
Supported TypeScript provider clients, metered surfaces, compatible endpoints, Responses limits, and exact preview qualification versions.
Solwyn wraps a provider client that your application constructs. Provider SDKs are optional peer dependencies: install only the client packages you use, and keep provider authentication on those clients. Solwyn does not import a provider SDK in its core or accept provider credentials.
Provider and surface matrix
| Integration | Client package | Metered text surface | Streaming usage |
|---|---|---|---|
| OpenAI | openai | chat.completions.create; native responses.create, responses.parse, and responses.stream | Terminal Chat Completions or Responses usage event |
| Azure OpenAI | openai AzureOpenAI client | Chat Completions and native Azure Responses | Terminal Chat Completions or Responses usage event |
| Anthropic | @anthropic-ai/sdk | messages.create | Terminal message_delta event |
| Google Gemini | @google/genai | models.generateContent and models.generateContentStream | Final stream chunk usage metadata |
| Amazon Bedrock | @aws-sdk/client-bedrock-runtime | send(new ConverseCommand(...)) and send(new ConverseStreamCommand(...)) | Terminal metadata event |
| Native Together | together-ai | chat.completions.create | OpenAI-compatible terminal usage chunk when provided |
| OpenAI-compatible | openai with baseURL | chat.completions.create | Terminal usage when the endpoint provides it; otherwise a flagged estimate |
| Vercel AI SDK | ai plus an AI SDK provider package | Language-model middleware around generateText and streamText | Buffered result or terminal stream usage |
See Vercel AI SDK integration for middleware setup. The LangChain.js and OpenAI Agents JS integrations add run attribution on top of a wrapped OpenAI client; the wrapped client still owns metering and enforcement. Media calls are covered separately below.
Wrap a native provider
Each example closes the wrapper after use. Replace the model with one available to your provider account.
import { Solwyn } from "@solwyn/sdk";
import OpenAI from "openai";
const solwynApiKey = process.env.SOLWYN_API_KEY;
if (!solwynApiKey) throw new Error("SOLWYN_API_KEY is required");
await using client = new Solwyn(new OpenAI(), { apiKey: solwynApiKey });
const response = await client.responses.create({
model: "gpt-4o",
input: "Return one short greeting.",
});
console.log(response.output_text);import { Solwyn } from "@solwyn/sdk";
import Anthropic from "@anthropic-ai/sdk";
const solwynApiKey = process.env.SOLWYN_API_KEY;
if (!solwynApiKey) throw new Error("SOLWYN_API_KEY is required");
await using client = new Solwyn(new Anthropic(), { apiKey: solwynApiKey });
const response = await client.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 128,
messages: [{ role: "user", content: "Return one short greeting." }],
});
console.log(response.content);import { GoogleGenAI } from "@google/genai";
import { Solwyn } from "@solwyn/sdk";
const solwynApiKey = process.env.SOLWYN_API_KEY;
const googleApiKey = process.env.GOOGLE_API_KEY;
if (!solwynApiKey || !googleApiKey) throw new Error("Solwyn and Google keys are required");
await using client = new Solwyn(new GoogleGenAI({ apiKey: googleApiKey }), {
apiKey: solwynApiKey,
});
const response = await client.models.generateContent({
model: "gemini-2.0-flash",
contents: "Return one short greeting.",
});
console.log(response.text);import { BedrockRuntimeClient, ConverseCommand } from "@aws-sdk/client-bedrock-runtime";
import { Solwyn } from "@solwyn/sdk";
const solwynApiKey = process.env.SOLWYN_API_KEY;
if (!solwynApiKey) throw new Error("SOLWYN_API_KEY is required");
const bedrock = new BedrockRuntimeClient({ region: "us-east-1" });
await using client = new Solwyn(bedrock, { apiKey: solwynApiKey });
const response = await client.send(
new ConverseCommand({
modelId: "us.anthropic.claude-3-5-sonnet-20241022-v2:0",
messages: [{ role: "user", content: [{ text: "Return one short greeting." }] }],
inferenceConfig: { maxTokens: 128 },
}),
);
console.log(response.output?.message?.content);import { Solwyn } from "@solwyn/sdk";
import OpenAI from "openai";
const solwynApiKey = process.env.SOLWYN_API_KEY;
const groqApiKey = process.env.GROQ_API_KEY;
if (!solwynApiKey || !groqApiKey) throw new Error("Solwyn and Groq keys are required");
const groq = new OpenAI({
baseURL: "https://api.groq.com/openai/v1",
apiKey: groqApiKey,
});
await using client = new Solwyn(groq, { apiKey: solwynApiKey });
const response = await client.chat.completions.create({
model: "llama-3.3-70b-versatile",
messages: [{ role: "user", content: "Return one short greeting." }],
});
console.log(response.choices[0]?.message.content);The wrapper preserves the provider client's parameter types. Intercepted OpenAI-style methods
return ordinary promises rather than OpenAI APIPromise objects, so .withResponse() and
.asResponse() are intentionally unavailable. Non-intercepted methods retain their native
types and behavior.
OpenAI-compatible detection
For an OpenAI-shaped client with a non-OpenAI baseURL, Solwyn assigns a provider name from the
URL. That name controls attribution, budgets, and circuit breakers; the wire dialect remains
OpenAI Chat Completions.
| Provider name | Detected host or local port |
|---|---|
xai | api.x.ai |
deepseek | api.deepseek.com |
mistral | api.mistral.ai |
qwen | dashscope.aliyuncs.com, dashscope-intl.aliyuncs.com, or dashscope-us.aliyuncs.com |
zai | api.z.ai |
groq | api.groq.com |
together | api.together.xyz or api.together.ai |
fireworks | api.fireworks.ai |
perplexity | api.perplexity.ai |
azure_openai | *.openai.azure.com or *.cognitiveservices.azure.com |
openrouter | openrouter.ai |
ollama | local port 11434 |
vllm | local port 8000 |
lmstudio | local port 1234 |
openai_compatible | Any other HTTP(S) non-OpenAI baseURL |
If detection cannot name an endpoint, pass an explicit provider option. The pin bypasses
detection, then synchronously verifies that the object matches the pinned client family. An
unknown name or incompatible client fails with ConfigurationError before background work or
provider I/O begins. The same override can be the fourth member of a fallback tuple; see
TypeScript SDK failover.
To preserve native OpenAI attribution and Responses support through a corporate gateway, use
provider: "openai" with an OpenAI-compatible client shape. Do this only when that gateway
preserves the native OpenAI contract.
Native Responses support and limits
Solwyn meters responses.create, responses.parse, and the deferred responses.stream() helper
only for native OpenAI and Azure OpenAI identities. These calls are primary-only: they do not
enter provider failover or cross-dialect translation.
The wrapper rejects these shapes before budget or provider I/O because it cannot meter them consistently:
responses.create({ background: true });- streaming
responses.parse(...); - second-argument request options containing
bodyorquery, which could override the request evaluated by the budget check.
Headers, abort signals, timeouts, and maxRetries request options remain supported. For
responses.stream(), control-plane and provider work begins only when iteration or a result/event
helper first needs the stream. Aborting before activation performs no provider dispatch.
Other compatible providers retain any Responses manager exposed by their underlying client, but
Solwyn treats it under the configured unmetered posture. A compatible provider having a method
named responses.create is not evidence that it implements the native OpenAI wire contract.
Media surfaces
Tracked non-text calls use the same pre-flight, provider, settlement, and reporting lifecycle. They are primary-only: media surfaces do not fail over, translate, or walk same-provider retries.
| Modality | Tracked methods |
|---|---|
| Embeddings | OpenAI and compatible embeddings.create; Google models.embedContent |
| Images | OpenAI and compatible images.generate / images.edit; Google models.generateImages |
| Audio input | OpenAI and compatible audio.transcriptions.create |
| Audio output | OpenAI and compatible audio.speech.create |
| Video | OpenAI videos.create; Google models.generateVideos |
Provider-reported usage is settlement truth. When it is unavailable, Solwyn derives only a bounded billing quantity available from the request, such as an input length, count, duration, resolution, or quality selector, and marks estimates explicitly. It never reads media bytes. If neither usage nor a billing quantity is observable, the successful call is reported as unpriced rather than silently assigned zero usage.
Current deliberate limitations include unpriced Whisper responses without usage, untracked
gpt-4o-mini-tts calls whose API exposes no usable billing quantity, and untracked
audio.translations. Bedrock InvokeModelCommand, InvokeModelWithResponseStreamCommand,
InvokeModelWithBidirectionalStreamCommand, and StartAsyncInvokeCommand are classified as
blocked and fail loudly with ConfigurationError; use the Converse API for tracked Bedrock
calls.
Tracked and unmetered surfaces
Wrapping a client does not imply that every public provider method is budget-trackable. Solwyn
classifies the pre-call provider graph and applies onUnmetered to known unmetered and newly
observed leaves:
| Posture | Behavior |
|---|---|
"warn" | Allow and log once per process. This is the default. |
"raise" | Throw UntrackedSpendSurfaceError before provider I/O. |
"allow" | Allow without a warning. |
acknowledgeUntracked accepts exact reviewed terminal surface tokens, not namespaces. A local
coverage(client) report can be compared with an independently reviewed fingerprint in CI. This
is a cooperative pre-call guard, not a sandbox: retaining the raw client or invoking operations
on returned resources can bypass it.
Legacy raw-request and client escapes on native OpenAI, Azure OpenAI, Anthropic, and Together
clients, OpenAI Realtime session and client-secret creation and call acceptance, and Google GenAI
Live and ApiClient transports are classified as unmetered_spend with explicit capability
scopes. They follow onUnmetered. OpenAI chat.completions.stream, .parse, and .runTools
helpers and Anthropic messages.stream and messages.parse helpers are also unmetered.
Surface classifications can change between SDK releases even when provider SDK versions stay
pinned. After upgrading @solwyn/sdk, review and refresh any pinned
coverage(client).expect(...) fingerprints; existing exact acknowledgeUntracked tokens remain
valid.
See TypeScript SDK configuration for the controls and defaults.
Exact preview qualification cells
The 0.2.0 qualification matrix names exact boundary cells. A floor/latest pair checks both
listed package versions; it does not prove that every intervening version received every
runtime scenario. Manifest peer ranges may admit versions outside these cells, but no broader
release-validation claim is made here.
| Family | Optional peer range | Exact surface boundary cells | Deeper installed checks |
|---|---|---|---|
| OpenAI and Azure client family | >=4.41.0 <8 | openai@4.41.0, openai@7.36.0 | Installed native declaration checks at 6.45.0 |
| Anthropic | >=0.30.0 <1 | @anthropic-ai/sdk@0.30.0, @anthropic-ai/sdk@0.135.0 | Native runtime and declaration checks at 0.123.0 |
| Amazon Bedrock Runtime | >=3.422.0 <4 | @aws-sdk/client-bedrock-runtime@3.422.0, @aws-sdk/client-bedrock-runtime@3.1124.0 | Converse/foreign-command behavior at the current 3.1124.0 AWS boundary |
| Google GenAI | >=0.3.1 <3 | @google/genai@0.3.1, @google/genai@2.30.0 | Buffered, streaming, abort, deadline, and lifecycle checks at 0.3.1 and 2.20.0 |
| Native Together | >=0.16.0 <1 | together-ai@0.16.0, together-ai@0.58.0 | Surface classification at both boundaries |
| Vercel AI SDK | >=7.0.14 <8 | ai@7.0.14 | Installed runtime and strict declaration checks |
| OpenAI Agents JS | >=0.20.0 <1 | @openai/agents@0.20.0 | HTTP recipe checks with openai@7.36.0 |
| LangChain.js | @langchain/core >=1.2.14 <2 | @langchain/core@1.2.18 | Recipe checks with @langchain/openai@1.6.2 and @langchain/langgraph@1.5.1 |
| Legacy Google Generative AI graph | Not a peer | @google/generative-ai@0.24.1 | Surface-drift review only; this is not a supported wrapped runtime client |
OpenAI 7, AI SDK 7, and the LangChain and OpenAI Agents recipes require Node.js 22 or later. The
Solwyn core still supports Node.js 20; use a compatible older provider SDK there. The optional
@openai/agents and @langchain/core peers can cause npm ERESOLVE in an application that
already installs an out-of-range version, even when the application does not use the integration;
upgrade that dependency to the supported range or stay on SDK 0.1.1.
Provider-free ESM and CommonJS consumers are also exercised with none of the optional peers
installed. TypeScript declarations are checked with exact compiler versions 5.8.3 and 6.0.3;
runtime policy is detailed under configuration.