openkbs 0.0.42 → 0.0.44
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 +47 -30
- package/src/utils.js +27 -15
- package/templates/CLAUDE.md +1 -1
- package/templates/scripts/utils/agent_client.js +11 -1
package/package.json
CHANGED
package/src/actions.js
CHANGED
|
@@ -563,19 +563,21 @@ async function updateKnowledgeAction() {
|
|
|
563
563
|
}
|
|
564
564
|
|
|
565
565
|
// Check remote version from S3
|
|
566
|
-
const
|
|
567
|
-
const s3Client = new S3Client({ region: 'us-east-1' });
|
|
566
|
+
const https = require('https');
|
|
568
567
|
const bucket = 'openkbs-downloads';
|
|
569
568
|
const remoteMetadataKey = 'templates/.openkbs/knowledge/metadata.json';
|
|
570
569
|
|
|
571
570
|
let remoteVersion = null;
|
|
572
571
|
try {
|
|
573
|
-
const
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
572
|
+
const fileUrl = `https://${bucket}.s3.amazonaws.com/${remoteMetadataKey}`;
|
|
573
|
+
const remoteMetadataContent = await new Promise((resolve, reject) => {
|
|
574
|
+
https.get(fileUrl, (res) => {
|
|
575
|
+
let data = '';
|
|
576
|
+
res.on('data', (chunk) => data += chunk);
|
|
577
|
+
res.on('end', () => resolve(data));
|
|
578
|
+
}).on('error', reject);
|
|
579
|
+
});
|
|
577
580
|
|
|
578
|
-
const remoteMetadataContent = await response.Body.transformToString();
|
|
579
581
|
const remoteMetadata = JSON.parse(remoteMetadataContent);
|
|
580
582
|
remoteVersion = remoteMetadata.version;
|
|
581
583
|
} catch (error) {
|
|
@@ -605,26 +607,33 @@ async function updateKnowledgeAction() {
|
|
|
605
607
|
}
|
|
606
608
|
|
|
607
609
|
async function downloadKnowledgeFromS3(targetDir) {
|
|
608
|
-
const
|
|
609
|
-
const s3Client = new S3Client({ region: 'us-east-1' });
|
|
610
|
+
const https = require('https');
|
|
610
611
|
const bucket = 'openkbs-downloads';
|
|
611
612
|
const prefix = 'templates/.openkbs/knowledge/';
|
|
613
|
+
const baseUrl = `https://${bucket}.s3.amazonaws.com`;
|
|
612
614
|
|
|
613
615
|
try {
|
|
614
616
|
// List all objects in knowledge folder
|
|
615
|
-
const
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
617
|
+
const listUrl = `${baseUrl}/?list-type=2&prefix=${prefix}`;
|
|
618
|
+
const listXml = await new Promise((resolve, reject) => {
|
|
619
|
+
https.get(listUrl, (res) => {
|
|
620
|
+
let data = '';
|
|
621
|
+
res.on('data', (chunk) => data += chunk);
|
|
622
|
+
res.on('end', () => resolve(data));
|
|
623
|
+
}).on('error', reject);
|
|
624
|
+
});
|
|
619
625
|
|
|
620
|
-
|
|
626
|
+
// Parse XML to extract object keys
|
|
627
|
+
const keyMatches = listXml.match(/<Key>([^<]+)<\/Key>/g) || [];
|
|
628
|
+
const keys = keyMatches.map(match => match.replace(/<\/?Key>/g, ''));
|
|
629
|
+
|
|
630
|
+
if (keys.length === 0) {
|
|
621
631
|
console.yellow('No knowledge files found in remote repository.');
|
|
622
632
|
return;
|
|
623
633
|
}
|
|
624
634
|
|
|
625
635
|
// Download all files in parallel
|
|
626
|
-
const downloadPromises =
|
|
627
|
-
const key = obj.Key;
|
|
636
|
+
const downloadPromises = keys.map(async (key) => {
|
|
628
637
|
const relativePath = key.substring(prefix.length);
|
|
629
638
|
|
|
630
639
|
// Skip if it's a directory marker
|
|
@@ -636,12 +645,14 @@ async function downloadKnowledgeFromS3(targetDir) {
|
|
|
636
645
|
await fs.ensureDir(path.dirname(localPath));
|
|
637
646
|
|
|
638
647
|
// Download file
|
|
639
|
-
const
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
648
|
+
const fileUrl = `${baseUrl}/${key}`;
|
|
649
|
+
const fileContent = await new Promise((resolve, reject) => {
|
|
650
|
+
https.get(fileUrl, (res) => {
|
|
651
|
+
const chunks = [];
|
|
652
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
653
|
+
res.on('end', () => resolve(Buffer.concat(chunks)));
|
|
654
|
+
}).on('error', reject);
|
|
655
|
+
});
|
|
645
656
|
await fs.writeFile(localPath, fileContent);
|
|
646
657
|
|
|
647
658
|
console.log(`Downloaded: ${relativePath}`);
|
|
@@ -656,25 +667,31 @@ async function downloadKnowledgeFromS3(targetDir) {
|
|
|
656
667
|
}
|
|
657
668
|
|
|
658
669
|
async function downloadClaudeMdFromS3(claudeMdPath) {
|
|
659
|
-
const
|
|
660
|
-
const s3Client = new S3Client({ region: 'us-east-1' });
|
|
670
|
+
const https = require('https');
|
|
661
671
|
const bucket = 'openkbs-downloads';
|
|
662
672
|
const claudeMdKey = 'templates/CLAUDE.md';
|
|
663
673
|
|
|
664
674
|
try {
|
|
665
675
|
// Download CLAUDE.md file from S3
|
|
666
|
-
const
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
676
|
+
const fileUrl = `https://${bucket}.s3.amazonaws.com/${claudeMdKey}`;
|
|
677
|
+
const fileContent = await new Promise((resolve, reject) => {
|
|
678
|
+
https.get(fileUrl, (res) => {
|
|
679
|
+
if (res.statusCode === 404) {
|
|
680
|
+
reject(new Error('NoSuchKey'));
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
const chunks = [];
|
|
684
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
685
|
+
res.on('end', () => resolve(Buffer.concat(chunks)));
|
|
686
|
+
}).on('error', reject);
|
|
687
|
+
});
|
|
670
688
|
|
|
671
|
-
const fileContent = await response.Body.transformToByteArray();
|
|
672
689
|
await fs.writeFile(claudeMdPath, fileContent);
|
|
673
690
|
|
|
674
691
|
console.log('Downloaded: CLAUDE.md');
|
|
675
692
|
|
|
676
693
|
} catch (error) {
|
|
677
|
-
if (error.
|
|
694
|
+
if (error.message === 'NoSuchKey') {
|
|
678
695
|
console.yellow('CLAUDE.md not found in remote repository, skipping...');
|
|
679
696
|
} else {
|
|
680
697
|
console.red('Error downloading CLAUDE.md:', error.message);
|
package/src/utils.js
CHANGED
|
@@ -1047,25 +1047,34 @@ async function downloadTemplates() {
|
|
|
1047
1047
|
}
|
|
1048
1048
|
|
|
1049
1049
|
async function downloadTemplatesFromS3(targetDir) {
|
|
1050
|
-
const
|
|
1051
|
-
const { ListObjectsV2Command, GetObjectCommand } = require('@aws-sdk/client-s3');
|
|
1050
|
+
const https = require('https');
|
|
1052
1051
|
|
|
1053
1052
|
const bucket = 'openkbs-downloads';
|
|
1054
1053
|
const prefix = 'templates/';
|
|
1054
|
+
const baseUrl = `https://${bucket}.s3.amazonaws.com`;
|
|
1055
1055
|
|
|
1056
|
-
// List all objects in templates folder
|
|
1057
|
-
const
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1056
|
+
// List all objects in templates folder using S3 REST API
|
|
1057
|
+
const listUrl = `${baseUrl}/?list-type=2&prefix=${prefix}`;
|
|
1058
|
+
|
|
1059
|
+
const listXml = await new Promise((resolve, reject) => {
|
|
1060
|
+
https.get(listUrl, (res) => {
|
|
1061
|
+
let data = '';
|
|
1062
|
+
res.on('data', (chunk) => data += chunk);
|
|
1063
|
+
res.on('end', () => resolve(data));
|
|
1064
|
+
}).on('error', reject);
|
|
1065
|
+
});
|
|
1066
|
+
|
|
1067
|
+
// Parse XML to extract object keys
|
|
1068
|
+
const keyMatches = listXml.match(/<Key>([^<]+)<\/Key>/g) || [];
|
|
1069
|
+
|
|
1070
|
+
const keys = keyMatches.map(match => match.replace(/<\/?Key>/g, ''));
|
|
1061
1071
|
|
|
1062
1072
|
// Download all files in parallel
|
|
1063
|
-
const downloadPromises =
|
|
1064
|
-
const key = obj.Key;
|
|
1073
|
+
const downloadPromises = keys.map(async (key) => {
|
|
1065
1074
|
const relativePath = key.substring(prefix.length);
|
|
1066
1075
|
|
|
1067
1076
|
// Skip if it's a directory marker
|
|
1068
|
-
if (relativePath.endsWith('/')) return;
|
|
1077
|
+
if (relativePath.endsWith('/') || !relativePath) return;
|
|
1069
1078
|
|
|
1070
1079
|
const localPath = path.join(targetDir, relativePath);
|
|
1071
1080
|
|
|
@@ -1073,12 +1082,15 @@ async function downloadTemplatesFromS3(targetDir) {
|
|
|
1073
1082
|
await fs.ensureDir(path.dirname(localPath));
|
|
1074
1083
|
|
|
1075
1084
|
// Download file
|
|
1076
|
-
const
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1085
|
+
const fileUrl = `${baseUrl}/${key}`;
|
|
1086
|
+
const fileContent = await new Promise((resolve, reject) => {
|
|
1087
|
+
https.get(fileUrl, (res) => {
|
|
1088
|
+
const chunks = [];
|
|
1089
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
1090
|
+
res.on('end', () => resolve(Buffer.concat(chunks)));
|
|
1091
|
+
}).on('error', reject);
|
|
1092
|
+
});
|
|
1080
1093
|
|
|
1081
|
-
const fileContent = await streamToBuffer(response.Body);
|
|
1082
1094
|
await fs.writeFile(localPath, fileContent);
|
|
1083
1095
|
});
|
|
1084
1096
|
|
package/templates/CLAUDE.md
CHANGED
|
@@ -95,7 +95,7 @@ The `contentRender.js` file is central to frontend customization, exporting key
|
|
|
95
95
|
- **`onRenderChatMessage(params)`:** function called every time a chat message is rendered.
|
|
96
96
|
|
|
97
97
|
#### OpenKBS commands
|
|
98
|
-
`openkbs push` -
|
|
98
|
+
`openkbs push` - after completing changes to your agent, use this command to deploy it to the OpenKBS cloud.
|
|
99
99
|
`openkbs create my-agent` - creates a directory structure for a new agent
|
|
100
100
|
|
|
101
101
|
### Creating Related Agents
|
|
@@ -67,7 +67,17 @@ class OpenKBSAgentClient {
|
|
|
67
67
|
resolve(key);
|
|
68
68
|
});
|
|
69
69
|
|
|
70
|
-
rl._writeToOutput = (str) =>
|
|
70
|
+
rl._writeToOutput = (str) => {
|
|
71
|
+
if (str === '\n' || str === '\r\n') {
|
|
72
|
+
rl.output.write(str);
|
|
73
|
+
} else if (str.match(/[\x08\x7f]/)) {
|
|
74
|
+
rl.output.write(str);
|
|
75
|
+
} else if (rl.line && str.length === 1) {
|
|
76
|
+
rl.output.write('*');
|
|
77
|
+
} else {
|
|
78
|
+
rl.output.write(str);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
71
81
|
});
|
|
72
82
|
}
|
|
73
83
|
|