@syncagent/js 0.1.9 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -90
- package/dist/index.d.mts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,21 +15,12 @@ import { SyncAgentClient } from "@syncagent/js";
|
|
|
15
15
|
|
|
16
16
|
const agent = new SyncAgentClient({
|
|
17
17
|
apiKey: "sa_your_api_key",
|
|
18
|
-
connectionString: process.env.DATABASE_URL,
|
|
18
|
+
connectionString: process.env.DATABASE_URL,
|
|
19
|
+
// baseUrl: "http://localhost:3100", // dev only — defaults to https://syncagent.dev
|
|
19
20
|
});
|
|
20
21
|
|
|
21
|
-
// Streaming
|
|
22
|
-
await agent.chat(
|
|
23
|
-
[{ role: "user", content: "Show me all active users" }],
|
|
24
|
-
{
|
|
25
|
-
onToken: (token) => process.stdout.write(token),
|
|
26
|
-
onComplete: (text) => console.log("\nDone"),
|
|
27
|
-
}
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
// Non-streaming (await full response)
|
|
31
22
|
const result = await agent.chat([
|
|
32
|
-
{ role: "user", content: "How many
|
|
23
|
+
{ role: "user", content: "How many users do we have?" }
|
|
33
24
|
]);
|
|
34
25
|
console.log(result.text);
|
|
35
26
|
```
|
|
@@ -40,11 +31,12 @@ console.log(result.text);
|
|
|
40
31
|
new SyncAgentClient(config: SyncAgentConfig)
|
|
41
32
|
```
|
|
42
33
|
|
|
43
|
-
| Option | Type
|
|
44
|
-
| ------------------ |
|
|
45
|
-
| `apiKey` | `string`
|
|
46
|
-
| `connectionString` | `string`
|
|
47
|
-
| `tools` | `Record<string, ToolDefinition>`
|
|
34
|
+
| Option | Type | Required | Description |
|
|
35
|
+
| ------------------ | -------------------------------- | -------- | -------------------------------------------------------------- |
|
|
36
|
+
| `apiKey` | `string` | ✅ | Your SyncAgent API key (`sa_...`) |
|
|
37
|
+
| `connectionString` | `string` | ✅ | Your database URL — sent at runtime, never stored |
|
|
38
|
+
| `tools` | `Record<string, ToolDefinition>` | — | Custom tools the agent can call client-side |
|
|
39
|
+
| `baseUrl` | `string` | — | Override API URL. Defaults to `https://syncagent.dev` |
|
|
48
40
|
|
|
49
41
|
## `client.chat(messages, options?)`
|
|
50
42
|
|
|
@@ -60,122 +52,121 @@ const result = await agent.chat(messages, options);
|
|
|
60
52
|
|
|
61
53
|
**`options`** — `ChatOptions`
|
|
62
54
|
|
|
63
|
-
| Option | Type
|
|
64
|
-
| ------------ |
|
|
65
|
-
| `onToken` | `(token: string) => void`
|
|
66
|
-
| `onComplete` | `(text: string) => void`
|
|
67
|
-
| `onError` | `(error: Error) => void`
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
55
|
+
| Option | Type | Description |
|
|
56
|
+
| ------------ | ------------------------------------------------ | ---------------------------------------------- |
|
|
57
|
+
| `onToken` | `(token: string) => void` | Called for each streamed text chunk |
|
|
58
|
+
| `onComplete` | `(text: string) => void` | Called with the full response text |
|
|
59
|
+
| `onError` | `(error: Error) => void` | Called on error |
|
|
60
|
+
| `onStatus` | `(step: string, label: string) => void` | Called with live status updates while working |
|
|
61
|
+
| `onData` | `(data: ToolData) => void` | Called when a DB tool returns structured data |
|
|
62
|
+
| `onToolCall` | `(name: string, args: any, result: any) => void` | Called when a custom tool executes |
|
|
63
|
+
| `signal` | `AbortSignal` | Cancel the request |
|
|
64
|
+
| `context` | `Record<string, any>` | Extra context injected into every message |
|
|
70
65
|
|
|
71
66
|
**Returns** `Promise<ChatResult>` → `{ text: string }`
|
|
72
67
|
|
|
73
|
-
|
|
68
|
+
### Status steps
|
|
74
69
|
|
|
75
|
-
|
|
70
|
+
`onStatus` fires with these `step` values:
|
|
71
|
+
- `"connecting"` — connecting to the database
|
|
72
|
+
- `"schema"` — discovering schema
|
|
73
|
+
- `"thinking"` — AI is reasoning
|
|
74
|
+
- `"querying"` — executing a DB tool
|
|
75
|
+
- `"done"` — complete
|
|
76
|
+
|
|
77
|
+
## `client.getSchema()`
|
|
76
78
|
|
|
77
79
|
```typescript
|
|
78
80
|
const schema = await agent.getSchema();
|
|
79
|
-
//
|
|
80
|
-
// [{ name: "users", fields: [{ name: "email", type: "string" }], documentCount: 1200 }]
|
|
81
|
+
// CollectionSchema[]
|
|
81
82
|
```
|
|
82
83
|
|
|
83
|
-
##
|
|
84
|
+
## Context injection
|
|
84
85
|
|
|
85
|
-
|
|
86
|
+
Pass per-message context so the agent knows what the user is looking at:
|
|
86
87
|
|
|
87
88
|
```typescript
|
|
88
|
-
|
|
89
|
+
await agent.chat(messages, {
|
|
90
|
+
context: {
|
|
91
|
+
userId: "user_123",
|
|
92
|
+
currentPage: "orders",
|
|
93
|
+
selectedOrderId: "ord_456",
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## `onData` callback
|
|
89
99
|
|
|
100
|
+
React to structured query results in your own UI:
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
90
103
|
const agent = new SyncAgentClient({
|
|
91
|
-
apiKey: "
|
|
104
|
+
apiKey: "sa_your_key",
|
|
105
|
+
connectionString: process.env.DATABASE_URL,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
await agent.chat(messages, {
|
|
109
|
+
onData: (data) => {
|
|
110
|
+
// data.tool — "query_documents" | "aggregate_documents"
|
|
111
|
+
// data.collection — e.g. "orders"
|
|
112
|
+
// data.data — array of result rows
|
|
113
|
+
// data.count — number of results
|
|
114
|
+
console.log(`Got ${data.count} rows from ${data.collection}`);
|
|
115
|
+
setTableData(data.data); // update your own table component
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Custom Tools
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
const agent = new SyncAgentClient({
|
|
124
|
+
apiKey: "sa_your_key",
|
|
92
125
|
connectionString: process.env.DATABASE_URL,
|
|
93
126
|
tools: {
|
|
94
127
|
sendEmail: {
|
|
95
128
|
description: "Send an email to a user",
|
|
96
129
|
inputSchema: {
|
|
97
|
-
to: { type: "string",
|
|
98
|
-
subject: { type: "string",
|
|
99
|
-
body: { type: "string",
|
|
130
|
+
to: { type: "string", description: "Recipient email" },
|
|
131
|
+
subject: { type: "string", description: "Subject line" },
|
|
132
|
+
body: { type: "string", description: "Email body" },
|
|
100
133
|
},
|
|
101
134
|
execute: async ({ to, subject, body }) => {
|
|
102
135
|
await mailer.send({ to, subject, text: body });
|
|
103
|
-
return { sent: true
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
createInvoice: {
|
|
107
|
-
description: "Create a Stripe invoice for a customer",
|
|
108
|
-
inputSchema: {
|
|
109
|
-
customerId: { type: "string", description: "Stripe customer ID" },
|
|
110
|
-
amount: { type: "number", description: "Amount in cents" },
|
|
111
|
-
memo: { type: "string", description: "Invoice memo", required: false },
|
|
112
|
-
},
|
|
113
|
-
execute: async ({ customerId, amount, memo }) => {
|
|
114
|
-
const inv = await stripe.invoices.create({ customer: customerId, description: memo });
|
|
115
|
-
return { invoiceId: inv.id };
|
|
136
|
+
return { sent: true };
|
|
116
137
|
},
|
|
117
138
|
},
|
|
118
139
|
},
|
|
119
140
|
});
|
|
120
|
-
|
|
121
|
-
// The agent can now query your DB AND call your tools
|
|
122
|
-
await agent.chat([
|
|
123
|
-
{ role: "user", content: "Find all users with expired subscriptions and email them" }
|
|
124
|
-
], {
|
|
125
|
-
onToolCall: (name, args, result) => console.log(`Tool called: ${name}`, result),
|
|
126
|
-
});
|
|
127
141
|
```
|
|
128
142
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
| Field | Type | Description |
|
|
132
|
-
| -------------------------- | ----------------------------------------------------------- | ------------------------------------------------ |
|
|
133
|
-
| `description` | `string` | What the tool does — the AI reads this |
|
|
134
|
-
| `inputSchema` | `Record<string, ToolParameter>` | Parameters the tool accepts |
|
|
135
|
-
| `inputSchema.*.type` | `"string" \| "number" \| "boolean" \| "object" \| "array"` | Parameter type |
|
|
136
|
-
| `inputSchema.*.description`| `string?` | Helps the AI know what value to pass |
|
|
137
|
-
| `inputSchema.*.required` | `boolean?` | Defaults to `true` — set `false` for optional |
|
|
138
|
-
| `inputSchema.*.enum` | `string[]?` | Restrict to specific values |
|
|
139
|
-
| `execute` | `(args) => any \| Promise<any>` | Your function — runs in your app, not on servers |
|
|
140
|
-
|
|
141
|
-
## Multi-turn Conversations
|
|
143
|
+
## Multi-turn conversations
|
|
142
144
|
|
|
143
145
|
```typescript
|
|
144
|
-
const
|
|
146
|
+
const history: Message[] = [];
|
|
145
147
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
messages.push({ role: "assistant", content: r1.text });
|
|
148
|
+
history.push({ role: "user", content: "Show top 5 customers" });
|
|
149
|
+
const r1 = await agent.chat(history);
|
|
150
|
+
history.push({ role: "assistant", content: r1.text });
|
|
150
151
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const r2 = await agent.chat(messages);
|
|
152
|
+
history.push({ role: "user", content: "Now email all of them" });
|
|
153
|
+
const r2 = await agent.chat(history);
|
|
154
154
|
```
|
|
155
155
|
|
|
156
|
-
## Abort /
|
|
156
|
+
## Abort / cancel
|
|
157
157
|
|
|
158
158
|
```typescript
|
|
159
159
|
const controller = new AbortController();
|
|
160
|
-
|
|
161
160
|
agent.chat(messages, { signal: controller.signal });
|
|
162
|
-
|
|
163
|
-
// Cancel at any time
|
|
164
|
-
controller.abort();
|
|
161
|
+
controller.abort(); // cancel at any time
|
|
165
162
|
```
|
|
166
163
|
|
|
167
|
-
## TypeScript
|
|
164
|
+
## TypeScript types
|
|
168
165
|
|
|
169
166
|
```typescript
|
|
170
167
|
import type {
|
|
171
|
-
SyncAgentConfig,
|
|
172
|
-
|
|
173
|
-
ChatOptions,
|
|
174
|
-
ChatResult,
|
|
175
|
-
CollectionSchema,
|
|
176
|
-
SchemaField,
|
|
177
|
-
ToolDefinition,
|
|
178
|
-
ToolParameter,
|
|
168
|
+
SyncAgentConfig, Message, ChatOptions, ChatResult,
|
|
169
|
+
CollectionSchema, SchemaField, ToolDefinition, ToolParameter, ToolData,
|
|
179
170
|
} from "@syncagent/js";
|
|
180
171
|
```
|
|
181
172
|
|
package/dist/index.d.mts
CHANGED
|
@@ -15,6 +15,11 @@ interface SyncAgentConfig {
|
|
|
15
15
|
connectionString: string;
|
|
16
16
|
/** Custom tools the AI agent can call — executed client-side in your app */
|
|
17
17
|
tools?: Record<string, ToolDefinition>;
|
|
18
|
+
/**
|
|
19
|
+
* Override the API base URL. Defaults to https://syncagent.dev
|
|
20
|
+
* Use this in development: baseUrl: "http://localhost:3100"
|
|
21
|
+
*/
|
|
22
|
+
baseUrl?: string;
|
|
18
23
|
}
|
|
19
24
|
interface Message {
|
|
20
25
|
role: "user" | "assistant";
|
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,11 @@ interface SyncAgentConfig {
|
|
|
15
15
|
connectionString: string;
|
|
16
16
|
/** Custom tools the AI agent can call — executed client-side in your app */
|
|
17
17
|
tools?: Record<string, ToolDefinition>;
|
|
18
|
+
/**
|
|
19
|
+
* Override the API base URL. Defaults to https://syncagent.dev
|
|
20
|
+
* Use this in development: baseUrl: "http://localhost:3100"
|
|
21
|
+
*/
|
|
22
|
+
baseUrl?: string;
|
|
18
23
|
}
|
|
19
24
|
interface Message {
|
|
20
25
|
role: "user" | "assistant";
|
package/dist/index.js
CHANGED
|
@@ -72,13 +72,13 @@ function parseChunk(chunk) {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
// src/client.ts
|
|
75
|
-
var SYNCAGENT_API_URL = "https://
|
|
75
|
+
var SYNCAGENT_API_URL = "https://syncagentdev.vercel.app";
|
|
76
76
|
var SyncAgentClient = class {
|
|
77
77
|
constructor(config) {
|
|
78
78
|
if (!config.apiKey) throw new Error("SyncAgent: apiKey is required");
|
|
79
79
|
if (!config.connectionString) throw new Error("SyncAgent: connectionString is required");
|
|
80
80
|
this.apiKey = config.apiKey;
|
|
81
|
-
this.baseUrl = SYNCAGENT_API_URL;
|
|
81
|
+
this.baseUrl = (config.baseUrl || SYNCAGENT_API_URL).replace(/\/$/, "");
|
|
82
82
|
this.connectionString = config.connectionString;
|
|
83
83
|
this.tools = config.tools || {};
|
|
84
84
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -46,13 +46,13 @@ function parseChunk(chunk) {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// src/client.ts
|
|
49
|
-
var SYNCAGENT_API_URL = "https://
|
|
49
|
+
var SYNCAGENT_API_URL = "https://syncagentdev.vercel.app";
|
|
50
50
|
var SyncAgentClient = class {
|
|
51
51
|
constructor(config) {
|
|
52
52
|
if (!config.apiKey) throw new Error("SyncAgent: apiKey is required");
|
|
53
53
|
if (!config.connectionString) throw new Error("SyncAgent: connectionString is required");
|
|
54
54
|
this.apiKey = config.apiKey;
|
|
55
|
-
this.baseUrl = SYNCAGENT_API_URL;
|
|
55
|
+
this.baseUrl = (config.baseUrl || SYNCAGENT_API_URL).replace(/\/$/, "");
|
|
56
56
|
this.connectionString = config.connectionString;
|
|
57
57
|
this.tools = config.tools || {};
|
|
58
58
|
}
|