openkbs 0.0.76 → 0.0.78
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/package.json +1 -1
- package/src/actions.js +29 -0
- package/templates/.claude/CLAUDE.md +1 -1
- package/templates/.claude/skills/openkbs/SKILL.md +1 -0
- package/templates/.claude/skills/openkbs/reference/elastic-services.md +96 -0
- package/version.json +3 -3
- package/.claude/skills/openkbs/SKILL.md +0 -250
- package/.claude/skills/openkbs/examples/ai-copywriter-agent/app/icon.png +0 -0
- package/.claude/skills/openkbs/examples/ai-copywriter-agent/app/instructions.txt +0 -96
- package/.claude/skills/openkbs/examples/ai-copywriter-agent/app/settings.json +0 -6
- package/.claude/skills/openkbs/examples/ai-copywriter-agent/src/Events/actions.js +0 -132
- package/.claude/skills/openkbs/examples/ai-copywriter-agent/src/Events/handler.js +0 -57
- package/.claude/skills/openkbs/examples/ai-copywriter-agent/src/Events/onRequest.js +0 -3
- package/.claude/skills/openkbs/examples/ai-copywriter-agent/src/Events/onRequest.json +0 -5
- package/.claude/skills/openkbs/examples/ai-copywriter-agent/src/Events/onResponse.js +0 -3
- package/.claude/skills/openkbs/examples/ai-copywriter-agent/src/Events/onResponse.json +0 -5
- package/.claude/skills/openkbs/examples/ai-copywriter-agent/src/Frontend/contentRender.js +0 -147
- package/.claude/skills/openkbs/examples/ai-copywriter-agent/src/Frontend/contentRender.json +0 -11
- package/.claude/skills/openkbs/examples/ai-marketing-agent/README.md +0 -64
- package/.claude/skills/openkbs/examples/ai-marketing-agent/app/instructions.txt +0 -160
- package/.claude/skills/openkbs/examples/ai-marketing-agent/app/settings.json +0 -7
- package/.claude/skills/openkbs/examples/ai-marketing-agent/src/Events/actions.js +0 -258
- package/.claude/skills/openkbs/examples/ai-marketing-agent/src/Events/onRequest.js +0 -13
- package/.claude/skills/openkbs/examples/ai-marketing-agent/src/Events/onRequest.json +0 -3
- package/.claude/skills/openkbs/examples/ai-marketing-agent/src/Events/onResponse.js +0 -13
- package/.claude/skills/openkbs/examples/ai-marketing-agent/src/Events/onResponse.json +0 -3
- package/.claude/skills/openkbs/examples/ai-marketing-agent/src/Frontend/contentRender.js +0 -170
- package/.claude/skills/openkbs/examples/ai-marketing-agent/src/Frontend/contentRender.json +0 -3
- package/.claude/skills/openkbs/examples/monitoring-bot/README.md +0 -55
- package/.claude/skills/openkbs/examples/monitoring-bot/app/instructions.txt +0 -40
- package/.claude/skills/openkbs/examples/monitoring-bot/app/settings.json +0 -41
- package/.claude/skills/openkbs/examples/monitoring-bot/openkbs.json +0 -3
- package/.claude/skills/openkbs/examples/monitoring-bot/src/Events/actions.js +0 -141
- package/.claude/skills/openkbs/examples/monitoring-bot/src/Events/handler.js +0 -32
- package/.claude/skills/openkbs/examples/monitoring-bot/src/Events/memoryHelpers.js +0 -91
- package/.claude/skills/openkbs/examples/monitoring-bot/src/Events/onCronjob.js +0 -105
- package/.claude/skills/openkbs/examples/monitoring-bot/src/Events/onPublicAPIRequest.js +0 -165
- package/.claude/skills/openkbs/examples/monitoring-bot/src/Events/onRequest.js +0 -2
- package/.claude/skills/openkbs/examples/monitoring-bot/src/Events/onResponse.js +0 -2
- package/.claude/skills/openkbs/examples/monitoring-bot/src/Frontend/contentRender.js +0 -74
- package/.claude/skills/openkbs/examples/monitoring-bot/src/Frontend/contentRender.json +0 -3
- package/.claude/skills/openkbs/examples/nodejs-demo/functions/auth/index.mjs +0 -228
- package/.claude/skills/openkbs/examples/nodejs-demo/functions/auth/package.json +0 -7
- package/.claude/skills/openkbs/examples/nodejs-demo/functions/posts/index.mjs +0 -287
- package/.claude/skills/openkbs/examples/nodejs-demo/functions/posts/package.json +0 -10
- package/.claude/skills/openkbs/examples/nodejs-demo/functions/settings.json +0 -4
- package/.claude/skills/openkbs/examples/nodejs-demo/openkbs.json +0 -16
- package/.claude/skills/openkbs/examples/nodejs-demo/site/index.html +0 -658
- package/.claude/skills/openkbs/examples/nodejs-demo/site/settings.json +0 -4
- package/.claude/skills/openkbs/metadata.json +0 -1
- package/.claude/skills/openkbs/patterns/cronjob-batch-processing.md +0 -278
- package/.claude/skills/openkbs/patterns/cronjob-monitoring.md +0 -341
- package/.claude/skills/openkbs/patterns/file-upload.md +0 -205
- package/.claude/skills/openkbs/patterns/image-generation.md +0 -139
- package/.claude/skills/openkbs/patterns/memory-system.md +0 -264
- package/.claude/skills/openkbs/patterns/public-api-item-proxy.md +0 -254
- package/.claude/skills/openkbs/patterns/scheduled-tasks.md +0 -157
- package/.claude/skills/openkbs/patterns/telegram-webhook.md +0 -424
- package/.claude/skills/openkbs/patterns/telegram.md +0 -222
- package/.claude/skills/openkbs/patterns/vectordb-archive.md +0 -231
- package/.claude/skills/openkbs/patterns/video-generation.md +0 -145
- package/.claude/skills/openkbs/patterns/web-publishing.md +0 -257
- package/.claude/skills/openkbs/reference/backend-sdk.md +0 -439
- package/.claude/skills/openkbs/reference/commands.md +0 -370
- package/.claude/skills/openkbs/reference/elastic-services.md +0 -359
- package/.claude/skills/openkbs/reference/frontend-sdk.md +0 -299
package/package.json
CHANGED
package/src/actions.js
CHANGED
|
@@ -800,6 +800,35 @@ async function updateSkillsAction(silent = false) {
|
|
|
800
800
|
return;
|
|
801
801
|
}
|
|
802
802
|
|
|
803
|
+
// Always download the root CLAUDE.md file (even if skills are up to date)
|
|
804
|
+
const claudeDir = path.join(process.cwd(), '.claude');
|
|
805
|
+
await fs.ensureDir(claudeDir);
|
|
806
|
+
|
|
807
|
+
const claudeMdKey = 'templates/.claude/CLAUDE.md';
|
|
808
|
+
const claudeMdUrl = `https://${bucket}.s3.amazonaws.com/${claudeMdKey}`;
|
|
809
|
+
|
|
810
|
+
try {
|
|
811
|
+
const claudeMdContent = await new Promise((resolve, reject) => {
|
|
812
|
+
https.get(claudeMdUrl, (res) => {
|
|
813
|
+
if (res.statusCode === 404) {
|
|
814
|
+
reject(new Error('CLAUDE.md not found'));
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
const chunks = [];
|
|
818
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
819
|
+
res.on('end', () => resolve(Buffer.concat(chunks)));
|
|
820
|
+
}).on('error', reject);
|
|
821
|
+
});
|
|
822
|
+
await fs.writeFile(path.join(claudeDir, 'CLAUDE.md'), claudeMdContent);
|
|
823
|
+
if (!silent) {
|
|
824
|
+
console.log('Downloaded: CLAUDE.md');
|
|
825
|
+
}
|
|
826
|
+
} catch (error) {
|
|
827
|
+
if (!silent) {
|
|
828
|
+
console.yellow('Could not download CLAUDE.md:', error.message);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
|
|
803
832
|
// Compare versions
|
|
804
833
|
if (localVersion === remoteVersion) {
|
|
805
834
|
console.green('OpenKBS skill is already up to date.');
|
|
@@ -121,6 +121,7 @@ openkbs postgres shell # Connect to Postgres
|
|
|
121
121
|
openkbs storage ls # List S3 objects
|
|
122
122
|
openkbs pulse status # WebSocket status
|
|
123
123
|
openkbs site push # Deploy static site
|
|
124
|
+
openkbs site spa /app/index.html # Enable SPA routing
|
|
124
125
|
```
|
|
125
126
|
|
|
126
127
|
### Image Generation Service
|
|
@@ -240,6 +240,102 @@ channel.presence.subscribe((members) => {
|
|
|
240
240
|
|
|
241
241
|
---
|
|
242
242
|
|
|
243
|
+
## SPA (Single Page Application) Support
|
|
244
|
+
|
|
245
|
+
Host React, Vue, or Angular apps on your whitelabel domain with client-side routing.
|
|
246
|
+
|
|
247
|
+
### Enable SPA Mode
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
openkbs site spa /app/index.html # Enable SPA fallback
|
|
251
|
+
openkbs site spa --disable # Disable SPA mode
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### How It Works
|
|
255
|
+
|
|
256
|
+
When SPA mode is enabled, CloudFront catches 403/404 errors and serves your fallback file with HTTP 200. This allows client-side routing to handle all `/app/*` paths.
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
yourdomain.com/ → serves /index.html (landing page)
|
|
260
|
+
yourdomain.com/app/ → serves /app/index.html (SPA)
|
|
261
|
+
yourdomain.com/app/dashboard → serves /app/index.html (SPA handles route)
|
|
262
|
+
yourdomain.com/app/profile → serves /app/index.html (SPA handles route)
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Project Structure
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
my-platform/
|
|
269
|
+
├── site/
|
|
270
|
+
│ ├── index.html # Static landing page
|
|
271
|
+
│ └── app/ # Built React app (copied from spa/dist)
|
|
272
|
+
│ ├── index.html
|
|
273
|
+
│ └── assets/
|
|
274
|
+
├── spa/ # React source (not deployed)
|
|
275
|
+
│ ├── package.json
|
|
276
|
+
│ ├── vite.config.js
|
|
277
|
+
│ └── src/
|
|
278
|
+
│ ├── main.jsx
|
|
279
|
+
│ └── App.jsx
|
|
280
|
+
└── openkbs.json
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Example: React + Vite SPA
|
|
284
|
+
|
|
285
|
+
**1. Create React app:**
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
npm create vite@latest spa -- --template react
|
|
289
|
+
cd spa
|
|
290
|
+
npm install react-router-dom
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**2. Configure Vite for /app base path:**
|
|
294
|
+
|
|
295
|
+
```javascript
|
|
296
|
+
// spa/vite.config.js
|
|
297
|
+
import { defineConfig } from 'vite'
|
|
298
|
+
import react from '@vitejs/plugin-react'
|
|
299
|
+
|
|
300
|
+
export default defineConfig({
|
|
301
|
+
plugins: [react()],
|
|
302
|
+
base: '/app/'
|
|
303
|
+
})
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**3. Add routing:**
|
|
307
|
+
|
|
308
|
+
```jsx
|
|
309
|
+
// spa/src/App.jsx
|
|
310
|
+
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom'
|
|
311
|
+
|
|
312
|
+
function App() {
|
|
313
|
+
return (
|
|
314
|
+
<BrowserRouter basename="/app">
|
|
315
|
+
<nav>
|
|
316
|
+
<Link to="/">Home</Link>
|
|
317
|
+
<Link to="/dashboard">Dashboard</Link>
|
|
318
|
+
</nav>
|
|
319
|
+
<Routes>
|
|
320
|
+
<Route path="/" element={<Home />} />
|
|
321
|
+
<Route path="/dashboard" element={<Dashboard />} />
|
|
322
|
+
</Routes>
|
|
323
|
+
</BrowserRouter>
|
|
324
|
+
)
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**4. Build and deploy:**
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
cd spa && npm run build
|
|
332
|
+
cp -r dist/* ../site/app/
|
|
333
|
+
cd .. && openkbs site push
|
|
334
|
+
openkbs site spa /app/index.html
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
243
339
|
## Full-Stack Example
|
|
244
340
|
|
|
245
341
|
Complete Node.js application with all services:
|
package/version.json
CHANGED
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: openkbs
|
|
3
|
-
description: OpenKBS AI agent development framework. Use when creating, modifying, or deploying AI agents with backend handlers (onRequest, onResponse, actions.js), frontend components (contentRender.js), or elastic services (functions, postgres, storage, pulse). Trigger keywords: openkbs, kb, agent, handler, contentRender, elastic, memory, scheduled task.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# OpenKBS Development
|
|
7
|
-
|
|
8
|
-
OpenKBS is a framework for building AI-powered applications - from simple agents to full-stack platforms.
|
|
9
|
-
|
|
10
|
-
## Two Usage Modes
|
|
11
|
-
|
|
12
|
-
### 1. Agent-Only Mode
|
|
13
|
-
Build a single conversational AI agent with backend handlers and custom UI.
|
|
14
|
-
```
|
|
15
|
-
openkbs create my-agent
|
|
16
|
-
openkbs push
|
|
17
|
-
```
|
|
18
|
-
Simplest way to get started - just an agent with memory, commands, and custom frontend.
|
|
19
|
-
|
|
20
|
-
### 2. Platform Mode (Full-Stack)
|
|
21
|
-
Build complete SaaS platforms that **include agents** plus additional infrastructure.
|
|
22
|
-
```
|
|
23
|
-
openkbs deploy # Deploy from openkbs.json
|
|
24
|
-
openkbs stack status # View deployed resources
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Platform mode extends agent capabilities with:
|
|
28
|
-
- **Multiple Agents**: Run several agents on one platform (in `agents/` folder)
|
|
29
|
-
- **Elastic Functions**: Serverless Lambda (Node.js, Python, Java)
|
|
30
|
-
- **Elastic Postgres**: Managed PostgreSQL (Neon) for relational data
|
|
31
|
-
- **Elastic Storage**: S3 buckets + CloudFront CDN for files
|
|
32
|
-
- **Elastic Pulse**: Real-time WebSocket pub/sub
|
|
33
|
-
- **Whitelabel**: Custom domains (`example.com`) with static site (`site/` folder)
|
|
34
|
-
|
|
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
|
-
|
|
37
|
-
## Project Structure
|
|
38
|
-
|
|
39
|
-
### Agent Structure
|
|
40
|
-
```
|
|
41
|
-
my-agent/
|
|
42
|
-
├── app/
|
|
43
|
-
│ ├── settings.json # Agent configuration (model, itemTypes, MCP)
|
|
44
|
-
│ └── instructions.txt # System prompt for LLM
|
|
45
|
-
├── src/
|
|
46
|
-
│ ├── Events/
|
|
47
|
-
│ │ ├── onRequest.js # Pre-process user messages
|
|
48
|
-
│ │ ├── onResponse.js # Parse LLM output, execute commands
|
|
49
|
-
│ │ ├── actions.js # Command implementations
|
|
50
|
-
│ │ ├── onCronjob.js # Scheduled periodic tasks
|
|
51
|
-
│ │ └── onPublicAPIRequest.js # Webhook handler
|
|
52
|
-
│ └── Frontend/
|
|
53
|
-
│ ├── contentRender.js # Custom React UI
|
|
54
|
-
│ └── contentRender.json # Frontend dependencies
|
|
55
|
-
│
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### Platform Structure
|
|
59
|
-
```
|
|
60
|
-
my-platform/
|
|
61
|
-
├── agents/ # Multiple AI agents
|
|
62
|
-
│ ├── marketing-assistant/ # Each agent has full structure
|
|
63
|
-
│ │ ├── app/
|
|
64
|
-
│ │ │ ├── settings.json
|
|
65
|
-
│ │ │ └── instructions.txt
|
|
66
|
-
│ │ └── src/
|
|
67
|
-
│ │ ├── Events/
|
|
68
|
-
│ │ │ ├── onRequest.js
|
|
69
|
-
│ │ │ ├── onResponse.js
|
|
70
|
-
│ │ │ └── actions.js
|
|
71
|
-
│ │ └── Frontend/
|
|
72
|
-
│ │ └── contentRender.js
|
|
73
|
-
│ └── support-agent/ # Another agent
|
|
74
|
-
│ ├── app/
|
|
75
|
-
│ └── src/
|
|
76
|
-
├── functions/ # Serverless Lambda functions
|
|
77
|
-
│ └── api/
|
|
78
|
-
│ └── index.mjs
|
|
79
|
-
├── site/ # Static site for whitelabel domain
|
|
80
|
-
│ └── index.html
|
|
81
|
-
└── openkbs.json # Elastic services config
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### openkbs.json
|
|
85
|
-
```json
|
|
86
|
-
{
|
|
87
|
-
"elastic": {
|
|
88
|
-
"postgres": true,
|
|
89
|
-
"storage": true,
|
|
90
|
-
"pulse": true,
|
|
91
|
-
"functions": {
|
|
92
|
-
"api": { "runtime": "nodejs24.x", "memory": 512 }
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
## Quick Commands
|
|
99
|
-
|
|
100
|
-
### Agent Commands
|
|
101
|
-
```bash
|
|
102
|
-
openkbs create <name> # Create new agent
|
|
103
|
-
openkbs push # Deploy to cloud
|
|
104
|
-
openkbs pull # Download from cloud
|
|
105
|
-
openkbs update skills # Update this skill
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### Platform Commands
|
|
109
|
-
```bash
|
|
110
|
-
openkbs deploy # Deploy all elastic services
|
|
111
|
-
openkbs stack status # Show deployed resources
|
|
112
|
-
openkbs destroy # Remove all resources (DANGEROUS)
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### Elastic Services
|
|
116
|
-
```bash
|
|
117
|
-
openkbs fn list # List Lambda functions
|
|
118
|
-
openkbs fn push api # Deploy function
|
|
119
|
-
openkbs fn logs api # View function logs
|
|
120
|
-
openkbs postgres shell # Connect to Postgres
|
|
121
|
-
openkbs storage ls # List S3 objects
|
|
122
|
-
openkbs pulse status # WebSocket status
|
|
123
|
-
openkbs site push # Deploy static site
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### Image Generation Service
|
|
127
|
-
Generate images directly from CLI using OpenKBS AI services:
|
|
128
|
-
|
|
129
|
-
```bash
|
|
130
|
-
# Generate with GPT
|
|
131
|
-
openkbs service -m gpt-image -d '{"action":"createImage","prompt":"a logo"}' -o logo.png
|
|
132
|
-
|
|
133
|
-
# Generate with Gemini
|
|
134
|
-
openkbs service -m gemini-image -d '{"action":"createImage","prompt":"hero image"}' -o hero.png
|
|
135
|
-
|
|
136
|
-
# Edit existing image
|
|
137
|
-
openkbs service -m gpt-image -d '{"action":"createImage","prompt":"make it blue","imageUrls":["https://..."]}' -o edited.png
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
**Available models:**
|
|
141
|
-
- `gpt-image` - OpenAI GPT Image (gpt-image-1.5)
|
|
142
|
-
- `gemini-image` - Google Gemini Flash (gemini-2.5-flash-image)
|
|
143
|
-
|
|
144
|
-
**Options for gpt-image:**
|
|
145
|
-
| Option | Values | Default |
|
|
146
|
-
|--------|--------|---------|
|
|
147
|
-
| prompt | (required) | - |
|
|
148
|
-
| size | "1024x1024", "1024x1536", "1536x1024", "auto" | "auto" |
|
|
149
|
-
| quality | "low", "medium", "high", "auto" | "auto" |
|
|
150
|
-
| n | Number of images | 1 |
|
|
151
|
-
| output_format | "png", "jpg", "webp" | "png" |
|
|
152
|
-
| background | "transparent", "opaque", "auto" | "auto" |
|
|
153
|
-
| output_compression | 0-100 | 100 |
|
|
154
|
-
| imageUrls | Array of URLs for editing | - |
|
|
155
|
-
|
|
156
|
-
**Options for gemini-image:**
|
|
157
|
-
| Option | Values | Default |
|
|
158
|
-
|--------|--------|---------|
|
|
159
|
-
| prompt | (required) | - |
|
|
160
|
-
| aspect_ratio | "1:1", "16:9", "9:16", "4:3", "3:4" | "1:1" |
|
|
161
|
-
| imageUrls | Array of URLs for reference | - |
|
|
162
|
-
|
|
163
|
-
## Backend Handler Pattern
|
|
164
|
-
|
|
165
|
-
Commands are XML tags with JSON content that the LLM outputs:
|
|
166
|
-
|
|
167
|
-
```xml
|
|
168
|
-
<commandName>{"param": "value"}</commandName>
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
The `handler.js` parses these tags, matches regex patterns in `actions.js`, and executes async functions:
|
|
172
|
-
|
|
173
|
-
```javascript
|
|
174
|
-
// actions.js pattern
|
|
175
|
-
[/<googleSearch>([\s\S]*?)<\/googleSearch>/s, async (match) => {
|
|
176
|
-
const data = JSON.parse(match[1].trim());
|
|
177
|
-
const results = await openkbs.googleSearch(data.query);
|
|
178
|
-
return {
|
|
179
|
-
type: 'SEARCH_RESULTS',
|
|
180
|
-
data: results,
|
|
181
|
-
_meta_actions: ["REQUEST_CHAT_MODEL"] // Loop back to LLM
|
|
182
|
-
};
|
|
183
|
-
}]
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
## Meta Actions
|
|
187
|
-
|
|
188
|
-
Control flow after command execution:
|
|
189
|
-
|
|
190
|
-
- `["REQUEST_CHAT_MODEL"]` - Send result back to LLM for processing
|
|
191
|
-
- `[]` - Display result to user, stop conversation
|
|
192
|
-
|
|
193
|
-
## Memory System
|
|
194
|
-
|
|
195
|
-
Configure in `settings.json`:
|
|
196
|
-
|
|
197
|
-
```json
|
|
198
|
-
{
|
|
199
|
-
"itemTypes": {
|
|
200
|
-
"memory": {
|
|
201
|
-
"attributes": [
|
|
202
|
-
{ "attrName": "itemId", "attrType": "itemId", "encrypted": false },
|
|
203
|
-
{ "attrName": "body", "attrType": "body", "encrypted": true }
|
|
204
|
-
]
|
|
205
|
-
}
|
|
206
|
-
},
|
|
207
|
-
"options": {
|
|
208
|
-
"priorityItems": [{ "prefix": "memory_", "limit": 100 }]
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
Priority items are auto-injected into LLM context.
|
|
214
|
-
|
|
215
|
-
## Additional Resources
|
|
216
|
-
|
|
217
|
-
### Reference Documentation
|
|
218
|
-
- [reference/backend-sdk.md](reference/backend-sdk.md) - Backend SDK methods (openkbs.*)
|
|
219
|
-
- [reference/frontend-sdk.md](reference/frontend-sdk.md) - Frontend React patterns
|
|
220
|
-
- [reference/commands.md](reference/commands.md) - XML command definitions
|
|
221
|
-
- [reference/elastic-services.md](reference/elastic-services.md) - Functions, Postgres, Storage, Pulse
|
|
222
|
-
|
|
223
|
-
### Ready-to-Use Patterns
|
|
224
|
-
Production-tested code blocks for common tasks:
|
|
225
|
-
|
|
226
|
-
**Content & Media:**
|
|
227
|
-
- [patterns/image-generation.md](patterns/image-generation.md) - AI image generation with upload
|
|
228
|
-
- [patterns/video-generation.md](patterns/video-generation.md) - Async video generation with polling
|
|
229
|
-
- [patterns/file-upload.md](patterns/file-upload.md) - Presigned URL file uploads
|
|
230
|
-
- [patterns/web-publishing.md](patterns/web-publishing.md) - HTML page publishing
|
|
231
|
-
|
|
232
|
-
**Memory & Storage:**
|
|
233
|
-
- [patterns/memory-system.md](patterns/memory-system.md) - Memory CRUD with settings.json config
|
|
234
|
-
- [patterns/vectordb-archive.md](patterns/vectordb-archive.md) - Long-term archive with semantic search
|
|
235
|
-
|
|
236
|
-
**Scheduling & Automation:**
|
|
237
|
-
- [patterns/scheduled-tasks.md](patterns/scheduled-tasks.md) - Task scheduling (one-time & recurring)
|
|
238
|
-
- [patterns/cronjob-batch-processing.md](patterns/cronjob-batch-processing.md) - Batch file processing with state
|
|
239
|
-
- [patterns/cronjob-monitoring.md](patterns/cronjob-monitoring.md) - Continuous monitoring with pulse control
|
|
240
|
-
|
|
241
|
-
**External Integrations:**
|
|
242
|
-
- [patterns/telegram.md](patterns/telegram.md) - Telegram bot commands (send messages)
|
|
243
|
-
- [patterns/telegram-webhook.md](patterns/telegram-webhook.md) - Telegram webhook (receive messages)
|
|
244
|
-
- [patterns/public-api-item-proxy.md](patterns/public-api-item-proxy.md) - Public API with geolocation
|
|
245
|
-
|
|
246
|
-
### Complete Examples
|
|
247
|
-
- [examples/ai-copywriter-agent/](examples/ai-copywriter-agent/) - Content generation agent
|
|
248
|
-
- [examples/ai-marketing-agent/](examples/ai-marketing-agent/) - Marketing automation agent
|
|
249
|
-
- [examples/monitoring-bot/](examples/monitoring-bot/) - Cronjob + Telegram monitoring agent
|
|
250
|
-
- [examples/nodejs-demo/](examples/nodejs-demo/) - Platform with elastic functions
|
|
Binary file
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
You are an autonomous agent for crafting intelligent, creative, and consistent content:
|
|
2
|
-
|
|
3
|
-
Job:
|
|
4
|
-
- Find and open at least one site that have correct, reliable and detailed information about the product
|
|
5
|
-
- paraphrase and enrich it and generate a SEO friendly product description
|
|
6
|
-
- Always search the official website of the manufacturer (Brand) and find information about the product from there.
|
|
7
|
-
- If you see additional instructions in PROCESS_PRODUCT, execute them.
|
|
8
|
-
- When you have obtained all the necessary information, output JOB_COMPLETED response.
|
|
9
|
-
|
|
10
|
-
Important Guidelines:
|
|
11
|
-
- use webpageToText command to read websites content in details
|
|
12
|
-
- Always output one command per response and wait for the response before continuing
|
|
13
|
-
- If an API call fails, so that you can't extract a required data, retry with different website or search query
|
|
14
|
-
- When searching for product information, use the format: Product Name + Product Code.
|
|
15
|
-
- Once all necessary information is obtained, deliver the final result using the following JSON format
|
|
16
|
-
|
|
17
|
-
Output Format Success:
|
|
18
|
-
{
|
|
19
|
-
"type": "JOB_COMPLETED",
|
|
20
|
-
"productID": "[productID]",
|
|
21
|
-
"productDescription": "[short plain text description]",
|
|
22
|
-
"metaDescription": "...",
|
|
23
|
-
"images": [{"url": "...", "title": "..."}, ...],
|
|
24
|
-
"attributes": {"size": "L", ...},
|
|
25
|
-
"videos": [
|
|
26
|
-
{"url": "[video1_url]", "title": "[video1_title]"},
|
|
27
|
-
{"url": "[video2_url]", "title": "[video2_title]"}
|
|
28
|
-
]
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
Description: """
|
|
32
|
-
Use this JSON format to output the final job response
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
Output Format Failed:
|
|
36
|
-
{"type": "JOB_FAILED", "reason": "fail reason summary"}
|
|
37
|
-
Description: """
|
|
38
|
-
Output this JSON format if you can't extract the required data
|
|
39
|
-
"""
|
|
40
|
-
|
|
41
|
-
LIST OF AVAILABLE COMMANDS:
|
|
42
|
-
To execute a command, output it as text and wait for system response.
|
|
43
|
-
|
|
44
|
-
<googleSearch>
|
|
45
|
-
{
|
|
46
|
-
"query": "search query"
|
|
47
|
-
}
|
|
48
|
-
</googleSearch>
|
|
49
|
-
Description: """
|
|
50
|
-
Get results from Google Search API.
|
|
51
|
-
"""
|
|
52
|
-
|
|
53
|
-
<youtubeSearch>
|
|
54
|
-
{
|
|
55
|
-
"query": "search query"
|
|
56
|
-
}
|
|
57
|
-
</youtubeSearch>
|
|
58
|
-
Description: """
|
|
59
|
-
Get results from YouTube Search API.
|
|
60
|
-
"""
|
|
61
|
-
|
|
62
|
-
<googleImageSearch>
|
|
63
|
-
{
|
|
64
|
-
"query": "search query"
|
|
65
|
-
}
|
|
66
|
-
</googleImageSearch>
|
|
67
|
-
Description: """
|
|
68
|
-
Get results from Google Image Search.
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
<webpageToText>
|
|
72
|
-
{
|
|
73
|
-
"url": "https://example.com/page"
|
|
74
|
-
}
|
|
75
|
-
</webpageToText>
|
|
76
|
-
Description: """
|
|
77
|
-
Use this API to open/read web pages like product pages.
|
|
78
|
-
"""
|
|
79
|
-
|
|
80
|
-
<documentToText>
|
|
81
|
-
{
|
|
82
|
-
"url": "https://example.com/document.pdf"
|
|
83
|
-
}
|
|
84
|
-
</documentToText>
|
|
85
|
-
Description: """
|
|
86
|
-
Extract text from documents (PDF, DOC, etc.).
|
|
87
|
-
"""
|
|
88
|
-
|
|
89
|
-
<imageToText>
|
|
90
|
-
{
|
|
91
|
-
"url": "https://example.com/image.png"
|
|
92
|
-
}
|
|
93
|
-
</imageToText>
|
|
94
|
-
Description: """
|
|
95
|
-
OCR - Extract text from images.
|
|
96
|
-
"""
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
const extractJSONFromText = (text) => {
|
|
2
|
-
let braceCount = 0, startIndex = text.indexOf('{');
|
|
3
|
-
if (startIndex === -1) return null;
|
|
4
|
-
|
|
5
|
-
for (let i = startIndex; i < text.length; i++) {
|
|
6
|
-
if (text[i] === '{') braceCount++;
|
|
7
|
-
if (text[i] === '}' && --braceCount === 0) {
|
|
8
|
-
try {
|
|
9
|
-
return JSON.parse(text.slice(startIndex, i + 1));
|
|
10
|
-
} catch {
|
|
11
|
-
return null;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const getActions = (meta) => [
|
|
19
|
-
// IMPORTANT: Actions returning JOB_COMPLETED or JOB_FAILED stop agent execution and return final result
|
|
20
|
-
[/[\s\S]*"type"\s*:\s*"JOB_COMPLETED"[\s\S]*/, async (match, event) => {
|
|
21
|
-
const parsedData = extractJSONFromText(match[0]);
|
|
22
|
-
if (parsedData && parsedData.type === "JOB_COMPLETED") {
|
|
23
|
-
await openkbs.chats({
|
|
24
|
-
action: "updateChat",
|
|
25
|
-
title: await openkbs.encrypt(parsedData?.name),
|
|
26
|
-
chatIcon: '🟢',
|
|
27
|
-
chatId: event?.payload?.chatId
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
return parsedData;
|
|
31
|
-
}
|
|
32
|
-
}],
|
|
33
|
-
|
|
34
|
-
[/[\s\S]*"type"\s*:\s*"JOB_FAILED"[\s\S]*/, async (match, event) => {
|
|
35
|
-
const parsedData = extractJSONFromText(match[0]);
|
|
36
|
-
if (parsedData && parsedData.type === "JOB_FAILED") {
|
|
37
|
-
await openkbs.chats({
|
|
38
|
-
action: "updateChat",
|
|
39
|
-
title: await openkbs.encrypt(parsedData.reason),
|
|
40
|
-
chatIcon: '🔴',
|
|
41
|
-
chatId: event?.payload?.chatId
|
|
42
|
-
})
|
|
43
|
-
return parsedData;
|
|
44
|
-
}
|
|
45
|
-
}],
|
|
46
|
-
|
|
47
|
-
// Google Search with XML+JSON format
|
|
48
|
-
[/<googleSearch>([\s\S]*?)<\/googleSearch>/s, async (match) => {
|
|
49
|
-
try {
|
|
50
|
-
const data = JSON.parse(match[1].trim());
|
|
51
|
-
const response = await openkbs.googleSearch(data.query);
|
|
52
|
-
const results = response?.map(({ title, link, snippet, pagemap }) => ({
|
|
53
|
-
title, link, snippet, image: pagemap?.metatags?.[0]?.["og:image"]
|
|
54
|
-
}));
|
|
55
|
-
return { data: results, ...meta };
|
|
56
|
-
} catch (e) {
|
|
57
|
-
return { error: e.message, ...meta };
|
|
58
|
-
}
|
|
59
|
-
}],
|
|
60
|
-
|
|
61
|
-
// YouTube Search with XML+JSON format
|
|
62
|
-
[/<youtubeSearch>([\s\S]*?)<\/youtubeSearch>/s, async (match) => {
|
|
63
|
-
try {
|
|
64
|
-
const data = JSON.parse(match[1].trim());
|
|
65
|
-
const response = await openkbs.googleSearch(data.query + ' site:youtube.com', { videoOnly: true });
|
|
66
|
-
const results = response?.map(({ title, link, snippet, pagemap }) => ({
|
|
67
|
-
title,
|
|
68
|
-
link: link.replace('www.youtube.com/watch?v=', 'youtu.be/'),
|
|
69
|
-
snippet,
|
|
70
|
-
thumbnail: pagemap?.videoobject?.[0]?.thumbnailurl || pagemap?.metatags?.[0]?.["og:image"],
|
|
71
|
-
duration: pagemap?.videoobject?.[0]?.duration,
|
|
72
|
-
channel: pagemap?.metatags?.[0]?.["og:site_name"],
|
|
73
|
-
})).filter(item => item.link.includes('youtu'));
|
|
74
|
-
return { data: results, ...meta };
|
|
75
|
-
} catch (e) {
|
|
76
|
-
return { error: e.message, ...meta };
|
|
77
|
-
}
|
|
78
|
-
}],
|
|
79
|
-
|
|
80
|
-
// Google Image Search with XML+JSON format
|
|
81
|
-
[/<googleImageSearch>([\s\S]*?)<\/googleImageSearch>/s, async (match) => {
|
|
82
|
-
try {
|
|
83
|
-
const data = JSON.parse(match[1].trim());
|
|
84
|
-
const response = await openkbs.googleSearch(data.query, { searchType: 'image' });
|
|
85
|
-
const results = response?.map(({ title, link, snippet, pagemap }) => {
|
|
86
|
-
const imageObj = pagemap?.cse_image?.[0];
|
|
87
|
-
const thumbnail = imageObj?.src || pagemap?.metatags?.[0]?.["og:image"] || link;
|
|
88
|
-
return { title, link, snippet, image: thumbnail };
|
|
89
|
-
});
|
|
90
|
-
return { data: results, ...meta };
|
|
91
|
-
} catch (e) {
|
|
92
|
-
return { error: e.message, ...meta };
|
|
93
|
-
}
|
|
94
|
-
}],
|
|
95
|
-
|
|
96
|
-
// Webpage to Text with XML+JSON format
|
|
97
|
-
[/<webpageToText>([\s\S]*?)<\/webpageToText>/s, async (match) => {
|
|
98
|
-
try {
|
|
99
|
-
const data = JSON.parse(match[1].trim());
|
|
100
|
-
let response = await openkbs.webpageToText(data.url);
|
|
101
|
-
if (!response?.url) return { data: { error: "Unable to read website" }, ...meta };
|
|
102
|
-
return { data: response, ...meta };
|
|
103
|
-
} catch (e) {
|
|
104
|
-
return { error: e.response?.data || e.message, ...meta };
|
|
105
|
-
}
|
|
106
|
-
}],
|
|
107
|
-
|
|
108
|
-
// Document to Text with XML+JSON format
|
|
109
|
-
[/<documentToText>([\s\S]*?)<\/documentToText>/s, async (match) => {
|
|
110
|
-
try {
|
|
111
|
-
const data = JSON.parse(match[1].trim());
|
|
112
|
-
let response = await openkbs.documentToText(data.url);
|
|
113
|
-
return { data: response, ...meta };
|
|
114
|
-
} catch (e) {
|
|
115
|
-
return { error: e.response?.data || e.message, ...meta };
|
|
116
|
-
}
|
|
117
|
-
}],
|
|
118
|
-
|
|
119
|
-
// Image to Text (OCR) with XML+JSON format
|
|
120
|
-
[/<imageToText>([\s\S]*?)<\/imageToText>/s, async (match) => {
|
|
121
|
-
try {
|
|
122
|
-
const data = JSON.parse(match[1].trim());
|
|
123
|
-
let response = await openkbs.imageToText(data.url);
|
|
124
|
-
if (response?.detections?.[0]?.txt) {
|
|
125
|
-
response = { detections: response?.detections?.[0]?.txt };
|
|
126
|
-
}
|
|
127
|
-
return { data: response, ...meta };
|
|
128
|
-
} catch (e) {
|
|
129
|
-
return { error: e.response?.data || e.message, ...meta };
|
|
130
|
-
}
|
|
131
|
-
}],
|
|
132
|
-
];
|