
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.
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,
// baseUrl: "http://localhost:3100", // dev only
}}
/>
);
}
<SyncAgentChat> Props| Prop | Type | Default | Description |
|---|---|---|---|
config | SyncAgentConfig | Required* | API key, connection string, tools, baseUrl |
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 (replaced by status while active) |
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[] | ["Show all records", ...] | 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 — scopes ALL DB operations. Use for multi-tenant SaaS. |
operations | ("read"|"create"|"update"|"delete")[] | — | Restrict operations for this session. Subset of project's configured ops. |
onReaction | (idx, reaction, content) => void | — | Called when user reacts 👍/👎 to a message |
onData | (data: ToolData) => void | — | Called when a DB tool returns structured data |
className | string | — | CSS class on the panel container |
style | CSSProperties | — | Inline styles on the panel container |
*config is required unless wrapped in <SyncAgentProvider>.
● Querying users... while the agent worksonReactionpersistKey to save history to localStorageprefers-color-schemePass filter to scope every agent operation to the current user's organization. Enforced server-side — the agent cannot query outside this scope.
// In your app, after the user logs in:
<SyncAgentChat
config={{
apiKey: "sa_your_key",
connectionString: process.env.DATABASE_URL,
filter: { organizationId: currentUser.orgId },
}}
/>
// Every query is now automatically scoped:
// "Show all orders" → db.orders.find({ organizationId: "org_123" })
// "Add a product" → db.products.insertOne({ ...doc, organizationId: "org_123" })
Without filter — agent queries everything (single-tenant or admin tools).
With filter — every read, write, update, and delete is strictly scoped.
// Common patterns:
filter: { organizationId: org.id } // by org
filter: { tenant: "acme-corp" } // by tenant slug
filter: { userId: currentUser.id } // personal data only
filter: { orgId: org.id, deleted: false } // multiple conditions
<SyncAgentChat
config={{ apiKey: "...", connectionString: "..." }}
persistKey="project-123" // unique per project/user
/>
History saves to localStorage under sa_chat_project-123. The "New" button clears it.
The SDK automatically detects the current page from window.location on every message — zero config needed. The agent knows what page the user is on, what record they're viewing, and any relevant query params.
URL: /dashboard/orders/ord_123?tab=details
Auto-detected:
currentPage: "orders"
currentPath: "/dashboard/orders/ord_123"
currentRecordId: "ord_123"
param_tab: "details"
The user can say "show me this order" and the agent queries ord_123 automatically.
Pass additional context to enrich the auto-detected values:
<SyncAgentChat
config={{ apiKey: "...", connectionString: "..." }}
context={{ userId: currentUser.id, userRole: "admin" }}
/>
To disable auto-detection:
<SyncAgentChat
config={{ apiKey: "...", connectionString: "...", autoDetectPage: false }}
context={{ userId: currentUser.id, page: "orders" }}
/>
## `onData` — react to query results
```tsx
<SyncAgentChat
config={{ apiKey: "...", connectionString: "..." }}
onData={(data) => {
// Update your own table when the agent queries data
if (data.collection === "orders") setOrders(data.data);
}}
/>
<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 };
},
},
},
}}
/>
When you want the agent to only use your custom tools — with no database access at all — set toolsOnly: true. No connectionString needed.
<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();
},
},
placeOrder: {
description: "Place an order for a product",
inputSchema: {
productId: { type: "string" },
quantity: { type: "number" },
},
execute: async (args) => {
const res = await fetch("/api/orders", { method: "POST", body: JSON.stringify(args) });
return res.json();
},
},
},
}}
/>
The agent will only call your custom tools. No DB connection, no schema discovery, no built-in database tools.
useSyncAgentimport { 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.label shows "Querying users..." etc. */}
{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 optionsuseSyncAgent({
client?: SyncAgentClient, // pass directly instead of using Provider
context?: Record<string, any>, // injected into every message
onData?: (data: ToolData) => void, // called on DB tool results
})
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 |
No npm required — drop a script tag into any HTML page:
<script src="https://syncagent.dev/api/v1/widget"></script>
<script>
SyncAgent.init({
apiKey: "sa_your_key",
connectionString: "your_database_url",
position: "right", // "right" or "left"
accentColor: "#10b981", // brand color
title: "AI Assistant",
persistKey: "my-app", // localStorage persistence
open: false,
});
// Programmatic control
SyncAgent.open();
SyncAgent.close();
SyncAgent.toggle();
SyncAgent.clearHistory();
</script>
import type {
SyncAgentConfig, Message, ChatOptions, ToolDefinition,
ToolParameter, ToolData, SyncAgentChatProps,
} from "@syncagent/react";
MIT
FAQs
SyncAgent React SDK — AI database chat widget & hooks
The npm package @syncagent/react receives a total of 169 weekly downloads. As such, @syncagent/react popularity was classified as not popular.
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.