SDK Migration
Migrate from @cova/sdk or @cova/async to @cova/gateway
The @cova/gateway SDK replaces the older @cova/sdk and @cova/async
packages. This guide shows side-by-side before/after code for each migration
path.
@cova/gateway is a thin header helper — it does NOT wrap or intercept
your LLM calls. Unlike @cova/sdk (which subclassed the OpenAI client) and
@cova/async (which monkey-patched providers), the new SDK only builds
Cova-* headers and parses gateway response metadata. You make requests
with the standard OpenAI SDK or any HTTP client.
Migrate from @cova/sdk (TypeScript)
The old @cova/sdk package replaced the OpenAI client with a subclass that
injected metadata. The new @cova/gateway SDK keeps the standard OpenAI
client and adds headers via buildHeaders() or streamChat().
Installation
Before:
npm install @cova/sdkAfter:
npm install @cova/gateway openaiBasic chat completion
Before (@cova/sdk):
import { CoreValueProxyOpenAI as OpenAI } from "@cova/sdk";
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
corevalueMeta: {
apiKey: process.env.COVA_API_KEY,
properties: { feature: "chat" },
},
});
const completion = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Hello" }],
});After (@cova/gateway):
import OpenAI from "openai";
import { buildHeaders } from "@cova/gateway";
const client = new OpenAI({
baseURL: "https://gateway.corevalue.dev/v1",
apiKey: process.env.COVA_API_KEY, // sk-cova-XXXXXXXXXXXXXXXX
});
const completion = await client.chat.completions.create(
{
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Hello" }],
},
{
headers: buildHeaders({
properties: { feature: "chat" },
}),
},
);Streaming
Before (@cova/sdk):
const { CoreValueProxyOpenAI as OpenAI } = require("@cova/sdk");
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
corevalueMeta: { apiKey: process.env.COVA_API_KEY },
});
const stream = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Hello" }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices?.[0]?.delta?.content ?? "");
}After (@cova/gateway):
import OpenAI from "openai";
import { streamChat } from "@cova/gateway";
const client = new OpenAI({
baseURL: "https://gateway.corevalue.dev/v1",
apiKey: process.env.COVA_API_KEY,
});
const stream = streamChat(
client,
{
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Hello" }],
stream: true,
},
{ properties: { feature: "chat" } }
);
for await (const chunk of stream) {
if ("cova" in chunk) {
console.log(chunk.cova.requestCost);
} else {
process.stdout.write(chunk.choices?.[0]?.delta?.content ?? "");
}
}Retrieving the request ID
Before (@cova/sdk):
const { data, response } = await openai.chat.completions
.create({ /* ... */ })
.withResponse();
const corevalueId = response.headers.get("corevalue-id");After (@cova/gateway):
import { buildHeaders, wrap } from "@cova/gateway";
const response = await fetch("https://gateway.corevalue.dev/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.COVA_API_KEY}`,
...buildHeaders({ properties: { feature: "chat" } }),
},
body: JSON.stringify({ model: "gpt-4o-mini", messages: [/* ... */] }),
});
const result = wrap(await response.json(), response.headers);
console.log(result.gateway.requestId); // Cova-Id headerMigrate from @cova/async (TypeScript)
The old @cova/async package monkey-patched provider SDKs (OpenAI, Anthropic,
Cohere) to log requests asynchronously. The new @cova/gateway SDK does not
intercept calls — you route requests through the gateway by changing the base
URL, and the SDK adds metadata headers.
Installation
Before:
npm install @cova/asyncAfter:
npm install @cova/gateway openaiInitialization
Before (@cova/async):
import { CovaAsyncLogger } from "@cova/async";
import OpenAI from "openai";
const logger = new CovaAsyncLogger({
apiKey: process.env.COVA_API_KEY,
providers: { openAI: OpenAI },
});
logger.init();
const openai = new OpenAI();
const completion = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Hello" }],
});After (@cova/gateway):
import OpenAI from "openai";
import { buildHeaders } from "@cova/gateway";
const client = new OpenAI({
baseURL: "https://gateway.corevalue.dev/v1",
apiKey: process.env.COVA_API_KEY,
});
const completion = await client.chat.completions.create(
{
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Hello" }],
},
{
headers: buildHeaders({
userId: "user_abc123",
properties: { feature: "chat" },
}),
},
);Properties / sessions
Before (@cova/async):
logger.withProperties({
"Cova-Session-Id": sessionId,
"Cova-Session-Path": "/chat",
}, () => {
const completion = await openai.chat.completions.create({ /* ... */ });
});After (@cova/gateway):
const completion = await client.chat.completions.create(
{
model: "gpt-4o-mini",
messages: [/* ... */],
},
{
headers: buildHeaders({
userId: "user_abc123",
properties: {
"session-id": sessionId,
"session-path": "/chat",
},
}),
},
);Key Differences
| Aspect | @cova/sdk | @cova/async | @cova/gateway |
|---|---|---|---|
| Approach | Subclasses OpenAI client | Monkey-patches providers | Thin header helper |
| Wraps LLM calls? | Yes | Yes | No |
| Gateway routing | Optional | No (async logging) | Required (base URL change) |
| Metadata | corevalueMeta option | Logger properties | CovaHeaderOptions |
| Response metadata | Response headers | N/A | CovaGatewayMeta via wrap() / streamChat() |
| Streaming meta | Manual header extraction | N/A | Final SSE { cova: ... } frame |
| Package | @cova/sdk | @cova/async | @cova/gateway |
Next Steps
SDK Quick Start
Full API reference and examples for @cova/gateway.
AI Gateway Overview
Learn how the gateway routes requests and returns metadata.