Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

TypeScript SDK

The @smista-ai/sdk package is a thin, typed client over the smista-router HTTP API. It sends requests and returns typed results; it never reimplements routing, policy evaluation, provider selection or tool mediation — that logic stays in the router.

Add it to your project

npm install @smista-ai/sdk

The package targets Node.js 22 or newer and ships as ES modules.

Talk to the router

SmistaClient implements every router endpoint and holds your credentials for you. bootstrap mints and stores the API key, signIn exchanges it for a session token the client then keeps, and every authenticated call reuses that token — you never pass a credential per call:

import { SmistaClient } from '@smista-ai/sdk';

// Defaults target http://localhost:7331; pass a baseUrl to point elsewhere.
const client = new SmistaClient({ baseUrl: 'http://localhost:7331' });

// First run only: create the first user and store its API key.
await client.bootstrap();
// Exchange the held API key for a session token the client keeps.
await client.signIn();

const sessions = await client.listSessions();
console.log(`you have ${sessions.sessions.length} session(s)`);

await client.signOut();

An authenticated call made before you sign in fails right away, before any network request, so a missing token never reaches the router.

Reuse a session token

If you already hold an API key or a still-valid session token (for example from a secure store), seed it when constructing the client and skip the step you no longer need:

const client = new SmistaClient({ sessionToken: savedToken });

// The seeded token authenticates calls without a fresh sign-in.
const me = await client.me();

Reach upstream models

The keys the router needs to call upstream models are configured once with providerCredentials. They travel as request headers only on the calls that can reach a model — execute, continueRun, streamExecute, streamContinue and listModels — and never appear in a query parameter, log or error:

import { ProviderCredentials, SmistaClient } from '@smista-ai/sdk';

const client = new SmistaClient({
  sessionToken: savedToken,
  providerCredentials: ProviderCredentials.empty().withProvider('anthropic', 'sk-ant-...'),
});

const models = await client.listModels();
console.log(`${models.models.length} model(s) available`);

Stream a turn

streamExecute and streamContinue yield the turn one event at a time. Iterate the result with for await; the stream ends after the terminal turn_end event, which carries the final turn:

for await (const event of await client.streamExecute(sessionId, request)) {
  if (event.type === 'text_delta') {
    process.stdout.write(event.delta);
  } else if (event.type === 'turn_end') {
    console.log('\nturn complete');
  }
}

Handle errors

Every method rejects with a SmistaError, whose kind says what went wrong: an api error pairs the HTTP status with the router’s structured error code, while decode, transport and notAuthenticated cover the rest. Use isSmistaError to narrow an unknown value in a catch:

import { isSmistaError, SmistaClient } from '@smista-ai/sdk';

try {
  await client.getSession(sessionId);
} catch (error) {
  if (isSmistaError(error) && error.kind === 'api') {
    console.error(`router said ${error.code} (status ${error.status})`);
  } else {
    throw error;
  }
}