@snap-agent/core 0.1.0
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/LICENSE +22 -0
- package/README.md +625 -0
- package/dist/chunk-V4TPAVOY.mjs +2227 -0
- package/dist/chunk-Y5TTFQWC.mjs +801 -0
- package/dist/dist-2CMI4QQD.mjs +1825 -0
- package/dist/dist-JU54Y3G4.mjs +3216 -0
- package/dist/index-CDsqnM8L.d.mts +680 -0
- package/dist/index-CDsqnM8L.d.ts +680 -0
- package/dist/index.d.mts +472 -0
- package/dist/index.d.ts +472 -0
- package/dist/index.js +9413 -0
- package/dist/index.mjs +1284 -0
- package/dist/storage/index.d.mts +1 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.js +829 -0
- package/dist/storage/index.mjs +10 -0
- package/package.json +114 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 ViloTech
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,625 @@
|
|
|
1
|
+
# SnapAgent
|
|
2
|
+
|
|
3
|
+
**The AI Agent SDK that runs everywhere.** A TypeScript-first SDK for building stateful AI agents with multi-provider support (OpenAI, Anthropic, Google). Extensible via plugins. Edge-runtime compatible.
|
|
4
|
+
|
|
5
|
+
## Why SnapAgent?
|
|
6
|
+
|
|
7
|
+
| | SnapAgent | OpenAI Agents SDK | LangChain |
|
|
8
|
+
|--|-----------|-------------------|-----------|
|
|
9
|
+
| **Edge Compatible** | ✅ | ❌ | ❌ |
|
|
10
|
+
| **Bundle Size** | ~63 KB | ~150 KB | ~2 MB+ |
|
|
11
|
+
| **Multi-Provider** | OpenAI, Anthropic, Google | OpenAI only | ✅ |
|
|
12
|
+
| **Plugin Architecture** | RAG, Tools, Middleware, Analytics | Tools only | Chains |
|
|
13
|
+
| **Persistent Storage** | Upstash, MongoDB, Memory | In-memory only | Via integrations |
|
|
14
|
+
| **Zero-Config RAG** | Built-in | Manual | Manual |
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- **Multi-Provider** — Switch between OpenAI, Anthropic, and Google seamlessly
|
|
19
|
+
- **Edge Runtime** — Deploy to Cloudflare Workers, Vercel Edge, Deno Deploy
|
|
20
|
+
- **Plugin Architecture** — Extend with RAG, tools, middleware, and analytics plugins
|
|
21
|
+
- **Persistent Storage** — Upstash Redis (edge), MongoDB (server), or bring your own
|
|
22
|
+
- **Zero-Config RAG** — Add semantic search with one line of config
|
|
23
|
+
- **Stateful Threads** — Automatic conversation history management
|
|
24
|
+
- **TypeScript First** — Full type safety and excellent IDE support
|
|
25
|
+
- **Streaming** — Real-time response streaming built-in
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install @snap-agent/core ai @ai-sdk/openai
|
|
31
|
+
|
|
32
|
+
# Optional: Additional providers
|
|
33
|
+
npm install @ai-sdk/anthropic @ai-sdk/google
|
|
34
|
+
|
|
35
|
+
# Optional: Persistent storage
|
|
36
|
+
npm install mongodb # For server environments
|
|
37
|
+
# Upstash works out of the box (REST API, no package needed)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { createClient, MongoDBStorage } from '@snap-agent/core';
|
|
44
|
+
|
|
45
|
+
// Initialize the SDK
|
|
46
|
+
const client = createClient({
|
|
47
|
+
storage: new MongoDBStorage('mongodb://localhost:27017/agents'),
|
|
48
|
+
providers: {
|
|
49
|
+
openai: { apiKey: process.env.OPENAI_API_KEY! },
|
|
50
|
+
anthropic: { apiKey: process.env.ANTHROPIC_API_KEY! },
|
|
51
|
+
google: { apiKey: process.env.GOOGLE_API_KEY! },
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Create an agent
|
|
56
|
+
const agent = await client.createAgent({
|
|
57
|
+
name: 'Customer Support Bot',
|
|
58
|
+
instructions: 'You are a helpful customer support agent.',
|
|
59
|
+
model: 'gpt-4o',
|
|
60
|
+
userId: 'user-123',
|
|
61
|
+
provider: 'openai', // or 'anthropic', 'google'
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Create a conversation thread
|
|
65
|
+
const thread = await client.createThread({
|
|
66
|
+
agentId: agent.id,
|
|
67
|
+
userId: 'user-123',
|
|
68
|
+
name: 'Support Conversation',
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Chat!
|
|
72
|
+
const response = await client.chat({
|
|
73
|
+
threadId: thread.id,
|
|
74
|
+
message: 'Hello! I need help with my account.',
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
console.log(response.reply);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Core Concepts
|
|
81
|
+
|
|
82
|
+
### Agents
|
|
83
|
+
|
|
84
|
+
Agents are AI assistants with specific instructions, using a specific LLM provider and model.
|
|
85
|
+
Snap Agents are extendable via plugins and support middlewares to intercept requests or enriching responses
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
// Create an agent
|
|
89
|
+
const agent = await client.createAgent({
|
|
90
|
+
name: 'Code Reviewer',
|
|
91
|
+
instructions: 'You are an expert code reviewer. Provide constructive feedback.',
|
|
92
|
+
provider: 'anthropic',
|
|
93
|
+
model: 'claude-3-5-sonnet-20241022',
|
|
94
|
+
userId: 'user-123',
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Update agent
|
|
98
|
+
await agent.update({
|
|
99
|
+
instructions: 'You are a senior code reviewer with 10 years of experience.',
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// List all agents for a user
|
|
103
|
+
const agents = await client.listAgents('user-123');
|
|
104
|
+
|
|
105
|
+
// Delete agent
|
|
106
|
+
await client.deleteAgent(agent.id);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Threads
|
|
110
|
+
|
|
111
|
+
Threads represent conversation sessions with persistent message history.
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// Create a thread
|
|
115
|
+
const thread = await client.createThread({
|
|
116
|
+
agentId: agent.id,
|
|
117
|
+
userId: 'user-123',
|
|
118
|
+
name: 'Code Review Session',
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Get thread
|
|
122
|
+
const loadedThread = await client.getThread(thread.id);
|
|
123
|
+
|
|
124
|
+
// List threads for an agent
|
|
125
|
+
const threads = await client.listThreads({ agentId: agent.id });
|
|
126
|
+
|
|
127
|
+
// Delete thread
|
|
128
|
+
await client.deleteThread(thread.id);
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Messages & Chat
|
|
132
|
+
|
|
133
|
+
Send messages and get AI responses with automatic history management.
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
// Simple chat
|
|
137
|
+
const response = await client.chat({
|
|
138
|
+
threadId: thread.id,
|
|
139
|
+
message: 'Review this code: const x = 1;',
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// Streaming chat
|
|
143
|
+
await client.chatStream(
|
|
144
|
+
{
|
|
145
|
+
threadId: thread.id,
|
|
146
|
+
message: 'Tell me a story',
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
onChunk: (chunk) => process.stdout.write(chunk),
|
|
150
|
+
onComplete: (fullResponse) => console.log('\nDone'),
|
|
151
|
+
onError: (error) => console.error('Error:', error),
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Multi-Provider Support
|
|
157
|
+
|
|
158
|
+
Switch between OpenAI, Anthropic, and Google models easily:
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
import { Models } from '@snap-agent/core';
|
|
162
|
+
|
|
163
|
+
// OpenAI
|
|
164
|
+
const gptAgent = await client.createAgent({
|
|
165
|
+
name: 'GPT Agent',
|
|
166
|
+
provider: 'openai',
|
|
167
|
+
model: Models.OpenAI.GPT4O,
|
|
168
|
+
instructions: 'You are helpful.',
|
|
169
|
+
userId: 'user-123',
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Anthropic (Claude)
|
|
173
|
+
const claudeAgent = await client.createAgent({
|
|
174
|
+
name: 'Claude Agent',
|
|
175
|
+
provider: 'anthropic',
|
|
176
|
+
model: Models.Anthropic.CLAUDE_35_SONNET,
|
|
177
|
+
instructions: 'You are helpful.',
|
|
178
|
+
userId: 'user-123',
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Google (Gemini)
|
|
182
|
+
const geminiAgent = await client.createAgent({
|
|
183
|
+
name: 'Gemini Agent',
|
|
184
|
+
provider: 'google',
|
|
185
|
+
model: Models.Google.GEMINI_2_FLASH,
|
|
186
|
+
instructions: 'You are helpful.',
|
|
187
|
+
userId: 'user-123',
|
|
188
|
+
});
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Plugin Architecture
|
|
192
|
+
|
|
193
|
+
SnapAgent is built around a powerful plugin system. Extend your agents with any combination of plugins:
|
|
194
|
+
|
|
195
|
+
### Plugin Types
|
|
196
|
+
|
|
197
|
+
| Type | Purpose | Example Use Cases |
|
|
198
|
+
|------|---------|-------------------|
|
|
199
|
+
| **RAG Plugins** | Semantic search & document retrieval | Knowledge bases, product catalogs, support docs |
|
|
200
|
+
| **Tool Plugins** | Give agents executable capabilities | API calls, calculations, data lookups |
|
|
201
|
+
| **Middleware Plugins** | Intercept and transform requests/responses | Rate limiting, content moderation, logging |
|
|
202
|
+
| **Analytics Plugins** | Track usage and performance | Monitoring, billing, optimization |
|
|
203
|
+
|
|
204
|
+
### Combining Multiple Plugins
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
import { createClient, MemoryStorage } from '@snap-agent/core';
|
|
208
|
+
import { EcommerceRAGPlugin } from '@snap-agent/rag-ecommerce';
|
|
209
|
+
import { RateLimiter } from '@snap-agent/middleware-ratelimit';
|
|
210
|
+
import { SlackNotifications } from '@snap-agent/middleware-slack';
|
|
211
|
+
import { ConsoleAnalytics } from '@snap-agent/analytics-console';
|
|
212
|
+
|
|
213
|
+
const agent = await client.createAgent({
|
|
214
|
+
name: 'Production Agent',
|
|
215
|
+
instructions: 'You are a helpful shopping assistant.',
|
|
216
|
+
provider: 'openai',
|
|
217
|
+
model: 'gpt-4o',
|
|
218
|
+
userId: 'user-123',
|
|
219
|
+
plugins: [
|
|
220
|
+
// RAG: Search product catalog
|
|
221
|
+
new EcommerceRAGPlugin({
|
|
222
|
+
mongoUri: process.env.MONGODB_URI!,
|
|
223
|
+
openaiApiKey: process.env.OPENAI_API_KEY!,
|
|
224
|
+
tenantId: 'my-store',
|
|
225
|
+
}),
|
|
226
|
+
|
|
227
|
+
// Middleware: Rate limiting
|
|
228
|
+
new RateLimiter({
|
|
229
|
+
maxRequests: 100,
|
|
230
|
+
windowMs: 60000,
|
|
231
|
+
}),
|
|
232
|
+
|
|
233
|
+
// Middleware: Slack alerts on errors
|
|
234
|
+
new SlackNotifications({
|
|
235
|
+
webhookUrl: process.env.SLACK_WEBHOOK!,
|
|
236
|
+
onError: true,
|
|
237
|
+
}),
|
|
238
|
+
|
|
239
|
+
// Analytics: Log everything
|
|
240
|
+
new ConsoleAnalytics(),
|
|
241
|
+
],
|
|
242
|
+
});
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Building Custom Plugins
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
import { MiddlewarePlugin, AnalyticsPlugin } from '@snap-agent/core';
|
|
249
|
+
|
|
250
|
+
// Custom middleware
|
|
251
|
+
class LoggingMiddleware implements MiddlewarePlugin {
|
|
252
|
+
type = 'middleware' as const;
|
|
253
|
+
name = 'logging';
|
|
254
|
+
|
|
255
|
+
async beforeRequest(context: any) {
|
|
256
|
+
console.log('Request:', context.message);
|
|
257
|
+
return context;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
async afterResponse(context: any, response: any) {
|
|
261
|
+
console.log('Response:', response.reply.substring(0, 100));
|
|
262
|
+
return response;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Custom analytics
|
|
267
|
+
class CustomAnalytics implements AnalyticsPlugin {
|
|
268
|
+
type = 'analytics' as const;
|
|
269
|
+
name = 'custom-analytics';
|
|
270
|
+
|
|
271
|
+
async trackRequest(data: RequestTrackingData) {
|
|
272
|
+
await myAnalyticsService.track('agent_request', data);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
async trackResponse(data: ResponseTrackingData) {
|
|
276
|
+
await myAnalyticsService.track('agent_response', data);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Available Plugins
|
|
282
|
+
|
|
283
|
+
| Package | Description |
|
|
284
|
+
|---------|-------------|
|
|
285
|
+
| `@snap-agent/rag-ecommerce` | E-commerce product search with attribute extraction |
|
|
286
|
+
| `@snap-agent/rag-support` | Support ticket and documentation search |
|
|
287
|
+
| `@snap-agent/rag-docs` | General documentation search |
|
|
288
|
+
| `@snap-agent/middleware-ratelimit` | Request rate limiting |
|
|
289
|
+
| `@snap-agent/middleware-moderation` | Content moderation |
|
|
290
|
+
| `@snap-agent/middleware-slack` | Slack notifications |
|
|
291
|
+
| `@snap-agent/middleware-discord` | Discord notifications |
|
|
292
|
+
| `@snap-agent/middleware-webhooks` | Custom webhook notifications |
|
|
293
|
+
| `@snap-agent/analytics-console` | Console logging analytics |
|
|
294
|
+
|
|
295
|
+
## Zero-Config RAG
|
|
296
|
+
|
|
297
|
+
Add semantic search and retrieval-augmented generation to your agents with zero configuration:
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
// Just add rag: { enabled: true }
|
|
301
|
+
const agent = await client.createAgent({
|
|
302
|
+
name: 'Knowledge Assistant',
|
|
303
|
+
instructions: 'You are a helpful assistant with access to a knowledge base.',
|
|
304
|
+
model: 'gpt-4o',
|
|
305
|
+
userId: 'user-123',
|
|
306
|
+
rag: {
|
|
307
|
+
enabled: true // That's it! Uses DefaultRAGPlugin automatically
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// Ingest documents
|
|
312
|
+
await agent.ingestDocuments([
|
|
313
|
+
{
|
|
314
|
+
id: 'doc-1',
|
|
315
|
+
content: 'Your document content here...',
|
|
316
|
+
metadata: { title: 'Doc Title', category: 'general' }
|
|
317
|
+
}
|
|
318
|
+
]);
|
|
319
|
+
|
|
320
|
+
// Chat with RAG
|
|
321
|
+
const response = await client.chat({
|
|
322
|
+
threadId: thread.id,
|
|
323
|
+
message: 'What does the documentation say about...?',
|
|
324
|
+
useRAG: true // Enable RAG for this query
|
|
325
|
+
});
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Advanced RAG Configuration
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
const agent = await client.createAgent({
|
|
332
|
+
name: 'Advanced Agent',
|
|
333
|
+
model: 'gpt-4o',
|
|
334
|
+
userId: 'user-123',
|
|
335
|
+
rag: {
|
|
336
|
+
enabled: true,
|
|
337
|
+
embeddingModel: 'text-embedding-3-large', // Custom model
|
|
338
|
+
limit: 10, // Return more results
|
|
339
|
+
// Optional: Use different API key for embeddings
|
|
340
|
+
embeddingProviderApiKey: process.env.CUSTOM_API_KEY,
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Using Specialized RAG Plugins
|
|
346
|
+
|
|
347
|
+
For production use cases with advanced features (attribute extraction, rescoring, reranking, caching), use specialized plugins:
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
import { EcommerceRAGPlugin } from '@snap-agent/rag-ecommerce';
|
|
351
|
+
|
|
352
|
+
const agent = await client.createAgent({
|
|
353
|
+
name: 'Shopping Assistant',
|
|
354
|
+
model: 'gpt-4o',
|
|
355
|
+
userId: 'user-123',
|
|
356
|
+
plugins: [
|
|
357
|
+
new EcommerceRAGPlugin({
|
|
358
|
+
mongoUri: process.env.MONGODB_URI!,
|
|
359
|
+
openaiApiKey: process.env.OPENAI_API_KEY!,
|
|
360
|
+
voyageApiKey: process.env.VOYAGE_API_KEY!,
|
|
361
|
+
tenantId: 'my-store',
|
|
362
|
+
cache: {
|
|
363
|
+
embeddings: { enabled: true },
|
|
364
|
+
attributes: { enabled: true }
|
|
365
|
+
}
|
|
366
|
+
})
|
|
367
|
+
]
|
|
368
|
+
});
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## Storage Adapters
|
|
372
|
+
|
|
373
|
+
### Upstash Redis (Edge + Server)
|
|
374
|
+
|
|
375
|
+
**Recommended for edge deployments.** Uses REST API, works everywhere.
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
import { UpstashStorage } from '@snap-agent/core';
|
|
379
|
+
|
|
380
|
+
const storage = new UpstashStorage({
|
|
381
|
+
url: process.env.UPSTASH_REDIS_REST_URL!,
|
|
382
|
+
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
|
|
383
|
+
prefix: 'myapp', // Optional: key prefix for multi-tenancy
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
const client = createClient({
|
|
387
|
+
storage,
|
|
388
|
+
providers: { openai: { apiKey: process.env.OPENAI_API_KEY! } },
|
|
389
|
+
});
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### MongoDB Storage (Server)
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
import { MongoDBStorage } from '@snap-agent/core';
|
|
396
|
+
|
|
397
|
+
const storage = new MongoDBStorage({
|
|
398
|
+
uri: 'mongodb://localhost:27017',
|
|
399
|
+
dbName: 'myapp',
|
|
400
|
+
agentsCollection: 'agents',
|
|
401
|
+
threadsCollection: 'threads',
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
// Or use simple string URI
|
|
405
|
+
const storage = new MongoDBStorage('mongodb://localhost:27017/myapp');
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Memory Storage (Development/Testing)
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
import { MemoryStorage } from '@snap-agent/core';
|
|
412
|
+
|
|
413
|
+
const storage = new MemoryStorage();
|
|
414
|
+
|
|
415
|
+
// Useful methods
|
|
416
|
+
storage.clear(); // Clear all data
|
|
417
|
+
console.log(storage.getStats()); // Get stats
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Custom Storage Adapter
|
|
421
|
+
|
|
422
|
+
Implement your own storage adapter for any database:
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
import { StorageAdapter } from '@snap-agent/core';
|
|
426
|
+
|
|
427
|
+
class PostgresStorage implements StorageAdapter {
|
|
428
|
+
async createAgent(config: AgentConfig): Promise<string> {
|
|
429
|
+
// Your implementation
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
async getAgent(agentId: string): Promise<AgentData | null> {
|
|
433
|
+
// Your implementation
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// ... implement all required methods
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
## Advanced Usage
|
|
441
|
+
|
|
442
|
+
### Working with Agent and Thread Objects
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
// Load and use agent directly
|
|
446
|
+
const agent = await client.getAgent('agent-id');
|
|
447
|
+
console.log(agent.name);
|
|
448
|
+
console.log(agent.provider);
|
|
449
|
+
console.log(agent.model);
|
|
450
|
+
|
|
451
|
+
// Generate response directly
|
|
452
|
+
const messages = [
|
|
453
|
+
{ role: 'user', content: 'Hello!' }
|
|
454
|
+
];
|
|
455
|
+
const reply = await agent.generateResponse(messages);
|
|
456
|
+
|
|
457
|
+
// Load and use thread directly
|
|
458
|
+
const thread = await client.getThread('thread-id');
|
|
459
|
+
await thread.addMessage('user', 'Hello!');
|
|
460
|
+
const messages = await thread.getMessages(10);
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Auto-Generate Thread Names
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
const thread = await client.createThread({
|
|
467
|
+
agentId: agent.id,
|
|
468
|
+
userId: 'user-123',
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
// Generate a descriptive name based on first message
|
|
472
|
+
const name = await client.generateThreadName('Help me debug this error');
|
|
473
|
+
await thread.updateName(name);
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### Message Attachments
|
|
477
|
+
|
|
478
|
+
```typescript
|
|
479
|
+
await client.chat({
|
|
480
|
+
threadId: thread.id,
|
|
481
|
+
message: 'Can you review this document?',
|
|
482
|
+
attachments: [
|
|
483
|
+
{
|
|
484
|
+
fileId: 'file-123',
|
|
485
|
+
filename: 'document.pdf',
|
|
486
|
+
contentType: 'application/pdf',
|
|
487
|
+
size: 1024000,
|
|
488
|
+
},
|
|
489
|
+
],
|
|
490
|
+
});
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Organization Support (Multi-Tenancy)
|
|
494
|
+
|
|
495
|
+
```typescript
|
|
496
|
+
const agent = await client.createAgent({
|
|
497
|
+
name: 'Org Agent',
|
|
498
|
+
userId: 'user-123',
|
|
499
|
+
organizationId: 'org-456',
|
|
500
|
+
// ... other config
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
// List agents for an organization
|
|
504
|
+
const orgAgents = await client.listAgents('user-123', 'org-456');
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
## Error Handling
|
|
508
|
+
|
|
509
|
+
```typescript
|
|
510
|
+
import {
|
|
511
|
+
AgentNotFoundError,
|
|
512
|
+
ThreadNotFoundError,
|
|
513
|
+
ProviderNotFoundError,
|
|
514
|
+
InvalidConfigError,
|
|
515
|
+
} from '@snap-agent/core';
|
|
516
|
+
|
|
517
|
+
try {
|
|
518
|
+
const agent = await client.getAgent('invalid-id');
|
|
519
|
+
} catch (error) {
|
|
520
|
+
if (error instanceof AgentNotFoundError) {
|
|
521
|
+
console.error('Agent not found:', error.message);
|
|
522
|
+
} else if (error instanceof ProviderNotFoundError) {
|
|
523
|
+
console.error('Provider not configured:', error.message);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
## Environment Variables
|
|
529
|
+
|
|
530
|
+
```bash
|
|
531
|
+
# .env
|
|
532
|
+
|
|
533
|
+
# LLM Providers
|
|
534
|
+
OPENAI_API_KEY=sk-...
|
|
535
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
536
|
+
GOOGLE_API_KEY=AI...
|
|
537
|
+
|
|
538
|
+
# Storage (choose one)
|
|
539
|
+
MONGODB_URI=mongodb://localhost:27017/agents # Server environments
|
|
540
|
+
UPSTASH_REDIS_REST_URL=https://your-redis.upstash.io # Edge + Server
|
|
541
|
+
UPSTASH_REDIS_REST_TOKEN=your-token
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
## Examples
|
|
545
|
+
|
|
546
|
+
**Getting Started:**
|
|
547
|
+
- [Basic Usage](./examples/basic.ts) - Simple agent creation and chat
|
|
548
|
+
- [Multi-Provider](./examples/multi-provider.ts) - Using different AI providers
|
|
549
|
+
- [Streaming](./examples/streaming.ts) - Real-time response streaming
|
|
550
|
+
|
|
551
|
+
**RAG & Ingestion:**
|
|
552
|
+
- [Zero-Config RAG](./examples/zero-config-rag.ts) - RAG with zero configuration
|
|
553
|
+
- [Product Ingestion](./examples/product-ingestion.ts) - Ingest product catalogs
|
|
554
|
+
- [URL Ingestion](./examples/url-ingestion-example.ts) - Ingest from URLs
|
|
555
|
+
|
|
556
|
+
**Deployment:**
|
|
557
|
+
- [Express Server](./examples/express-server.ts) - Building an API server
|
|
558
|
+
- [Cloudflare Workers](./examples/edge-cloudflare-worker.ts) - Edge deployment
|
|
559
|
+
- [Vercel Edge](./examples/edge-vercel.ts) - Vercel Edge Functions
|
|
560
|
+
|
|
561
|
+
## Edge Runtime
|
|
562
|
+
|
|
563
|
+
Deploy AI agents to edge runtimes for low latency and global distribution:
|
|
564
|
+
|
|
565
|
+
```typescript
|
|
566
|
+
// Cloudflare Workers
|
|
567
|
+
import { createClient, UpstashStorage } from '@snap-agent/core';
|
|
568
|
+
|
|
569
|
+
export default {
|
|
570
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
571
|
+
const client = createClient({
|
|
572
|
+
storage: new UpstashStorage({
|
|
573
|
+
url: env.UPSTASH_REDIS_REST_URL,
|
|
574
|
+
token: env.UPSTASH_REDIS_REST_TOKEN,
|
|
575
|
+
}),
|
|
576
|
+
providers: { openai: { apiKey: env.OPENAI_API_KEY } },
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
const agent = await client.createAgent({
|
|
580
|
+
name: 'Edge Agent',
|
|
581
|
+
instructions: 'You are helpful.',
|
|
582
|
+
provider: 'openai',
|
|
583
|
+
model: 'gpt-4o-mini',
|
|
584
|
+
userId: 'edge-user',
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
const body = await request.json() as { message: string };
|
|
588
|
+
const { reply } = await agent.chat(body.message);
|
|
589
|
+
|
|
590
|
+
return Response.json({ reply });
|
|
591
|
+
},
|
|
592
|
+
};
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
**Supported runtimes:** Cloudflare Workers, Vercel Edge, Deno Deploy, AWS Lambda@Edge, any WinterCG-compliant runtime.
|
|
596
|
+
|
|
597
|
+
See [EDGE_RUNTIME.md](./EDGE_RUNTIME.md) for complete documentation.
|
|
598
|
+
|
|
599
|
+
## Comparison
|
|
600
|
+
|
|
601
|
+
| Feature | SnapAgent | OpenAI Agents SDK | LangChain | Vercel AI SDK |
|
|
602
|
+
|---------|-----------|-------------------|-----------|---------------|
|
|
603
|
+
| Edge Compatible | ✅ | ❌ | ❌ | ✅ |
|
|
604
|
+
| Multi-Provider | ✅ | OpenAI only | ✅ | ✅ |
|
|
605
|
+
| Plugin Architecture | RAG, Tools, Middleware | Tools only | Chains | No |
|
|
606
|
+
| Persistent Storage | Upstash, MongoDB | In-memory | Via integrations | No |
|
|
607
|
+
| Zero-Config RAG | ✅ | ❌ | ❌ | ❌ |
|
|
608
|
+
| Agent Management | ✅ | ✅ | Complex | No |
|
|
609
|
+
| Thread Management | ✅ | ✅ | ❌ | ❌ |
|
|
610
|
+
| TypeScript First | ✅ | ✅ | Partial | ✅ |
|
|
611
|
+
| Bundle Size | ~63 KB | ~150 KB | ~2 MB+ | ~15 KB |
|
|
612
|
+
| Self-Hosted | ✅ | ❌ | ✅ | ✅ |
|
|
613
|
+
|
|
614
|
+
## Contributing
|
|
615
|
+
|
|
616
|
+
Contributions are welcome! Please open an issue or submit a pull request on [GitHub](https://github.com/vilo-hq/snap-agent).
|
|
617
|
+
|
|
618
|
+
## License
|
|
619
|
+
|
|
620
|
+
MIT © ViloTech
|
|
621
|
+
|
|
622
|
+
## Support
|
|
623
|
+
|
|
624
|
+
- [GitHub Issues](https://github.com/vilo-hq/snap-agent/issues)
|
|
625
|
+
|