Docker image, code exe, callstack
- Docker image update - Code exex tool standalone result variables in python and nodejs returned - Agent chain callstack fix after chat loading from file
frdel committed
Oct 15, 2024 at 23:25 UTC
763ec9e228194a5d9d55260fa75a54c2a1d6a8fc
9 files changed
+115
-30
agent.py
+35
-12
@@ -23,9 +23,14 @@ class AgentContext:
23
_counter: int = 0
24
25
def __init__(
26
- self, config: "AgentConfig", id: str | None = None, name: str | None = None, agent0: "Agent|None" = None,
26
+ self,
27
+ config: "AgentConfig",
28
+ id: str | None = None,
29
+ name: str | None = None,
30
+ agent0: "Agent|None" = None,
31
log: Log.Log | None = None,
28
- paused: bool = False, streaming_agent: "Agent|None" = None,
32
+ paused: bool = False,
33
+ streaming_agent: "Agent|None" = None,
34
):
35
# build context
36
self.id = id or str(uuid.uuid4())
@@ -38,7 +43,7 @@ class AgentContext:
43
self.process: DeferredTask | None = None
44
AgentContext._counter += 1
45
self.no = AgentContext._counter
41
-
46
+
47
self._contexts[self.id] = self
48
49
@staticmethod
@@ -69,12 +74,12 @@ class AgentContext:
74
def communicate(self, msg: str, broadcast_level: int = 1):
75
self.paused = False # unpause if paused
76
72
- if self.process and self.process.is_alive():
73
- if self.streaming_agent:
74
- current_agent = self.streaming_agent
75
- else:
76
- current_agent = self.agent0
77
+ if self.streaming_agent:
78
+ current_agent = self.streaming_agent
79
+ else:
80
+ current_agent = self.agent0
81
82
+ if self.process and self.process.is_alive():
83
# set intervention messages to agent(s):
84
intervention_agent = current_agent
85
while intervention_agent and broadcast_level != 0:
@@ -82,10 +87,30 @@ class AgentContext:
87
broadcast_level -= 1
88
intervention_agent = intervention_agent.data.get("superior", None)
89
else:
85
- self.process = DeferredTask(self.agent0.monologue, msg)
90
+
91
+ # self.process = DeferredTask(current_agent.monologue, msg)
92
+ self.process = DeferredTask(self._process_chain, current_agent, msg)
93
94
return self.process
95
96
+ # this wrapper ensures that superior agents are called back if the chat was loaded from file and original callstack is gone
97
+ async def _process_chain(self, agent: 'Agent', msg: str, user=True):
98
+ try:
99
+ msg_template = (
100
+ agent.read_prompt("fw.user_message.md", message=msg)
101
+ if user
102
+ else agent.read_prompt(
103
+ "fw.tool_response.md",
104
+ tool_name="call_subordinate",
105
+ tool_response=msg,
106
+ )
107
+ )
108
+ response = await agent.monologue(msg_template)
109
+ superior = agent.data.get("superior", None)
110
+ if superior:
111
+ await self._process_chain(superior, response, False)
112
+ except Exception as e:
113
+ agent.handle_critical_exception(e)
114
115
@dataclass
116
class AgentConfig:
@@ -220,9 +245,7 @@ class Agent:
245
await self.call_extensions("monologue_start", loop_data=loop_data)
246
247
printer = PrintStyle(italic=True, font_color="#b3ffd9", padding=False)
223
- user_message = self.read_prompt(
224
- "fw.user_message.md", message=loop_data.message
225
- )
248
+ user_message = loop_data.message
249
await self.append_message(user_message, human=True)
250
251
# let the agent run message loop until he stops it with a response tool
docker/exe/Dockerfile
+14
-4
@@ -13,7 +13,12 @@ RUN apt-get update && apt-get install -y \
13
npm \
14
openssh-server \
15
sudo \
16
- && rm -rf /var/lib/apt/lists/*
16
+ curl \
17
+ wget \
18
+ git
19
+
20
+# Cleanup package list
21
+RUN rm -rf /var/lib/apt/lists/*
22
23
# Set up SSH
24
RUN mkdir /var/run/sshd && \
@@ -24,16 +29,21 @@ RUN mkdir /var/run/sshd && \
29
ENV VIRTUAL_ENV=/opt/venv
30
RUN python3 -m venv $VIRTUAL_ENV
31
27
-# Copy initial .bashrc with virtual environment activation to a temporary location
28
-COPY .bashrc /etc/skel/.bashrc
29
-
32
# Copy the script to ensure .bashrc is in the root directory
33
COPY initialize.sh /usr/local/bin/initialize.sh
34
RUN chmod +x /usr/local/bin/initialize.sh
35
36
+# Copy contents of filesystem directory to /
37
+COPY ./fs/ /
38
+
39
# Ensure the virtual environment and pip setup
40
RUN $VIRTUAL_ENV/bin/pip install --upgrade pip
41
42
+# Install additional python packages
43
+RUN $VIRTUAL_ENV/bin/pip install \
44
+ ipython \
45
+ requests
46
+
47
# Expose SSH port
48
EXPOSE 22
49
docker/exe/build.txt
+1
@@ -1 +1,2 @@
1
+docker login
2
docker buildx build --platform linux/amd64,linux/arm64 -t frdel/agent-zero-exe:latest --push .
\ No newline at end of file
docker/exe/fs/exe/node_eval.js
new
+41
@@ -0,0 +1,41 @@
1
+#!/usr/bin/env node
2
+
3
+const vm = require('vm');
4
+const path = require('path');
5
+
6
+// Create a comprehensive context with all important global objects
7
+const context = vm.createContext({
8
+ ...global,
9
+ require: require,
10
+ __filename: path.join(process.cwd(), 'eval.js'),
11
+ __dirname: process.cwd(),
12
+ module: { exports: {} },
13
+ exports: module.exports,
14
+ console: console,
15
+ process: process,
16
+ Buffer: Buffer,
17
+ setTimeout: setTimeout,
18
+ setInterval: setInterval,
19
+ setImmediate: setImmediate,
20
+ clearTimeout: clearTimeout,
21
+ clearInterval: clearInterval,
22
+ clearImmediate: clearImmediate
23
+});
24
+
25
+const code = process.argv[2];
26
+const wrappedCode = `
27
+ (async function() {
28
+ try {
29
+ const __result__ = await eval(${JSON.stringify(code)});
30
+ if (__result__ !== undefined) console.log('Out[1]:', __result__);
31
+ } catch (error) {
32
+ console.error(error);
33
+ }
34
+ })();
35
+`;
36
+
37
+vm.runInContext(wrappedCode, context, {
38
+ filename: 'eval.js',
39
+ lineOffset: -2,
40
+ columnOffset: 0,
41
+}).catch(console.error);
\ No newline at end of file
docker/exe/fs/root/.bashrc
renamed
docker/exe/fs/root/.profile
new
+9
@@ -0,0 +1,9 @@
1
+# .bashrc
2
+
3
+# Source global definitions
4
+if [ -f /etc/bashrc ]; then
5
+ . /etc/bashrc
6
+fi
7
+
8
+# Activate the virtual environment
9
+source /opt/venv/bin/activate
docker/exe/initialize.sh
+11
-11
@@ -1,18 +1,18 @@
1
#!/bin/bash
2
3
-# Ensure .bashrc is in the root directory
4
-if [ ! -f /root/.bashrc ]; then
5
- cp /etc/skel/.bashrc /root/.bashrc
6
- chmod 444 /root/.bashrc
7
-fi
3
+# # Ensure .bashrc is in the root directory
4
+# if [ ! -f /root/.bashrc ]; then
5
+# cp /etc/skel/.bashrc /root/.bashrc
6
+# chmod 444 /root/.bashrc
7
+# fi
8
9
-# Ensure .profile is in the root directory
10
-if [ ! -f /root/.profile ]; then
11
- cp /etc/skel/.bashrc /root/.profile
12
- chmod 444 /root/.profile
13
-fi
9
+# # Ensure .profile is in the root directory
10
+# if [ ! -f /root/.profile ]; then
11
+# cp /etc/skel/.bashrc /root/.profile
12
+# chmod 444 /root/.profile
13
+# fi
14
15
apt-get update
16
17
# Start SSH service
18
-exec /usr/sbin/sshd -D
18
+exec /usr/sbin/sshd -D
\ No newline at end of file
python/helpers/persist_chat.py
+2
-1
@@ -102,7 +102,7 @@ def _deserialize_context(data):
102
103
context = AgentContext(
104
config=config,
105
- id=data.get("id", None),
105
+ # id=data.get("id", None), #get new id
106
name=data.get("name", None),
107
log=log,
108
paused=False,
@@ -143,6 +143,7 @@ def _deserialize_agents(
143
if prev:
144
prev.set_data("subordinate", current)
145
current.set_data("superior", prev)
146
+ prev = current
147
148
return zero or Agent(0, config, context)
149
python/tools/code_execution_tool.py
+2
-2
@@ -112,12 +112,12 @@ class CodeExecution(Tool):
112
113
async def execute_python_code(self, code: str, reset: bool = False):
114
escaped_code = shlex.quote(code)
115
- command = f"python3 -c {escaped_code}"
115
+ command = f"ipython -c {escaped_code}"
116
return await self.terminal_session(command, reset)
117
118
async def execute_nodejs_code(self, code: str, reset: bool = False):
119
escaped_code = shlex.quote(code)
120
- command = f"node -e {escaped_code}"
120
+ command = f"node /exe/node_eval.js {escaped_code}"
121
return await self.terminal_session(command, reset)
122
123
async def execute_terminal_command(self, command: str, reset: bool = False):