Latest Supply Chain Attack:Mini Shai-Hulud Hits @antv npm Packages, 639 Versions Compromised.Learn More
Sign In

@syncagent/react

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@syncagent/react

SyncAgent React SDK — AI database chat widget & hooks

Source
npmnpm
Version
0.3.2
Version published
Weekly downloads
197
1131.25%
Maintainers
1
Weekly downloads
 
Created
Source

@syncagent/react

React SDK for SyncAgent — drop-in AI database chat widget and hooks.

Install

npm install @syncagent/react @syncagent/js

Quick Start

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

PropTypeDefaultDescription
configSyncAgentConfigRequired*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)
defaultOpenbooleanfalseStart with the panel open
titlestring"SyncAgent"Header title
subtitlestring"AI Database Assistant"Header subtitle (replaced by status while active)
placeholderstring"Ask anything..."Input placeholder
welcomeMessagestring"Hi! I can query..."Empty state message
accentColorstring"#10b981"Brand color for header, FAB, send button
suggestionsstring[]["Show all records", ...]Quick-start suggestion chips
persistKeystringlocalStorage key for conversation persistence
contextRecord<string, any>Extra context injected into every message
filterRecord<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) => voidCalled when user reacts 👍/👎 to a message
onData(data: ToolData) => voidCalled when a DB tool returns structured data
classNamestringCSS class on the panel container
styleCSSPropertiesInline styles on the panel container

*config is required unless wrapped in <SyncAgentProvider>.

Features

  • Auto page detection — automatically detects current page, record ID, and query params from the URL
  • Live status — header subtitle shows ● Querying users... while the agent works
  • Markdown rendering — tables, code blocks, bold, italic, lists, headers
  • Streaming cursor — blinking cursor while text streams in
  • Copy button — on every AI response
  • Reactions — 👍/👎 on AI messages, fires onReaction
  • Retry — retry button on failed messages
  • Conversation persistence — pass persistKey to save history to localStorage
  • New conversation — "New" button in header clears history
  • Suggestion chips — configurable quick-start prompts, with pin/unpin to localStorage
  • Query history — ↑/↓ in input to cycle through previous messages
  • Export CSV — "⬇ CSV" button on messages containing markdown tables
  • Bar charts — auto-renders aggregation results as a mini bar chart
  • Resize handle — drag the top edge to resize the floating panel
  • Mobile responsive — full-width on small screens
  • Dark mode — respects prefers-color-scheme

Multi-tenant SaaS — scoping queries per organization

Pass 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

Conversation Persistence

<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.

Context — auto page detection

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);
  }}
/>

Custom Tools

<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 };
        },
      },
    },
  }}
/>

Tools-only mode

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.

Custom UI with useSyncAgent

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.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 options

useSyncAgent({
  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

ReturnTypeDescription
messagesMessage[]Full conversation history
isLoadingbooleantrue while streaming
errorError | nullLast error
status{ step, label } | nullLive status while agent is working
lastDataToolData | nullLast structured data from a DB tool
sendMessage(content: string) => voidSend a user message
stop() => voidAbort the current stream
reset() => voidClear all messages

Vanilla JS Widget

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>

TypeScript types

import type {
  SyncAgentConfig, Message, ChatOptions, ToolDefinition,
  ToolParameter, ToolData, SyncAgentChatProps,
} from "@syncagent/react";

License

MIT

Keywords

syncagent

FAQs

Package last updated on 08 Apr 2026

Did you know?

Socket

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.

Install

Related posts