openkbs 0.0.65 → 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/README.md +0 -2
- package/package.json +1 -1
- package/src/actions.js +41 -85
- package/src/index.js +8 -9
- 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
package/README.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# OpenKBS · [](https://github.com/open-kbs/openkbs-chat/blob/main/LICENSE) [](https://www.npmjs.com/package/openkbs)
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
3
|
OpenKBS is an extendable AI service designed to build,
|
|
6
4
|
deploy and integrate AI agents and applications.
|
|
7
5
|
|
package/package.json
CHANGED
package/src/actions.js
CHANGED
|
@@ -611,20 +611,11 @@ async function downloadModifyAction() {
|
|
|
611
611
|
});
|
|
612
612
|
}
|
|
613
613
|
|
|
614
|
-
async function
|
|
614
|
+
async function updateSkillsAction(silent = false) {
|
|
615
615
|
try {
|
|
616
|
-
const
|
|
617
|
-
const metadataPath = path.join(
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
// Check if .openkbs/knowledge directory exists
|
|
621
|
-
if (!fs.existsSync(knowledgeDir)) {
|
|
622
|
-
if (!silent) {
|
|
623
|
-
console.red('Knowledge directory not found. Please ensure you are in an OpenKBS project directory.');
|
|
624
|
-
}
|
|
625
|
-
return;
|
|
626
|
-
}
|
|
627
|
-
|
|
616
|
+
const skillsDir = path.join(process.cwd(), '.claude', 'skills', 'openkbs');
|
|
617
|
+
const metadataPath = path.join(skillsDir, 'metadata.json');
|
|
618
|
+
|
|
628
619
|
// Get local metadata version
|
|
629
620
|
let localVersion = null;
|
|
630
621
|
if (fs.existsSync(metadataPath)) {
|
|
@@ -635,15 +626,14 @@ async function updateKnowledgeAction(silent = false) {
|
|
|
635
626
|
if (!silent) {
|
|
636
627
|
console.red('Error reading local metadata.json:', error.message);
|
|
637
628
|
}
|
|
638
|
-
return;
|
|
639
629
|
}
|
|
640
630
|
}
|
|
641
|
-
|
|
631
|
+
|
|
642
632
|
// Check remote version from S3
|
|
643
633
|
const https = require('https');
|
|
644
634
|
const bucket = 'openkbs-downloads';
|
|
645
|
-
const remoteMetadataKey = 'templates/.openkbs/
|
|
646
|
-
|
|
635
|
+
const remoteMetadataKey = 'templates/.claude/skills/openkbs/metadata.json';
|
|
636
|
+
|
|
647
637
|
let remoteVersion = null;
|
|
648
638
|
try {
|
|
649
639
|
const fileUrl = `https://${bucket}.s3.amazonaws.com/${remoteMetadataKey}`;
|
|
@@ -654,7 +644,7 @@ async function updateKnowledgeAction(silent = false) {
|
|
|
654
644
|
res.on('end', () => resolve(data));
|
|
655
645
|
}).on('error', reject);
|
|
656
646
|
});
|
|
657
|
-
|
|
647
|
+
|
|
658
648
|
const remoteMetadata = JSON.parse(remoteMetadataContent);
|
|
659
649
|
remoteVersion = remoteMetadata.version;
|
|
660
650
|
} catch (error) {
|
|
@@ -663,26 +653,23 @@ async function updateKnowledgeAction(silent = false) {
|
|
|
663
653
|
}
|
|
664
654
|
return;
|
|
665
655
|
}
|
|
666
|
-
|
|
656
|
+
|
|
667
657
|
// Compare versions
|
|
668
658
|
if (localVersion === remoteVersion) {
|
|
669
|
-
console.green('
|
|
659
|
+
console.green('OpenKBS skill is already up to date.');
|
|
670
660
|
return;
|
|
671
661
|
}
|
|
672
|
-
|
|
673
|
-
console.log(`Updating
|
|
674
|
-
|
|
675
|
-
// Download updated
|
|
676
|
-
await
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
console.green('Knowledge base updated successfully!');
|
|
682
|
-
|
|
662
|
+
|
|
663
|
+
console.log(`Updating OpenKBS skill from version ${localVersion || 'not installed'} to ${remoteVersion}...`);
|
|
664
|
+
|
|
665
|
+
// Download updated skill files from S3
|
|
666
|
+
await downloadSkillsFromS3(skillsDir);
|
|
667
|
+
|
|
668
|
+
console.green('OpenKBS skill updated successfully!');
|
|
669
|
+
|
|
683
670
|
} catch (error) {
|
|
684
671
|
if (!silent) {
|
|
685
|
-
console.red('Error updating
|
|
672
|
+
console.red('Error updating skills:', error.message);
|
|
686
673
|
}
|
|
687
674
|
}
|
|
688
675
|
}
|
|
@@ -744,8 +731,8 @@ async function updateCliAction() {
|
|
|
744
731
|
console.red('Error fetching CLI version metadata:', error.message);
|
|
745
732
|
}
|
|
746
733
|
|
|
747
|
-
// Also update
|
|
748
|
-
await
|
|
734
|
+
// Also update skills silently
|
|
735
|
+
await updateSkillsAction(true);
|
|
749
736
|
|
|
750
737
|
} catch (error) {
|
|
751
738
|
console.red('Error updating CLI:', error.message);
|
|
@@ -816,14 +803,17 @@ function compareVersions(version1, version2) {
|
|
|
816
803
|
}
|
|
817
804
|
|
|
818
805
|
|
|
819
|
-
async function
|
|
806
|
+
async function downloadSkillsFromS3(targetDir) {
|
|
820
807
|
const https = require('https');
|
|
821
808
|
const bucket = 'openkbs-downloads';
|
|
822
|
-
const prefix = 'templates/.openkbs/
|
|
809
|
+
const prefix = 'templates/.claude/skills/openkbs/';
|
|
823
810
|
const baseUrl = `https://${bucket}.s3.amazonaws.com`;
|
|
824
|
-
|
|
811
|
+
|
|
825
812
|
try {
|
|
826
|
-
//
|
|
813
|
+
// Ensure directory exists
|
|
814
|
+
await fs.ensureDir(targetDir);
|
|
815
|
+
|
|
816
|
+
// List all objects in skills folder
|
|
827
817
|
const listUrl = `${baseUrl}/?list-type=2&prefix=${prefix}`;
|
|
828
818
|
const listXml = await new Promise((resolve, reject) => {
|
|
829
819
|
https.get(listUrl, (res) => {
|
|
@@ -832,28 +822,28 @@ async function downloadKnowledgeFromS3(targetDir) {
|
|
|
832
822
|
res.on('end', () => resolve(data));
|
|
833
823
|
}).on('error', reject);
|
|
834
824
|
});
|
|
835
|
-
|
|
825
|
+
|
|
836
826
|
// Parse XML to extract object keys
|
|
837
827
|
const keyMatches = listXml.match(/<Key>([^<]+)<\/Key>/g) || [];
|
|
838
828
|
const keys = keyMatches.map(match => match.replace(/<\/?Key>/g, ''));
|
|
839
|
-
|
|
829
|
+
|
|
840
830
|
if (keys.length === 0) {
|
|
841
|
-
console.yellow('No
|
|
831
|
+
console.yellow('No skill files found in remote repository.');
|
|
842
832
|
return;
|
|
843
833
|
}
|
|
844
|
-
|
|
834
|
+
|
|
845
835
|
// Download all files in parallel
|
|
846
836
|
const downloadPromises = keys.map(async (key) => {
|
|
847
837
|
const relativePath = key.substring(prefix.length);
|
|
848
|
-
|
|
838
|
+
|
|
849
839
|
// Skip if it's a directory marker
|
|
850
840
|
if (relativePath.endsWith('/') || relativePath === '') return;
|
|
851
|
-
|
|
841
|
+
|
|
852
842
|
const localPath = path.join(targetDir, relativePath);
|
|
853
|
-
|
|
843
|
+
|
|
854
844
|
// Ensure directory exists
|
|
855
845
|
await fs.ensureDir(path.dirname(localPath));
|
|
856
|
-
|
|
846
|
+
|
|
857
847
|
// Download file
|
|
858
848
|
const fileUrl = `${baseUrl}/${key}`;
|
|
859
849
|
const fileContent = await new Promise((resolve, reject) => {
|
|
@@ -864,49 +854,15 @@ async function downloadKnowledgeFromS3(targetDir) {
|
|
|
864
854
|
}).on('error', reject);
|
|
865
855
|
});
|
|
866
856
|
await fs.writeFile(localPath, fileContent);
|
|
867
|
-
|
|
857
|
+
|
|
868
858
|
console.log(`Downloaded: ${relativePath}`);
|
|
869
859
|
});
|
|
870
|
-
|
|
860
|
+
|
|
871
861
|
await Promise.all(downloadPromises);
|
|
872
|
-
|
|
873
|
-
} catch (error) {
|
|
874
|
-
console.red('Error downloading knowledge files from S3:', error.message);
|
|
875
|
-
throw error;
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
862
|
|
|
879
|
-
async function downloadClaudeMdFromS3(claudeMdPath) {
|
|
880
|
-
const https = require('https');
|
|
881
|
-
const bucket = 'openkbs-downloads';
|
|
882
|
-
const claudeMdKey = 'templates/CLAUDE.md';
|
|
883
|
-
|
|
884
|
-
try {
|
|
885
|
-
// Download CLAUDE.md file from S3
|
|
886
|
-
const fileUrl = `https://${bucket}.s3.amazonaws.com/${claudeMdKey}`;
|
|
887
|
-
const fileContent = await new Promise((resolve, reject) => {
|
|
888
|
-
https.get(fileUrl, (res) => {
|
|
889
|
-
if (res.statusCode === 404) {
|
|
890
|
-
reject(new Error('NoSuchKey'));
|
|
891
|
-
return;
|
|
892
|
-
}
|
|
893
|
-
const chunks = [];
|
|
894
|
-
res.on('data', (chunk) => chunks.push(chunk));
|
|
895
|
-
res.on('end', () => resolve(Buffer.concat(chunks)));
|
|
896
|
-
}).on('error', reject);
|
|
897
|
-
});
|
|
898
|
-
|
|
899
|
-
await fs.writeFile(claudeMdPath, fileContent);
|
|
900
|
-
|
|
901
|
-
console.log('Downloaded: CLAUDE.md');
|
|
902
|
-
|
|
903
863
|
} catch (error) {
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
} else {
|
|
907
|
-
console.red('Error downloading CLAUDE.md:', error.message);
|
|
908
|
-
throw error;
|
|
909
|
-
}
|
|
864
|
+
console.red('Error downloading skill files from S3:', error.message);
|
|
865
|
+
throw error;
|
|
910
866
|
}
|
|
911
867
|
}
|
|
912
868
|
|
|
@@ -2490,7 +2446,7 @@ module.exports = {
|
|
|
2490
2446
|
installFrontendPackageAction,
|
|
2491
2447
|
modifyAction,
|
|
2492
2448
|
downloadModifyAction,
|
|
2493
|
-
|
|
2449
|
+
updateSkillsAction,
|
|
2494
2450
|
updateCliAction,
|
|
2495
2451
|
publishAction,
|
|
2496
2452
|
unpublishAction,
|
package/src/index.js
CHANGED
|
@@ -13,7 +13,7 @@ const {
|
|
|
13
13
|
deleteFileAction,
|
|
14
14
|
describeAction, deployAction, createByTemplateAction, initByTemplateAction,
|
|
15
15
|
logoutAction, installFrontendPackageAction, modifyAction, downloadModifyAction,
|
|
16
|
-
|
|
16
|
+
updateSkillsAction, updateCliAction, publishAction, unpublishAction,
|
|
17
17
|
fnAction,
|
|
18
18
|
siteAction,
|
|
19
19
|
storageAction,
|
|
@@ -194,25 +194,24 @@ This file will be automatically included when you run the 'openkbs modify' comma
|
|
|
194
194
|
|
|
195
195
|
program
|
|
196
196
|
.command('update [target]')
|
|
197
|
-
.description('Update OpenKBS CLI or
|
|
197
|
+
.description('Update OpenKBS CLI or skills (default: CLI)')
|
|
198
198
|
.action((target) => {
|
|
199
199
|
if (!target) {
|
|
200
200
|
updateCliAction();
|
|
201
|
-
} else if (target === '
|
|
202
|
-
|
|
201
|
+
} else if (target === 'skills') {
|
|
202
|
+
updateSkillsAction();
|
|
203
203
|
} else {
|
|
204
|
-
console.error(`Unknown update target: ${target}.
|
|
204
|
+
console.error(`Unknown update target: ${target}. Supported: skills`);
|
|
205
205
|
process.exit(1);
|
|
206
206
|
}
|
|
207
207
|
})
|
|
208
208
|
.addHelpText('after', `
|
|
209
209
|
Examples:
|
|
210
210
|
$ openkbs update
|
|
211
|
-
|
|
211
|
+
Check for CLI updates and install them.
|
|
212
212
|
|
|
213
|
-
$ openkbs update
|
|
214
|
-
|
|
215
|
-
and update it if necessary.
|
|
213
|
+
$ openkbs update skills
|
|
214
|
+
Update .claude/skills/openkbs/ with latest OpenKBS skill files.
|
|
216
215
|
`);
|
|
217
216
|
|
|
218
217
|
program
|
|
@@ -0,0 +1,184 @@
|
|
|
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 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.
|
|
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
|
+
└── openkbs.json # Elastic services config
|
|
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": "nodejs22.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
|
+
## Backend Handler Pattern
|
|
127
|
+
|
|
128
|
+
Commands are XML tags with JSON content that the LLM outputs:
|
|
129
|
+
|
|
130
|
+
```xml
|
|
131
|
+
<commandName>{"param": "value"}</commandName>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The `handler.js` parses these tags, matches regex patterns in `actions.js`, and executes async functions:
|
|
135
|
+
|
|
136
|
+
```javascript
|
|
137
|
+
// actions.js pattern
|
|
138
|
+
[/<googleSearch>([\s\S]*?)<\/googleSearch>/s, async (match) => {
|
|
139
|
+
const data = JSON.parse(match[1].trim());
|
|
140
|
+
const results = await openkbs.googleSearch(data.query);
|
|
141
|
+
return {
|
|
142
|
+
type: 'SEARCH_RESULTS',
|
|
143
|
+
data: results,
|
|
144
|
+
_meta_actions: ["REQUEST_CHAT_MODEL"] // Loop back to LLM
|
|
145
|
+
};
|
|
146
|
+
}]
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Meta Actions
|
|
150
|
+
|
|
151
|
+
Control flow after command execution:
|
|
152
|
+
|
|
153
|
+
- `["REQUEST_CHAT_MODEL"]` - Send result back to LLM for processing
|
|
154
|
+
- `[]` - Display result to user, stop conversation
|
|
155
|
+
|
|
156
|
+
## Memory System
|
|
157
|
+
|
|
158
|
+
Configure in `settings.json`:
|
|
159
|
+
|
|
160
|
+
```json
|
|
161
|
+
{
|
|
162
|
+
"itemTypes": {
|
|
163
|
+
"memory": {
|
|
164
|
+
"attributes": [
|
|
165
|
+
{ "attrName": "itemId", "attrType": "itemId", "encrypted": false },
|
|
166
|
+
{ "attrName": "body", "attrType": "body", "encrypted": true }
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
"options": {
|
|
171
|
+
"priorityItems": [{ "prefix": "memory_", "limit": 100 }]
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Priority items are auto-injected into LLM context.
|
|
177
|
+
|
|
178
|
+
## Additional Resources
|
|
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/)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version": "0.1.0"}
|