@syncagent/js
Core JavaScript/TypeScript SDK for SyncAgent — add an AI database agent to any app.
Install
npm install @syncagent/js
Quick Start
import { SyncAgentClient } from "@syncagent/js";
const agent = new SyncAgentClient({
apiKey: "sa_your_api_key",
connectionString: process.env.DATABASE_URL,
});
const result = await agent.chat([
{ role: "user", content: "How many users do we have?" }
]);
console.log(result.text);
Configuration
new SyncAgentClient(config: SyncAgentConfig)
apiKey | string | ✅ | Your SyncAgent API key (sa_...) |
connectionString | string | ✅ | Your database URL — sent at runtime, never stored |
tools | Record<string, ToolDefinition> | — | Custom tools the agent can call client-side |
baseUrl | string | — | Override API URL. Defaults to https://syncagent.dev |
client.chat(messages, options?)
const result = await agent.chat(messages, options);
messages — Message[]
{ role: "user" | "assistant"; content: string }
options — ChatOptions
onToken | (token: string) => void | Called for each streamed text chunk |
onComplete | (text: string) => void | Called with the full response text |
onError | (error: Error) => void | Called on error |
onStatus | (step: string, label: string) => void | Called with live status updates while working |
onData | (data: ToolData) => void | Called when a DB tool returns structured data |
onToolCall | (name: string, args: any, result: any) => void | Called when a custom tool executes |
signal | AbortSignal | Cancel the request |
context | Record<string, any> | Extra context injected into every message |
Returns Promise<ChatResult> → { text: string }
Status steps
onStatus fires with these step values:
"connecting" — connecting to the database
"schema" — discovering schema
"thinking" — AI is reasoning
"querying" — executing a DB tool
"done" — complete
client.getSchema()
const schema = await agent.getSchema();
Context injection
Pass per-message context so the agent knows what the user is looking at:
await agent.chat(messages, {
context: {
userId: "user_123",
currentPage: "orders",
selectedOrderId: "ord_456",
}
});
onData callback
React to structured query results in your own UI:
const agent = new SyncAgentClient({
apiKey: "sa_your_key",
connectionString: process.env.DATABASE_URL,
});
await agent.chat(messages, {
onData: (data) => {
console.log(`Got ${data.count} rows from ${data.collection}`);
setTableData(data.data);
}
});
Custom Tools
const agent = new SyncAgentClient({
apiKey: "sa_your_key",
connectionString: process.env.DATABASE_URL,
tools: {
sendEmail: {
description: "Send an email to a user",
inputSchema: {
to: { type: "string", description: "Recipient email" },
subject: { type: "string", description: "Subject line" },
body: { type: "string", description: "Email body" },
},
execute: async ({ to, subject, body }) => {
await mailer.send({ to, subject, text: body });
return { sent: true };
},
},
},
});
Multi-turn conversations
const history: Message[] = [];
history.push({ role: "user", content: "Show top 5 customers" });
const r1 = await agent.chat(history);
history.push({ role: "assistant", content: r1.text });
history.push({ role: "user", content: "Now email all of them" });
const r2 = await agent.chat(history);
Abort / cancel
const controller = new AbortController();
agent.chat(messages, { signal: controller.signal });
controller.abort();
TypeScript types
import type {
SyncAgentConfig, Message, ChatOptions, ChatResult,
CollectionSchema, SchemaField, ToolDefinition, ToolParameter, ToolData,
} from "@syncagent/js";
License
MIT