JavaScript / TypeScript SDK

Stable

Unified routing, tracing, and agent runtime for Node.js, browsers, and edge workers.

Install

npm install @skyaiapp/sdk
# or
pnpm add @skyaiapp/sdk
yarn add @skyaiapp/sdk

Set your API key in the environment:

export SKYAIAPP_API_KEY="sk_live_..."

5-minute quickstart

import { SkyAI } from "@skyaiapp/sdk";

const sky = new SkyAI({
  apiKey: process.env.SKYAIAPP_API_KEY!,
  projectId: "proj_123",
});

const res = await sky.route({
  goal: "cost",
  strategy: "balanced",
  messages: [{ role: "user", content: "Summarize this document..." }],
});

console.log(res.output);
console.log(res.traceId);

`route()` chooses a model pool and returns a trace you can inspect in the dashboard.

Routing options

Most apps start with `goal` and `strategy`, then graduate to policy IDs and per-tenant budgets.

type RouteRequest = {
  goal?: "cost" | "quality" | "stability";
  strategy?: "balanced" | "cost-optimized" | "quality-first";
  policyId?: string;               // explicit policy version
  messages: { role: "user" | "assistant" | "system"; content: string }[];
  tools?: SkyAITool[];             // optional function/tool calls
  metadata?: Record<string, any>;  // tenant, locale, user tier, etc.
};

If both `policyId` and `goal/strategy` are provided, the policy wins.

Streaming

const stream = await sky.routeStream({
  goal: "quality",
  strategy: "quality-first",
  messages: [{ role: "user", content: "Draft a launch email." }],
});

for await (const chunk of stream) {
  process.stdout.write(chunk.delta ?? "");
}

Streaming preserves routing decisions while returning tokens as they arrive.

Agent runtime

const result = await sky.agent.run({
  name: "support-triage",
  input: { ticketId: "TCK-9912" },
  tools: {
    lookupTicket,
    summarizeHistory,
    createReplyDraft,
  },
  policyId: "pol_latest",
});

console.log(result.output);
console.log(result.traceId);

The runtime enforces idempotent retries, timeouts, and trace spans for each tool call.

Errors and retries

try {
  await sky.route({ messages, goal: "cost" });
} catch (err) {
  if (err.code === "RATE_LIMITED") {
    // Backoff + retry
  }
  if (err.code === "POLICY_BLOCKED") {
    // Safety/guardrail block
  }
  throw err;
}

By default the SDK performs one fast retry for transient provider errors. You can override this per request.

JavaScript / TypeScript SDK — SkyAIApp