nyxora 1.3.0 → 1.4.0
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/dashboard/dist/assets/index-Cy7yprIz.css +1 -0
- package/dashboard/dist/assets/index-L20NVlIh.js +9 -0
- package/dashboard/dist/index.html +2 -2
- package/dist/agent/reasoning.js +66 -3
- package/dist/agent/updateProfile.js +52 -0
- package/dist/gateway/server.js +4 -0
- package/dist/system/pluginManager.js +56 -0
- package/dist/system/skills/browseWeb.js +50 -0
- package/dist/system/skills/executeShell.js +38 -0
- package/dist/system/skills/installSkill.js +51 -0
- package/dist/system/skills/readFile.js +39 -0
- package/dist/system/skills/updateSecurityPolicy.js +60 -0
- package/dist/system/skills/writeFile.js +44 -0
- package/package.json +1 -1
- package/user.md +1 -1
- package/dashboard/dist/assets/index-33NxKAJt.css +0 -1
- package/dashboard/dist/assets/index-CKUbyknW.js +0 -9
package/dist/agent/reasoning.js
CHANGED
|
@@ -22,6 +22,14 @@ const checkSecurity_1 = require("../web3/skills/checkSecurity");
|
|
|
22
22
|
const marketAnalysis_1 = require("../web3/skills/marketAnalysis");
|
|
23
23
|
const checkPortfolio_1 = require("../web3/skills/checkPortfolio");
|
|
24
24
|
const limitOrderManager_1 = require("./limitOrderManager");
|
|
25
|
+
const updateProfile_1 = require("./updateProfile");
|
|
26
|
+
const updateSecurityPolicy_1 = require("../system/skills/updateSecurityPolicy");
|
|
27
|
+
const readFile_1 = require("../system/skills/readFile");
|
|
28
|
+
const writeFile_1 = require("../system/skills/writeFile");
|
|
29
|
+
const executeShell_1 = require("../system/skills/executeShell");
|
|
30
|
+
const browseWeb_1 = require("../system/skills/browseWeb");
|
|
31
|
+
const installSkill_1 = require("../system/skills/installSkill");
|
|
32
|
+
const pluginManager_1 = require("../system/pluginManager");
|
|
25
33
|
const paths_1 = require("../config/paths");
|
|
26
34
|
exports.logger = new logger_1.Logger();
|
|
27
35
|
let currentKeyIndex = 0;
|
|
@@ -113,6 +121,17 @@ If the user doesn't specify a chain, default to: ${config.agent.default_chain}.`
|
|
|
113
121
|
catch (error) {
|
|
114
122
|
console.error('Failed to read user.md:', error);
|
|
115
123
|
}
|
|
124
|
+
// Read security_policy.md for NLP security constraints
|
|
125
|
+
try {
|
|
126
|
+
const policyPath = (0, paths_1.getPath)('security_policy.md');
|
|
127
|
+
if (fs_1.default.existsSync(policyPath)) {
|
|
128
|
+
const securityInstructions = fs_1.default.readFileSync(policyPath, 'utf8');
|
|
129
|
+
basePrompt += `\n\n--- SECURITY POLICY (MANDATORY RULES) ---\n${securityInstructions}\n\nCRITICAL: If the user asks you to perform an action that violates the Security Policy above, YOU MUST NOT EXECUTE IT DIRECTLY. Instead, ask for their explicit permission first.`;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
console.error('Failed to read security_policy.md:', error);
|
|
134
|
+
}
|
|
116
135
|
return basePrompt;
|
|
117
136
|
}
|
|
118
137
|
async function processUserInput(input, role = 'user') {
|
|
@@ -162,7 +181,15 @@ async function processUserInput(input, role = 'user') {
|
|
|
162
181
|
checkPortfolio_1.checkPortfolioToolDefinition,
|
|
163
182
|
limitOrderManager_1.createLimitOrderToolDefinition,
|
|
164
183
|
limitOrderManager_1.listLimitOrdersToolDefinition,
|
|
165
|
-
limitOrderManager_1.cancelLimitOrderToolDefinition
|
|
184
|
+
limitOrderManager_1.cancelLimitOrderToolDefinition,
|
|
185
|
+
updateProfile_1.updateProfileToolDefinition,
|
|
186
|
+
updateSecurityPolicy_1.updateSecurityPolicyToolDefinition,
|
|
187
|
+
readFile_1.readLocalFileToolDefinition,
|
|
188
|
+
writeFile_1.writeLocalFileToolDefinition,
|
|
189
|
+
executeShell_1.runTerminalCommandToolDefinition,
|
|
190
|
+
browseWeb_1.browseWebsiteToolDefinition,
|
|
191
|
+
installSkill_1.installExternalSkillToolDefinition,
|
|
192
|
+
...pluginManager_1.pluginManager.getToolDefinitions()
|
|
166
193
|
],
|
|
167
194
|
tool_choice: "auto",
|
|
168
195
|
});
|
|
@@ -244,8 +271,44 @@ async function processUserInput(input, role = 'user') {
|
|
|
244
271
|
result = limitOrderManager_1.limitOrderManager.cancelOrder(args.id);
|
|
245
272
|
break;
|
|
246
273
|
}
|
|
247
|
-
|
|
248
|
-
result =
|
|
274
|
+
case 'update_profile': {
|
|
275
|
+
result = (0, updateProfile_1.updateProfile)(args.content, args.mode);
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
case 'update_security_policy': {
|
|
279
|
+
result = (0, updateSecurityPolicy_1.updateSecurityPolicy)(args.rule, args.action);
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
case 'read_local_file': {
|
|
283
|
+
result = (0, readFile_1.readLocalFile)(args.filePath);
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
case 'write_local_file': {
|
|
287
|
+
result = (0, writeFile_1.writeLocalFile)(args.filePath, args.content);
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
case 'run_terminal_command': {
|
|
291
|
+
result = await (0, executeShell_1.runTerminalCommand)(args.command);
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
case 'browse_website': {
|
|
295
|
+
result = await (0, browseWeb_1.browseWebsite)(args.url);
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
case 'install_external_skill': {
|
|
299
|
+
result = await (0, installSkill_1.installExternalSkill)(args.url);
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
default: {
|
|
303
|
+
const externalResult = await pluginManager_1.pluginManager.executeTool(toolName, args);
|
|
304
|
+
if (externalResult !== null) {
|
|
305
|
+
result = externalResult;
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
result = `Error: Tool ${toolName} is not implemented.`;
|
|
309
|
+
}
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
249
312
|
}
|
|
250
313
|
exports.logger.addEntry({
|
|
251
314
|
role: 'tool',
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.updateProfileToolDefinition = void 0;
|
|
7
|
+
exports.updateProfile = updateProfile;
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const paths_1 = require("../config/paths");
|
|
10
|
+
function updateProfile(content, mode) {
|
|
11
|
+
try {
|
|
12
|
+
const userMdPath = (0, paths_1.getPath)('user.md');
|
|
13
|
+
if (mode === 'replace') {
|
|
14
|
+
fs_1.default.writeFileSync(userMdPath, content, 'utf8');
|
|
15
|
+
return "Profile replaced successfully. New user.md has been saved.";
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
let existingContent = "";
|
|
19
|
+
if (fs_1.default.existsSync(userMdPath)) {
|
|
20
|
+
existingContent = fs_1.default.readFileSync(userMdPath, 'utf8');
|
|
21
|
+
}
|
|
22
|
+
const newContent = existingContent + "\n" + content;
|
|
23
|
+
fs_1.default.writeFileSync(userMdPath, newContent, 'utf8');
|
|
24
|
+
return "Profile appended successfully. New instructions added to user.md.";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
return `Failed to update profile: ${error.message}`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.updateProfileToolDefinition = {
|
|
32
|
+
type: "function",
|
|
33
|
+
function: {
|
|
34
|
+
name: "update_profile",
|
|
35
|
+
description: "Updates or rewrites the user.md file. Use this when the user asks you to remember something about them, change their persona, or update your instructions.",
|
|
36
|
+
parameters: {
|
|
37
|
+
type: "object",
|
|
38
|
+
properties: {
|
|
39
|
+
content: {
|
|
40
|
+
type: "string",
|
|
41
|
+
description: "The content to write or append to user.md",
|
|
42
|
+
},
|
|
43
|
+
mode: {
|
|
44
|
+
type: "string",
|
|
45
|
+
enum: ["append", "replace"],
|
|
46
|
+
description: "Whether to append the content to the existing file or replace the entire file.",
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
required: ["content", "mode"],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
package/dist/gateway/server.js
CHANGED
|
@@ -13,6 +13,7 @@ const parser_1 = require("../config/parser");
|
|
|
13
13
|
const tracker_1 = require("./tracker");
|
|
14
14
|
const transactionManager_1 = require("../agent/transactionManager");
|
|
15
15
|
const limitOrderManager_1 = require("../agent/limitOrderManager");
|
|
16
|
+
const pluginManager_1 = require("../system/pluginManager");
|
|
16
17
|
const transfer_1 = require("../web3/skills/transfer");
|
|
17
18
|
const swapToken_1 = require("../web3/skills/swapToken");
|
|
18
19
|
const getBalance_1 = require("../web3/skills/getBalance");
|
|
@@ -181,6 +182,9 @@ app.use((req, res, next) => {
|
|
|
181
182
|
}
|
|
182
183
|
});
|
|
183
184
|
function startServer() {
|
|
185
|
+
pluginManager_1.pluginManager.loadPlugins().then(() => {
|
|
186
|
+
console.log(`[PluginManager] Finished loading external skills.`);
|
|
187
|
+
});
|
|
184
188
|
limitOrderManager_1.limitOrderManager.startMonitor();
|
|
185
189
|
const PORT = process.env.PORT || 3000;
|
|
186
190
|
app.listen(PORT, () => {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.pluginManager = exports.PluginManager = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
class PluginManager {
|
|
10
|
+
skills = new Map();
|
|
11
|
+
async loadPlugins() {
|
|
12
|
+
const pluginsDir = path_1.default.join(process.cwd(), 'src', 'external_skills');
|
|
13
|
+
if (!fs_1.default.existsSync(pluginsDir)) {
|
|
14
|
+
fs_1.default.mkdirSync(pluginsDir, { recursive: true });
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const files = fs_1.default.readdirSync(pluginsDir);
|
|
18
|
+
for (const file of files) {
|
|
19
|
+
if (file.endsWith('.js') || file.endsWith('.ts')) {
|
|
20
|
+
try {
|
|
21
|
+
// Dynamic import requires relative path from this file or absolute path
|
|
22
|
+
// For TS compiled to JS, absolute path is safer
|
|
23
|
+
const absolutePath = path_1.default.resolve(pluginsDir, file);
|
|
24
|
+
// Note: In development with ts-node, requiring .ts works.
|
|
25
|
+
// In production, we need compiled .js files.
|
|
26
|
+
const module = require(absolutePath);
|
|
27
|
+
if (module.toolDefinition && module.execute) {
|
|
28
|
+
const toolName = module.toolDefinition.function.name;
|
|
29
|
+
this.skills.set(toolName, module);
|
|
30
|
+
console.log(`[PluginManager] Loaded external skill: ${toolName}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
console.error(`[PluginManager] Failed to load plugin ${file}:`, error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
getToolDefinitions() {
|
|
40
|
+
return Array.from(this.skills.values()).map(skill => skill.toolDefinition);
|
|
41
|
+
}
|
|
42
|
+
async executeTool(toolName, args) {
|
|
43
|
+
const skill = this.skills.get(toolName);
|
|
44
|
+
if (skill) {
|
|
45
|
+
try {
|
|
46
|
+
return await skill.execute(args);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
return `External skill ${toolName} failed: ${error.message}`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return null; // Tool not found in external skills
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.PluginManager = PluginManager;
|
|
56
|
+
exports.pluginManager = new PluginManager();
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.browseWebsiteToolDefinition = void 0;
|
|
4
|
+
exports.browseWebsite = browseWebsite;
|
|
5
|
+
async function browseWebsite(url) {
|
|
6
|
+
try {
|
|
7
|
+
const response = await fetch(url, {
|
|
8
|
+
headers: {
|
|
9
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Nyxora/1.0',
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
if (!response.ok) {
|
|
13
|
+
return `Error: Failed to fetch URL, Status: ${response.status} ${response.statusText}`;
|
|
14
|
+
}
|
|
15
|
+
const html = await response.text();
|
|
16
|
+
// A very basic HTML to text stripping to avoid exceeding context limits
|
|
17
|
+
// In a production app, we would use cheerio or puppeteer.
|
|
18
|
+
const text = html
|
|
19
|
+
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
|
|
20
|
+
.replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, '')
|
|
21
|
+
.replace(/<[^>]+>/g, ' ')
|
|
22
|
+
.replace(/\s+/g, ' ')
|
|
23
|
+
.trim();
|
|
24
|
+
// Limit to first 20000 characters to prevent context overflow
|
|
25
|
+
if (text.length > 20000) {
|
|
26
|
+
return text.substring(0, 20000) + "... [Content Truncated]";
|
|
27
|
+
}
|
|
28
|
+
return text;
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
return `Failed to browse website: ${error.message}`;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.browseWebsiteToolDefinition = {
|
|
35
|
+
type: "function",
|
|
36
|
+
function: {
|
|
37
|
+
name: "browse_website",
|
|
38
|
+
description: "Fetches and reads the textual content of a webpage.",
|
|
39
|
+
parameters: {
|
|
40
|
+
type: "object",
|
|
41
|
+
properties: {
|
|
42
|
+
url: {
|
|
43
|
+
type: "string",
|
|
44
|
+
description: "The URL of the webpage to read.",
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
required: ["url"],
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runTerminalCommandToolDefinition = void 0;
|
|
4
|
+
exports.runTerminalCommand = runTerminalCommand;
|
|
5
|
+
const child_process_1 = require("child_process");
|
|
6
|
+
function runTerminalCommand(command) {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
(0, child_process_1.exec)(command, { maxBuffer: 1024 * 1024 * 10 }, (error, stdout, stderr) => {
|
|
9
|
+
let output = "";
|
|
10
|
+
if (stdout)
|
|
11
|
+
output += `STDOUT:\n${stdout}\n`;
|
|
12
|
+
if (stderr)
|
|
13
|
+
output += `STDERR:\n${stderr}\n`;
|
|
14
|
+
if (error)
|
|
15
|
+
output += `ERROR:\n${error.message}\n`;
|
|
16
|
+
if (!output)
|
|
17
|
+
output = "Command executed successfully with no output.";
|
|
18
|
+
resolve(output);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
exports.runTerminalCommandToolDefinition = {
|
|
23
|
+
type: "function",
|
|
24
|
+
function: {
|
|
25
|
+
name: "run_terminal_command",
|
|
26
|
+
description: "Executes a shell/terminal command on the user's host machine. Use this to install packages, run scripts, manage processes, etc.",
|
|
27
|
+
parameters: {
|
|
28
|
+
type: "object",
|
|
29
|
+
properties: {
|
|
30
|
+
command: {
|
|
31
|
+
type: "string",
|
|
32
|
+
description: "The terminal command to execute.",
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
required: ["command"],
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.installExternalSkillToolDefinition = void 0;
|
|
7
|
+
exports.installExternalSkill = installExternalSkill;
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
async function installExternalSkill(url) {
|
|
11
|
+
try {
|
|
12
|
+
const response = await fetch(url);
|
|
13
|
+
if (!response.ok) {
|
|
14
|
+
return `Failed to fetch skill from URL. Status: ${response.status}`;
|
|
15
|
+
}
|
|
16
|
+
const code = await response.text();
|
|
17
|
+
// Extract a filename from URL, or generate a random one
|
|
18
|
+
let filename = url.split('/').pop() || '';
|
|
19
|
+
if (!filename.endsWith('.ts') && !filename.endsWith('.js')) {
|
|
20
|
+
filename = `skill_${Date.now()}.ts`;
|
|
21
|
+
}
|
|
22
|
+
// Ensure external_skills directory exists
|
|
23
|
+
const pluginsDir = path_1.default.join(process.cwd(), 'src', 'external_skills');
|
|
24
|
+
if (!fs_1.default.existsSync(pluginsDir)) {
|
|
25
|
+
fs_1.default.mkdirSync(pluginsDir, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
const filePath = path_1.default.join(pluginsDir, filename);
|
|
28
|
+
fs_1.default.writeFileSync(filePath, code, 'utf8');
|
|
29
|
+
return `Skill successfully downloaded and installed to ${filePath}. Please restart the server for the plugin manager to compile and load it.`;
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
return `Failed to install skill: ${error.message}`;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.installExternalSkillToolDefinition = {
|
|
36
|
+
type: "function",
|
|
37
|
+
function: {
|
|
38
|
+
name: "install_external_skill",
|
|
39
|
+
description: "Downloads and installs a third-party typescript skill from a URL (e.g. GitHub Gist raw URL).",
|
|
40
|
+
parameters: {
|
|
41
|
+
type: "object",
|
|
42
|
+
properties: {
|
|
43
|
+
url: {
|
|
44
|
+
type: "string",
|
|
45
|
+
description: "The direct raw URL to the .ts or .js file of the skill.",
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
required: ["url"],
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.readLocalFileToolDefinition = void 0;
|
|
7
|
+
exports.readLocalFile = readLocalFile;
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
function readLocalFile(filePath) {
|
|
11
|
+
try {
|
|
12
|
+
const absolutePath = path_1.default.resolve(filePath);
|
|
13
|
+
if (!fs_1.default.existsSync(absolutePath)) {
|
|
14
|
+
return `Error: File not found at ${absolutePath}`;
|
|
15
|
+
}
|
|
16
|
+
const content = fs_1.default.readFileSync(absolutePath, 'utf8');
|
|
17
|
+
return content;
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return `Failed to read file: ${error.message}`;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.readLocalFileToolDefinition = {
|
|
24
|
+
type: "function",
|
|
25
|
+
function: {
|
|
26
|
+
name: "read_local_file",
|
|
27
|
+
description: "Reads the content of a local file on the user's computer.",
|
|
28
|
+
parameters: {
|
|
29
|
+
type: "object",
|
|
30
|
+
properties: {
|
|
31
|
+
filePath: {
|
|
32
|
+
type: "string",
|
|
33
|
+
description: "The absolute or relative path to the file.",
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
required: ["filePath"],
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.updateSecurityPolicyToolDefinition = void 0;
|
|
7
|
+
exports.updateSecurityPolicy = updateSecurityPolicy;
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const paths_1 = require("../../config/paths");
|
|
10
|
+
function updateSecurityPolicy(rule, action) {
|
|
11
|
+
try {
|
|
12
|
+
const policyPath = (0, paths_1.getPath)('security_policy.md');
|
|
13
|
+
let existingContent = "";
|
|
14
|
+
if (fs_1.default.existsSync(policyPath)) {
|
|
15
|
+
existingContent = fs_1.default.readFileSync(policyPath, 'utf8');
|
|
16
|
+
}
|
|
17
|
+
if (action === 'clear') {
|
|
18
|
+
fs_1.default.writeFileSync(policyPath, '', 'utf8');
|
|
19
|
+
return "Security policy cleared.";
|
|
20
|
+
}
|
|
21
|
+
else if (action === 'add') {
|
|
22
|
+
const newContent = existingContent + (existingContent.endsWith('\n') || existingContent === '' ? '' : '\n') + `* ${rule}`;
|
|
23
|
+
fs_1.default.writeFileSync(policyPath, newContent, 'utf8');
|
|
24
|
+
return `Rule added to security policy: ${rule}`;
|
|
25
|
+
}
|
|
26
|
+
else if (action === 'remove') {
|
|
27
|
+
// Very basic line removal
|
|
28
|
+
const lines = existingContent.split('\n');
|
|
29
|
+
const filtered = lines.filter(l => !l.includes(rule));
|
|
30
|
+
fs_1.default.writeFileSync(policyPath, filtered.join('\n'), 'utf8');
|
|
31
|
+
return `Rule removed (if it existed).`;
|
|
32
|
+
}
|
|
33
|
+
return "Invalid action.";
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
return `Failed to update security policy: ${error.message}`;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.updateSecurityPolicyToolDefinition = {
|
|
40
|
+
type: "function",
|
|
41
|
+
function: {
|
|
42
|
+
name: "update_security_policy",
|
|
43
|
+
description: "Updates the security_policy.md file to restrict your own autonomous behavior. Use this when the user explicitly forbids you from doing something (e.g. 'do not touch drive E').",
|
|
44
|
+
parameters: {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
rule: {
|
|
48
|
+
type: "string",
|
|
49
|
+
description: "The rule to add or remove.",
|
|
50
|
+
},
|
|
51
|
+
action: {
|
|
52
|
+
type: "string",
|
|
53
|
+
enum: ["add", "remove", "clear"],
|
|
54
|
+
description: "The action to perform on the policy.",
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
required: ["rule", "action"],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.writeLocalFileToolDefinition = void 0;
|
|
7
|
+
exports.writeLocalFile = writeLocalFile;
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
function writeLocalFile(filePath, content) {
|
|
11
|
+
try {
|
|
12
|
+
const absolutePath = path_1.default.resolve(filePath);
|
|
13
|
+
const dir = path_1.default.dirname(absolutePath);
|
|
14
|
+
if (!fs_1.default.existsSync(dir)) {
|
|
15
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
16
|
+
}
|
|
17
|
+
fs_1.default.writeFileSync(absolutePath, content, 'utf8');
|
|
18
|
+
return `Success: File written to ${absolutePath}`;
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
return `Failed to write file: ${error.message}`;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.writeLocalFileToolDefinition = {
|
|
25
|
+
type: "function",
|
|
26
|
+
function: {
|
|
27
|
+
name: "write_local_file",
|
|
28
|
+
description: "Writes or overwrites a local file on the user's computer with the provided content.",
|
|
29
|
+
parameters: {
|
|
30
|
+
type: "object",
|
|
31
|
+
properties: {
|
|
32
|
+
filePath: {
|
|
33
|
+
type: "string",
|
|
34
|
+
description: "The absolute or relative path to the file.",
|
|
35
|
+
},
|
|
36
|
+
content: {
|
|
37
|
+
type: "string",
|
|
38
|
+
description: "The string content to write to the file.",
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
required: ["filePath", "content"],
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
};
|
package/package.json
CHANGED
package/user.md
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
:root{--bg-color:#0f172a;--bg-secondary:#1e293b;--bg-sidebar:#0b1120;--text-primary:#f8fafc;--text-secondary:#94a3b8;--accent:#3b82f6;--accent-hover:#2563eb;--glass-bg:#1e293bb3;--glass-border:#ffffff1a;--chat-user:#3b82f6;--chat-agent:#1e293b;--tool-bg:#0f172a}*{box-sizing:border-box;margin:0;padding:0}body{background-color:var(--bg-color);color:var(--text-primary);height:100vh;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;overflow:hidden}#root{width:100vw;height:100vh;display:flex}.sidebar{-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);border-right:1px solid var(--glass-border);z-index:100;background-color:#0b1120d9;flex-direction:column;width:280px;display:flex;box-shadow:10px 0 30px -10px #00000080}.agent-identity-card{background:linear-gradient(#3b82f60d 0%,#0000 100%);border-bottom:1px solid #ffffff0d;align-items:center;gap:16px;margin-bottom:8px;padding:24px;display:flex}.agent-avatar{background:#3b82f626;border:1px solid #3b82f64d;border-radius:16px;justify-content:center;align-items:center;padding:12px;display:flex;box-shadow:0 0 20px #3b82f633}.agent-info{flex-direction:column;gap:4px;display:flex}.agent-name{color:#fff;letter-spacing:-.025em;font-size:1.1rem;font-weight:700}.agent-status{color:#4ade80;letter-spacing:.05em;align-items:center;gap:6px;font-size:.75rem;font-weight:600;display:flex}.status-dot{background-color:#4ade80;border-radius:50%;width:8px;height:8px;animation:2s infinite pulse-green;box-shadow:0 0 8px #4ade80}@keyframes pulse-green{0%{transform:scale(.95);box-shadow:0 0 #4ade80b3}70%{transform:scale(1);box-shadow:0 0 0 6px #4ade8000}to{transform:scale(.95);box-shadow:0 0 #4ade8000}}.sidebar-scroll-area{flex:1;padding-bottom:24px;overflow-y:auto}.sidebar-scroll-area::-webkit-scrollbar{width:4px}.sidebar-scroll-area::-webkit-scrollbar-thumb{background:#ffffff0d}.sidebar-section{text-transform:uppercase;letter-spacing:.15em;color:#64748b;padding:24px 24px 12px;font-size:.7rem;font-weight:700}.sidebar-nav{flex-direction:column;gap:4px;padding:0 16px;display:flex}.nav-item{color:#94a3b8;cursor:pointer;border:1px solid #0000;border-radius:12px;align-items:center;gap:14px;padding:12px 16px;font-size:.95rem;font-weight:500;transition:all .25s cubic-bezier(.4,0,.2,1);display:flex}.nav-icon{transition:transform .25s cubic-bezier(.4,0,.2,1)}.nav-item:hover{color:#fff;background-color:#ffffff08;transform:translate(4px)}.nav-item:hover .nav-icon{color:var(--accent);transform:scale(1.1)}.nav-item.active{color:#fff;border-left:3px solid var(--accent);background:linear-gradient(90deg,#3b82f626 0%,#0000 100%);border-radius:4px 12px 12px 4px;font-weight:600}.nav-item.active .nav-icon{color:var(--accent)}.main-content{background-image:radial-gradient(at 0 0,#3b82f61a 0,#0000 50%),radial-gradient(at 100% 100%,#8b5cf61a 0,#0000 50%);flex-direction:column;flex:1;display:flex}.topbar{border-bottom:1px solid var(--glass-border);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);background:#0f172a99;justify-content:space-between;align-items:center;height:64px;padding:0 24px;display:flex}.topbar-left{color:var(--text-secondary);align-items:center;gap:16px;font-size:.95rem;font-weight:500;display:flex}.topbar-right{align-items:center;gap:12px;display:flex}.config-dropdown{background:var(--bg-secondary);border:1px solid var(--glass-border);color:#fff;cursor:pointer;border-radius:6px;outline:none;min-width:120px;padding:8px 12px;font-size:.85rem;transition:all .2s}.config-dropdown:hover{border-color:var(--accent)}.config-dropdown:focus{border-color:var(--accent);box-shadow:0 0 0 2px #3b82f633}.workspace-container{width:100%;height:calc(100vh - 64px);display:flex}.chat-wrapper{flex-direction:column;height:100%;padding:24px 0;display:flex}.resizer{background:var(--glass-border);cursor:col-resize;z-index:10;width:6px;transition:background .2s}.resizer:hover,.resizer:active{background:var(--accent)}.canvas-panel{background:var(--bg-sidebar);background-image:radial-gradient(#3b82f60d 0,#0000 80%);flex-direction:column;flex:1;padding:32px;display:flex;position:relative;overflow-y:auto}.canvas-header{border-bottom:1px solid #ffffff0d;justify-content:space-between;align-items:center;margin-bottom:32px;padding-bottom:16px;display:flex}.canvas-title{color:#94a3b8;text-transform:uppercase;letter-spacing:.05em;align-items:center;gap:8px;font-family:monospace;font-size:.85rem;display:flex}.canvas-empty{color:#475569;flex-direction:column;justify-content:center;align-items:center;gap:16px;height:100%;display:flex}.chat-container{flex-direction:column;flex:1;gap:20px;padding:0 24px;display:flex;overflow-y:auto}.chat-container::-webkit-scrollbar{width:6px}.chat-container::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:4px}.message-wrapper{flex-direction:column;max-width:85%;animation:.3s ease-out forwards fadeIn;display:flex}.message-wrapper.user{align-self:flex-end}.message-wrapper.agent{align-self:flex-start}.message-bubble{border-radius:18px;padding:14px 18px;font-size:.95rem;line-height:1.6;box-shadow:0 4px 6px -1px #0000001a}.user .message-bubble{background-color:var(--chat-user);color:#fff;border-bottom-right-radius:4px}.agent .message-bubble{background-color:var(--chat-agent);border:1px solid var(--glass-border);border-bottom-left-radius:4px}.tool-call{color:var(--text-secondary);background:var(--tool-bg);border:1px solid #ffffff0d;border-radius:12px;align-items:center;gap:8px;margin-top:10px;padding:10px 14px;font-size:.85rem;display:flex}.tool-call code{color:#a78bfa;font-family:monospace}.input-area{padding:20px 24px 0}.input-form{background:var(--bg-secondary);border:1px solid var(--glass-border);border-radius:16px;gap:12px;padding:8px;transition:all .2s;display:flex}.input-form:focus-within{border-color:var(--accent);box-shadow:0 0 0 2px #3b82f633}.chat-input{color:#fff;background:0 0;border:none;outline:none;flex:1;padding:12px 16px;font-family:inherit;font-size:.95rem}.send-button{background:var(--accent);color:#fff;cursor:pointer;border:none;border-radius:12px;justify-content:center;align-items:center;width:44px;height:44px;transition:all .2s;display:flex}.voice-button{background:var(--bg-secondary);color:var(--text-secondary);border:1px solid var(--glass-border);cursor:pointer;border-radius:12px;justify-content:center;align-items:center;width:44px;height:44px;transition:all .2s;display:flex}.voice-button:hover{color:#fff;border-color:#ef4444}.voice-button.listening{color:#ef4444;background:#ef444433;border-color:#ef4444;animation:1.5s infinite pulse-red}.voice-button.active-mode{color:#3b82f6;border-color:#3b82f6}.voice-button.speaking{color:#3b82f6;background:#3b82f633;border-color:#3b82f6;animation:1.5s infinite pulse-blue}@keyframes pulse-red{0%{box-shadow:0 0 #ef444466}70%{box-shadow:0 0 0 10px #ef444400}to{box-shadow:0 0 #ef444400}}@keyframes pulse-blue{0%{box-shadow:0 0 #3b82f666}70%{box-shadow:0 0 0 10px #3b82f600}to{box-shadow:0 0 #3b82f600}}.send-button:hover:not(:disabled){background:var(--accent-hover);transform:scale(1.05)}.send-button:disabled{opacity:.5;cursor:not-allowed}.typing-indicator{background-color:var(--chat-agent);border:1px solid var(--glass-border);border-radius:18px 18px 18px 4px;align-self:flex-start;gap:4px;width:fit-content;padding:14px 18px;display:flex}.dot{background:var(--text-secondary);border-radius:50%;width:6px;height:6px;animation:1.4s ease-in-out infinite both bounce}.dot:first-child{animation-delay:-.32s}.dot:nth-child(2){animation-delay:-.16s}@keyframes bounce{0%,80%,to{transform:scale(0)}40%{transform:scale(1)}}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.overview-container{color:#fff;max-width:1200px;height:calc(100vh - 64px);margin:0 auto;padding:24px;font-family:Inter,sans-serif;overflow-y:auto}.overview-container::-webkit-scrollbar{width:6px}.overview-container::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:4px}.overview-header h1{margin-bottom:4px;font-size:1.5rem;font-weight:600}.overview-header p{color:var(--text-secondary);margin-bottom:24px;font-size:.9rem}.panel{background:#14182099;border:1px solid #ffffff0d;border-radius:12px;margin-bottom:24px;padding:20px}.panel-header h3{margin-bottom:4px;font-size:1.1rem;font-weight:600}.panel-header p{color:var(--text-secondary);margin-bottom:16px;font-size:.85rem}.form-group{margin-bottom:16px}.form-row{gap:16px;display:flex}.flex-1{flex:1}label{text-transform:uppercase;color:var(--text-secondary);letter-spacing:.05em;margin-bottom:8px;font-size:.75rem;display:block}input,select{color:#fff;background:#0000004d;border:1px solid #ffffff1a;border-radius:8px;width:100%;padding:10px 12px;font-family:monospace;font-size:.9rem}input:read-only{color:var(--text-secondary)}.input-with-icon{align-items:center;display:flex;position:relative}.input-with-icon svg{color:var(--text-secondary);cursor:pointer;position:absolute;right:12px}.form-actions{align-items:center;gap:12px;margin-top:20px;display:flex}.btn-primary{color:#fff;cursor:pointer;background:#3b82f6;border:none;border-radius:6px;padding:8px 16px;font-size:.9rem}.btn-secondary{color:#fff;cursor:pointer;background:0 0;border:1px solid #fff3;border-radius:6px;padding:8px 16px;font-size:.9rem}.action-hint{color:var(--text-secondary);margin-left:8px;font-size:.85rem}.snapshot-grid{grid-template-columns:repeat(4,1fr);gap:20px;display:grid}.stat-val{margin-bottom:4px;font-size:1.5rem;font-weight:700}.text-green{color:#22c55e}.stat-block p{color:var(--text-secondary);margin-top:8px;font-size:.8rem;line-height:1.4}.metrics-grid{grid-template-columns:repeat(5,1fr);gap:16px;margin-bottom:32px;display:grid}.metric-card{background:#14182099;border:1px solid #ffffff0d;border-radius:12px;padding:16px}.metric-val{margin-bottom:4px;font-size:1.5rem;font-weight:700}.metric-sub{color:var(--text-secondary);font-size:.75rem}.section-title{text-transform:uppercase;color:var(--text-secondary);letter-spacing:.05em;margin-bottom:12px;font-size:.75rem}.session-item{justify-content:space-between;margin-bottom:24px;padding:16px 20px;display:flex}.text-secondary{color:var(--text-secondary)}.attention-panel{background:#eab3081a;border:1px solid #eab30833;border-radius:12px;flex-direction:column;margin-bottom:24px;padding:16px 20px;display:flex}.attention-header{color:#eab308;align-items:center;gap:8px;margin-bottom:8px;display:flex}.attention-header h4{font-size:1rem;font-weight:600}.attention-content p{margin-bottom:4px;font-size:.95rem}.attention-content span{font-size:.85rem}.logs-grid{grid-template-columns:1fr 1fr;gap:16px;display:grid}.log-panel{background:#0a0c10cc;border:1px solid #ffffff0d;border-radius:12px;flex-direction:column;height:300px;display:flex;overflow:hidden}.log-header{background:#ffffff0d;border-bottom:1px solid #ffffff0d;padding:12px 16px;font-size:.85rem;font-weight:600}.badge{background:#ffffff1a;border-radius:10px;margin-left:8px;padding:2px 6px;font-size:.7rem}.log-content{flex-direction:column;gap:4px;padding:12px 16px;display:flex;overflow-y:auto}.log-content code,.log-json{color:#a3a3a3;word-break:break-all;font-family:Consolas,Monaco,monospace;font-size:.75rem;line-height:1.4}.log-row{gap:12px;margin-bottom:4px;font-family:Consolas,Monaco,monospace;font-size:.75rem;display:flex}.log-time{color:#fb923c;min-width:60px}.log-msg{color:#d1d5db}.log-meta{color:#6b7280}.gateway-row{margin-bottom:2px}
|