SDK Reference

TypeScript client SDK for programmatic access to Sandcaster agents.

Installation

bun add @sandcaster/sdk

Also works with npm and yarn:

npm install @sandcaster/sdk
yarn add @sandcaster/sdk

Quick Start

import { SandcasterClient } from "@sandcaster/sdk";

const client = new SandcasterClient({
	baseUrl: "http://localhost:8000",
	apiKey: "your-token",
});

for await (const event of client.query({ prompt: "Analyze this market" })) {
	if (event.type === "assistant") console.log(event.content);
	if (event.type === "file") console.log(`artifact: ${event.path}`);
	if (event.type === "result") console.log(`cost: $${event.costUsd}`);
}

SandcasterClient

Constructor Options

OptionTypeRequiredDescription
baseUrlstringYesBase URL of the Sandcaster API server
apiKeystringNoBearer token for authentication (if server requires it)
const client = new SandcasterClient({
	baseUrl: "https://agents.example.com",
	apiKey: process.env.SANDCASTER_API_KEY,
});

client.query()

Sends a prompt to the agent and returns an async iterable of SSE events.

Parameters

ParameterTypeRequiredDescription
promptstringYesThe user prompt to send to the agent
modelstringNoModel alias or full ID
maxTurnsintegerNoMax conversation turns
timeoutintegerNoSandbox lifetime in seconds
filesobject[]NoFiles to upload: [{ name, content }] where content is a Uint8Array or base64 string
outputFormatobjectNoJSON Schema for structured output
allowedToolsstring[]NoTool whitelist for this run
compositeobjectNoMulti-sandbox settings
signalAbortSignalNoSignal to cancel the request mid-stream

Event Types

Events yielded by client.query() match the SSE events from the API:

Event typePropertiesDescription
systemmessage: stringServer lifecycle messages
assistantcontent: stringA chunk of the agent’s text response
usercontent: stringUser-turn message (multi-turn runs)
filepath: string, mimeType: stringFile artifact produced by the agent
resultcontent: string, costUsd: number, inputTokens: number, outputTokens: numberFinal result with usage stats
warningmessage: stringNon-fatal issue
errormessage: string, code: stringFatal error

Cancellation with AbortSignal

Pass an AbortSignal to cancel an in-flight query:

const controller = new AbortController();

setTimeout(() => controller.abort(), 30_000); // cancel after 30s

for await (const event of client.query({
	prompt: "Run a deep analysis...",
	signal: controller.signal,
})) {
	if (event.type === "assistant") process.stdout.write(event.content);
}

When aborted, the async iterable stops yielding events and the sandbox is terminated server-side.

Symbol.asyncDispose

SandcasterClient implements Symbol.asyncDispose for use with the await using syntax (TypeScript 5.2+):

await using client = new SandcasterClient({ baseUrl: "http://localhost:8000" });

for await (const event of client.query({ prompt: "Summarize this" })) {
	console.log(event);
}
// client is disposed automatically here

Error Handling

Errors thrown by client.query() include both network errors and agent-level errors from the error event type:

try {
	for await (const event of client.query({ prompt: "Do the thing" })) {
		if (event.type === "error") {
			console.error(`Agent error: ${event.message} (${event.code})`);
			break;
		}
		if (event.type === "result") {
			console.log(event.content);
		}
	}
} catch (err) {
	// Network error, auth failure, or server-side exception
	console.error("Request failed:", err);
}

Collecting the Full Response

If you want the complete text response rather than streaming chunks:

let fullResponse = "";

for await (const event of client.query({ prompt: "Write a brief" })) {
	if (event.type === "assistant") fullResponse += event.content;
	if (event.type === "result") {
		console.log(fullResponse);
		console.log(`Total cost: $${event.costUsd}`);
	}
}