🚀. Socket Launch Week Day 2:Introducing Manifest Alerts.Learn more
Sign In

@useatlas/sdk

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@useatlas/sdk

TypeScript SDK for the Atlas text-to-SQL agent API

latest
Source
npmnpm
Version
0.1.0
Version published
Maintainers
1
Created
Source

@useatlas/sdk

TypeScript SDK for the Atlas text-to-SQL agent API.

Install

bun add @useatlas/sdk

Quick Start

import { createAtlasClient } from "@useatlas/sdk";

const atlas = createAtlasClient({
  baseUrl: "https://api.example.com",
  apiKey: "my-key",
});

const result = await atlas.query("How many users signed up last week?");
console.log(result.answer);
console.log(result.sql);    // SQL queries the agent executed
console.log(result.data);   // Raw query results ({ columns, rows }[])

Authentication

Pass either apiKey (simple key auth) or bearerToken (BYOT / managed auth):

// Simple API key
const atlas = createAtlasClient({ baseUrl: "...", apiKey: "my-key" });

// Bearer token (JWT from your auth provider)
const atlas = createAtlasClient({ baseUrl: "...", bearerToken: "eyJ..." });

API Reference

Query

MethodDescription
atlas.query(question, opts?)Run a synchronous query. Returns { answer, sql, data, steps, usage }
atlas.streamQuery(question, opts?)Stream a query as an async iterator of typed StreamEvents
atlas.chat(messages, opts?)Start a streaming chat session. Returns a raw Response with SSE body (AI SDK UI Message Stream Protocol)

Schema

MethodDescription
atlas.listTables()List all queryable tables with column details. Returns { tables: TableInfo[] }
const { tables } = await atlas.listTables();
for (const t of tables) {
  console.log(`${t.table}: ${t.description}`);
  for (const col of t.columns) {
    console.log(`  ${col.name} (${col.type}) — ${col.description}`);
  }
}

Conversations

MethodDescription
atlas.conversations.list(opts?)List conversations (paginated)
atlas.conversations.get(id)Get a conversation with messages
atlas.conversations.delete(id)Delete a conversation
atlas.conversations.star(id)Star a conversation
atlas.conversations.unstar(id)Unstar a conversation

Scheduled Tasks

MethodDescription
atlas.scheduledTasks.list(opts?)List scheduled tasks (paginated)
atlas.scheduledTasks.get(id)Get a task with recent runs
atlas.scheduledTasks.create(input)Create a scheduled task
atlas.scheduledTasks.update(id, input)Update a scheduled task
atlas.scheduledTasks.delete(id)Delete a scheduled task
atlas.scheduledTasks.trigger(id)Trigger immediate execution
atlas.scheduledTasks.listRuns(id, opts?)List past runs

Admin (requires admin role)

MethodDescription
atlas.admin.overview()Dashboard overview data
atlas.admin.semantic.entities()List semantic layer entities
atlas.admin.semantic.entity(name)Get entity detail
atlas.admin.semantic.metrics()List metrics
atlas.admin.semantic.glossary()Get glossary
atlas.admin.semantic.catalog()Get catalog
atlas.admin.semantic.stats()Aggregate semantic stats
atlas.admin.connections()List datasource connections
atlas.admin.testConnection(id)Test connection health
atlas.admin.audit(opts?)Query audit log
atlas.admin.auditStats()Aggregate audit stats
atlas.admin.plugins()List installed plugins
atlas.admin.pluginHealth(id)Check plugin health

Streaming

Use streamQuery() to receive typed events as the agent works:

import type { StreamEvent } from "@useatlas/sdk";

for await (const event of atlas.streamQuery("How many users signed up last week?")) {
  switch (event.type) {
    case "text":
      process.stdout.write(event.content);
      break;
    case "tool-call":
      console.log(`Calling ${event.name}`, event.args);
      break;
    case "tool-result":
      console.log(`${event.name} returned`, event.result);
      break;
    case "result":
      console.table(event.rows); // convenience: { columns, rows } from executeSQL
      break;
    case "error":
      // Mid-stream errors carry a typed `code` and a `retryAfterSeconds`
      // delta when the server emits a structured `ChatErrorInfo` body
      // (e.g. provider rate limiting). Older servers populate only `message`.
      console.error(event.code ?? "error", event.message);
      if (event.retryable && event.retryAfterSeconds !== undefined) {
        console.warn(`Server suggests retrying in ${event.retryAfterSeconds}s`);
      }
      break;
    case "parse-error":
      console.warn("Malformed SSE frame", event.raw);
      break;
    case "finish":
      console.log(`\nDone (${event.reason})`);
      break;
  }
}

Connection Drops & Partial Results

streamQuery() uses a one-shot SSE connection over fetch. If the connection drops mid-stream:

  • Events already yielded are still valid — the async generator delivers each event to your for await loop before advancing, so any text, result, or tool-result events you've already processed are safe to keep.
  • The generator throws an AtlasError with code network_error and a message starting with "Stream interrupted: ...".
  • There is no automatic reconnect or resume — start a new streamQuery() call to retry.
