@yesvara/svara 0.1.2 → 0.1.3
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/CONTRIBUTING.md +1 -1
- package/README.md +183 -13
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +10 -0
- package/dist/index.mjs +10 -0
- package/examples/03-rag-knowledge/index.ts +2 -4
- package/package.json +1 -1
- package/src/core/agent.ts +12 -0
- package/svara@1.0.0 +0 -0
- package/test-rag.ts +0 -20
- package/tsx +0 -0
package/CONTRIBUTING.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Contributing to SvaraJS
|
|
2
2
|
|
|
3
|
-
Thanks for your interest in contributing! We welcome all contributions
|
|
3
|
+
Thanks for your interest in contributing! We welcome all contributions such as bug reports, feature requests, documentation improvements, and pull requests.
|
|
4
4
|
|
|
5
5
|
## Code of Conduct
|
|
6
6
|
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ const app = new SvaraApp();
|
|
|
29
29
|
const agent = new SvaraAgent({
|
|
30
30
|
name: 'Support Bot',
|
|
31
31
|
model: 'gpt-4o-mini', // provider auto-detected
|
|
32
|
-
knowledge: './docs', // PDF, MD, TXT
|
|
32
|
+
knowledge: './docs', // PDF, MD, TXT, just point to a folder
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
app.route('/chat', agent.handler());
|
|
@@ -44,7 +44,7 @@ That's it. No pipeline setup. No embedding boilerplate. No webhook configuration
|
|
|
44
44
|
|
|
45
45
|
## Features
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
|||
|
|
48
48
|
|---|---|
|
|
49
49
|
| **Zero-config LLM** | Pass a model name, provider is auto-detected |
|
|
50
50
|
| **Instant RAG** | Point to a folder, documents are indexed automatically |
|
|
@@ -359,7 +359,7 @@ agent
|
|
|
359
359
|
verifyToken: process.env.WA_VERIFY_TOKEN,
|
|
360
360
|
});
|
|
361
361
|
|
|
362
|
-
await agent.start();
|
|
362
|
+
await agent.start(); // Start all channels
|
|
363
363
|
```
|
|
364
364
|
|
|
365
365
|
### Events
|
|
@@ -416,12 +416,15 @@ console.log(reply); // "It's currently 14:32 UTC..."
|
|
|
416
416
|
const agent = new SvaraAgent({
|
|
417
417
|
name: 'Support Bot',
|
|
418
418
|
model: 'gpt-4o-mini',
|
|
419
|
-
knowledge: './docs',
|
|
419
|
+
knowledge: './docs', // Auto-loaded on first request
|
|
420
420
|
systemPrompt: 'You are a customer support agent. Answer using the documentation.',
|
|
421
421
|
memory: { window: 20 },
|
|
422
422
|
});
|
|
423
423
|
|
|
424
|
-
|
|
424
|
+
const app = new SvaraApp({ cors: true });
|
|
425
|
+
app.route('/chat', agent.handler());
|
|
426
|
+
app.listen(3000);
|
|
427
|
+
// Knowledge indexes automatically on first request
|
|
425
428
|
```
|
|
426
429
|
|
|
427
430
|
### Multi-channel (Web + Telegram + WhatsApp)
|
|
@@ -462,21 +465,105 @@ app.listen(3000);
|
|
|
462
465
|
|
|
463
466
|
---
|
|
464
467
|
|
|
468
|
+
## Adding Knowledge & Tools at Runtime
|
|
469
|
+
|
|
470
|
+
### Adding knowledge (dynamic indexing)
|
|
471
|
+
|
|
472
|
+
After the agent is created, add more documents **without restarting**:
|
|
473
|
+
|
|
474
|
+
```ts
|
|
475
|
+
const agent = new SvaraAgent({
|
|
476
|
+
name: 'Support Bot',
|
|
477
|
+
model: 'gpt-4o-mini',
|
|
478
|
+
knowledge: './docs', // Initial knowledge
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
// ── Later (no restart needed) ──────────────────────
|
|
482
|
+
// Add a single document
|
|
483
|
+
await agent.addKnowledge('./policies/new-policy-2024.pdf');
|
|
484
|
+
|
|
485
|
+
// Add multiple documents
|
|
486
|
+
await agent.addKnowledge(['./faq.md', './terms.txt', './pricing.pdf']);
|
|
487
|
+
|
|
488
|
+
// Agent immediately has the new knowledge
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
**Real-world example** — admin endpoint to upload documents:
|
|
492
|
+
|
|
493
|
+
```ts
|
|
494
|
+
const app = new SvaraApp({ cors: true });
|
|
495
|
+
app.route('/chat', agent.handler());
|
|
496
|
+
|
|
497
|
+
// Admin: dynamically add knowledge
|
|
498
|
+
app.post('/admin/add-knowledge', async (req, res) => {
|
|
499
|
+
const { path } = req.body;
|
|
500
|
+
try {
|
|
501
|
+
await agent.addKnowledge(path);
|
|
502
|
+
res.json({ status: 'Knowledge added', path });
|
|
503
|
+
} catch (err) {
|
|
504
|
+
res.status(400).json({ error: (err as Error).message });
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
app.listen(3000);
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
### Adding tools (dynamic function calling)
|
|
512
|
+
|
|
513
|
+
Add tools at runtime with `addTool()`:
|
|
514
|
+
|
|
515
|
+
```ts
|
|
516
|
+
import { SvaraAgent, createTool } from '@yesvara/svara';
|
|
517
|
+
|
|
518
|
+
const agent = new SvaraAgent({
|
|
519
|
+
name: 'Assistant',
|
|
520
|
+
model: 'gpt-4o-mini',
|
|
521
|
+
tools: [initialTool], // Start with one tool
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
// ── Later ────────────────────────────────────────
|
|
525
|
+
// Add more tools dynamically
|
|
526
|
+
const newTool = createTool({
|
|
527
|
+
name: 'send_email',
|
|
528
|
+
description: 'Send an email to a user',
|
|
529
|
+
parameters: {
|
|
530
|
+
to: { type: 'string', description: 'Email address', required: true },
|
|
531
|
+
subject: { type: 'string', description: 'Email subject', required: true },
|
|
532
|
+
body: { type: 'string', description: 'Email body', required: true },
|
|
533
|
+
},
|
|
534
|
+
async run({ to, subject, body }) {
|
|
535
|
+
// Call your email service
|
|
536
|
+
return { status: 'sent', to, subject };
|
|
537
|
+
},
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
agent.addTool(newTool);
|
|
541
|
+
|
|
542
|
+
// Agent can now use send_email tool
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
**Chainable tool registration** (multiple tools):
|
|
546
|
+
|
|
547
|
+
```ts
|
|
548
|
+
agent
|
|
549
|
+
.addTool(emailTool)
|
|
550
|
+
.addTool(databaseTool)
|
|
551
|
+
.addTool(slackTool)
|
|
552
|
+
.addTool(webhookTool);
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
465
557
|
## CLI
|
|
466
558
|
|
|
559
|
+
### Create a new project
|
|
560
|
+
|
|
467
561
|
```bash
|
|
468
|
-
# Scaffold a new project
|
|
469
562
|
svara new my-app
|
|
470
|
-
|
|
471
|
-
# Start dev server with hot-reload
|
|
472
|
-
svara dev
|
|
473
|
-
|
|
474
|
-
# Build for production
|
|
475
|
-
svara build
|
|
476
563
|
```
|
|
477
564
|
|
|
565
|
+
Output:
|
|
478
566
|
```
|
|
479
|
-
$ svara new my-app
|
|
480
567
|
✨ Creating SvaraJS project: my-app
|
|
481
568
|
|
|
482
569
|
✓ package.json
|
|
@@ -494,6 +581,89 @@ $ svara new my-app
|
|
|
494
581
|
npm run dev
|
|
495
582
|
```
|
|
496
583
|
|
|
584
|
+
Options:
|
|
585
|
+
- `--template <name>` — Use a specific template (default: `basic`)
|
|
586
|
+
- `basic` — Simple agent with HTTP endpoint
|
|
587
|
+
- `rag` — RAG-powered agent with document loader
|
|
588
|
+
- `multi-channel` — Web + Telegram + WhatsApp setup
|
|
589
|
+
- `tools` — Agent with tool calling examples
|
|
590
|
+
|
|
591
|
+
### Start development server
|
|
592
|
+
|
|
593
|
+
```bash
|
|
594
|
+
svara dev
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
Features:
|
|
598
|
+
- Hot-reload on file changes
|
|
599
|
+
- Auto-restart agent on code updates
|
|
600
|
+
- Debug logging enabled
|
|
601
|
+
- Serves on `http://localhost:3000` (configurable)
|
|
602
|
+
|
|
603
|
+
Options:
|
|
604
|
+
- `--port <number>` — Custom port (default: `3000`)
|
|
605
|
+
- `--watch <glob>` — Watch additional paths (default: `src/**`)
|
|
606
|
+
- `--env <file>` — Load custom .env file
|
|
607
|
+
|
|
608
|
+
### Build for production
|
|
609
|
+
|
|
610
|
+
```bash
|
|
611
|
+
svara build
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
Outputs:
|
|
615
|
+
- `dist/` — Compiled JavaScript
|
|
616
|
+
- `dist/index.js` — Entry point (ready for Node or Docker)
|
|
617
|
+
- Source maps and type declarations included
|
|
618
|
+
|
|
619
|
+
Options:
|
|
620
|
+
- `--minify` — Minify output
|
|
621
|
+
- `--sourcemaps` — Include source maps (default: true)
|
|
622
|
+
- `--outdir <path>` — Custom output directory (default: `dist/`)
|
|
623
|
+
|
|
624
|
+
### Running built projects
|
|
625
|
+
|
|
626
|
+
```bash
|
|
627
|
+
# After building
|
|
628
|
+
node dist/index.js
|
|
629
|
+
|
|
630
|
+
# Or with env file
|
|
631
|
+
NODE_ENV=production OPENAI_API_KEY=sk-... node dist/index.js
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
### Database management
|
|
635
|
+
|
|
636
|
+
```bash
|
|
637
|
+
# Initialize database (auto-creates tables)
|
|
638
|
+
svara db init
|
|
639
|
+
|
|
640
|
+
# Show database schema
|
|
641
|
+
svara db schema
|
|
642
|
+
|
|
643
|
+
# Export users and conversation history
|
|
644
|
+
svara db export --format json
|
|
645
|
+
svara db export --format csv --table svara_messages
|
|
646
|
+
|
|
647
|
+
# Query database directly
|
|
648
|
+
svara db query "SELECT COUNT(*) FROM svara_users"
|
|
649
|
+
|
|
650
|
+
# Reset database (⚠️ deletes all data)
|
|
651
|
+
svara db reset
|
|
652
|
+
|
|
653
|
+
# Backup database
|
|
654
|
+
svara db backup --output backup-2026-01-15.db
|
|
655
|
+
|
|
656
|
+
# Restore from backup
|
|
657
|
+
svara db restore --input backup-2026-01-15.db
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
Options:
|
|
661
|
+
- `--db <path>` — Custom database path (default: `./data/svara.db`)
|
|
662
|
+
- `--format <type>` — Export format: `json`, `csv`, `sql` (default: `json`)
|
|
663
|
+
- `--table <name>` — Specific table to export
|
|
664
|
+
- `--output <path>` — Output file path
|
|
665
|
+
- `--force` — Skip confirmation prompts (use with `reset` carefully!)
|
|
666
|
+
|
|
497
667
|
---
|
|
498
668
|
|
|
499
669
|
## Built-in Database
|
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1701,6 +1701,7 @@ var SvaraAgent = class extends import_events.default {
|
|
|
1701
1701
|
// Store VectorRetriever for retrieveChunks access
|
|
1702
1702
|
knowledgePaths = [];
|
|
1703
1703
|
isStarted = false;
|
|
1704
|
+
isKnowledgeInitialized = false;
|
|
1704
1705
|
db;
|
|
1705
1706
|
constructor(config) {
|
|
1706
1707
|
super();
|
|
@@ -1809,6 +1810,15 @@ var SvaraAgent = class extends import_events.default {
|
|
|
1809
1810
|
*/
|
|
1810
1811
|
handler() {
|
|
1811
1812
|
return async (req, res) => {
|
|
1813
|
+
if (this.knowledgePaths.length > 0 && !this.isKnowledgeInitialized) {
|
|
1814
|
+
try {
|
|
1815
|
+
await this.initKnowledge(this.knowledgePaths);
|
|
1816
|
+
this.isKnowledgeInitialized = true;
|
|
1817
|
+
} catch (err) {
|
|
1818
|
+
const error = err;
|
|
1819
|
+
this.log("error", `Failed to initialize knowledge: ${error.message}`);
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1812
1822
|
const { message, sessionId, userId } = req.body;
|
|
1813
1823
|
if (!message?.trim()) {
|
|
1814
1824
|
res.status(400).json({
|
package/dist/index.mjs
CHANGED
|
@@ -891,6 +891,7 @@ var SvaraAgent = class extends EventEmitter {
|
|
|
891
891
|
// Store VectorRetriever for retrieveChunks access
|
|
892
892
|
knowledgePaths = [];
|
|
893
893
|
isStarted = false;
|
|
894
|
+
isKnowledgeInitialized = false;
|
|
894
895
|
db;
|
|
895
896
|
constructor(config) {
|
|
896
897
|
super();
|
|
@@ -999,6 +1000,15 @@ var SvaraAgent = class extends EventEmitter {
|
|
|
999
1000
|
*/
|
|
1000
1001
|
handler() {
|
|
1001
1002
|
return async (req, res) => {
|
|
1003
|
+
if (this.knowledgePaths.length > 0 && !this.isKnowledgeInitialized) {
|
|
1004
|
+
try {
|
|
1005
|
+
await this.initKnowledge(this.knowledgePaths);
|
|
1006
|
+
this.isKnowledgeInitialized = true;
|
|
1007
|
+
} catch (err) {
|
|
1008
|
+
const error = err;
|
|
1009
|
+
this.log("error", `Failed to initialize knowledge: ${error.message}`);
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1002
1012
|
const { message, sessionId, userId } = req.body;
|
|
1003
1013
|
if (!message?.trim()) {
|
|
1004
1014
|
res.status(400).json({
|
|
@@ -31,11 +31,9 @@ Always be friendly and professional.`,
|
|
|
31
31
|
memory: { window: 20 },
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
// You can also add knowledge dynamically (hot reload, no restart needed)
|
|
35
|
-
// await agent.addKnowledge('./new-policy-2024.pdf');
|
|
36
|
-
|
|
37
34
|
const app = new SvaraApp({ cors: true });
|
|
38
35
|
app.route('/chat', agent.handler());
|
|
39
36
|
|
|
40
|
-
await agent.start(); // indexes documents
|
|
41
37
|
app.listen(3000);
|
|
38
|
+
console.log('✓ Agent running on http://localhost:3000');
|
|
39
|
+
console.log(' Knowledge base auto-loads on first request');
|
package/package.json
CHANGED
package/src/core/agent.ts
CHANGED
|
@@ -173,6 +173,7 @@ export class SvaraAgent extends EventEmitter {
|
|
|
173
173
|
private retriever: any = null; // Store VectorRetriever for retrieveChunks access
|
|
174
174
|
private knowledgePaths: string[] = [];
|
|
175
175
|
private isStarted = false;
|
|
176
|
+
private isKnowledgeInitialized = false;
|
|
176
177
|
private db: SvaraDB;
|
|
177
178
|
|
|
178
179
|
constructor(config: AgentConfig) {
|
|
@@ -303,6 +304,17 @@ export class SvaraAgent extends EventEmitter {
|
|
|
303
304
|
*/
|
|
304
305
|
handler(): RequestHandler {
|
|
305
306
|
return async (req, res) => {
|
|
307
|
+
// Auto-initialize knowledge on first request (lazy loading)
|
|
308
|
+
if (this.knowledgePaths.length > 0 && !this.isKnowledgeInitialized) {
|
|
309
|
+
try {
|
|
310
|
+
await this.initKnowledge(this.knowledgePaths);
|
|
311
|
+
this.isKnowledgeInitialized = true;
|
|
312
|
+
} catch (err) {
|
|
313
|
+
const error = err as Error;
|
|
314
|
+
this.log('error', `Failed to initialize knowledge: ${error.message}`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
306
318
|
const { message, sessionId, userId } = req.body as {
|
|
307
319
|
message?: string;
|
|
308
320
|
sessionId?: string;
|
package/svara@1.0.0
DELETED
|
File without changes
|
package/test-rag.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import 'dotenv/config';
|
|
2
|
-
import { SvaraApp, SvaraAgent } from './src/index.js';
|
|
3
|
-
|
|
4
|
-
async function main() {
|
|
5
|
-
const app = new SvaraApp({ cors: true });
|
|
6
|
-
|
|
7
|
-
const agent = new SvaraAgent({
|
|
8
|
-
name: 'TestAgent',
|
|
9
|
-
model: 'gpt-4o-mini',
|
|
10
|
-
knowledge: '/Users/920078/Documents/svara/contoh_folder_knowledge/**/*',
|
|
11
|
-
verbose: true,
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
await agent.start();
|
|
15
|
-
app.route('/chat', agent.handler());
|
|
16
|
-
app.listen(3000);
|
|
17
|
-
console.log('✓ Test server on port 3000');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
main().catch(console.error);
|
package/tsx
DELETED
|
File without changes
|