openkbs 0.0.64 → 0.0.66
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/elastic/README.md +1150 -0
- package/elastic/functions.md +328 -0
- package/elastic/postgres.md +287 -0
- package/elastic/pulse.md +386 -0
- package/elastic/storage.md +291 -0
- package/package.json +1 -1
- package/src/actions.js +76 -92
- package/src/index.js +23 -10
- package/src/utils.js +8 -4
- package/templates/.claude/skills/openkbs/SKILL.md +184 -0
- package/templates/.claude/skills/openkbs/metadata.json +1 -0
- package/templates/.claude/skills/openkbs/reference/backend-sdk.md +428 -0
- package/templates/.claude/skills/openkbs/reference/commands.md +370 -0
- package/templates/.claude/skills/openkbs/reference/elastic-services.md +327 -0
- package/templates/.claude/skills/openkbs/reference/frontend-sdk.md +299 -0
- package/version.json +3 -3
- package/templates/.openkbs/knowledge/metadata.json +0 -3
- package/templates/CLAUDE.md +0 -655
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-copywriter-agent/app/icon.png +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-copywriter-agent/app/instructions.txt +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-copywriter-agent/app/settings.json +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-copywriter-agent/scripts/run_job.js +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-copywriter-agent/scripts/utils/agent_client.js +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-copywriter-agent/src/Events/actions.js +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-copywriter-agent/src/Events/handler.js +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-copywriter-agent/src/Events/onRequest.js +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-copywriter-agent/src/Events/onRequest.json +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-copywriter-agent/src/Events/onResponse.js +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-copywriter-agent/src/Events/onResponse.json +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-copywriter-agent/src/Frontend/contentRender.js +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-copywriter-agent/src/Frontend/contentRender.json +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-marketing-agent/README.md +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-marketing-agent/app/instructions.txt +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-marketing-agent/app/settings.json +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-marketing-agent/src/Events/actions.js +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-marketing-agent/src/Events/onRequest.js +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-marketing-agent/src/Events/onRequest.json +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-marketing-agent/src/Events/onResponse.js +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-marketing-agent/src/Events/onResponse.json +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-marketing-agent/src/Frontend/contentRender.js +0 -0
- /package/templates/{.openkbs/knowledge → .claude/skills/openkbs}/examples/ai-marketing-agent/src/Frontend/contentRender.json +0 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# Frontend SDK Reference
|
|
2
|
+
|
|
3
|
+
OpenKBS frontend is a React 18 application. Customize through `src/Frontend/contentRender.js`.
|
|
4
|
+
|
|
5
|
+
## Built-in Libraries (No Install Needed)
|
|
6
|
+
|
|
7
|
+
These libraries are provided by OpenKBS and marked with `(fixed)` in `contentRender.json`:
|
|
8
|
+
|
|
9
|
+
- React 18 (`react`, `react-dom`)
|
|
10
|
+
- Material-UI (`@mui/material`, `@mui/icons-material`)
|
|
11
|
+
- Emotion (`@emotion/react`, `@emotion/styled`)
|
|
12
|
+
|
|
13
|
+
## contentRender.js Exports
|
|
14
|
+
|
|
15
|
+
| Export | Purpose |
|
|
16
|
+
|--------|---------|
|
|
17
|
+
| `onRenderChatMessage` | Custom message rendering |
|
|
18
|
+
| `Header` | Custom header component |
|
|
19
|
+
|
|
20
|
+
## onRenderChatMessage
|
|
21
|
+
|
|
22
|
+
Receives each message and returns custom rendering:
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
const onRenderChatMessage = async (params) => {
|
|
26
|
+
const { content, role } = params.messages[params.msgIndex];
|
|
27
|
+
const { msgIndex, messages, markdownHandler } = params;
|
|
28
|
+
|
|
29
|
+
// Return null for default markdown rendering
|
|
30
|
+
// Return React component for custom rendering
|
|
31
|
+
// Return JSON.stringify({ type: 'HIDDEN_MESSAGE' }) to hide
|
|
32
|
+
|
|
33
|
+
return null;
|
|
34
|
+
};
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Parameters
|
|
38
|
+
|
|
39
|
+
- `params.messages` - All messages in conversation
|
|
40
|
+
- `params.msgIndex` - Current message index
|
|
41
|
+
- `params.markdownHandler` - Function to render markdown
|
|
42
|
+
- `params.setSystemAlert({ severity, message })` - Show alerts (success, error, warning, info)
|
|
43
|
+
- `params.setBlockingLoading(bool)` - Show loading overlay
|
|
44
|
+
- `params.RequestChatAPI(messages)` - Send messages to LLM
|
|
45
|
+
- `params.kbUserData()` - Get user info
|
|
46
|
+
- `params.generateMsgId()` - Generate unique message ID
|
|
47
|
+
- `params.theme` - Current MUI theme
|
|
48
|
+
|
|
49
|
+
### Return Values
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
// Default rendering
|
|
53
|
+
return null;
|
|
54
|
+
|
|
55
|
+
// Custom component
|
|
56
|
+
return <div>Custom content</div>;
|
|
57
|
+
|
|
58
|
+
// Hide message
|
|
59
|
+
return JSON.stringify({ type: 'HIDDEN_MESSAGE' });
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Header Component
|
|
63
|
+
|
|
64
|
+
Customize the chat header:
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
const Header = ({ setRenderSettings }) => {
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
setRenderSettings({
|
|
70
|
+
disableShareButton: true,
|
|
71
|
+
disableBalanceView: true
|
|
72
|
+
});
|
|
73
|
+
}, [setRenderSettings]);
|
|
74
|
+
|
|
75
|
+
return <div>Custom Header</div>;
|
|
76
|
+
};
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Command Rendering Pattern
|
|
80
|
+
|
|
81
|
+
Define commands with icons:
|
|
82
|
+
|
|
83
|
+
```javascript
|
|
84
|
+
// commands.js
|
|
85
|
+
import SearchIcon from '@mui/icons-material/Search';
|
|
86
|
+
import ImageIcon from '@mui/icons-material/Image';
|
|
87
|
+
|
|
88
|
+
export const COMMANDS = {
|
|
89
|
+
googleSearch: { icon: SearchIcon },
|
|
90
|
+
createAIImage: { icon: ImageIcon },
|
|
91
|
+
cleanupMemory: { icon: ClearIcon, selfClosing: true }
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// Generate regex patterns
|
|
95
|
+
export const COMMAND_PATTERNS = Object.entries(COMMANDS).map(([name, config]) => {
|
|
96
|
+
if (config.selfClosing) {
|
|
97
|
+
return new RegExp(`<${name}\\s*\\/>`);
|
|
98
|
+
}
|
|
99
|
+
return new RegExp(`<${name}>[\\s\\S]*?<\\/${name}>`);
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Command Circle Component
|
|
104
|
+
|
|
105
|
+
Render commands as interactive icons:
|
|
106
|
+
|
|
107
|
+
```javascript
|
|
108
|
+
const CommandCircle = ({ command, response }) => {
|
|
109
|
+
const IconComponent = COMMANDS[command.name]?.icon || BoltIcon;
|
|
110
|
+
const isSuccess = response && !response.error;
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<Tooltip title={getTooltipContent()}>
|
|
114
|
+
<Box sx={{
|
|
115
|
+
width: 36, height: 36,
|
|
116
|
+
borderRadius: '50%',
|
|
117
|
+
backgroundColor: isSuccess ? 'rgba(76, 175, 80, 0.08)' : 'rgba(0, 0, 0, 0.04)',
|
|
118
|
+
border: '2px solid',
|
|
119
|
+
borderColor: isSuccess ? 'rgba(76, 175, 80, 0.3)' : 'rgba(0, 0, 0, 0.12)',
|
|
120
|
+
display: 'flex',
|
|
121
|
+
alignItems: 'center',
|
|
122
|
+
justifyContent: 'center'
|
|
123
|
+
}}>
|
|
124
|
+
<IconComponent sx={{ fontSize: 18 }} />
|
|
125
|
+
</Box>
|
|
126
|
+
</Tooltip>
|
|
127
|
+
);
|
|
128
|
+
};
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Image Display with Download
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
const ImageWithDownload = ({ imageUrl }) => {
|
|
135
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
136
|
+
|
|
137
|
+
const handleDownload = async () => {
|
|
138
|
+
const link = document.createElement('a');
|
|
139
|
+
link.download = 'image.png';
|
|
140
|
+
|
|
141
|
+
const response = await fetch(imageUrl);
|
|
142
|
+
const blob = await response.blob();
|
|
143
|
+
link.href = URL.createObjectURL(blob);
|
|
144
|
+
link.click();
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<div>
|
|
149
|
+
<img
|
|
150
|
+
src={imageUrl}
|
|
151
|
+
onLoad={() => setIsLoading(false)}
|
|
152
|
+
style={{ maxWidth: '100%', borderRadius: 8 }}
|
|
153
|
+
/>
|
|
154
|
+
{!isLoading && (
|
|
155
|
+
<button onClick={handleDownload}>
|
|
156
|
+
<DownloadIcon /> Download
|
|
157
|
+
</button>
|
|
158
|
+
)}
|
|
159
|
+
</div>
|
|
160
|
+
);
|
|
161
|
+
};
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Parsing JSON Results
|
|
165
|
+
|
|
166
|
+
```javascript
|
|
167
|
+
const onRenderChatMessage = async (params) => {
|
|
168
|
+
const { content } = params.messages[params.msgIndex];
|
|
169
|
+
|
|
170
|
+
let JSONData;
|
|
171
|
+
try { JSONData = JSON.parse(content); } catch (e) {}
|
|
172
|
+
|
|
173
|
+
// Handle CHAT_IMAGE result
|
|
174
|
+
if (JSONData?.type === 'CHAT_IMAGE' && JSONData?.data?.imageUrl) {
|
|
175
|
+
return <ImageWithDownload imageUrl={JSONData.data.imageUrl} />;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Hide CONTINUE messages
|
|
179
|
+
if (JSONData?.type === 'CONTINUE') {
|
|
180
|
+
return JSON.stringify({ type: 'HIDDEN_MESSAGE' });
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return null;
|
|
184
|
+
};
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## contentRender.json
|
|
188
|
+
|
|
189
|
+
Declare dependencies:
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"dependencies": {
|
|
194
|
+
"react": "^18.2.0 (fixed)",
|
|
195
|
+
"react-dom": "^18.2.0 (fixed)",
|
|
196
|
+
"@mui/material": "^5.16.1 (fixed)",
|
|
197
|
+
"@mui/icons-material": "^5.16.1 (fixed)",
|
|
198
|
+
"@emotion/react": "^11.10.6 (fixed)",
|
|
199
|
+
"@emotion/styled": "^11.10.6 (fixed)"
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The `(fixed)` suffix indicates built-in libraries that don't need bundling.
|
|
205
|
+
|
|
206
|
+
## Frontend openkbs Object
|
|
207
|
+
|
|
208
|
+
The `openkbs` object is available globally in frontend code.
|
|
209
|
+
|
|
210
|
+
### Item CRUD
|
|
211
|
+
|
|
212
|
+
```javascript
|
|
213
|
+
// Create item
|
|
214
|
+
await openkbs.createItem({
|
|
215
|
+
itemType: 'memory',
|
|
216
|
+
itemId: 'memory_key',
|
|
217
|
+
body: { value: 'data' }
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Update item
|
|
221
|
+
await openkbs.updateItem({
|
|
222
|
+
itemType: 'memory',
|
|
223
|
+
itemId: 'memory_key',
|
|
224
|
+
body: { value: 'updated' }
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// Get single item
|
|
228
|
+
const item = await openkbs.getItem('memory_key');
|
|
229
|
+
console.log(item.item.body.value);
|
|
230
|
+
|
|
231
|
+
// Fetch multiple items
|
|
232
|
+
const items = await openkbs.fetchItems({
|
|
233
|
+
itemType: 'memory',
|
|
234
|
+
beginsWith: 'memory_',
|
|
235
|
+
limit: 100
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
// Delete item
|
|
239
|
+
await openkbs.deleteItem('memory_key');
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Files API
|
|
243
|
+
|
|
244
|
+
```javascript
|
|
245
|
+
// List files
|
|
246
|
+
const files = await openkbs.Files.listFiles('files');
|
|
247
|
+
// Returns: [{ Key, Size, LastModified }, ...]
|
|
248
|
+
|
|
249
|
+
// Upload with progress
|
|
250
|
+
const onProgress = (percent) => console.log(`${percent}%`);
|
|
251
|
+
await openkbs.Files.uploadFileAPI(fileObject, 'files', onProgress);
|
|
252
|
+
|
|
253
|
+
// Delete file
|
|
254
|
+
await openkbs.Files.deleteRawKBFile('filename.jpg', 'files');
|
|
255
|
+
|
|
256
|
+
// Rename file
|
|
257
|
+
await openkbs.Files.renameFile('old.jpg', 'new.jpg', 'files');
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Sharing API
|
|
261
|
+
|
|
262
|
+
```javascript
|
|
263
|
+
// Share KB
|
|
264
|
+
await openkbs.KBAPI.shareKBWith('user@example.com');
|
|
265
|
+
|
|
266
|
+
// Get shares
|
|
267
|
+
const shares = await openkbs.KBAPI.getKBShares();
|
|
268
|
+
// Returns: { sharedWith: ['email1', 'email2'] }
|
|
269
|
+
|
|
270
|
+
// Remove share
|
|
271
|
+
await openkbs.KBAPI.unshareKBWith('user@example.com');
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Properties
|
|
275
|
+
|
|
276
|
+
```javascript
|
|
277
|
+
openkbs.kbId // Current KB ID
|
|
278
|
+
openkbs.isMobile // Boolean - is mobile device
|
|
279
|
+
openkbs.KBData // KB metadata
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Debug Mode
|
|
283
|
+
|
|
284
|
+
Add `?debug=1` to URL to see raw messages:
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
https://YOUR_KB_ID.apps.openkbs.com?debug=1
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Mobile Detection
|
|
291
|
+
|
|
292
|
+
```javascript
|
|
293
|
+
const isMobile = window.innerWidth < 960;
|
|
294
|
+
// Or use: openkbs.isMobile
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## Complete Example
|
|
298
|
+
|
|
299
|
+
See [examples/ai-marketing-agent/src/Frontend/](../examples/ai-marketing-agent/src/Frontend/) for a full implementation.
|
package/version.json
CHANGED