From ca16dbc8f791780fa602b1b55237362dafffadd3 Mon Sep 17 00:00:00 2001 From: MaxRobinsonTheGreat Date: Mon, 18 Nov 2024 23:19:31 -0600 Subject: [PATCH] remove external obj references from bot.modes --- src/agent/modes.js | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/agent/modes.js b/src/agent/modes.js index 2c0b3e0..0a4bae5 100644 --- a/src/agent/modes.js +++ b/src/agent/modes.js @@ -23,7 +23,7 @@ async function say(agent, message) { // the order of this list matters! first modes will be prioritized // while update functions are async, they should *not* be awaited longer than ~100ms as it will block the update loop // to perform longer actions, use the execute function which won't block the update loop -const modes = [ +const modes_list = [ { name: 'self_preservation', description: 'Respond to drowning, burning, and damage at low health. Interrupts all actions.', @@ -267,13 +267,19 @@ async function execute(mode, agent, func, timeout=-1) { console.log(`Mode ${mode.name} finished executing, code_return: ${code_return.message}`); } +let _agent = null; + class ModeController { - constructor(agent) { - this.agent = agent; - this.modes_list = modes; + /* + SECURITY WARNING: + ModesController must be isolated. Do not store references to external objects like `agent`. + This object is accessible by LLM generated code, so any stored references are also accessible. + This can be used to expose sensitive information by malicious human prompters. + */ + constructor() { this.modes_map = {}; this.behavior_log = ''; - for (let mode of this.modes_list) { + for (let mode of modes_list) { this.modes_map[mode.name] = mode; } } @@ -299,7 +305,7 @@ class ModeController { } unPauseAll() { - for (let mode of this.modes_list) { + for (let mode of modes_list) { if (mode.paused) console.log(`Unpausing mode ${mode.name}`); mode.paused = false; } @@ -307,7 +313,7 @@ class ModeController { getMiniDocs() { // no descriptions let res = 'Agent Modes:'; - for (let mode of this.modes_list) { + for (let mode of modes_list) { let on = mode.on ? 'ON' : 'OFF'; res += `\n- ${mode.name}(${on})`; } @@ -316,7 +322,7 @@ class ModeController { getDocs() { let res = 'Agent Modes:'; - for (let mode of this.modes_list) { + for (let mode of modes_list) { let on = mode.on ? 'ON' : 'OFF'; res += `\n- ${mode.name}(${on}): ${mode.description}`; } @@ -324,13 +330,13 @@ class ModeController { } async update() { - if (this.agent.isIdle()) { + if (_agent.isIdle()) { this.unPauseAll(); } - for (let mode of this.modes_list) { - let interruptible = mode.interrupts.some(i => i === 'all') || mode.interrupts.some(i => i === this.agent.actions.currentActionLabel); - if (mode.on && !mode.paused && !mode.active && (this.agent.isIdle() || interruptible)) { - await mode.update(this.agent); + for (let mode of modes_list) { + let interruptible = mode.interrupts.some(i => i === 'all') || mode.interrupts.some(i => i === _agent.actions.currentActionLabel); + if (mode.on && !mode.paused && !mode.active && (_agent.isIdle() || interruptible)) { + await mode.update(_agent); } if (mode.active) break; } @@ -344,14 +350,14 @@ class ModeController { getJson() { let res = {}; - for (let mode of this.modes_list) { + for (let mode of modes_list) { res[mode.name] = mode.on; } return res; } loadJson(json) { - for (let mode of this.modes_list) { + for (let mode of modes_list) { if (json[mode.name] != undefined) { mode.on = json[mode.name]; } @@ -360,10 +366,11 @@ class ModeController { } export function initModes(agent) { + _agent = agent; // the mode controller is added to the bot object so it is accessible from anywhere the bot is used - agent.bot.modes = new ModeController(agent); - let modes = agent.prompter.getInitModes(); - if (modes) { - agent.bot.modes.loadJson(modes); + agent.bot.modes = new ModeController(); + let modes_json = agent.prompter.getInitModes(); + if (modes_json) { + agent.bot.modes.loadJson(modes_json); } }