import { AtlasError } from "@useatlas/sdk";

const collected: string[] = [];

try {
  for await (const event of atlas.streamQuery("Revenue by region")) {
    if (event.type === "text") collected.push(event.content);
    if (event.type === "result") console.table(event.rows);
  }
} catch (err) {
  if (err instanceof AtlasError && err.code === "network_error") {
    console.warn("Stream dropped — partial text:", collected.join(""));
    // Decide whether to retry or use the partial data you have
  } else {
    throw err;
  }
}

Cancellation

Pass an AbortSignal to cancel the stream. The signal aborts the underlying reader, and an AbortError is thrown from the for await loop. Events yielded before cancellation are already consumed by your code.

const controller = new AbortController();

// Cancel after 10 seconds
setTimeout(() => controller.abort(), 10_000);

try {
  for await (const event of atlas.streamQuery("...", { signal: controller.signal })) {
    if (event.type === "text") process.stdout.write(event.content);
  }
} catch (err) {
  if (err instanceof Error && err.name === "AbortError") {
    console.log("Stream cancelled");
  }
}

Stream Event Types

TypeFieldsDescription
textcontentText chunk from the agent
tool-calltoolCallId, name, argsAgent is calling a tool
tool-resulttoolCallId, name, resultTool returned a result
resultcolumns, rowsConvenience event extracted from tool-result when executeSQL returns data. Both tool-result and result are emitted.
errormessage, code?, retryable?, retryAfterSeconds?, requestId?Mid-stream error. When the server sends a structured ChatErrorInfo body (provider_rate_limit, provider_timeout, etc.) the typed code and upstream Retry-After delta travel alongside the human-readable message. Older servers populate only message.
parse-errorraw, errorClient-side: an SSE frame contained invalid JSON. The raw data is preserved for debugging.
finishreasonStream completed

Context Warnings (Degraded Answer Signal)

The chat route emits data-context-warning frames whenever the agent ran past a non-fatal degradation — the org semantic layer or learned-patterns lookup failed, or the workspace is approaching its plan budget — and the run was allowed to proceed against reduced context. These are not stream events from streamQuery(); they arrive on the AI-SDK UI Message Stream channel that chat() returns. If you are routing a raw Response from atlas.chat() through your own SSE consumer, parse each data-context-warning frame body with parseContextWarning from @useatlas/types:

import { parseContextWarning, type ChatContextWarning } from "@useatlas/types";

// Inside your SSE frame handler:
if (frame.type === "data-context-warning") {
  const warning: ChatContextWarning | null = parseContextWarning(frame.data);
  if (warning) {
    console.warn(`[${warning.code}]`, warning.title, warning.detail ?? "");
    // Surface a per-message warning banner — the answer is still usable
    // but was generated against reduced context. Do NOT treat it as a
    // hard error.
  } else {
    // Log on null so a future server-side wire-shape change (unknown
    // code, missing title, wrong severity literal) is observable in dev
    // rather than silently dropped. In production, gate this behind a
    // one-shot ref so a runaway stream of malformed frames doesn't
    // flood the console — see the in-tree `useContextWarnings` hook for
    // an example dedup pattern.
    console.warn("[atlas-sdk] dropped malformed data-context-warning frame", frame.data);
  }
}

The frame's severity: "warning" discriminator separates these from data-error frames, so a single SSE consumer can route both without misclassifying a degraded answer as a failure.

Error Handling

All methods throw AtlasError on failure. See the full Error Codes Reference for every error code, HTTP status, retry guidance, and a complete retry-with-backoff example.

import { AtlasError } from "@useatlas/sdk";

try {
  await atlas.query("...");
} catch (err) {
  if (err instanceof AtlasError) {
    console.error(err.code);     // e.g. "rate_limited", "auth_error"
    console.error(err.status);   // HTTP status code
    console.error(err.message);  // Human-readable message
    console.error(err.retryable); // true if retrying may help
  }
}

AtlasError Properties

PropertyTypeDescription
codeAtlasErrorCodeError code (e.g. rate_limited, network_error)
statusnumberHTTP status code (0 for client-side errors like network_error)
messagestringHuman-readable description
retryablebooleanWhether retrying the same request may succeed
retryAfterSecondsnumber | undefinedServer-suggested delay — only populated when the server includes retryAfterSeconds in the error response body (currently only for rate_limited). Always guard against undefined

Retry with Backoff

Use retryable for generic retry logic. For rate_limited, prefer the server-suggested delay when available, falling back to exponential backoff:

import { AtlasError } from "@useatlas/sdk";

try {
  await atlas.query("...");
} catch (err) {
  if (!(err instanceof AtlasError) || !err.retryable) throw err;

  // Use server delay if available, otherwise exponential backoff
  const delay = err.retryAfterSeconds != null
    ? err.retryAfterSeconds * 1000
    : 5000;
  await new Promise((r) => setTimeout(r, delay));
  await atlas.query("...");
}

License

MIT

Keywords

atlas

FAQs

Package last updated on 14 May 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts