Getting Started

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/sdk

After:

npm install @cova/gateway openai

Basic 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 header

Migrate 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/async

After:

npm install @cova/gateway openai

Initialization

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
ApproachSubclasses OpenAI clientMonkey-patches providersThin header helper
Wraps LLM calls?YesYesNo
Gateway routingOptionalNo (async logging)Required (base URL change)
MetadatacorevalueMeta optionLogger propertiesCovaHeaderOptions
Response metadataResponse headersN/ACovaGatewayMeta via wrap() / streamChat()
Streaming metaManual header extractionN/AFinal 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.

On this page