@syncagent/react
React SDK for SyncAgent — drop-in AI database chat widget and hooks.
Install
npm install @syncagent/react @syncagent/js
Quick Start — Drop-in Widget
The fastest way to add an AI assistant to your app:
import { SyncAgentChat } from "@syncagent/react";
export default function App() {
return (
<SyncAgentChat
config={{
apiKey: "sa_your_api_key",
connectionString: process.env.DATABASE_URL,
}}
/>
);
}
This renders a floating chat button (bottom-right) that opens a chat panel. Your database URL is sent at runtime and never stored on SyncAgent servers.
<SyncAgentChat> Props
config | SyncAgentConfig | Required* | API key, connection string, tools |
mode | "floating" | "inline" | "floating" | Floating FAB or embedded inline panel |
position | "bottom-right" | "bottom-left" | "bottom-right" | FAB position (floating mode only) |
defaultOpen | boolean | false | Start with the panel open |
title | string | "✨ AI Assistant" | Header title |
placeholder | string | "Ask about your data..." | Input placeholder text |
welcomeMessage | string | "Ask me anything..." | Message shown when chat is empty |
accentColor | string | "#10b981" | Brand color for header, FAB, send button |
className | string | — | CSS class on the panel container |
style | CSSProperties | — | Inline styles on the panel container |
*config is required unless you wrap in <SyncAgentProvider>.
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 |
Inline Mode
Embed the chat panel directly in your layout instead of a floating widget:
<div style={{ height: 600 }}>
<SyncAgentChat
config={{ apiKey: "...", connectionString: "..." }}
mode="inline"
/>
</div>
Custom Accent Color
<SyncAgentChat
config={{ apiKey: "...", connectionString: "..." }}
accentColor="#6366f1"
title="Data Assistant"
position="bottom-left"
/>
Custom Tools
Give the agent capabilities beyond your database. Tools run entirely in your app — SyncAgent only sees the schema and the result you return.
import { SyncAgentChat } from "@syncagent/react";
<SyncAgentChat
config={{
apiKey: "sa_your_api_key",
connectionString: process.env.DATABASE_URL,
tools: {
sendEmail: {
description: "Send an email to a user",
inputSchema: {
to: { type: "string", description: "Recipient email address" },
subject: { type: "string", description: "Email subject line" },
body: { type: "string", description: "Email body" },
},
execute: async ({ to, subject, body }) => {
await mailer.send({ to, subject, text: body });
return { sent: true };
},
},
},
}}
/>
Custom UI with useSyncAgent
Build your own chat UI using the hook:
import { SyncAgentProvider, useSyncAgent } from "@syncagent/react";
function App() {
return (
<SyncAgentProvider config={{ apiKey: "...", connectionString: "..." }}>
<MyChat />
</SyncAgentProvider>
);
}
function MyChat() {
const { messages, isLoading, error, sendMessage, stop, reset } = useSyncAgent();
const [input, setInput] = useState("");
return (
<div>
{messages.map((msg, i) => (
<div key={i} className={msg.role === "user" ? "user" : "assistant"}>
{msg.content}
</div>
))}
{isLoading && <div>Thinking...</div>}
{error && <div>Error: {error.message}</div>}
<input value={input} onChange={(e) => setInput(e.target.value)} />
<button onClick={() => { sendMessage(input); setInput(""); }}>Send</button>
<button onClick={stop}>Stop</button>
<button onClick={reset}>Clear</button>
</div>
);
}
useSyncAgent Returns
messages | Message[] | Full conversation history |
isLoading | boolean | true while streaming |
error | Error | null | Last error, null if none |
sendMessage | (content: string) => void | Send a user message |
stop | () => void | Abort the current streaming response |
reset | () => void | Clear all messages and reset state |
Pass a client directly (without Provider)
import { SyncAgentClient } from "@syncagent/js";
import { useSyncAgent } from "@syncagent/react";
const client = new SyncAgentClient({
apiKey: "sa_your_api_key",
connectionString: process.env.DATABASE_URL,
});
function MyChat() {
const { messages, sendMessage } = useSyncAgent({ client });
}
<SyncAgentProvider>
Provides a shared SyncAgentClient instance to all child components via context.
import { SyncAgentProvider, useSyncAgentClient } from "@syncagent/react";
<SyncAgentProvider config={{ apiKey: "...", connectionString: "..." }}>
<App />
</SyncAgentProvider>
function Somewhere() {
const client = useSyncAgentClient();
}
TypeScript Types
All types are re-exported from @syncagent/js for convenience:
import type {
SyncAgentConfig,
Message,
ChatOptions,
ToolDefinition,
ToolParameter,
SyncAgentChatProps,
} from "@syncagent/react";
License
MIT