openkbs 0.0.67 → 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.
Files changed (62) hide show
  1. package/README.md +1 -0
  2. package/elastic/README.md +1 -1
  3. package/elastic/functions.md +5 -5
  4. package/elastic/pulse.md +2 -2
  5. package/package.json +2 -2
  6. package/scripts/deploy.js +68 -0
  7. package/src/actions.js +7 -0
  8. package/templates/.claude/skills/openkbs/SKILL.md +37 -8
  9. package/templates/.claude/skills/openkbs/examples/monitoring-bot/README.md +55 -0
  10. package/templates/.claude/skills/openkbs/examples/monitoring-bot/app/instructions.txt +40 -0
  11. package/templates/.claude/skills/openkbs/examples/monitoring-bot/app/settings.json +41 -0
  12. package/templates/.claude/skills/openkbs/examples/monitoring-bot/openkbs.json +3 -0
  13. package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Events/actions.js +141 -0
  14. package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Events/handler.js +32 -0
  15. package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Events/memoryHelpers.js +91 -0
  16. package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Events/onCronjob.js +105 -0
  17. package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Events/onPublicAPIRequest.js +165 -0
  18. package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Events/onRequest.js +2 -0
  19. package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Events/onResponse.js +2 -0
  20. package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Frontend/contentRender.js +74 -0
  21. package/templates/.claude/skills/openkbs/examples/monitoring-bot/src/Frontend/contentRender.json +3 -0
  22. package/templates/.claude/skills/openkbs/examples/nodejs-demo/functions/auth/index.mjs +228 -0
  23. package/templates/.claude/skills/openkbs/examples/nodejs-demo/functions/auth/package.json +7 -0
  24. package/templates/.claude/skills/openkbs/examples/nodejs-demo/functions/posts/index.mjs +287 -0
  25. package/templates/.claude/skills/openkbs/examples/nodejs-demo/functions/posts/package.json +10 -0
  26. package/templates/.claude/skills/openkbs/examples/nodejs-demo/functions/settings.json +4 -0
  27. package/templates/.claude/skills/openkbs/examples/nodejs-demo/openkbs.json +16 -0
  28. package/templates/.claude/skills/openkbs/examples/nodejs-demo/site/index.html +658 -0
  29. package/templates/.claude/skills/openkbs/examples/nodejs-demo/site/settings.json +4 -0
  30. package/templates/.claude/skills/openkbs/patterns/cronjob-batch-processing.md +278 -0
  31. package/templates/.claude/skills/openkbs/patterns/cronjob-monitoring.md +341 -0
  32. package/templates/.claude/skills/openkbs/patterns/file-upload.md +205 -0
  33. package/templates/.claude/skills/openkbs/patterns/image-generation.md +139 -0
  34. package/templates/.claude/skills/openkbs/patterns/memory-system.md +264 -0
  35. package/templates/.claude/skills/openkbs/patterns/public-api-item-proxy.md +254 -0
  36. package/templates/.claude/skills/openkbs/patterns/scheduled-tasks.md +157 -0
  37. package/templates/.claude/skills/openkbs/patterns/telegram-webhook.md +424 -0
  38. package/templates/.claude/skills/openkbs/patterns/telegram.md +222 -0
  39. package/templates/.claude/skills/openkbs/patterns/vectordb-archive.md +231 -0
  40. package/templates/.claude/skills/openkbs/patterns/video-generation.md +145 -0
  41. package/templates/.claude/skills/openkbs/patterns/web-publishing.md +257 -0
  42. package/templates/.claude/skills/openkbs/reference/backend-sdk.md +13 -2
  43. package/templates/.claude/skills/openkbs/reference/elastic-services.md +61 -29
  44. package/templates/platform/README.md +15 -50
  45. package/templates/platform/agents/assistant/app/icon.png +0 -0
  46. package/templates/platform/agents/assistant/app/instructions.txt +9 -21
  47. package/templates/platform/agents/assistant/app/settings.json +11 -15
  48. package/templates/platform/agents/assistant/src/Events/actions.js +31 -62
  49. package/templates/platform/agents/assistant/src/Events/handler.js +54 -0
  50. package/templates/platform/agents/assistant/src/Events/onRequest.js +3 -0
  51. package/templates/platform/agents/assistant/src/Events/onRequest.json +5 -0
  52. package/templates/platform/agents/assistant/src/Events/onResponse.js +2 -40
  53. package/templates/platform/agents/assistant/src/Events/onResponse.json +4 -2
  54. package/templates/platform/agents/assistant/src/Frontend/contentRender.js +17 -16
  55. package/templates/platform/agents/assistant/src/Frontend/contentRender.json +1 -1
  56. package/templates/platform/functions/api/index.mjs +17 -23
  57. package/templates/platform/functions/api/package.json +4 -0
  58. package/templates/platform/openkbs.json +7 -2
  59. package/templates/platform/site/index.html +18 -19
  60. package/version.json +3 -3
  61. package/templates/.claude/skills/openkbs/examples/ai-copywriter-agent/scripts/run_job.js +0 -26
  62. 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 · [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/open-kbs/openkbs-chat/blob/main/LICENSE) [![npm version](https://img.shields.io/badge/npm-v0.0.20-orange.svg)](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
@@ -908,7 +908,7 @@ openkbs pulse enable
908
908
  Install:
909
909
 
910
910
  ```html
911
- <script src="https://unpkg.com/openkbs-pulse@2.0.1/pulse.js"></script>
911
+ <script src="https://unpkg.com/openkbs-pulse/pulse.js"></script>
912
912
  ```
913
913
 
914
914
  Or with npm:
@@ -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://your-kb.openkbs.com/api`.
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://your-kb.openkbs.com/api \
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://your-kb.openkbs.com/api
290
- auth 256MB 30s https://your-kb.openkbs.com/auth
291
- posts 512MB 60s https://your-kb.openkbs.com/posts
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@2.0.1/pulse.js"></script>
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@2.0.1/pulse.js"></script>
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.67",
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": "npm run build && npm run deploy:linux && npm run deploy:macos && npm run deploy:win && npm run deploy:templates && npm run deploy:version",
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
@@ -2462,6 +2462,13 @@ async function stackCreateAction(name) {
2462
2462
  // Copy platform template
2463
2463
  fs.copySync(platformTemplateDir, targetDir);
2464
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
+
2465
2472
  // Replace placeholders in all files
2466
2473
  replacePlaceholderInFiles(targetDir, name);
2467
2474
 
@@ -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 a KB 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`. All agents share the platform's elastic services via the parent kbId.
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
- └── openkbs.json # Elastic services config
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": "nodejs22.x", "memory": 512 }
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
- - For backend SDK methods, see [reference/backend-sdk.md](reference/backend-sdk.md)
181
- - For frontend React patterns, see [reference/frontend-sdk.md](reference/frontend-sdk.md)
182
- - For XML command definitions, see [reference/commands.md](reference/commands.md)
183
- - For elastic services, see [reference/elastic-services.md](reference/elastic-services.md)
184
- - For complete examples, see [examples/](examples/)
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
+ };
@@ -0,0 +1,91 @@
1
+ // Memory Helpers - Atomic operations
2
+
3
+ async function _upsertItem(itemType, itemId, body) {
4
+ try {
5
+ await openkbs.updateItem({ itemType, itemId, body });
6
+ } catch (e) {
7
+ await openkbs.createItem({ itemType, itemId, body });
8
+ }
9
+ return { success: true, itemId };
10
+ }
11
+
12
+ export async function setMemoryValue(itemId, value, expirationInMinutes = null) {
13
+ if (!itemId.startsWith('memory_')) {
14
+ throw new Error(`itemId must start with "memory_"`);
15
+ }
16
+
17
+ const body = {
18
+ value,
19
+ updatedAt: new Date().toISOString()
20
+ };
21
+
22
+ if (expirationInMinutes != null) {
23
+ body.exp = new Date(Date.now() + expirationInMinutes * 60 * 1000).toISOString();
24
+ }
25
+
26
+ return _upsertItem('memory', itemId, body);
27
+ }
28
+
29
+ export async function deleteItem(itemId) {
30
+ try {
31
+ await openkbs.deleteItem(itemId);
32
+ return { success: true };
33
+ } catch (e) {
34
+ return { success: false, error: e.message };
35
+ }
36
+ }
37
+
38
+ export async function setAgentSetting(itemId, value) {
39
+ if (!itemId.startsWith('agent_')) {
40
+ itemId = `agent_${itemId}`;
41
+ }
42
+ return _upsertItem('agent', itemId, { value, updatedAt: new Date().toISOString() });
43
+ }
44
+
45
+ export async function getAgentSetting(itemId) {
46
+ try {
47
+ const item = await openkbs.getItem(itemId);
48
+ return item?.item?.body?.value;
49
+ } catch (e) {
50
+ return null;
51
+ }
52
+ }
53
+
54
+ export async function storeTelegramMessage(messageId, data) {
55
+ const itemId = `telegram_${messageId.toString().padStart(12, '0')}`;
56
+ const body = { ...data, storedAt: new Date().toISOString() };
57
+ return _upsertItem('telegram', itemId, body);
58
+ }
59
+
60
+ export async function getTelegramMessage(messageId) {
61
+ const itemId = `telegram_${messageId.toString().padStart(12, '0')}`;
62
+ try {
63
+ const result = await openkbs.getItem(itemId);
64
+ return result?.item?.body;
65
+ } catch (e) {
66
+ return null;
67
+ }
68
+ }
69
+
70
+ export async function deleteTelegramMessage(itemId) {
71
+ return deleteItem(itemId);
72
+ }
73
+
74
+ export async function cleanupExpiredMemory() {
75
+ try {
76
+ const items = await openkbs.fetchItems({
77
+ beginsWith: 'memory_',
78
+ limit: 100
79
+ });
80
+
81
+ const now = new Date();
82
+ for (const item of items?.items || []) {
83
+ const exp = item.item?.body?.exp;
84
+ if (exp && new Date(exp) < now) {
85
+ await deleteItem(item.meta.itemId);
86
+ }
87
+ }
88
+ } catch (e) {
89
+ console.error('Cleanup error:', e.message);
90
+ }
91
+ }