openkbs 0.0.31 → 0.0.32
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/MODIFY.md +52 -28
- package/package.json +1 -1
- package/src/actions.js +29 -1
package/MODIFY.md
CHANGED
|
@@ -15,7 +15,7 @@ A typical OpenKBS project has the following key directories:
|
|
|
15
15
|
|
|
16
16
|
* **`src/`**: Contains your custom source code.
|
|
17
17
|
* **`Events/`**: Houses backend event handlers.
|
|
18
|
-
* `actions.js`:
|
|
18
|
+
* `actions.js`: Example file commonly used for shared logic/tools definitions.
|
|
19
19
|
* `onRequest.js`: Handles incoming user messages before LLM processing.
|
|
20
20
|
* `onRequest.json`: NPM dependencies for `onRequest.js`.
|
|
21
21
|
* `onResponse.js`: Handles LLM responses before sending to the user.
|
|
@@ -32,52 +32,76 @@ A typical OpenKBS project has the following key directories:
|
|
|
32
32
|
* `instructions.txt`: Instructions for the LLM.
|
|
33
33
|
* `icon.png`: Application icon.
|
|
34
34
|
|
|
35
|
+
#### Important Coding guidelines
|
|
36
|
+
Organize new features across multiple files (like Events/utils.js) rather than adding everything to actions.js; export functionality from separate modules and import them in actions.js as needed.
|
|
37
|
+
|
|
35
38
|
#### onRequest and onResponse Handlers
|
|
36
39
|
|
|
37
40
|
The core of the OpenKBS backend framework revolves around the `onRequest` and `onResponse` event handlers.
|
|
38
41
|
These handlers act as middleware, intercepting messages before and after they are processed by the LLM.
|
|
39
42
|
|
|
40
|
-
* **`onRequest` Handler:** This handler is invoked every time a user sends a message to the chat. It provides an opportunity to pre-process the user's input, extract commands and perform actions based on the user's message.
|
|
43
|
+
* **`onRequest` Handler:** This handler is invoked every time a user sends a message to the chat. It provides an opportunity to pre-process the user's input, extract commands and perform actions based on the user's message. The `onRequest.js` file must export a function that receives `request` and `metadata` parameters and returns a modified request object.
|
|
44
|
+
|
|
45
|
+
* **`onResponse` Handler:** This handler is invoked after the LLM generates a response. It allows post-processing of the LLM's output, execution of commands based on the LLM's intentions. The `onResponse.js` file must export a function that receives `response` and `metadata` parameters and returns a modified response object.
|
|
46
|
+
|
|
47
|
+
#### NPM Dependencies for Handlers
|
|
41
48
|
|
|
42
|
-
|
|
49
|
+
**Important**: Files with names starting with "on" (like onRequest.js) are entry points for Node.js builds:
|
|
50
|
+
|
|
51
|
+
1. Each handler has its own build process
|
|
52
|
+
2. If a file imports node-fetch, then node-fetch must be in that handler's JSON file
|
|
53
|
+
3. Example: If utils.js uses node-fetch and is imported by onRequest.js, then node-fetch must be in onRequest.json
|
|
43
54
|
|
|
44
55
|
|
|
45
56
|
## Backend Dependencies
|
|
46
57
|
|
|
47
58
|
To use external NPM packages in your backend event handlers, you must declare them in the corresponding `.json` file.
|
|
48
|
-
OpenKBS also provides a secure way to handle sensitive information using the `{{secrets.your_secret_name}}` syntax.
|
|
49
59
|
|
|
50
|
-
**Example: Using
|
|
60
|
+
**Example: Using https module with an API key**
|
|
51
61
|
|
|
52
62
|
1. **Declare dependencies** in both `src/Events/onRequest.json` and `src/Events/onResponse.json` (as each handler have separate build):
|
|
53
63
|
```json
|
|
54
64
|
{
|
|
55
65
|
"dependencies": {
|
|
56
|
-
"
|
|
66
|
+
"got": "^11.8.5"
|
|
57
67
|
}
|
|
58
68
|
}
|
|
59
69
|
```
|
|
60
70
|
|
|
61
|
-
2. **Implement
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
// ... other actions
|
|
78
|
-
];
|
|
79
|
-
};
|
|
80
|
-
```
|
|
71
|
+
2. **Implement in any JavaScript file** (actions.js is just an example name):
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
export const getActions = (meta) => {
|
|
75
|
+
return [
|
|
76
|
+
[/\/?getNews\("(.*)"\)/, async (match) => {
|
|
77
|
+
const { body } = await got(`https://newsapi.org/v2/everything?q=${match[1]}&apiKey={{secrets.news_api_key}}`,
|
|
78
|
+
{ responseType: 'json' });
|
|
79
|
+
|
|
80
|
+
return { result: body.articles, ...meta };
|
|
81
|
+
}],
|
|
82
|
+
// ... other actions
|
|
83
|
+
];
|
|
84
|
+
};
|
|
85
|
+
```
|
|
86
|
+
|
|
81
87
|
## Secrets Management
|
|
82
|
-
|
|
83
|
-
|
|
88
|
+
OpenKBS provides a secure way to handle sensitive information using the `{{secrets.your_secret_name}}` syntax.
|
|
89
|
+
Never hardcode secrets in the code, if any secrets are provided by the user replace them with placeholders syntax above.
|
|
90
|
+
The user will later insert the secrets using the secrets manager
|
|
91
|
+
|
|
92
|
+
#### LLM Instructions
|
|
93
|
+
`app/instructions.txt`
|
|
94
|
+
This file contains the instructions for the agent
|
|
95
|
+
|
|
96
|
+
**Example Instructions:**
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
You are an AI assistant.
|
|
100
|
+
|
|
101
|
+
You can execute the following commands:
|
|
102
|
+
|
|
103
|
+
/getNews("query")
|
|
104
|
+
Description: """
|
|
105
|
+
Get the latest news
|
|
106
|
+
"""
|
|
107
|
+
```
|
package/package.json
CHANGED
package/src/actions.js
CHANGED
|
@@ -247,12 +247,31 @@ async function pushAction(location = 'origin', targetFile, options) {
|
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
async function cloneAction(kbId) {
|
|
250
|
+
// Store the original directory so we can restore it if needed
|
|
251
|
+
const originalDir = process.cwd();
|
|
252
|
+
|
|
250
253
|
try {
|
|
254
|
+
// Create a subdirectory with the name of the kbId
|
|
255
|
+
const targetDir = path.join(originalDir, kbId);
|
|
256
|
+
|
|
257
|
+
// Check if directory already exists
|
|
258
|
+
if (fs.existsSync(targetDir)) {
|
|
259
|
+
console.red(`Directory ${kbId} already exists.`);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Create the subdirectory
|
|
264
|
+
fs.mkdirSync(targetDir);
|
|
265
|
+
|
|
266
|
+
// Change to the new directory
|
|
267
|
+
process.chdir(targetDir);
|
|
268
|
+
|
|
251
269
|
const localKBData = await fetchLocalKBData({forceInit: true});
|
|
252
270
|
|
|
253
271
|
if (localKBData?.kbId) {
|
|
254
272
|
console.red(`KB ${localKBData?.kbId} already saved in settings.json.`);
|
|
255
273
|
console.yellow(`To pull the changes from OpenKBS remote use "openkbs pull"`);
|
|
274
|
+
process.chdir(originalDir); // Change back to original directory
|
|
256
275
|
return;
|
|
257
276
|
}
|
|
258
277
|
|
|
@@ -262,9 +281,18 @@ async function cloneAction(kbId) {
|
|
|
262
281
|
await fetchAndSaveSettings({ kbId }, kbId, kbToken);
|
|
263
282
|
await downloadIcon(kbId);
|
|
264
283
|
await downloadFiles(['functions', 'frontend'], kbId, kbToken);
|
|
265
|
-
console.green(
|
|
284
|
+
console.green(`Cloning complete! Files created in directory: ${kbId}`);
|
|
266
285
|
} catch (error) {
|
|
267
286
|
console.error('Error during clone operation:', error.message);
|
|
287
|
+
// Make sure we return to the original directory in case of error
|
|
288
|
+
if (process.cwd() !== originalDir) {
|
|
289
|
+
process.chdir(originalDir);
|
|
290
|
+
}
|
|
291
|
+
} finally {
|
|
292
|
+
// Always ensure we return to the original directory
|
|
293
|
+
if (process.cwd() !== originalDir) {
|
|
294
|
+
process.chdir(originalDir);
|
|
295
|
+
}
|
|
268
296
|
}
|
|
269
297
|
}
|
|
270
298
|
|