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/sdkSet 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.