samarthya-bot 1.1.3 ā 2.0.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/README.md +274 -96
- package/backend/.env.example +31 -7
- package/backend/bin/samarthya.js +114 -25
- package/backend/package-lock.json +47 -25
- package/backend/package.json +4 -3
- package/backend/public/assets/index-BFRAq8Y1.js +149 -0
- package/backend/public/assets/index-DdCKkq38.js +149 -0
- package/backend/public/assets/index-kzffNwzo.js +149 -0
- package/backend/public/index.html +1 -1
- package/backend/server.js +70 -22
- package/backend/server.log +29 -0
- package/backend/services/agent/spawnService.js +140 -0
- package/backend/services/discord/discordService.js +188 -0
- package/backend/services/heartbeat/heartbeatService.js +157 -0
- package/backend/services/llm/llmService.js +118 -1
- package/backend/services/security/sandboxService.js +115 -0
- package/backend/services/voice/voiceService.js +151 -0
- package/package.json +2 -2
- package/server.log +35 -0
package/backend/bin/samarthya.js
CHANGED
|
@@ -28,13 +28,13 @@ const isServerRunning = () => {
|
|
|
28
28
|
|
|
29
29
|
if (!command) {
|
|
30
30
|
console.log(`
|
|
31
|
-
|
|
31
|
+
š®š³ SamarthyaBot ā Your Local Agentic OS
|
|
32
32
|
Usage:
|
|
33
|
-
samarthya onboard - Setup
|
|
33
|
+
samarthya onboard - Setup + Start everything (single command!)
|
|
34
34
|
samarthya model - Change your active AI provider/model
|
|
35
|
-
samarthya gateway - Start the local server
|
|
35
|
+
samarthya gateway - Start the local server only
|
|
36
|
+
samarthya tunnel - Expose to internet & setup webhooks
|
|
36
37
|
samarthya status - Check if the agent is running
|
|
37
|
-
samarthya tunnel - Expose to internet & setup webhooks
|
|
38
38
|
samarthya stop - Stop the running gateway
|
|
39
39
|
samarthya restart - Restart the gateway
|
|
40
40
|
`);
|
|
@@ -54,14 +54,17 @@ switch (command) {
|
|
|
54
54
|
|
|
55
55
|
(async () => {
|
|
56
56
|
console.log("\nš Select your primary AI Provider:");
|
|
57
|
-
console.log(" 1) Google Gemini (Default)");
|
|
58
|
-
console.log(" 2) Anthropic Claude");
|
|
57
|
+
console.log(" 1) Google Gemini (Default, Free tier)");
|
|
58
|
+
console.log(" 2) Anthropic Claude (Smartest)");
|
|
59
59
|
console.log(" 3) Groq (Fastest)");
|
|
60
|
-
console.log(" 4) OpenAI");
|
|
61
|
-
console.log(" 5)
|
|
62
|
-
console.log(" 6)
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
console.log(" 4) OpenAI (GPT-5)");
|
|
61
|
+
console.log(" 5) DeepSeek (Budget-friendly)");
|
|
62
|
+
console.log(" 6) Qwen (Alibaba)");
|
|
63
|
+
console.log(" 7) OpenRouter (100+ models via 1 key)");
|
|
64
|
+
console.log(" 8) Local Ollama (Offline, Private)");
|
|
65
|
+
console.log(" 9) Mistral AI\n");
|
|
66
|
+
|
|
67
|
+
let providerRaw = await question("Enter choice (1-9, default 1): ");
|
|
65
68
|
let activeProvider = 'gemini';
|
|
66
69
|
let useOllama = 'false';
|
|
67
70
|
|
|
@@ -69,11 +72,14 @@ switch (command) {
|
|
|
69
72
|
case '2': activeProvider = 'anthropic'; break;
|
|
70
73
|
case '3': activeProvider = 'groq'; break;
|
|
71
74
|
case '4': activeProvider = 'openai'; break;
|
|
72
|
-
case '5':
|
|
75
|
+
case '5': activeProvider = 'deepseek'; break;
|
|
76
|
+
case '6': activeProvider = 'qwen'; break;
|
|
77
|
+
case '7': activeProvider = 'openrouter'; break;
|
|
78
|
+
case '8':
|
|
73
79
|
activeProvider = 'ollama';
|
|
74
80
|
useOllama = 'true';
|
|
75
81
|
break;
|
|
76
|
-
case '
|
|
82
|
+
case '9': activeProvider = 'mistral'; break;
|
|
77
83
|
case '1':
|
|
78
84
|
default:
|
|
79
85
|
activeProvider = 'gemini';
|
|
@@ -86,7 +92,12 @@ switch (command) {
|
|
|
86
92
|
const anthropicKey = await question('š Enter Anthropic (Claude) API Key (or press Enter to skip): ');
|
|
87
93
|
const groqKey = await question('š Enter Groq API Key (or press Enter to skip): ');
|
|
88
94
|
const openAiKey = await question('š Enter OpenAI API Key (or press Enter to skip): ');
|
|
95
|
+
const deepseekKey = await question('š Enter DeepSeek API Key (or press Enter to skip): ');
|
|
96
|
+
const qwenKey = await question('š Enter Qwen API Key (or press Enter to skip): ');
|
|
97
|
+
const openrouterKey = await question('š Enter OpenRouter API Key (or press Enter to skip): ');
|
|
89
98
|
const telegramToken = await question('š¤ Enter Telegram Bot Token (or press Enter to skip): ');
|
|
99
|
+
const discordToken = await question('š£ Enter Discord Bot Token (or press Enter to skip): ');
|
|
100
|
+
const encKey = await question('š Enter 32-char Encryption Key (or press Enter for auto-generate): ');
|
|
90
101
|
|
|
91
102
|
const envPath = path.join(backendDir, '.env');
|
|
92
103
|
let envVars = {};
|
|
@@ -95,13 +106,17 @@ switch (command) {
|
|
|
95
106
|
if (fs.existsSync(envPath)) {
|
|
96
107
|
const currentEnv = fs.readFileSync(envPath, 'utf8');
|
|
97
108
|
currentEnv.split('\n').forEach(line => {
|
|
98
|
-
const
|
|
99
|
-
if (
|
|
109
|
+
const eqIndex = line.indexOf('=');
|
|
110
|
+
if (eqIndex > 0) {
|
|
111
|
+
const k = line.substring(0, eqIndex).trim();
|
|
112
|
+
const v = line.substring(eqIndex + 1).trim();
|
|
113
|
+
if (k) envVars[k] = v;
|
|
114
|
+
}
|
|
100
115
|
});
|
|
101
116
|
} else {
|
|
102
117
|
envVars = {
|
|
103
118
|
PORT: '5000',
|
|
104
|
-
|
|
119
|
+
MONGO_URI: 'mongodb://localhost:27017/samarthya',
|
|
105
120
|
JWT_SECRET: 'samarthya_secret_key_change_in_production',
|
|
106
121
|
NODE_ENV: 'production',
|
|
107
122
|
CORS_ORIGIN: 'http://localhost:5000',
|
|
@@ -109,7 +124,9 @@ switch (command) {
|
|
|
109
124
|
ACTIVE_PROVIDER: activeProvider,
|
|
110
125
|
ACTIVE_MODEL: activeProvider === 'gemini' ? 'gemini-2.5-flash' : '',
|
|
111
126
|
OLLAMA_URL: 'http://localhost:11434',
|
|
112
|
-
OLLAMA_MODEL: 'dolphin3:8b-llama3.1-q4_K_M'
|
|
127
|
+
OLLAMA_MODEL: 'dolphin3:8b-llama3.1-q4_K_M',
|
|
128
|
+
RESTRICT_TO_WORKSPACE: 'true',
|
|
129
|
+
HEARTBEAT_INTERVAL: '30'
|
|
113
130
|
};
|
|
114
131
|
}
|
|
115
132
|
|
|
@@ -121,7 +138,20 @@ switch (command) {
|
|
|
121
138
|
if (anthropicKey.trim()) envVars['ANTHROPIC_API_KEY'] = anthropicKey.trim();
|
|
122
139
|
if (groqKey.trim()) envVars['GROQ_API_KEY'] = groqKey.trim();
|
|
123
140
|
if (openAiKey.trim()) envVars['OPENAI_API_KEY'] = openAiKey.trim();
|
|
141
|
+
if (deepseekKey.trim()) envVars['DEEPSEEK_API_KEY'] = deepseekKey.trim();
|
|
142
|
+
if (qwenKey.trim()) envVars['QWEN_API_KEY'] = qwenKey.trim();
|
|
143
|
+
if (openrouterKey.trim()) envVars['OPENROUTER_API_KEY'] = openrouterKey.trim();
|
|
124
144
|
if (telegramToken.trim()) envVars['TELEGRAM_BOT_TOKEN'] = telegramToken.trim();
|
|
145
|
+
if (discordToken.trim()) envVars['DISCORD_BOT_TOKEN'] = discordToken.trim();
|
|
146
|
+
|
|
147
|
+
// Auto-generate encryption key if not provided
|
|
148
|
+
if (encKey.trim()) {
|
|
149
|
+
envVars['MEMORY_ENCRYPTION_KEY'] = encKey.trim();
|
|
150
|
+
} else if (!envVars['MEMORY_ENCRYPTION_KEY']) {
|
|
151
|
+
const crypto = require('crypto');
|
|
152
|
+
envVars['MEMORY_ENCRYPTION_KEY'] = crypto.randomBytes(16).toString('hex');
|
|
153
|
+
console.log('š Auto-generated encryption key.');
|
|
154
|
+
}
|
|
125
155
|
|
|
126
156
|
if (!envVars['GEMINI_API_KEY']) envVars['GEMINI_API_KEY'] = 'dummy';
|
|
127
157
|
|
|
@@ -130,14 +160,67 @@ switch (command) {
|
|
|
130
160
|
fs.writeFileSync(envPath, newEnvContent);
|
|
131
161
|
console.log('\nā
Keys saved to .env file securely.');
|
|
132
162
|
|
|
133
|
-
console.log('š¦ Installing backend dependencies
|
|
163
|
+
console.log('š¦ Installing backend dependencies...');
|
|
134
164
|
try {
|
|
135
165
|
execSync('npm install --production', { cwd: backendDir, stdio: 'ignore' });
|
|
136
166
|
} catch (e) { /* ignore */ }
|
|
137
167
|
|
|
138
|
-
console.log('\n⨠Onboarding complete! Run "samarthya gateway" to start your AI Operator.');
|
|
139
168
|
rl.close();
|
|
140
|
-
|
|
169
|
+
|
|
170
|
+
// āāāāāāā AUTO-START: Gateway + Tunnel in one command āāāāāāā
|
|
171
|
+
console.log('\nš Starting SamarthyaBot Gateway...');
|
|
172
|
+
|
|
173
|
+
// Load the .env we just wrote
|
|
174
|
+
try { require('dotenv').config({ path: envPath }); } catch (e) { }
|
|
175
|
+
|
|
176
|
+
const gatewayChild = spawn('node', ['server.js'], {
|
|
177
|
+
cwd: backendDir,
|
|
178
|
+
stdio: 'inherit'
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
gatewayChild.on('close', (code) => {
|
|
182
|
+
console.log(`Gateway exited with code ${code}`);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// Wait for server to boot, then start tunnel
|
|
186
|
+
setTimeout(() => {
|
|
187
|
+
if (envVars['TELEGRAM_BOT_TOKEN'] && envVars['TELEGRAM_BOT_TOKEN'] !== 'dummy') {
|
|
188
|
+
console.log('\nš Auto-starting tunnel for Telegram webhook...');
|
|
189
|
+
const isWin = process.platform === 'win32';
|
|
190
|
+
const tunnelChild = spawn('npm', ['exec', 'localtunnel', '--', '--port', '5000'], {
|
|
191
|
+
stdio: 'pipe',
|
|
192
|
+
shell: isWin
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
tunnelChild.stdout.on('data', async (data) => {
|
|
196
|
+
const output = data.toString();
|
|
197
|
+
console.log(output.trim());
|
|
198
|
+
const match = output.match(/your url is: (https:\/\/.+)/);
|
|
199
|
+
if (match && match[1]) {
|
|
200
|
+
const publicUrl = match[1];
|
|
201
|
+
console.log(`\nā
Public Gateway URL: ${publicUrl}`);
|
|
202
|
+
if (envVars['TELEGRAM_BOT_TOKEN']) {
|
|
203
|
+
try {
|
|
204
|
+
const tgUrl = `https://api.telegram.org/bot${envVars['TELEGRAM_BOT_TOKEN']}/setWebhook?url=${publicUrl}/api/telegram/webhook`;
|
|
205
|
+
const res = await fetch(tgUrl);
|
|
206
|
+
const result = await res.json();
|
|
207
|
+
if (result.ok) console.log('š¢ Telegram Webhook Set!');
|
|
208
|
+
else console.log('š“ Telegram Webhook failed:', result.description);
|
|
209
|
+
} catch (err) {
|
|
210
|
+
console.log('š“ Webhook error:', err.message);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
tunnelChild.stderr.on('data', (data) => console.error('Tunnel:', data.toString()));
|
|
217
|
+
} else {
|
|
218
|
+
console.log('\nā
Gateway is running! Open http://localhost:5000');
|
|
219
|
+
console.log('ā¹ļø No Telegram token found ā skipping tunnel. Run "samarthya tunnel" later if needed.');
|
|
220
|
+
}
|
|
221
|
+
}, 3000);
|
|
222
|
+
|
|
223
|
+
// Don't exit ā keep process alive
|
|
141
224
|
})();
|
|
142
225
|
break;
|
|
143
226
|
|
|
@@ -152,10 +235,13 @@ switch (command) {
|
|
|
152
235
|
console.log(" 2) Anthropic Claude");
|
|
153
236
|
console.log(" 3) Groq (Fastest)");
|
|
154
237
|
console.log(" 4) OpenAI");
|
|
155
|
-
console.log(" 5)
|
|
156
|
-
console.log(" 6)
|
|
238
|
+
console.log(" 5) DeepSeek");
|
|
239
|
+
console.log(" 6) Qwen (Alibaba)");
|
|
240
|
+
console.log(" 7) OpenRouter (100+ models)");
|
|
241
|
+
console.log(" 8) Local Ollama (Offline)");
|
|
242
|
+
console.log(" 9) Mistral AI\n");
|
|
157
243
|
|
|
158
|
-
let pRaw = await qModel("Enter choice (1-
|
|
244
|
+
let pRaw = await qModel("Enter choice (1-9, default 1): ");
|
|
159
245
|
let aProv = 'gemini';
|
|
160
246
|
let uOll = 'false';
|
|
161
247
|
|
|
@@ -163,8 +249,11 @@ switch (command) {
|
|
|
163
249
|
case '2': aProv = 'anthropic'; break;
|
|
164
250
|
case '3': aProv = 'groq'; break;
|
|
165
251
|
case '4': aProv = 'openai'; break;
|
|
166
|
-
case '5': aProv = '
|
|
167
|
-
case '6': aProv = '
|
|
252
|
+
case '5': aProv = 'deepseek'; break;
|
|
253
|
+
case '6': aProv = 'qwen'; break;
|
|
254
|
+
case '7': aProv = 'openrouter'; break;
|
|
255
|
+
case '8': aProv = 'ollama'; uOll = 'true'; break;
|
|
256
|
+
case '9': aProv = 'mistral'; break;
|
|
168
257
|
default: aProv = 'gemini'; break;
|
|
169
258
|
}
|
|
170
259
|
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"puppeteer-core": "^24.37.5",
|
|
27
27
|
"screenshot-desktop": "^1.15.3",
|
|
28
28
|
"socket.io": "^4.8.3",
|
|
29
|
-
"uuid": "^13.0.0"
|
|
29
|
+
"uuid": "^13.0.0",
|
|
30
|
+
"ws": "^8.19.0"
|
|
30
31
|
},
|
|
31
32
|
"bin": {
|
|
32
33
|
"samarthya": "bin/samarthya.js",
|
|
@@ -1041,6 +1042,27 @@
|
|
|
1041
1042
|
"node": ">= 0.6"
|
|
1042
1043
|
}
|
|
1043
1044
|
},
|
|
1045
|
+
"node_modules/engine.io/node_modules/ws": {
|
|
1046
|
+
"version": "8.18.3",
|
|
1047
|
+
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
|
|
1048
|
+
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
|
|
1049
|
+
"license": "MIT",
|
|
1050
|
+
"engines": {
|
|
1051
|
+
"node": ">=10.0.0"
|
|
1052
|
+
},
|
|
1053
|
+
"peerDependencies": {
|
|
1054
|
+
"bufferutil": "^4.0.1",
|
|
1055
|
+
"utf-8-validate": ">=5.0.2"
|
|
1056
|
+
},
|
|
1057
|
+
"peerDependenciesMeta": {
|
|
1058
|
+
"bufferutil": {
|
|
1059
|
+
"optional": true
|
|
1060
|
+
},
|
|
1061
|
+
"utf-8-validate": {
|
|
1062
|
+
"optional": true
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
},
|
|
1044
1066
|
"node_modules/es-define-property": {
|
|
1045
1067
|
"version": "1.0.1",
|
|
1046
1068
|
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
|
@@ -2643,27 +2665,6 @@
|
|
|
2643
2665
|
"node": ">=18"
|
|
2644
2666
|
}
|
|
2645
2667
|
},
|
|
2646
|
-
"node_modules/puppeteer-core/node_modules/ws": {
|
|
2647
|
-
"version": "8.19.0",
|
|
2648
|
-
"resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
|
|
2649
|
-
"integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
|
|
2650
|
-
"license": "MIT",
|
|
2651
|
-
"engines": {
|
|
2652
|
-
"node": ">=10.0.0"
|
|
2653
|
-
},
|
|
2654
|
-
"peerDependencies": {
|
|
2655
|
-
"bufferutil": "^4.0.1",
|
|
2656
|
-
"utf-8-validate": ">=5.0.2"
|
|
2657
|
-
},
|
|
2658
|
-
"peerDependenciesMeta": {
|
|
2659
|
-
"bufferutil": {
|
|
2660
|
-
"optional": true
|
|
2661
|
-
},
|
|
2662
|
-
"utf-8-validate": {
|
|
2663
|
-
"optional": true
|
|
2664
|
-
}
|
|
2665
|
-
}
|
|
2666
|
-
},
|
|
2667
2668
|
"node_modules/qs": {
|
|
2668
2669
|
"version": "6.15.0",
|
|
2669
2670
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz",
|
|
@@ -3031,6 +3032,27 @@
|
|
|
3031
3032
|
"ws": "~8.18.3"
|
|
3032
3033
|
}
|
|
3033
3034
|
},
|
|
3035
|
+
"node_modules/socket.io-adapter/node_modules/ws": {
|
|
3036
|
+
"version": "8.18.3",
|
|
3037
|
+
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
|
|
3038
|
+
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
|
|
3039
|
+
"license": "MIT",
|
|
3040
|
+
"engines": {
|
|
3041
|
+
"node": ">=10.0.0"
|
|
3042
|
+
},
|
|
3043
|
+
"peerDependencies": {
|
|
3044
|
+
"bufferutil": "^4.0.1",
|
|
3045
|
+
"utf-8-validate": ">=5.0.2"
|
|
3046
|
+
},
|
|
3047
|
+
"peerDependenciesMeta": {
|
|
3048
|
+
"bufferutil": {
|
|
3049
|
+
"optional": true
|
|
3050
|
+
},
|
|
3051
|
+
"utf-8-validate": {
|
|
3052
|
+
"optional": true
|
|
3053
|
+
}
|
|
3054
|
+
}
|
|
3055
|
+
},
|
|
3034
3056
|
"node_modules/socket.io-parser": {
|
|
3035
3057
|
"version": "4.2.5",
|
|
3036
3058
|
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.5.tgz",
|
|
@@ -3646,9 +3668,9 @@
|
|
|
3646
3668
|
"license": "ISC"
|
|
3647
3669
|
},
|
|
3648
3670
|
"node_modules/ws": {
|
|
3649
|
-
"version": "8.
|
|
3650
|
-
"resolved": "https://registry.npmjs.org/ws/-/ws-8.
|
|
3651
|
-
"integrity": "sha512-
|
|
3671
|
+
"version": "8.19.0",
|
|
3672
|
+
"resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
|
|
3673
|
+
"integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
|
|
3652
3674
|
"license": "MIT",
|
|
3653
3675
|
"engines": {
|
|
3654
3676
|
"node": ">=10.0.0"
|
package/backend/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "samarthya-agent",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"main": "server.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"samarthya": "./bin/samarthya.js",
|
|
@@ -33,9 +33,10 @@
|
|
|
33
33
|
"puppeteer-core": "^24.37.5",
|
|
34
34
|
"screenshot-desktop": "^1.15.3",
|
|
35
35
|
"socket.io": "^4.8.3",
|
|
36
|
-
"uuid": "^13.0.0"
|
|
36
|
+
"uuid": "^13.0.0",
|
|
37
|
+
"ws": "^8.19.0"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
40
|
"nodemon": "^3.1.14"
|
|
40
41
|
}
|
|
41
|
-
}
|
|
42
|
+
}
|