openkbs 0.0.66 → 0.0.70
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 +1 -0
- package/elastic/README.md +1 -1
- package/elastic/functions.md +5 -5
- package/elastic/pulse.md +2 -2
- package/package.json +2 -2
- package/scripts/deploy.js +68 -0
- package/src/actions.js +59 -0
- package/src/index.js +8 -6
- package/templates/.claude/skills/openkbs/SKILL.md +37 -8
- package/templates/.claude/skills/openkbs/examples/monitoring-bot/README.md +55 -0
- package/templates/.claude/skills/openkbs/examples/monitoring-bot/app/instructions.txt +40 -0
- package/templates/.claude/skills/openkbs/examples/monitoring-bot/app/settings.json +41 -0
- package/templates/.claude/skills/openkbs/examples/monitoring-bot/openkbs.json +3 -0
- package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Events/actions.js +141 -0
- package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Events/handler.js +32 -0
- package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Events/memoryHelpers.js +91 -0
- package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Events/onCronjob.js +105 -0
- package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Events/onPublicAPIRequest.js +165 -0
- package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Events/onRequest.js +2 -0
- package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Events/onResponse.js +2 -0
- package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Frontend/contentRender.js +74 -0
- package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Frontend/contentRender.json +3 -0
- package/templates/.claude/skills/openkbs/examples/nodejs-demo/functions/auth/index.mjs +228 -0
- package/templates/.claude/skills/openkbs/examples/nodejs-demo/functions/auth/package.json +7 -0
- package/templates/.claude/skills/openkbs/examples/nodejs-demo/functions/posts/index.mjs +287 -0
- package/templates/.claude/skills/openkbs/examples/nodejs-demo/functions/posts/package.json +10 -0
- package/templates/.claude/skills/openkbs/examples/nodejs-demo/functions/settings.json +4 -0
- package/templates/.claude/skills/openkbs/examples/nodejs-demo/openkbs.json +16 -0
- package/templates/.claude/skills/openkbs/examples/nodejs-demo/site/index.html +658 -0
- package/templates/.claude/skills/openkbs/examples/nodejs-demo/site/settings.json +4 -0
- package/templates/.claude/skills/openkbs/patterns/cronjob-batch-processing.md +278 -0
- package/templates/.claude/skills/openkbs/patterns/cronjob-monitoring.md +341 -0
- package/templates/.claude/skills/openkbs/patterns/file-upload.md +205 -0
- package/templates/.claude/skills/openkbs/patterns/image-generation.md +139 -0
- package/templates/.claude/skills/openkbs/patterns/memory-system.md +264 -0
- package/templates/.claude/skills/openkbs/patterns/public-api-item-proxy.md +254 -0
- package/templates/.claude/skills/openkbs/patterns/scheduled-tasks.md +157 -0
- package/templates/.claude/skills/openkbs/patterns/telegram-webhook.md +424 -0
- package/templates/.claude/skills/openkbs/patterns/telegram.md +222 -0
- package/templates/.claude/skills/openkbs/patterns/vectordb-archive.md +231 -0
- package/templates/.claude/skills/openkbs/patterns/video-generation.md +145 -0
- package/templates/.claude/skills/openkbs/patterns/web-publishing.md +257 -0
- package/templates/.claude/skills/openkbs/reference/backend-sdk.md +13 -2
- package/templates/.claude/skills/openkbs/reference/elastic-services.md +61 -29
- package/templates/platform/README.md +35 -0
- package/templates/platform/agents/assistant/app/icon.png +0 -0
- package/templates/platform/agents/assistant/app/instructions.txt +13 -0
- package/templates/platform/agents/assistant/app/settings.json +13 -0
- package/templates/platform/agents/assistant/src/Events/actions.js +50 -0
- package/templates/platform/agents/assistant/src/Events/handler.js +54 -0
- package/templates/platform/agents/assistant/src/Events/onRequest.js +3 -0
- package/templates/platform/agents/assistant/src/Events/onRequest.json +5 -0
- package/templates/platform/agents/assistant/src/Events/onResponse.js +3 -0
- package/templates/platform/agents/assistant/src/Events/onResponse.json +5 -0
- package/templates/platform/agents/assistant/src/Frontend/contentRender.js +27 -0
- package/templates/platform/agents/assistant/src/Frontend/contentRender.json +10 -0
- package/templates/platform/functions/api/index.mjs +63 -0
- package/templates/platform/functions/api/package.json +4 -0
- package/templates/platform/openkbs.json +19 -0
- package/templates/platform/site/index.html +75 -0
- package/version.json +3 -3
- package/templates/.claude/skills/openkbs/examples/ai-copywriter-agent/scripts/run_job.js +0 -26
- package/templates/.claude/skills/openkbs/examples/ai-copywriter-agent/scripts/utils/agent_client.js +0 -265
package/README.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# OpenKBS · [](https://github.com/open-kbs/openkbs-chat/blob/main/LICENSE) [](https://www.npmjs.com/package/openkbs)
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
OpenKBS is an extendable AI service designed to build,
|
|
4
5
|
deploy and integrate AI agents and applications.
|
|
5
6
|
|
package/elastic/README.md
CHANGED
package/elastic/functions.md
CHANGED
|
@@ -131,7 +131,7 @@ cd functions/api && npm install && cd ../..
|
|
|
131
131
|
openkbs fn push api
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
-
Your function is live at `https://
|
|
134
|
+
Your function is live at `https://yourdomain.com/api`.
|
|
135
135
|
|
|
136
136
|
## Test Your Function
|
|
137
137
|
|
|
@@ -157,7 +157,7 @@ console.log(data); // { message: "Hello, OpenKBS!" }
|
|
|
157
157
|
### With curl
|
|
158
158
|
|
|
159
159
|
```bash
|
|
160
|
-
curl -X POST https://
|
|
160
|
+
curl -X POST https://yourdomain.com/api \
|
|
161
161
|
-H "Content-Type: application/json" \
|
|
162
162
|
-d '{"action":"hello","name":"OpenKBS"}'
|
|
163
163
|
```
|
|
@@ -286,9 +286,9 @@ openkbs fn list
|
|
|
286
286
|
Output:
|
|
287
287
|
```
|
|
288
288
|
Functions:
|
|
289
|
-
api 128MB 30s https://
|
|
290
|
-
auth 256MB 30s https://
|
|
291
|
-
posts 512MB 60s https://
|
|
289
|
+
api 128MB 30s https://yourdomain.com/api
|
|
290
|
+
auth 256MB 30s https://yourdomain.com/auth
|
|
291
|
+
posts 512MB 60s https://yourdomain.com/posts
|
|
292
292
|
```
|
|
293
293
|
|
|
294
294
|
## Delete Function
|
package/elastic/pulse.md
CHANGED
|
@@ -34,7 +34,7 @@ openkbs pulse enable
|
|
|
34
34
|
### Install
|
|
35
35
|
|
|
36
36
|
```html
|
|
37
|
-
<script src="https://unpkg.com/openkbs-pulse
|
|
37
|
+
<script src="https://unpkg.com/openkbs-pulse/pulse.js"></script>
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
Or with npm:
|
|
@@ -263,7 +263,7 @@ export async function handler(event) {
|
|
|
263
263
|
<html>
|
|
264
264
|
<head>
|
|
265
265
|
<title>Live Posts</title>
|
|
266
|
-
<script src="https://unpkg.com/openkbs-pulse
|
|
266
|
+
<script src="https://unpkg.com/openkbs-pulse/pulse.js"></script>
|
|
267
267
|
</head>
|
|
268
268
|
<body>
|
|
269
269
|
<div id="online">Online: 0</div>
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openkbs",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.70",
|
|
4
4
|
"description": "OpenKBS - Command Line Interface",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "pkg .",
|
|
8
|
-
"deploy": "
|
|
8
|
+
"deploy": "node scripts/deploy.js",
|
|
9
9
|
"deploy:linux": "aws s3 cp build/openkbs-linux-x64 s3://openkbs-downloads/cli/linux/openkbs && aws s3 cp build/openkbs-linux-arm64 s3://openkbs-downloads/cli/linux/openkbs-arm64",
|
|
10
10
|
"deploy:macos": "aws s3 cp build/openkbs-macos-arm64 s3://openkbs-downloads/cli/macos/openkbs && aws s3 cp build/openkbs-macos-x64 s3://openkbs-downloads/cli/macos/openkbs-x64",
|
|
11
11
|
"deploy:win": "aws s3 cp build/openkbs-win-x64.exe s3://openkbs-downloads/cli/windows/openkbs.exe && aws s3 cp build/openkbs-win-arm64.exe s3://openkbs-downloads/cli/windows/openkbs-arm64.exe",
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const { execSync } = require('child_process');
|
|
2
|
+
const readline = require('readline');
|
|
3
|
+
|
|
4
|
+
function askOTP() {
|
|
5
|
+
return new Promise((resolve) => {
|
|
6
|
+
const rl = readline.createInterface({
|
|
7
|
+
input: process.stdin,
|
|
8
|
+
output: process.stdout
|
|
9
|
+
});
|
|
10
|
+
rl.question('Enter NPM OTP code: ', (otp) => {
|
|
11
|
+
rl.close();
|
|
12
|
+
resolve(otp?.trim() || '');
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function deploy() {
|
|
18
|
+
try {
|
|
19
|
+
// Check npm login status
|
|
20
|
+
console.log('\n🔐 Checking npm login...');
|
|
21
|
+
try {
|
|
22
|
+
execSync('npm whoami', { stdio: 'pipe' });
|
|
23
|
+
console.log('✓ Logged in to npm');
|
|
24
|
+
} catch {
|
|
25
|
+
console.log('Not logged in. Please login to npm:');
|
|
26
|
+
execSync('npm login', { stdio: 'inherit' });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Version bump
|
|
30
|
+
console.log('\n📦 Bumping version...');
|
|
31
|
+
execSync('npm version patch --no-git-tag-version', { stdio: 'inherit' });
|
|
32
|
+
|
|
33
|
+
// Build
|
|
34
|
+
console.log('\n🔨 Building...');
|
|
35
|
+
execSync('npm run build', { stdio: 'inherit' });
|
|
36
|
+
|
|
37
|
+
// Deploy binaries
|
|
38
|
+
console.log('\n☁️ Deploying binaries...');
|
|
39
|
+
execSync('npm run deploy:linux', { stdio: 'inherit' });
|
|
40
|
+
execSync('npm run deploy:macos', { stdio: 'inherit' });
|
|
41
|
+
execSync('npm run deploy:win', { stdio: 'inherit' });
|
|
42
|
+
|
|
43
|
+
// Deploy templates
|
|
44
|
+
console.log('\n📄 Deploying templates...');
|
|
45
|
+
execSync('npm run deploy:templates', { stdio: 'inherit' });
|
|
46
|
+
|
|
47
|
+
// Deploy version
|
|
48
|
+
console.log('\n🏷️ Deploying version...');
|
|
49
|
+
execSync('npm run deploy:version', { stdio: 'inherit' });
|
|
50
|
+
|
|
51
|
+
// Ask for OTP right before publish
|
|
52
|
+
console.log('\n🚀 Ready to publish to npm...');
|
|
53
|
+
const otp = await askOTP();
|
|
54
|
+
|
|
55
|
+
if (otp) {
|
|
56
|
+
execSync(`npm publish --otp=${otp}`, { stdio: 'inherit' });
|
|
57
|
+
console.log('\n✅ Deploy complete!');
|
|
58
|
+
} else {
|
|
59
|
+
console.log('\n⚠️ Skipped npm publish (no OTP provided)');
|
|
60
|
+
console.log('✅ S3 deploy complete!');
|
|
61
|
+
}
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.error('\n❌ Deploy failed:', error.message);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
deploy();
|
package/src/actions.js
CHANGED
|
@@ -2413,6 +2413,14 @@ async function elasticStatusAction() {
|
|
|
2413
2413
|
*/
|
|
2414
2414
|
async function stackAction(subCommand, args = []) {
|
|
2415
2415
|
switch (subCommand) {
|
|
2416
|
+
case 'create':
|
|
2417
|
+
const stackName = args[0];
|
|
2418
|
+
if (!stackName) {
|
|
2419
|
+
console.red('Error: Stack name is required');
|
|
2420
|
+
console.log('Usage: openkbs stack create <name>');
|
|
2421
|
+
process.exit(1);
|
|
2422
|
+
}
|
|
2423
|
+
return await stackCreateAction(stackName);
|
|
2416
2424
|
case 'deploy':
|
|
2417
2425
|
return await elasticDeployAction();
|
|
2418
2426
|
case 'destroy':
|
|
@@ -2425,10 +2433,61 @@ async function stackAction(subCommand, args = []) {
|
|
|
2425
2433
|
console.log('Commands:');
|
|
2426
2434
|
console.log(' deploy Deploy all resources from openkbs.json');
|
|
2427
2435
|
console.log(' destroy Delete all resources (DANGEROUS)');
|
|
2436
|
+
console.log(' create Create new platform stack');
|
|
2428
2437
|
console.log(' status Show status of all resources');
|
|
2429
2438
|
}
|
|
2430
2439
|
}
|
|
2431
2440
|
|
|
2441
|
+
/**
|
|
2442
|
+
* Create a new platform stack from template
|
|
2443
|
+
*/
|
|
2444
|
+
async function stackCreateAction(name) {
|
|
2445
|
+
try {
|
|
2446
|
+
// Download templates from S3 first
|
|
2447
|
+
await downloadTemplates();
|
|
2448
|
+
|
|
2449
|
+
const platformTemplateDir = path.join(TEMPLATE_DIR, 'platform');
|
|
2450
|
+
const targetDir = path.join(process.cwd(), name);
|
|
2451
|
+
|
|
2452
|
+
if (!fs.existsSync(platformTemplateDir)) {
|
|
2453
|
+
console.red('Error: Platform template not found. Run "openkbs update" first.');
|
|
2454
|
+
process.exit(1);
|
|
2455
|
+
}
|
|
2456
|
+
|
|
2457
|
+
if (fs.existsSync(targetDir)) {
|
|
2458
|
+
console.red(`Error: Directory ${name} already exists.`);
|
|
2459
|
+
process.exit(1);
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2462
|
+
// Copy platform template
|
|
2463
|
+
fs.copySync(platformTemplateDir, targetDir);
|
|
2464
|
+
|
|
2465
|
+
// Copy .claude folder with skills
|
|
2466
|
+
const claudeTemplateDir = path.join(TEMPLATE_DIR, '.claude');
|
|
2467
|
+
const claudeTargetDir = path.join(targetDir, '.claude');
|
|
2468
|
+
if (fs.existsSync(claudeTemplateDir)) {
|
|
2469
|
+
fs.copySync(claudeTemplateDir, claudeTargetDir);
|
|
2470
|
+
}
|
|
2471
|
+
|
|
2472
|
+
// Replace placeholders in all files
|
|
2473
|
+
replacePlaceholderInFiles(targetDir, name);
|
|
2474
|
+
|
|
2475
|
+
console.green(`\nPlatform stack "${name}" created successfully!\n`);
|
|
2476
|
+
console.log('Structure:');
|
|
2477
|
+
console.log(` ${name}/`);
|
|
2478
|
+
console.log(' ├── agents/ # AI agents (each with app/ and src/)');
|
|
2479
|
+
console.log(' ├── functions/ # Serverless Lambda functions');
|
|
2480
|
+
console.log(' ├── site/ # Static site for whitelabel');
|
|
2481
|
+
console.log(' └── openkbs.json # Elastic services config\n');
|
|
2482
|
+
console.log('Next steps:');
|
|
2483
|
+
console.log(` cd ${name}`);
|
|
2484
|
+
console.log(' openkbs deploy # Deploy elastic services');
|
|
2485
|
+
console.log(' openkbs fn push api # Deploy the API function');
|
|
2486
|
+
} catch (error) {
|
|
2487
|
+
console.red(`Error during stack create:`, error.message);
|
|
2488
|
+
}
|
|
2489
|
+
}
|
|
2490
|
+
|
|
2432
2491
|
module.exports = {
|
|
2433
2492
|
signAction,
|
|
2434
2493
|
loginAction,
|
package/src/index.js
CHANGED
|
@@ -143,16 +143,18 @@ Reads openkbs.json and deletes:
|
|
|
143
143
|
`);
|
|
144
144
|
|
|
145
145
|
program
|
|
146
|
-
.command('stack <subcommand>')
|
|
147
|
-
.description('Manage stack resources (deploy, destroy, status)')
|
|
148
|
-
.action((subCommand) => stackAction(subCommand))
|
|
146
|
+
.command('stack <subcommand> [args...]')
|
|
147
|
+
.description('Manage stack resources (create, deploy, destroy, status)')
|
|
148
|
+
.action((subCommand, args) => stackAction(subCommand, args))
|
|
149
149
|
.addHelpText('after', `
|
|
150
150
|
Commands:
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
151
|
+
create <name> Create new platform stack from template
|
|
152
|
+
deploy Deploy all resources from openkbs.json
|
|
153
|
+
destroy Delete all resources (DANGEROUS)
|
|
154
|
+
status Show status of all resources
|
|
154
155
|
|
|
155
156
|
Examples:
|
|
157
|
+
$ openkbs stack create my-platform
|
|
156
158
|
$ openkbs stack deploy
|
|
157
159
|
$ openkbs stack status
|
|
158
160
|
$ openkbs stack destroy
|
|
@@ -32,7 +32,7 @@ Platform mode extends agent capabilities with:
|
|
|
32
32
|
- **Elastic Pulse**: Real-time WebSocket pub/sub
|
|
33
33
|
- **Whitelabel**: Custom domains (`example.com`) with static site (`site/` folder)
|
|
34
34
|
|
|
35
|
-
**Architecture Note**: The whitelabel itself is
|
|
35
|
+
**Architecture Note**: The whitelabel itself is an app with its own `kbId` (a service agent, not user-facing). This "parent" kbId is used throughout the stack for elastic services. Each agent in `agents/` has its own separate `kbId`.
|
|
36
36
|
|
|
37
37
|
## Project Structure
|
|
38
38
|
|
|
@@ -52,7 +52,7 @@ my-agent/
|
|
|
52
52
|
│ └── Frontend/
|
|
53
53
|
│ ├── contentRender.js # Custom React UI
|
|
54
54
|
│ └── contentRender.json # Frontend dependencies
|
|
55
|
-
|
|
55
|
+
│
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
### Platform Structure
|
|
@@ -89,7 +89,7 @@ my-platform/
|
|
|
89
89
|
"storage": true,
|
|
90
90
|
"pulse": true,
|
|
91
91
|
"functions": {
|
|
92
|
-
"api": { "runtime": "
|
|
92
|
+
"api": { "runtime": "nodejs24.x", "memory": 512 }
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -177,8 +177,37 @@ Priority items are auto-injected into LLM context.
|
|
|
177
177
|
|
|
178
178
|
## Additional Resources
|
|
179
179
|
|
|
180
|
-
|
|
181
|
-
-
|
|
182
|
-
-
|
|
183
|
-
-
|
|
184
|
-
-
|
|
180
|
+
### Reference Documentation
|
|
181
|
+
- [reference/backend-sdk.md](reference/backend-sdk.md) - Backend SDK methods (openkbs.*)
|
|
182
|
+
- [reference/frontend-sdk.md](reference/frontend-sdk.md) - Frontend React patterns
|
|
183
|
+
- [reference/commands.md](reference/commands.md) - XML command definitions
|
|
184
|
+
- [reference/elastic-services.md](reference/elastic-services.md) - Functions, Postgres, Storage, Pulse
|
|
185
|
+
|
|
186
|
+
### Ready-to-Use Patterns
|
|
187
|
+
Production-tested code blocks for common tasks:
|
|
188
|
+
|
|
189
|
+
**Content & Media:**
|
|
190
|
+
- [patterns/image-generation.md](patterns/image-generation.md) - AI image generation with upload
|
|
191
|
+
- [patterns/video-generation.md](patterns/video-generation.md) - Async video generation with polling
|
|
192
|
+
- [patterns/file-upload.md](patterns/file-upload.md) - Presigned URL file uploads
|
|
193
|
+
- [patterns/web-publishing.md](patterns/web-publishing.md) - HTML page publishing
|
|
194
|
+
|
|
195
|
+
**Memory & Storage:**
|
|
196
|
+
- [patterns/memory-system.md](patterns/memory-system.md) - Memory CRUD with settings.json config
|
|
197
|
+
- [patterns/vectordb-archive.md](patterns/vectordb-archive.md) - Long-term archive with semantic search
|
|
198
|
+
|
|
199
|
+
**Scheduling & Automation:**
|
|
200
|
+
- [patterns/scheduled-tasks.md](patterns/scheduled-tasks.md) - Task scheduling (one-time & recurring)
|
|
201
|
+
- [patterns/cronjob-batch-processing.md](patterns/cronjob-batch-processing.md) - Batch file processing with state
|
|
202
|
+
- [patterns/cronjob-monitoring.md](patterns/cronjob-monitoring.md) - Continuous monitoring with pulse control
|
|
203
|
+
|
|
204
|
+
**External Integrations:**
|
|
205
|
+
- [patterns/telegram.md](patterns/telegram.md) - Telegram bot commands (send messages)
|
|
206
|
+
- [patterns/telegram-webhook.md](patterns/telegram-webhook.md) - Telegram webhook (receive messages)
|
|
207
|
+
- [patterns/public-api-item-proxy.md](patterns/public-api-item-proxy.md) - Public API with geolocation
|
|
208
|
+
|
|
209
|
+
### Complete Examples
|
|
210
|
+
- [examples/ai-copywriter-agent/](examples/ai-copywriter-agent/) - Content generation agent
|
|
211
|
+
- [examples/ai-marketing-agent/](examples/ai-marketing-agent/) - Marketing automation agent
|
|
212
|
+
- [examples/monitoring-bot/](examples/monitoring-bot/) - Cronjob + Telegram monitoring agent
|
|
213
|
+
- [examples/nodejs-demo/](examples/nodejs-demo/) - Platform with elastic functions
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Monitoring Bot Example
|
|
2
|
+
|
|
3
|
+
A simplified monitoring agent that demonstrates:
|
|
4
|
+
- **Cronjob** with pulse interval control
|
|
5
|
+
- **Telegram webhook** integration
|
|
6
|
+
- **Memory system** with reference images
|
|
7
|
+
- **Weather API** integration
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Monitors external data sources every N minutes
|
|
12
|
+
- Receives commands via Telegram
|
|
13
|
+
- Stores reference images for comparison
|
|
14
|
+
- Hibernation/sleep mode
|
|
15
|
+
- Weather data injection
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
cd monitoring-bot
|
|
21
|
+
openkbs push
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Then setup Telegram webhook:
|
|
25
|
+
```
|
|
26
|
+
https://chat.openkbs.com/publicAPIRequest?kbId=YOUR_KB_ID&setupTelegramWebhook=true
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## File Structure
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
monitoring-bot/
|
|
33
|
+
├── app/
|
|
34
|
+
│ ├── settings.json # Agent config
|
|
35
|
+
│ └── instructions.txt # System prompt
|
|
36
|
+
├── src/
|
|
37
|
+
│ ├── Events/
|
|
38
|
+
│ │ ├── actions.js # Command handlers
|
|
39
|
+
│ │ ├── onCronjob.js # Scheduled monitoring
|
|
40
|
+
│ │ ├── onPublicAPIRequest.js # Telegram webhook
|
|
41
|
+
│ │ ├── memoryHelpers.js # Memory utilities
|
|
42
|
+
│ │ ├── handler.js # Response parser
|
|
43
|
+
│ │ ├── onRequest.js
|
|
44
|
+
│ │ └── onResponse.js
|
|
45
|
+
│ └── Frontend/
|
|
46
|
+
│ └── contentRender.js
|
|
47
|
+
└── openkbs.json
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Commands
|
|
51
|
+
|
|
52
|
+
- `<setMemory>` - Store values
|
|
53
|
+
- `<hibernateAgent>` - Sleep until time
|
|
54
|
+
- `<setAgentSettings>` - Change pulse interval
|
|
55
|
+
- `<sendToTelegramChannel>` - Send messages
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
You are a monitoring assistant that analyzes data from external sources.
|
|
2
|
+
|
|
3
|
+
## Modes
|
|
4
|
+
|
|
5
|
+
### PROCESS_MONITORING_CHECK
|
|
6
|
+
Triggered automatically by cronjob. Analyze the provided data and report findings.
|
|
7
|
+
|
|
8
|
+
### PROCESS_TELEGRAM_MESSAGE
|
|
9
|
+
User message from Telegram. Respond using sendToTelegramChannel command.
|
|
10
|
+
Remember: This chat has no user listening - only output commands!
|
|
11
|
+
|
|
12
|
+
## Commands
|
|
13
|
+
|
|
14
|
+
### Memory
|
|
15
|
+
<setMemory>{"itemId": "memory_xyz", "value": "data", "expirationInMinutes": 60}</setMemory>
|
|
16
|
+
<deleteItem>{"itemId": "memory_xyz"}</deleteItem>
|
|
17
|
+
|
|
18
|
+
### Store reference image
|
|
19
|
+
<setMemory>{
|
|
20
|
+
"itemId": "memory_with_image_description",
|
|
21
|
+
"value": {
|
|
22
|
+
"imageUrl": "https://...",
|
|
23
|
+
"description": "Reference description"
|
|
24
|
+
}
|
|
25
|
+
}</setMemory>
|
|
26
|
+
|
|
27
|
+
### Agent control
|
|
28
|
+
<hibernateAgent>{"hours": 24}</hibernateAgent>
|
|
29
|
+
<hibernateAgent>{"until": "2025-01-15T08:00:00Z"}</hibernateAgent>
|
|
30
|
+
<setAgentSettings>{"pulseInterval": 5}</setAgentSettings>
|
|
31
|
+
<setAgentSettings>{"wakeUp": true}</setAgentSettings>
|
|
32
|
+
|
|
33
|
+
### Communication
|
|
34
|
+
<sendToTelegramChannel>{"message": "*Bold* message"}</sendToTelegramChannel>
|
|
35
|
+
<sendPhotoToTelegramChannel>{"photoUrl": "https://...", "caption": "Caption"}</sendPhotoToTelegramChannel>
|
|
36
|
+
|
|
37
|
+
## Response Format
|
|
38
|
+
|
|
39
|
+
For monitoring checks, provide a brief status report.
|
|
40
|
+
For Telegram messages, respond via sendToTelegramChannel only.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"AIChatModel": "gemini-2.5-pro-preview-05-06",
|
|
3
|
+
"chatVendor": "Google",
|
|
4
|
+
"title": "Monitoring Bot",
|
|
5
|
+
"description": "Automated monitoring agent with Telegram integration",
|
|
6
|
+
"category": "automation",
|
|
7
|
+
"active": true,
|
|
8
|
+
"embeddingModel": "text-embedding-3-large",
|
|
9
|
+
"embeddingDimension": 3072,
|
|
10
|
+
"searchEngine": "VectorDB",
|
|
11
|
+
"itemTypes": {
|
|
12
|
+
"memory": {
|
|
13
|
+
"attributes": [
|
|
14
|
+
{ "attrName": "itemId", "attrType": "itemId", "encrypted": false },
|
|
15
|
+
{ "attrName": "body", "attrType": "body", "encrypted": true }
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
"telegram": {
|
|
19
|
+
"attributes": [
|
|
20
|
+
{ "attrName": "itemId", "attrType": "itemId", "encrypted": false },
|
|
21
|
+
{ "attrName": "body", "attrType": "body", "encrypted": true }
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
"agent": {
|
|
25
|
+
"attributes": [
|
|
26
|
+
{ "attrName": "itemId", "attrType": "itemId", "encrypted": false },
|
|
27
|
+
{ "attrName": "body", "attrType": "body", "encrypted": true }
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"options": {
|
|
32
|
+
"priorityItems": [
|
|
33
|
+
{ "limit": 100, "prefix": "memory" },
|
|
34
|
+
{ "limit": 50, "prefix": "agent" },
|
|
35
|
+
{ "limit": 50, "prefix": "telegram" }
|
|
36
|
+
],
|
|
37
|
+
"vectorDBMaxTokens": 25000,
|
|
38
|
+
"vectorDBTopK": 30,
|
|
39
|
+
"vectorDBMinScore": 90
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { setMemoryValue, deleteItem, setAgentSetting, getAgentSetting } from './memoryHelpers.js';
|
|
2
|
+
|
|
3
|
+
const meta = { _meta_actions: ["REQUEST_CHAT_MODEL"] };
|
|
4
|
+
|
|
5
|
+
const TELEGRAM_BOT_TOKEN = '{{secrets.telegramBotToken}}';
|
|
6
|
+
|
|
7
|
+
async function getTelegramChannelId() {
|
|
8
|
+
const secretsId = '{{secrets.telegramChannelID}}';
|
|
9
|
+
if (secretsId && !secretsId.includes('{{')) return secretsId;
|
|
10
|
+
return await getAgentSetting('agent_telegramChannelID');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default [
|
|
14
|
+
// Set memory
|
|
15
|
+
[/<setMemory>([\s\S]*?)<\/setMemory>/s, async (match) => {
|
|
16
|
+
try {
|
|
17
|
+
const data = JSON.parse(match[1].trim());
|
|
18
|
+
if (!data.itemId?.startsWith('memory_')) {
|
|
19
|
+
return { type: "MEMORY_ERROR", error: "itemId must start with 'memory_'", ...meta };
|
|
20
|
+
}
|
|
21
|
+
await setMemoryValue(data.itemId, data.value, data.expirationInMinutes);
|
|
22
|
+
return { type: "MEMORY_UPDATED", itemId: data.itemId, ...meta };
|
|
23
|
+
} catch (e) {
|
|
24
|
+
return { type: "MEMORY_ERROR", error: e.message, ...meta };
|
|
25
|
+
}
|
|
26
|
+
}],
|
|
27
|
+
|
|
28
|
+
// Delete item
|
|
29
|
+
[/<deleteItem>([\s\S]*?)<\/deleteItem>/s, async (match) => {
|
|
30
|
+
try {
|
|
31
|
+
const data = JSON.parse(match[1].trim());
|
|
32
|
+
await deleteItem(data.itemId);
|
|
33
|
+
return { type: "ITEM_DELETED", itemId: data.itemId, ...meta };
|
|
34
|
+
} catch (e) {
|
|
35
|
+
return { type: "DELETE_ERROR", error: e.message, ...meta };
|
|
36
|
+
}
|
|
37
|
+
}],
|
|
38
|
+
|
|
39
|
+
// Hibernate agent
|
|
40
|
+
[/<hibernateAgent>([\s\S]*?)<\/hibernateAgent>/s, async (match) => {
|
|
41
|
+
try {
|
|
42
|
+
const data = JSON.parse(match[1].trim());
|
|
43
|
+
let sleepUntil;
|
|
44
|
+
|
|
45
|
+
if (data.hours) {
|
|
46
|
+
sleepUntil = new Date(Date.now() + data.hours * 60 * 60 * 1000);
|
|
47
|
+
} else if (data.days) {
|
|
48
|
+
sleepUntil = new Date(Date.now() + data.days * 24 * 60 * 60 * 1000);
|
|
49
|
+
} else if (data.until) {
|
|
50
|
+
sleepUntil = new Date(data.until);
|
|
51
|
+
} else {
|
|
52
|
+
throw new Error('Specify hours, days, or until');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
await setAgentSetting('agent_sleepUntil', sleepUntil.toISOString());
|
|
56
|
+
return { type: "AGENT_HIBERNATING", sleepUntil: sleepUntil.toISOString(), ...meta };
|
|
57
|
+
} catch (e) {
|
|
58
|
+
return { type: "HIBERNATE_ERROR", error: e.message, ...meta };
|
|
59
|
+
}
|
|
60
|
+
}],
|
|
61
|
+
|
|
62
|
+
// Agent settings
|
|
63
|
+
[/<setAgentSettings>([\s\S]*?)<\/setAgentSettings>/s, async (match) => {
|
|
64
|
+
try {
|
|
65
|
+
const data = JSON.parse(match[1].trim());
|
|
66
|
+
|
|
67
|
+
if (data.pulseInterval !== undefined) {
|
|
68
|
+
const interval = Math.max(1, Math.min(60, parseInt(data.pulseInterval)));
|
|
69
|
+
await setAgentSetting('agent_pulseInterval', interval);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (data.wakeUp === true) {
|
|
73
|
+
await setAgentSetting('agent_sleepUntil', null);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return { type: "SETTINGS_UPDATED", settings: data, ...meta };
|
|
77
|
+
} catch (e) {
|
|
78
|
+
return { type: "SETTINGS_ERROR", error: e.message, ...meta };
|
|
79
|
+
}
|
|
80
|
+
}],
|
|
81
|
+
|
|
82
|
+
// Send to Telegram
|
|
83
|
+
[/<sendToTelegramChannel>([\s\S]*?)<\/sendToTelegramChannel>/s, async (match) => {
|
|
84
|
+
try {
|
|
85
|
+
const data = JSON.parse(match[1].trim());
|
|
86
|
+
const channelId = await getTelegramChannelId();
|
|
87
|
+
|
|
88
|
+
if (!channelId) {
|
|
89
|
+
throw new Error('Telegram channel ID not configured');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const response = await axios.post(
|
|
93
|
+
`https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage`,
|
|
94
|
+
{
|
|
95
|
+
chat_id: channelId,
|
|
96
|
+
text: data.message,
|
|
97
|
+
parse_mode: 'Markdown',
|
|
98
|
+
disable_notification: data.silent || false
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
if (!response.data.ok) {
|
|
103
|
+
throw new Error(response.data.description);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return { type: "TELEGRAM_SENT", messageId: response.data.result.message_id, ...meta };
|
|
107
|
+
} catch (e) {
|
|
108
|
+
return { type: "TELEGRAM_ERROR", error: e.message, ...meta };
|
|
109
|
+
}
|
|
110
|
+
}],
|
|
111
|
+
|
|
112
|
+
// Send photo to Telegram
|
|
113
|
+
[/<sendPhotoToTelegramChannel>([\s\S]*?)<\/sendPhotoToTelegramChannel>/s, async (match) => {
|
|
114
|
+
try {
|
|
115
|
+
const data = JSON.parse(match[1].trim());
|
|
116
|
+
const channelId = await getTelegramChannelId();
|
|
117
|
+
|
|
118
|
+
if (!channelId) {
|
|
119
|
+
throw new Error('Telegram channel ID not configured');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const response = await axios.post(
|
|
123
|
+
`https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendPhoto`,
|
|
124
|
+
{
|
|
125
|
+
chat_id: channelId,
|
|
126
|
+
photo: data.photoUrl,
|
|
127
|
+
caption: data.caption || '',
|
|
128
|
+
parse_mode: 'Markdown'
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
if (!response.data.ok) {
|
|
133
|
+
throw new Error(response.data.description);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return { type: "TELEGRAM_PHOTO_SENT", messageId: response.data.result.message_id, ...meta };
|
|
137
|
+
} catch (e) {
|
|
138
|
+
return { type: "TELEGRAM_ERROR", error: e.message, ...meta };
|
|
139
|
+
}
|
|
140
|
+
}]
|
|
141
|
+
];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import actions from './actions.js';
|
|
2
|
+
|
|
3
|
+
export const handler = async (event) => {
|
|
4
|
+
const { text } = event.payload;
|
|
5
|
+
const results = [];
|
|
6
|
+
|
|
7
|
+
// Match all commands in parallel
|
|
8
|
+
const matchPromises = actions.map(async ([regex, handler]) => {
|
|
9
|
+
const matches = [...text.matchAll(new RegExp(regex.source, regex.flags + 'g'))];
|
|
10
|
+
return Promise.all(matches.map(match => handler(match)));
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const allResults = await Promise.all(matchPromises);
|
|
14
|
+
|
|
15
|
+
for (const resultGroup of allResults) {
|
|
16
|
+
for (const result of resultGroup) {
|
|
17
|
+
if (result) results.push(result);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (results.length === 0) {
|
|
22
|
+
return { type: 'NO_COMMANDS' };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// If any result requests chat model, return it
|
|
26
|
+
const needsChat = results.find(r => r._meta_actions?.includes('REQUEST_CHAT_MODEL'));
|
|
27
|
+
if (needsChat) {
|
|
28
|
+
return results.length === 1 ? results[0] : { type: 'BATCH_RESULTS', results, ...needsChat };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return results.length === 1 ? results[0] : { type: 'BATCH_RESULTS', results };
|
|
32
|
+
};
|