openkbs 0.0.53 → 0.0.55
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 +1490 -202
- package/package.json +2 -1
- package/src/actions.js +345 -1
- package/src/index.js +17 -1
- package/templates/.openkbs/knowledge/examples/ai-copywriter-agent/app/instructions.txt +44 -9
- package/templates/.openkbs/knowledge/examples/ai-copywriter-agent/src/Events/actions.js +43 -42
- package/templates/.openkbs/knowledge/examples/ai-copywriter-agent/src/Events/handler.js +14 -8
- package/templates/.openkbs/knowledge/examples/ai-copywriter-agent/src/Frontend/contentRender.js +95 -12
- package/templates/.openkbs/knowledge/examples/ai-marketing-agent/README.md +64 -0
- package/templates/.openkbs/knowledge/examples/ai-marketing-agent/app/instructions.txt +160 -0
- package/templates/.openkbs/knowledge/examples/ai-marketing-agent/app/settings.json +7 -0
- package/templates/.openkbs/knowledge/examples/ai-marketing-agent/src/Events/actions.js +258 -0
- package/templates/.openkbs/knowledge/examples/ai-marketing-agent/src/Events/onRequest.js +13 -0
- package/templates/.openkbs/knowledge/examples/ai-marketing-agent/src/Events/onRequest.json +3 -0
- package/templates/.openkbs/knowledge/examples/ai-marketing-agent/src/Events/onResponse.js +13 -0
- package/templates/.openkbs/knowledge/examples/ai-marketing-agent/src/Events/onResponse.json +3 -0
- package/templates/.openkbs/knowledge/examples/ai-marketing-agent/src/Frontend/contentRender.js +170 -0
- package/templates/.openkbs/knowledge/examples/ai-marketing-agent/src/Frontend/contentRender.json +3 -0
- package/templates/.openkbs/knowledge/metadata.json +1 -1
- package/templates/CLAUDE.md +593 -222
- package/templates/app/instructions.txt +13 -1
- package/templates/app/settings.json +5 -6
- package/templates/src/Events/actions.js +43 -9
- package/templates/src/Events/handler.js +24 -25
- package/templates/webpack.contentRender.config.js +8 -2
- package/version.json +3 -3
- package/MODIFY.md +0 -132
package/templates/CLAUDE.md
CHANGED
|
@@ -1,284 +1,655 @@
|
|
|
1
1
|
# Claude Code Instructions
|
|
2
2
|
|
|
3
|
+
> **Full Documentation**: For comprehensive SDK reference, API details, and advanced examples, fetch the official documentation:
|
|
4
|
+
> `https://raw.githubusercontent.com/open-kbs/openkbs/refs/heads/main/README.md`
|
|
5
|
+
> Or visit: https://github.com/open-kbs/openkbs
|
|
6
|
+
|
|
3
7
|
# MANDATORY FIRST STEPS
|
|
4
|
-
|
|
8
|
+
|
|
9
|
+
**CRITICAL**: Before taking ANY action, you must:
|
|
5
10
|
|
|
6
11
|
**FIRST**: Update the knowledge base:
|
|
7
12
|
```bash
|
|
8
13
|
openkbs update
|
|
9
14
|
```
|
|
10
15
|
|
|
11
|
-
**SECOND**: Read
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- You must read ALL files directly
|
|
16
|
+
**SECOND**: Read the https://github.com/open-kbs/tutorials and all files in `.openkbs/knowledge/examples/` directory and subdirectories using the Read tool (skip icon.png, src/Frontend/Presentational/*, src/Events/Helpers/*).
|
|
17
|
+
``
|
|
18
|
+
**THIRD**: Read existing agent code in `./app/` and `./src/` folders.
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
20
|
+
# Critical Rules
|
|
21
|
+
- Never skip reading examples
|
|
22
|
+
- Never guess framework methods, settings or variables — always reference the examples
|
|
23
|
+
- In src/Events and src/Frontend always use Imports (not Require)
|
|
24
|
+
- Valid values for `_meta_actions` key are `[]` or `["REQUEST_CHAT_MODEL"]`
|
|
25
|
+
- Add npm dependencies only if necessary
|
|
26
|
+
- Before using third-party services in handlers, ask the user for permission
|
|
19
27
|
|
|
20
|
-
|
|
28
|
+
---
|
|
21
29
|
|
|
22
|
-
|
|
23
|
-
- Never skip reading examples
|
|
24
|
-
- Study the complete working examples to understand OpenKBS patterns
|
|
25
|
-
- Never guess framework methods, settings or variables — always reference the examples.
|
|
30
|
+
# OpenKBS Framework Overview
|
|
26
31
|
|
|
27
|
-
##
|
|
32
|
+
## What is OpenKBS?
|
|
28
33
|
|
|
29
|
-
|
|
34
|
+
OpenKBS is a framework for building **AI agents** - intelligent assistants that can:
|
|
35
|
+
- Converse with users via LLM (Claude, GPT, etc.)
|
|
36
|
+
- Execute commands (generate images, send emails, search web, etc.)
|
|
37
|
+
- Store and retrieve data (memory system)
|
|
38
|
+
- Run scheduled tasks (cronjobs)
|
|
39
|
+
- Provide custom UI (React-based frontend)
|
|
30
40
|
|
|
31
|
-
|
|
32
|
-
2. **What resources does it need to access?** (List each: databases, APIs, files, etc.)
|
|
33
|
-
3. **Where does each resource exist?** (Public internet, local network, specific machine)
|
|
34
|
-
4. **Can the execution environment reach each resource?** (Network path exists?)
|
|
41
|
+
## How It Works - The Request/Response Cycle
|
|
35
42
|
|
|
36
|
-
|
|
43
|
+
```
|
|
44
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
45
|
+
│ USER SENDS MESSAGE │
|
|
46
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
47
|
+
│
|
|
48
|
+
▼
|
|
49
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
50
|
+
│ 1. onRequest Handler (optional) │
|
|
51
|
+
│ - Pre-process user message │
|
|
52
|
+
│ - Inject context (memory items, user data) │
|
|
53
|
+
│ - Validate or transform input │
|
|
54
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
55
|
+
│
|
|
56
|
+
▼
|
|
57
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
58
|
+
│ 2. LLM Processing │
|
|
59
|
+
│ - System instructions from app/instructions.txt │
|
|
60
|
+
│ - Conversation history │
|
|
61
|
+
│ - LLM generates response (may include <command> tags) │
|
|
62
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
63
|
+
│
|
|
64
|
+
▼
|
|
65
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
66
|
+
│ 3. onResponse Handler │
|
|
67
|
+
│ - Parse LLM response for commands: <commandName>{...}</commandName> │
|
|
68
|
+
│ - Execute matching actions from actions.js │
|
|
69
|
+
│ - Return result with _meta_actions: │
|
|
70
|
+
│ • [] = stop, show result to user │
|
|
71
|
+
│ • ["REQUEST_CHAT_MODEL"] = send result back to LLM for continuation │
|
|
72
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
73
|
+
│
|
|
74
|
+
┌───────────────┴───────────────┐
|
|
75
|
+
│ │
|
|
76
|
+
▼ ▼
|
|
77
|
+
┌───────────────────┐ ┌───────────────────┐
|
|
78
|
+
│ _meta_actions: [] │ │ REQUEST_CHAT_MODEL│
|
|
79
|
+
│ Show to user │ │ Loop back to LLM │
|
|
80
|
+
└───────────────────┘ └───────────────────┘
|
|
81
|
+
```
|
|
37
82
|
|
|
38
|
-
##
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
83
|
+
## Project Structure
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
my-agent/
|
|
87
|
+
├── app/
|
|
88
|
+
│ ├── settings.json # Agent config (model, title, tools)
|
|
89
|
+
│ ├── instructions.txt # System prompt for LLM
|
|
90
|
+
│ └── icon.png # Agent icon
|
|
91
|
+
├── src/
|
|
92
|
+
│ ├── Events/ # Backend handlers (serverless)
|
|
93
|
+
│ │ ├── onRequest.js # Pre-process user messages
|
|
94
|
+
│ │ ├── onResponse.js # Execute commands from LLM
|
|
95
|
+
│ │ ├── actions.js # Command implementations
|
|
96
|
+
│ │ ├── onCronjob.js # Scheduled tasks
|
|
97
|
+
│ │ └── *.json # NPM dependencies per handler
|
|
98
|
+
│ └── Frontend/ # Browser-side React code
|
|
99
|
+
│ ├── contentRender.js # Custom UI (Header, message rendering)
|
|
100
|
+
│ └── contentRender.json # Frontend NPM dependencies
|
|
101
|
+
└── README.md
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Two Execution Environments
|
|
105
|
+
|
|
106
|
+
### 1. Backend (Cloud) - `src/Events/`
|
|
107
|
+
- Runs in **serverless Lambda** (Node.js)
|
|
108
|
+
- Stateless, ephemeral execution
|
|
109
|
+
- Has `openkbs` SDK object with full capabilities
|
|
110
|
+
- Can access external APIs, databases, send emails
|
|
111
|
+
- Triggered by: user messages, LLM responses, cronjobs, API calls
|
|
112
|
+
|
|
113
|
+
### 2. Frontend (Browser) - `src/Frontend/`
|
|
114
|
+
- Runs in **user's browser** (React)
|
|
115
|
+
- Customizes chat UI (header, message rendering)
|
|
116
|
+
- Has `openkbs` object with item CRUD, Files API, Sharing API
|
|
117
|
+
- Cannot access secrets or server-side resources
|
|
118
|
+
|
|
119
|
+
## Event Handlers
|
|
120
|
+
|
|
121
|
+
| Handler | Trigger | Purpose |
|
|
122
|
+
|---------|---------|---------|
|
|
123
|
+
| `onRequest` | User sends message | Pre-process, inject context, validate |
|
|
124
|
+
| `onResponse` | LLM generates response | Parse commands, execute actions |
|
|
125
|
+
| `onCronjob` | Cron schedule | Automated tasks, cleanup, reports |
|
|
126
|
+
| `onAddMessages` | API adds messages | Process external integrations |
|
|
127
|
+
| `onPublicAPIRequest` | Public API call | Webhooks, external triggers |
|
|
128
|
+
|
|
129
|
+
## The Command Pattern
|
|
130
|
+
|
|
131
|
+
LLM outputs commands as XML tags. Backend parses and executes them:
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
User: "Generate an image of a sunset"
|
|
135
|
+
↓
|
|
136
|
+
LLM: "I'll create that for you. <createAIImage>{"prompt": "sunset"}</createAIImage>"
|
|
137
|
+
↓
|
|
138
|
+
onResponse: Matches pattern, calls openkbs.generateImage()
|
|
139
|
+
↓
|
|
140
|
+
Returns: { type: 'CHAT_IMAGE', data: { imageUrl: '...' }, _meta_actions: [] }
|
|
141
|
+
↓
|
|
142
|
+
Frontend: Renders image to user
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Memory System
|
|
146
|
+
|
|
147
|
+
Persistent key-value storage with automatic encryption:
|
|
148
|
+
|
|
149
|
+
```javascript
|
|
150
|
+
// Backend
|
|
151
|
+
await openkbs.createItem({ itemType: 'memory', itemId: 'memory_user_prefs', body: { theme: 'dark' } });
|
|
152
|
+
const item = await openkbs.getItem('memory_user_prefs');
|
|
153
|
+
|
|
154
|
+
// Frontend (same API)
|
|
155
|
+
await openkbs.createItem({ itemType: 'memory', itemId: 'memory_key', body: { data: 'value' } });
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Items are auto-encrypted and scoped to the KB. Use prefixes for organization:
|
|
159
|
+
- `memory_` - User/agent memory
|
|
160
|
+
- `agent_` - Agent configuration
|
|
161
|
+
- `cache_` - Temporary cached data
|
|
162
|
+
|
|
163
|
+
## Frontend Framework
|
|
164
|
+
|
|
165
|
+
The frontend is an **extendable React application** that runs in the user's browser. You customize it through `contentRender.js` which exports specific functions:
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
169
|
+
│ CHAT APPLICATION (React) │
|
|
170
|
+
├─────────────────────────────────────────────────────────────────────────────┤
|
|
171
|
+
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
|
172
|
+
│ │ Header Component (optional) │ │
|
|
173
|
+
│ │ - Custom UI above chat (settings panels, navigation, branding) │ │
|
|
174
|
+
│ │ - Receives: openkbs, setRenderSettings, setSystemAlert, etc. │ │
|
|
175
|
+
│ └─────────────────────────────────────────────────────────────────────┘ │
|
|
176
|
+
│ │
|
|
177
|
+
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
|
178
|
+
│ │ Chat Messages Area │ │
|
|
179
|
+
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
|
|
180
|
+
│ │ │ Each message passes through onRenderChatMessage() │ │ │
|
|
181
|
+
│ │ │ - Return React component → custom rendering │ │ │
|
|
182
|
+
│ │ │ - Return null → default markdown rendering │ │ │
|
|
183
|
+
│ │ │ - Return HIDDEN_MESSAGE → hide message completely │ │ │
|
|
184
|
+
│ │ └─────────────────────────────────────────────────────────────┘ │ │
|
|
185
|
+
│ └─────────────────────────────────────────────────────────────────────┘ │
|
|
186
|
+
│ │
|
|
187
|
+
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
|
188
|
+
│ │ Input Area (built-in, customizable via setRenderSettings) │ │
|
|
189
|
+
│ └─────────────────────────────────────────────────────────────────────┘ │
|
|
190
|
+
└─────────────────────────────────────────────────────────────────────────────┘
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Key Extension Points:**
|
|
194
|
+
|
|
195
|
+
| Export | Purpose |
|
|
196
|
+
|--------|---------|
|
|
197
|
+
| `Header` | Custom header component (settings panels, branding, navigation) |
|
|
198
|
+
| `onRenderChatMessage` | Custom message rendering (widgets, images, hidden messages) |
|
|
199
|
+
|
|
200
|
+
**What You Can Do:**
|
|
201
|
+
|
|
202
|
+
1. **Custom Command Widgets** - Render `<createAIImage>` as icon instead of raw XML
|
|
203
|
+
2. **Settings Panels** - Add tabbed panels for Memory, Files, Sharing management
|
|
204
|
+
3. **Hide System Messages** - Filter out technical responses from UI
|
|
205
|
+
4. **Custom Interactions** - Buttons that send follow-up messages via `RequestChatAPI`
|
|
206
|
+
5. **Branding** - Custom logos, colors via `setRenderSettings`
|
|
207
|
+
|
|
208
|
+
**Built-in Libraries** (no need to install):
|
|
209
|
+
- `react` - React 18
|
|
210
|
+
- `@mui/material` - Material UI components
|
|
211
|
+
- `@mui/icons-material` - Material icons
|
|
212
|
+
- `@emotion/react` - CSS-in-JS styling
|
|
213
|
+
|
|
214
|
+
**Frontend SDK (`openkbs` object):**
|
|
215
|
+
- Item CRUD - same API as backend
|
|
216
|
+
- `openkbs.Files` - Upload, list, delete files
|
|
217
|
+
- `openkbs.KBAPI` - Share KB with users
|
|
218
|
+
- `openkbs.kbId`, `openkbs.isMobile` - Context info
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
# Architecture Details
|
|
223
|
+
|
|
224
|
+
OpenKBS provides **two execution environments**:
|
|
225
|
+
|
|
226
|
+
## Cloud Environment (`./src/Events/`)
|
|
227
|
+
Runs in serverless compute (stateless, ephemeral). Can only reach internet-accessible resources.
|
|
228
|
+
|
|
229
|
+
### Backend Handlers
|
|
230
|
+
- **`onRequest`**: Triggered on user message, allows pre-processing
|
|
231
|
+
- **`onResponse`**: Activated after LLM response, enables command extraction and action execution
|
|
232
|
+
- **`onCronjob`**: Scheduled task execution (define schedule with `handler.CRON_SCHEDULE`)
|
|
233
|
+
- **`onAddMessages`**: Intercept messages added via API
|
|
234
|
+
- **`onPublicAPIRequest`**: Handle public API requests (no auth required)
|
|
235
|
+
|
|
236
|
+
### Command Format
|
|
237
|
+
Commands use XML tags with JSON content. The LLM outputs these as regular text:
|
|
238
|
+
```xml
|
|
239
|
+
<commandName>
|
|
132
240
|
{
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
"dotenv": "latest"
|
|
136
|
-
}
|
|
241
|
+
"param1": "value1",
|
|
242
|
+
"param2": "value2"
|
|
137
243
|
}
|
|
244
|
+
</commandName>
|
|
138
245
|
```
|
|
139
|
-
Run `npm install` before executing scripts.
|
|
140
246
|
|
|
141
|
-
|
|
142
|
-
|
|
247
|
+
Self-closing tags for commands without parameters:
|
|
248
|
+
```xml
|
|
249
|
+
<commandName/>
|
|
250
|
+
```
|
|
143
251
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
252
|
+
### Action Pattern
|
|
253
|
+
```javascript
|
|
254
|
+
// src/Events/actions.js
|
|
255
|
+
export const getActions = (meta, event) => [
|
|
256
|
+
// Basic command with JSON parsing
|
|
257
|
+
[/<commandName>([\s\S]*?)<\/commandName>/s, async (match) => {
|
|
258
|
+
const data = JSON.parse(match[1].trim());
|
|
259
|
+
return { type: 'RESULT', data: result, ...meta, _meta_actions: ['REQUEST_CHAT_MODEL'] };
|
|
260
|
+
}],
|
|
261
|
+
|
|
262
|
+
// View image - adds to LLM vision context
|
|
263
|
+
[/<viewImage>([\s\S]*?)<\/viewImage>/s, async (match) => {
|
|
264
|
+
const data = JSON.parse(match[1].trim());
|
|
265
|
+
return {
|
|
266
|
+
data: [
|
|
267
|
+
{ type: "text", text: `Viewing: ${data.url}` },
|
|
268
|
+
{ type: "image_url", image_url: { url: data.url } }
|
|
269
|
+
],
|
|
270
|
+
...meta, _meta_actions: ['REQUEST_CHAT_MODEL']
|
|
271
|
+
};
|
|
272
|
+
}],
|
|
273
|
+
|
|
274
|
+
// Memory operations
|
|
275
|
+
[/<setMemory>([\s\S]*?)<\/setMemory>/s, async (match) => {
|
|
276
|
+
const data = JSON.parse(match[1].trim());
|
|
277
|
+
await openkbs.updateItem({
|
|
278
|
+
itemType: 'memory',
|
|
279
|
+
itemId: data.itemId.startsWith('memory_') ? data.itemId : `memory_${data.itemId}`,
|
|
280
|
+
body: { value: data.value, updatedAt: new Date().toISOString() }
|
|
281
|
+
});
|
|
282
|
+
return { type: 'MEMORY_UPDATED', itemId: data.itemId, ...meta, _meta_actions: ['REQUEST_CHAT_MODEL'] };
|
|
283
|
+
}],
|
|
284
|
+
|
|
285
|
+
// Delete item
|
|
286
|
+
[/<deleteItem>([\s\S]*?)<\/deleteItem>/s, async (match) => {
|
|
287
|
+
const data = JSON.parse(match[1].trim());
|
|
288
|
+
await openkbs.deleteItem(data.itemId);
|
|
289
|
+
return { type: 'ITEM_DELETED', itemId: data.itemId, ...meta, _meta_actions: ['REQUEST_CHAT_MODEL'] };
|
|
290
|
+
}],
|
|
291
|
+
];
|
|
292
|
+
```
|
|
147
293
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
294
|
+
### onCronjob Handler
|
|
295
|
+
```javascript
|
|
296
|
+
// src/Events/onCronjob.js
|
|
297
|
+
export const handler = async (event) => {
|
|
298
|
+
// Create a new chat with notification
|
|
299
|
+
await openkbs.chats({
|
|
300
|
+
chatTitle: 'Scheduled Report',
|
|
301
|
+
message: JSON.stringify([{ type: "text", text: "Daily report" }])
|
|
302
|
+
});
|
|
303
|
+
return { success: true };
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
// IMPORTANT: Define schedule at end of file
|
|
307
|
+
handler.CRON_SCHEDULE = "0 * * * *"; // Every hour
|
|
308
|
+
```
|
|
152
309
|
|
|
153
|
-
|
|
154
|
-
|
|
310
|
+
Cron patterns: `* * * * *` (every min), `*/5 * * * *` (5 min), `0 * * * *` (hourly), `0 0 * * *` (daily)
|
|
311
|
+
|
|
312
|
+
## Backend SDK (openkbs object)
|
|
313
|
+
|
|
314
|
+
### Image & Video Generation
|
|
315
|
+
```javascript
|
|
316
|
+
// Generate image with Gemini (supports editing with reference images)
|
|
317
|
+
const images = await openkbs.generateImage(prompt, {
|
|
318
|
+
model: 'gemini-2.5-flash-image', // or 'gpt-image-1' (better for text)
|
|
319
|
+
aspect_ratio: '16:9', // gemini: 1:1, 16:9, 9:16, 4:3, 3:4
|
|
320
|
+
imageUrls: ['reference.jpg'], // gemini only - for editing
|
|
321
|
+
size: '1024x1024' // gpt-image-1: 1024x1024, 1536x1024, 1024x1536
|
|
322
|
+
});
|
|
323
|
+
const uploaded = await openkbs.uploadImage(images[0].b64_json, 'output.png', 'image/png');
|
|
324
|
+
console.log(uploaded.url);
|
|
325
|
+
|
|
326
|
+
// Generate video with Sora 2
|
|
327
|
+
const video = await openkbs.generateVideo(prompt, {
|
|
328
|
+
video_model: 'sora-2', // or 'sora-2-pro' (higher quality)
|
|
329
|
+
seconds: 8, // 4, 8, or 12
|
|
330
|
+
size: '1280x720', // or '720x1280' (portrait)
|
|
331
|
+
input_reference_url: 'img.jpg' // optional reference image
|
|
332
|
+
});
|
|
333
|
+
// Check status if pending
|
|
334
|
+
if (video[0]?.status === 'pending') {
|
|
335
|
+
const status = await openkbs.checkVideoStatus(video[0].video_id);
|
|
336
|
+
}
|
|
337
|
+
```
|
|
155
338
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
339
|
+
### Item Storage (Memory System)
|
|
340
|
+
```javascript
|
|
341
|
+
// Create/Update item (upsert pattern)
|
|
342
|
+
async function upsertItem(itemType, itemId, body) {
|
|
343
|
+
try {
|
|
344
|
+
await openkbs.updateItem({ itemType, itemId, body });
|
|
345
|
+
} catch (e) {
|
|
346
|
+
await openkbs.createItem({ itemType, itemId, body });
|
|
347
|
+
}
|
|
348
|
+
}
|
|
160
349
|
|
|
161
|
-
|
|
350
|
+
// Memory with expiration
|
|
351
|
+
await upsertItem('memory', 'memory_user_preferences', {
|
|
352
|
+
value: { theme: 'dark', language: 'en' },
|
|
353
|
+
updatedAt: new Date().toISOString(),
|
|
354
|
+
exp: new Date(Date.now() + 60 * 60 * 1000).toISOString() // 1 hour
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
// Get single item (body is auto-decrypted)
|
|
358
|
+
const item = await openkbs.getItem('memory_user_preferences');
|
|
359
|
+
console.log(item.item.body.value);
|
|
360
|
+
|
|
361
|
+
// Fetch multiple items with filters
|
|
362
|
+
const items = await openkbs.fetchItems({
|
|
363
|
+
itemType: 'memory',
|
|
364
|
+
beginsWith: 'memory_',
|
|
365
|
+
limit: 100
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
// Delete item
|
|
369
|
+
await openkbs.deleteItem('memory_user_preferences');
|
|
370
|
+
|
|
371
|
+
// Cleanup expired items
|
|
372
|
+
const now = new Date();
|
|
373
|
+
for (const item of items.items) {
|
|
374
|
+
if (item.item?.body?.exp && new Date(item.item.body.exp) < now) {
|
|
375
|
+
await openkbs.deleteItem(item.meta.itemId);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
```
|
|
162
379
|
|
|
163
|
-
|
|
380
|
+
### Search & Content
|
|
381
|
+
```javascript
|
|
382
|
+
// Google Search
|
|
383
|
+
const results = await openkbs.googleSearch('AI trends 2025');
|
|
384
|
+
const images = await openkbs.googleSearch('sunset', { searchType: 'image' });
|
|
164
385
|
|
|
165
|
-
|
|
386
|
+
// Extract text from webpage
|
|
387
|
+
const text = await openkbs.webpageToText('https://example.com');
|
|
166
388
|
|
|
167
|
-
|
|
389
|
+
// OCR - extract text from image
|
|
390
|
+
const ocr = await openkbs.imageToText('https://example.com/document.jpg');
|
|
391
|
+
console.log(ocr.results);
|
|
168
392
|
|
|
169
|
-
|
|
393
|
+
// Extract text from PDF/DOC
|
|
394
|
+
const docText = await openkbs.documentToText('https://example.com/file.pdf');
|
|
395
|
+
```
|
|
170
396
|
|
|
171
|
-
|
|
397
|
+
### Communication
|
|
398
|
+
```javascript
|
|
399
|
+
// Send email (HTML supported)
|
|
400
|
+
await openkbs.sendMail('user@example.com', 'Subject', '<h1>Hello</h1><p>Content</p>');
|
|
172
401
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
- Any service with a public endpoint
|
|
402
|
+
// Text to speech
|
|
403
|
+
const audio = await openkbs.textToSpeech('Hello world');
|
|
404
|
+
console.log(audio.audioContent); // base64
|
|
177
405
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
- Cloud agents via API calls
|
|
181
|
-
- Both local and internet resources
|
|
406
|
+
// Speech to text
|
|
407
|
+
const transcript = await openkbs.speechToText('https://example.com/audio.mp3');
|
|
182
408
|
|
|
183
|
-
|
|
409
|
+
// Translation
|
|
410
|
+
const { translation } = await openkbs.translate('Hello world', 'bg');
|
|
184
411
|
|
|
185
|
-
|
|
412
|
+
// Language detection
|
|
413
|
+
const { language } = await openkbs.detectLanguage('Здравей свят');
|
|
414
|
+
```
|
|
186
415
|
|
|
187
|
-
|
|
188
|
-
|
|
416
|
+
### Chat Operations
|
|
417
|
+
```javascript
|
|
418
|
+
// Create new chat (for notifications, scheduled tasks)
|
|
419
|
+
await openkbs.chats({
|
|
420
|
+
chatTitle: 'Alert: Fire Detected',
|
|
421
|
+
message: JSON.stringify([{ type: "text", text: "Fire detected at location X" }])
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
// Update chat title and icon
|
|
425
|
+
await openkbs.chats({
|
|
426
|
+
action: "updateChat",
|
|
427
|
+
title: await openkbs.encrypt('New Title'),
|
|
428
|
+
chatIcon: '🔥',
|
|
429
|
+
chatId: event.payload.chatId
|
|
430
|
+
});
|
|
431
|
+
```
|
|
189
432
|
|
|
190
|
-
|
|
433
|
+
### Scheduled Tasks
|
|
434
|
+
```javascript
|
|
435
|
+
// Create scheduled task (fires at specific time, creates new chat)
|
|
436
|
+
await openkbs.kb({
|
|
437
|
+
action: 'createScheduledTask',
|
|
438
|
+
scheduledTime: Date.now() + 3600000, // 1 hour from now (ms)
|
|
439
|
+
taskPayload: {
|
|
440
|
+
message: '[SCHEDULED_TASK] Send weekly report',
|
|
441
|
+
customData: { reportType: 'weekly' }
|
|
442
|
+
},
|
|
443
|
+
description: 'Weekly report'
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
// List scheduled tasks
|
|
447
|
+
const tasks = await openkbs.kb({ action: 'getScheduledTasks' });
|
|
448
|
+
|
|
449
|
+
// Delete scheduled task
|
|
450
|
+
await openkbs.kb({ action: 'deleteScheduledTask', timestamp: 1704067200000 });
|
|
451
|
+
```
|
|
191
452
|
|
|
192
|
-
###
|
|
453
|
+
### File Upload with Presigned URL
|
|
454
|
+
```javascript
|
|
455
|
+
// Download file and upload to KB storage
|
|
456
|
+
const fileResponse = await axios.get(sourceUrl, { responseType: 'arraybuffer' });
|
|
193
457
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
458
|
+
const presigned = await openkbs.kb({
|
|
459
|
+
action: 'createPresignedURL',
|
|
460
|
+
namespace: 'files',
|
|
461
|
+
fileName: 'uploaded.jpg',
|
|
462
|
+
fileType: 'image/jpeg',
|
|
463
|
+
presignedOperation: 'putObject'
|
|
464
|
+
});
|
|
197
465
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
- Secure credential management via {{secrets.KEY}} system
|
|
202
|
-
- Sequential tool call execution based on intermediate results
|
|
203
|
-
- Complex data extraction and structured JSON responses
|
|
204
|
-
- Access to cloud databases, public APIs, web services with proper credentials
|
|
466
|
+
await axios.put(presigned, fileResponse.data, {
|
|
467
|
+
headers: { 'Content-Type': 'image/jpeg', 'Content-Length': fileResponse.data.length }
|
|
468
|
+
});
|
|
205
469
|
|
|
206
|
-
|
|
207
|
-
```
|
|
208
|
-
User Message → Agent Processes → Tool Call 1 → Analyze Result → Decision → Tool Call 2 → ... → Final JSON Response
|
|
470
|
+
const publicUrl = `https://your-domain.file.vpc1.us/files/${openkbs.kbId}/uploaded.jpg`;
|
|
209
471
|
```
|
|
210
472
|
|
|
211
|
-
|
|
473
|
+
### Utilities
|
|
474
|
+
```javascript
|
|
475
|
+
// Exchange rates (latest, historical, time series)
|
|
476
|
+
const rates = await openkbs.getExchangeRates({ base: 'EUR', symbols: 'USD,GBP' });
|
|
477
|
+
const historical = await openkbs.getExchangeRates({ base: 'EUR', symbols: 'USD', period: '2024-01-15' });
|
|
478
|
+
const series = await openkbs.getExchangeRates({ base: 'EUR', symbols: 'USD', period: '2024-01-01..2024-01-31' });
|
|
212
479
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
**Purpose**: Agent orchestration and local infrastructure integration
|
|
480
|
+
// VAT validation
|
|
481
|
+
const vat = await openkbs.checkVAT('BG123456789');
|
|
216
482
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
- Direct access to local services (localhost databases, file systems)
|
|
220
|
-
- Dynamic workflow creation based on agent responses
|
|
221
|
-
- Parallel and sequential agent coordination
|
|
222
|
-
- Local credential management via .env files
|
|
223
|
-
- Bridge between cloud intelligence and local infrastructure
|
|
483
|
+
// Parse JSON from text (handles LLM output with extra text)
|
|
484
|
+
const data = openkbs.parseJSONFromText('Some text {"key": "value"} more text');
|
|
224
485
|
|
|
225
|
-
|
|
486
|
+
// Encryption (uses KB's AES key)
|
|
487
|
+
const encrypted = await openkbs.encrypt(JSON.stringify(sensitiveData));
|
|
488
|
+
const decrypted = JSON.parse(await openkbs.decrypt(encrypted));
|
|
226
489
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
490
|
+
// Create embeddings
|
|
491
|
+
const { embeddings, totalTokens } = await openkbs.createEmbeddings('Text to embed', 'text-embedding-3-large');
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### Properties
|
|
495
|
+
```javascript
|
|
496
|
+
openkbs.kbId // Current Knowledge Base ID
|
|
497
|
+
openkbs.clientHeaders // Request headers (IP, user-agent, etc.)
|
|
498
|
+
openkbs.AESKey // Encryption key
|
|
499
|
+
openkbs.chatJWT // Current chat JWT token
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### NPM Dependencies
|
|
503
|
+
Add to handler's JSON file (e.g., `onResponse.json`):
|
|
504
|
+
```json
|
|
505
|
+
{
|
|
506
|
+
"dependencies": { "mysql2": "latest", "decimal.js": "^10.4.3" }
|
|
507
|
+
}
|
|
508
|
+
```
|
|
231
509
|
|
|
232
|
-
###
|
|
510
|
+
### Secrets Management
|
|
511
|
+
Use `{{secrets.KEY}}` placeholders (replaced at runtime):
|
|
512
|
+
```javascript
|
|
513
|
+
const apiKey = "{{secrets.EXTERNAL_API_KEY}}";
|
|
514
|
+
const telegramToken = "{{secrets.TELEGRAM_BOT_TOKEN}}";
|
|
515
|
+
```
|
|
233
516
|
|
|
234
|
-
|
|
517
|
+
## Browser Environment (`./src/Frontend/`)
|
|
518
|
+
Runs in user's browser at `https://[kbId].apps.openkbs.com`. React-based UI customization.
|
|
519
|
+
|
|
520
|
+
### contentRender.js
|
|
521
|
+
|
|
522
|
+
**`onRenderChatMessage(params)`** - Custom message rendering. Key params:
|
|
523
|
+
- `msgIndex`, `messages`, `setMessages` - message context
|
|
524
|
+
- `setSystemAlert({ severity, message })` - show alerts (severity: 'success', 'error', 'warning', 'info')
|
|
525
|
+
- `setBlockingLoading(bool)` - loading overlay
|
|
526
|
+
- `RequestChatAPI(messages)` - send chat messages
|
|
527
|
+
- `kbUserData()`, `generateMsgId()` - user info and ID generation
|
|
528
|
+
- `markdownHandler`, `theme` - rendering utilities
|
|
529
|
+
|
|
530
|
+
Return: React component, `null` for default, `JSON.stringify({ type: 'HIDDEN_MESSAGE' })` to hide.
|
|
531
|
+
|
|
532
|
+
**`Header(props)`** - Custom header component. Same props plus `openkbs` object.
|
|
533
|
+
|
|
534
|
+
```javascript
|
|
535
|
+
import React, { useState, useEffect } from 'react';
|
|
536
|
+
import { Box, Button, CircularProgress } from '@mui/material';
|
|
537
|
+
|
|
538
|
+
const onRenderChatMessage = async (params) => {
|
|
539
|
+
const { content, role } = params.messages[params.msgIndex];
|
|
540
|
+
const { msgIndex, messages, setSystemAlert, RequestChatAPI, kbUserData, generateMsgId } = params;
|
|
541
|
+
|
|
542
|
+
// Hide system messages
|
|
543
|
+
if (role === 'system') return JSON.stringify({ type: 'HIDDEN_MESSAGE' });
|
|
544
|
+
|
|
545
|
+
// Custom rendering for commands
|
|
546
|
+
if (content.includes('<myCommand>')) {
|
|
547
|
+
return <MyComponent content={content} />;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// Send follow-up message example
|
|
551
|
+
const sendFollowUp = async () => {
|
|
552
|
+
await RequestChatAPI([...messages, {
|
|
553
|
+
role: 'user',
|
|
554
|
+
content: 'Follow up',
|
|
555
|
+
userId: kbUserData().chatUsername,
|
|
556
|
+
msgId: generateMsgId()
|
|
557
|
+
}]);
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
return null; // Use default rendering
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
const Header = ({ setRenderSettings, openkbs, setSystemAlert, setBlockingLoading }) => {
|
|
564
|
+
const [loading, setLoading] = useState(false);
|
|
565
|
+
|
|
566
|
+
useEffect(() => {
|
|
567
|
+
setRenderSettings({
|
|
568
|
+
disableEmojiButton: true,
|
|
569
|
+
disableBalanceView: false,
|
|
570
|
+
backgroundOpacity: 0.02
|
|
571
|
+
});
|
|
572
|
+
}, [setRenderSettings]);
|
|
573
|
+
|
|
574
|
+
return <Box>Custom Header</Box>;
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
const exports = { onRenderChatMessage, Header };
|
|
578
|
+
window.contentRender = exports;
|
|
579
|
+
export default exports;
|
|
580
|
+
```
|
|
235
581
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
582
|
+
### Frontend openkbs Object
|
|
583
|
+
|
|
584
|
+
```javascript
|
|
585
|
+
// Item CRUD (auto-encrypted)
|
|
586
|
+
await openkbs.createItem({ itemType: 'memory', itemId: 'memory_key', body: { value: 'data' } });
|
|
587
|
+
await openkbs.updateItem({ itemType: 'memory', itemId: 'memory_key', body: { value: 'updated' } });
|
|
588
|
+
const item = await openkbs.getItem('memory_key');
|
|
589
|
+
console.log(item.item.body.value);
|
|
590
|
+
|
|
591
|
+
// Fetch with filters
|
|
592
|
+
const items = await openkbs.fetchItems({
|
|
593
|
+
itemType: 'memory',
|
|
594
|
+
beginsWith: 'memory_',
|
|
595
|
+
limit: 100
|
|
596
|
+
});
|
|
597
|
+
items.items.forEach(({ item, meta }) => {
|
|
598
|
+
console.log(meta.itemId, item.body);
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
await openkbs.deleteItem('memory_key');
|
|
602
|
+
```
|
|
242
603
|
|
|
604
|
+
### Files API
|
|
605
|
+
```javascript
|
|
606
|
+
// List files in namespace
|
|
607
|
+
const files = await openkbs.Files.listFiles('files');
|
|
608
|
+
// Returns: [{ Key: 'files/kbId/filename.jpg', Size: 12345, LastModified: '...' }]
|
|
243
609
|
|
|
244
|
-
|
|
610
|
+
// Upload file with progress
|
|
611
|
+
const onProgress = (percent) => console.log(`${percent}% uploaded`);
|
|
612
|
+
await openkbs.Files.uploadFileAPI(fileObject, 'files', onProgress);
|
|
245
613
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
- Agents execute autonomously in the cloud
|
|
249
|
-
- Users can login to the chat UI at `https://[kbId].apps.openkbs.com` to monitor execution
|
|
250
|
-
- Each message and tool call is visible in the chat interface
|
|
251
|
-
- Agents make decisions, call tools, and process data autonomously
|
|
252
|
-
- The agent IS the intelligence - it thinks, decides, and acts
|
|
614
|
+
// Delete file
|
|
615
|
+
await openkbs.Files.deleteRawKBFile('filename.jpg', 'files');
|
|
253
616
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
- Call cloud agents via API
|
|
257
|
-
- Receive the final JSON result after agent completes its autonomous flow
|
|
258
|
-
- Handle local infrastructure (databases, files)
|
|
259
|
-
- Orchestrate multiple agent calls
|
|
260
|
-
- Process and route results between agents
|
|
617
|
+
// Rename file
|
|
618
|
+
await openkbs.Files.renameFile('old-path/file.jpg', 'new-path/file.jpg', 'files');
|
|
261
619
|
|
|
620
|
+
// File URL pattern
|
|
621
|
+
const fileUrl = `https://your-domain.file.vpc1.us/files/${openkbs.kbId}/filename.jpg`;
|
|
622
|
+
```
|
|
262
623
|
|
|
263
|
-
###
|
|
624
|
+
### Sharing API
|
|
625
|
+
```javascript
|
|
626
|
+
// Share KB with another user
|
|
627
|
+
await openkbs.KBAPI.shareKBWith('user@example.com');
|
|
264
628
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
- Each agent can have its own set of secrets
|
|
269
|
-
- Supports database passwords, API keys, OAuth tokens
|
|
629
|
+
// Get current shares
|
|
630
|
+
const shares = await openkbs.KBAPI.getKBShares();
|
|
631
|
+
// Returns: { sharedWith: ['email1@example.com', 'email2@example.com'] }
|
|
270
632
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
- Implement proper error handling and logging
|
|
275
|
-
- Use database transactions for consistency
|
|
633
|
+
// Remove share
|
|
634
|
+
await openkbs.KBAPI.unshareKBWith('user@example.com');
|
|
635
|
+
```
|
|
276
636
|
|
|
277
|
-
###
|
|
637
|
+
### Other Frontend Properties
|
|
638
|
+
```javascript
|
|
639
|
+
openkbs.kbId // Current KB ID
|
|
640
|
+
openkbs.isMobile // Boolean - is mobile device
|
|
641
|
+
openkbs.KBData // KB metadata (title, description, etc.)
|
|
642
|
+
```
|
|
278
643
|
|
|
279
|
-
|
|
280
|
-
-
|
|
281
|
-
- Local scripts orchestrate workflows and handle infrastructure
|
|
282
|
-
- You maintain full control while agents think and act independently
|
|
644
|
+
### NPM Dependencies
|
|
645
|
+
Add to `contentRender.json`. Built-in (fixed): react, @mui/material, @mui/icons-material, @emotion/react.
|
|
283
646
|
|
|
647
|
+
# OpenKBS Commands
|
|
648
|
+
- `openkbs create my-agent` - Create new agent
|
|
649
|
+
- `openkbs push` - Deploy to cloud
|
|
650
|
+
- `openkbs update` - Update knowledge base
|
|
284
651
|
|
|
652
|
+
# Development Guidelines
|
|
653
|
+
- Backend deps → `onRequest.json`, `onResponse.json`, `onCronjob.json`
|
|
654
|
+
- Frontend deps → `contentRender.json`
|
|
655
|
+
- Provide README.md for the agent
|