
Research
/Security News
Popular Go Decimal Library Targeted by Long-Running Typosquat with DNS Backdoor
A long-running Go typosquat impersonated the popular shopspring/decimal library and used DNS TXT records to execute commands.
@syncagent/react
Advanced tools
React SDK for SyncAgent — drop-in AI database chat widget and hooks for React apps.
Works with MongoDB, PostgreSQL, MySQL, SQLite, SQL Server, and Supabase.
sa_)Every new project gets a 14-day trial with 500 free requests — no credit card required. After the trial, you get 100 free requests/month on the Free plan.
npm install @syncagent/react @syncagent/js
import { SyncAgentChat } from "@syncagent/react";
export default function App() {
return (
<SyncAgentChat
config={{
apiKey: "sa_your_api_key",
connectionString: process.env.DATABASE_URL,
}}
/>
);
}
A floating chat button appears in the bottom-right corner. Your users can now query your database in plain English.
<SyncAgentChat> Props| Prop | Type | Default | Description |
|---|---|---|---|
config | SyncAgentConfig | Required* | API key, connection string, tools, filter, operations |
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 | "SyncAgent" | Header title |
subtitle | string | "AI Database Assistant" | Header subtitle |
placeholder | string | "Ask anything..." | Input placeholder |
welcomeMessage | string | "Hi! I can query..." | Empty state message |
accentColor | string | "#10b981" | Brand color for header, FAB, send button |
suggestions | string[] | 3 defaults | Quick-start suggestion chips |
persistKey | string | — | localStorage key for conversation persistence |
context | Record<string, any> | — | Extra context injected into every message |
filter | Record<string, any> | — | Mandatory query filter for multi-tenancy |
operations | ("read"|"create"|"update"|"delete")[] | — | Restrict operations for this session |
onReaction | (idx, reaction, content) => void | — | Called when user reacts 👍/👎 |
onData | (data: ToolData) => void | — | Called when a DB tool returns structured data |
*config is required unless wrapped in <SyncAgentProvider>.
Embed the chat inside your layout instead of a floating button:
<div style={{ height: 600 }}>
<SyncAgentChat
config={{ apiKey: "...", connectionString: "..." }}
mode="inline"
/>
</div>
useSyncAgentBuild your own chat UI with full control:
import { SyncAgentProvider, useSyncAgent } from "@syncagent/react";
export default function App() {
return (
<SyncAgentProvider config={{ apiKey: "...", connectionString: "..." }}>
<MyChat />
</SyncAgentProvider>
);
}
function MyChat() {
const { messages, isLoading, error, status, lastData, sendMessage, stop, reset } = useSyncAgent();
return (
<div>
{status && <div>⏳ {status.label}</div>}
{messages.map((msg, i) => (
<div key={i}><strong>{msg.role}:</strong> {msg.content}</div>
))}
<button onClick={() => sendMessage("Show all users")}>Ask</button>
<button onClick={stop}>Stop</button>
<button onClick={reset}>Clear</button>
</div>
);
}
useSyncAgent Returns| Return | Type | Description |
|---|---|---|
messages | Message[] | Full conversation history |
isLoading | boolean | true while streaming |
error | Error | null | Last error |
status | { step, label } | null | Live status while agent is working |
lastData | ToolData | null | Last structured data from a DB tool |
sendMessage | (content: string) => void | Send a user message |
stop | () => void | Abort the current stream |
reset | () => void | Clear all messages |
● Querying users... while the agent worksprefers-color-schemePass filter to scope every agent operation to the current user's organization. Enforced server-side.
<SyncAgentChat
config={{
apiKey: "sa_your_key",
connectionString: process.env.DATABASE_URL,
filter: { organizationId: currentUser.orgId },
operations: currentUser.isAdmin
? ["read", "create", "update", "delete"]
: ["read"],
}}
/>
Give the agent capabilities beyond your database:
<SyncAgentChat
config={{
apiKey: "sa_your_key",
connectionString: process.env.DATABASE_URL,
tools: {
createInvoice: {
description: "Create a Stripe invoice for a customer",
inputSchema: {
customerId: { type: "string", description: "Stripe customer ID" },
amount: { type: "number", description: "Amount in cents" },
},
execute: async ({ customerId, amount }) => {
const inv = await stripe.invoices.create({ customer: customerId });
return { invoiceId: inv.id };
},
},
},
}}
/>
Use the agent with only your custom tools — no database access:
<SyncAgentChat
config={{
apiKey: "sa_your_key",
toolsOnly: true,
tools: {
searchProducts: {
description: "Search products by name",
inputSchema: { query: { type: "string", description: "Search query" } },
execute: async ({ query }) => {
const res = await fetch(`/api/products?q=${query}`);
return res.json();
},
},
},
}}
/>
All config options from @syncagent/js work here too:
<SyncAgentChat
config={{
apiKey: "sa_your_key",
connectionString: process.env.DATABASE_URL,
systemInstruction: "You are a friendly sales assistant for Acme Corp.",
language: "French",
confirmWrites: true,
maxResults: 10,
sensitiveFields: ["ssn", "salary", "creditCard"],
onBeforeToolCall: (name, args) => { console.log(`[Audit] ${name}`, args); return true; },
onAfterToolCall: (name, args, result) => { analytics.track("tool_call", { tool: name }); },
}}
/>
<SyncAgentChat
config={{ apiKey: "...", connectionString: "..." }}
persistKey={currentUser.id}
/>
History saves to localStorage under sa_chat_{persistKey}. The "New" button clears it.
The SDK automatically detects the current page from window.location — zero config needed:
URL: /dashboard/orders/ord_123?tab=details
Auto-detected:
currentPage: "orders"
currentPath: "/dashboard/orders/ord_123"
currentRecordId: "ord_123"
param_tab: "details"
Pass additional context:
<SyncAgentChat
config={{ apiKey: "...", connectionString: "..." }}
context={{ userId: currentUser.id, userRole: "admin" }}
/>
No npm required — drop a script tag into any HTML page:
<script src="https://syncagentdev.vercel.app/api/v1/widget"></script>
<script>
SyncAgent.init({
apiKey: "sa_your_key",
connectionString: "your_database_url",
position: "right",
accentColor: "#10b981",
title: "AI Assistant",
persistKey: "my-app",
});
</script>
| Plan | Requests/mo | Collections | Price |
|---|---|---|---|
| Free (+ 14-day trial) | 100 (500 during trial) | 5 | GH₵0 |
| Starter | 5,000 | 20 | GH₵150/mo |
| Pro | 50,000 | Unlimited | GH₵500/mo |
| Enterprise | Unlimited | Unlimited | Custom |
MIT
FAQs
SyncAgent React SDK — AI database chat widget & hooks
We found that @syncagent/react demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

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.

Research
/Security News
A long-running Go typosquat impersonated the popular shopspring/decimal library and used DNS TXT records to execute commands.

Research
Active npm supply chain attack compromises @antv packages in a fast-moving malicious publish wave tied to Mini Shai-Hulud.

Security News
/Research
Socket detected malicious node-ipc versions with obfuscated stealer/backdoor behavior in a developing npm supply chain attack.