Skip to main content
The @raven/sdk package provides a type-safe TypeScript client for sending requests through the Raven AI Gateway. It handles authentication, streaming, error handling, and response parsing.

Installation

npm install @raven/sdk

Initialization

Create a client with your virtual key and base URL:
import { RavenClient } from "@raven/sdk";

const raven = new RavenClient({
  apiKey: "rk_live_abc123...",
  baseUrl: "http://localhost:4000"
});

Configuration Options

OptionTypeRequiredDescription
apiKeystringYesYour Raven virtual key
baseUrlstringYesRaven API base URL
headersRecord<string, string>NoAdditional headers for every request

Custom Headers

Pass additional headers that are included in every request:
const raven = new RavenClient({
  apiKey: "rk_live_...",
  baseUrl: "http://localhost:4000",
  headers: {
    "X-Session-Id": "session_abc123"
  }
});

Sending Requests

generateText

Send a non-streaming request and receive the complete response:
const result = await raven.generateText({
  model: "gpt-4o",
  provider: "openai",
  messages: [
    { role: "system", content: "You are a helpful assistant." },
    { role: "user", content: "What is TypeScript?" }
  ],
  temperature: 0.7,
  maxTokens: 500
});

console.log(result.text);
console.log(result.finishReason);    // "stop"
console.log(result.usage);           // { promptTokens, completionTokens, totalTokens }
console.log(result.toolCalls);       // ToolCall[] (empty if no tools used)

Request Parameters

ParameterTypeRequiredDescription
modelstringYesModel ID (e.g., gpt-4o)
providerstringYesProvider name (e.g., openai)
messagesMessage[]YesArray of conversation messages
systemstringNoSystem prompt (alternative to system message)
temperaturenumberNoSampling temperature (0-2)
topPnumberNoNucleus sampling parameter
maxTokensnumberNoMaximum tokens to generate
stopstring[]NoStop sequences
toolsToolDefinition[]NoFunction/tool definitions
toolChoiceToolChoiceNoTool selection strategy

Streaming

streamText

Stream responses token by token:
const stream = await raven.streamText({
  model: "gpt-4o",
  provider: "openai",
  messages: [{ role: "user", content: "Write a short story." }]
});

// Iterate over text deltas
for await (const text of stream) {
  process.stdout.write(text);
}

// After iteration completes, access accumulated values
const fullText = await stream.text;
const usage = await stream.usage;
const finishReason = await stream.finishReason;
const toolCalls = await stream.toolCalls;

Full Stream Access

Access the raw stream chunks for more control:
const stream = await raven.streamText({
  model: "gpt-4o",
  provider: "openai",
  messages: [{ role: "user", content: "Hello" }]
});

for await (const chunk of stream.fullStream()) {
  switch (chunk.type) {
    case "text-delta":
      process.stdout.write(chunk.textDelta ?? "");
      break;
    case "tool-call":
      console.log("Tool:", chunk.toolCall);
      break;
    case "finish":
      console.log("Done:", chunk.finishReason);
      console.log("Usage:", chunk.usage);
      break;
  }
}

Aborting a Stream

Cancel an in-progress stream:
const controller = new AbortController();

const stream = await raven.streamText(
  {
    model: "gpt-4o",
    provider: "openai",
    messages: [{ role: "user", content: "Write a very long essay." }]
  },
  controller.signal
);

// Cancel after 2 seconds
setTimeout(() => stream.abort(), 2000);

for await (const text of stream) {
  process.stdout.write(text);
}

Error Handling

The SDK throws typed errors for different failure scenarios:
import {
  RavenError,
  AuthenticationError,
  RateLimitError,
  ProviderError
} from "@raven/sdk";

try {
  const result = await raven.generateText({
    model: "gpt-4o",
    provider: "openai",
    messages: [{ role: "user", content: "Hello" }]
  });
} catch (error) {
  if (error instanceof AuthenticationError) {
    // 401 -- Invalid or missing API key
    console.error("Auth failed:", error.message);
  } else if (error instanceof RateLimitError) {
    // 429 -- Rate limit exceeded
    console.error("Rate limited:", error.message);
  } else if (error instanceof ProviderError) {
    // 500+ -- Upstream provider error
    console.error("Provider error:", error.message, error.status);
  } else if (error instanceof RavenError) {
    // Any other Raven error
    console.error("Raven error:", error.message, error.status);
  }
}

Error Types

ErrorStatusDescription
AuthenticationError401Invalid or missing API key
RateLimitError429Rate limit exceeded
ProviderError500+Upstream provider error
RavenErrorAnyBase error class for all other errors

Messages

The SDK uses a typed message format:
import type { Message, ContentPart } from "@raven/sdk";

// Simple text message
const textMessage: Message = {
  role: "user",
  content: "Hello, world!"
};

// Multi-part message with images
const multipartMessage: Message = {
  role: "user",
  content: [
    { type: "text", text: "What is in this image?" },
    { type: "image", image: "https://example.com/photo.jpg" }
  ]
};

// Tool result message
const toolMessage: Message = {
  role: "tool",
  content: '{"temperature": 72}',
  toolCallId: "call_abc123"
};

Function Calling

Define and use tools:
const result = await raven.generateText({
  model: "gpt-4o",
  provider: "openai",
  messages: [{ role: "user", content: "What's the weather in Tokyo?" }],
  tools: [
    {
      type: "function",
      function: {
        name: "get_weather",
        description: "Get current weather for a city",
        parameters: {
          type: "object",
          properties: {
            city: { type: "string" }
          },
          required: ["city"]
        }
      }
    }
  ],
  toolChoice: "auto"
});

if (result.toolCalls.length > 0) {
  for (const call of result.toolCalls) {
    console.log(`Call ${call.function.name}(${call.function.arguments})`);
  }
}

Using with OpenAI SDK

For chat completions, you can also use the OpenAI SDK pointed at Raven. This is recommended if you are migrating from OpenAI and want minimal code changes:
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "rk_live_...",
  baseURL: "http://localhost:4000/v1"
});

const response = await client.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello" }]
});
See OpenAI Compatibility for details.