feat(CodeActAgent): Support Agent-User Interaction during Task Execution and the Full Integration of CodeActAgent (#1290)

* initialize plugin definition

* initialize plugin definition

* simplify mixin

* further improve plugin mixin

* add cache dir for pip

* support clean up cache

* add script for setup jupyter and execution server

* integrate JupyterRequirement to ssh_box

* source bashrc at the end of plugin load

* add execute_cli that accept code via stdin

* make JUPYTER_EXEC_SERVER_PORT configurable via env var

* increase background cmd sleep time

* Update opendevin/sandbox/plugins/mixin.py

Co-authored-by: Robert Brennan <accounts@rbren.io>

* add mixin to base class

* make jupyter requirement a dataclass

* source plugins only when >0 requirements

* add `sandbox_plugins` for each agent & have controller take care of it

* update build.sh to make logs available in /opendevin/logs

* switch to use config for lib and cache dir

* Add SANDBOX_WORKSPACE_DIR into config

* Add SANDBOX_WORKSPACE_DIR into config

* fix occurence of /workspace

* fix permission issue with /workspace

* use python to implement execute_cli to avoid stdin escape issue

* add IPythonRunCellAction and get it working

* wait until jupyter is avaialble

* support plugin via copying instead of mounting

* add agent talk action

* support follow-up user language feedback

* add __str__ for action to be printed better

* only print PLAN at the beginning

* wip: update codeact agent

* get rid the initial messate

* update codeact agent to handle null action;
add thought to bash

* dispatch thought for RUN action as well

* fix weird behavior of pxssh where the output would not flush correctly

* make ssh box can handle exit_code properly as well

* add initial version of swe-agent plugin;

* rename swe cursors

* split setup script into two and create two requirements

* print SWE-agent command documentation

* update swe-agent to default to no custom docs

* add initial version of swe-agent plugin;

* rename swe cursors

* split setup script into two and create two requirements

* print SWE-agent command documentation

* update swe-agent to default to no custom docs

* update dockerfile with dependency from swe-agent

* make env setup a separate script for .bashrc source

* add wip prompt

* fix mount_dir for ssh_box

* update prompt

* fix mount_dir for ssh_box

* default to use host network

* default to use host network

* move prompt to a separate file

* fix swe-tool plugins;
add missing _split_string

* remove hostname from sshbox

* update the prompt with edit functionality

* fix swe-tool plugins;
add missing _split_string

* add awaiting into status bar

* fix the bug of additional send event

* remove some print action

* move logic to config.py

* remove debugging comments

* make host network as default

* make WORKSPACE_MOUNT_PATH as abspath

* implement execute_cli via file cp

* Revert "implement execute_cli via file cp"

This reverts commit 06f0155bc1.

* add codeact dependencies to default container

* add IPythonRunCellObservation

* add back cache dir and default to /tmp

* make USE_HOST_NETWORK a bool

* revert use host network to false

* add temporarily fix for IPython RUN action

* update prompt

* revert USE_HOST_NETWORK to true since it is not affecting anything

* attempt to fix lint

* remove newline

* fix jupyter execution server

* add `thought` to most action class

* fix unit tests for current action abstraction

* support user exit

* update test cases with the latest action format (added 'thought')

* fix integration test for CodeActAGent by mocking stdin

* only mock stdin for tests with user_responses.log

* remove -exec integration test for CodeActAgent since it is not supported

* remove specific stop word

* fix comments

* improve clarity of prompt

* fix py lint

* fix integration tests

* sandbox might failed in chown due to mounting, but it won't be fatal

* update debug instruction for sshbox

* fix typo

* get RUN_AS_DEVIN and network=host working with app sandbox

* get RUN_AS_DEVIN and network=host working with app sandbox

* attempt to fix the workspace base permission

* sandbox might failed in chown due to mounting, but it won't be fatal

* update sshbox instruction

* remove default user id since it will be passed in the instruction

* revert permission fix since it should be resolved by correct SANDBOX_USER_ID

* the permission issue can be fixed by simply provide correct env var

* remove log

* set sandbox user id to getuid by default

* move logging to initializer

* make the uid consistent across host, app container, and sandbox

* remove hostname as it causes sudo issue

* fix permission of entrypoint script

* make the uvicron app run as host user uid for jupyter plugin

* add warning message

* update dev md for instruction of running unit tests

* add back unit tests

* revert back to the original sandbox implementation to fix testcases

* revert use host network

* get docker socket gid and usermod instead of chmod 777

* allow unit test workflow to find docker.sock

* make sandbox test working via patch

* fix arg parser that's broken for some reason

* try to fix app build disk space issue

* fix integration test

* Revert "fix arg parser that's broken for some reason"

This reverts commit 6cc8961133.

* update Development.md

* cleanup intergration tests & add exception for CodeAct+execbox

* fix config

* implement user_message action

* fix doc

* fix event dict error

* fix frontend lint

* revert accidentally changes to integration tests

* revert accidentally changes to integration tests

---------

Co-authored-by: Robert Brennan <accounts@rbren.io>
Co-authored-by: Robert Brennan <contact@rbren.io>
This commit is contained in:
Xingyao Wang
2024-05-01 20:40:00 +08:00
committed by GitHub
parent ea214d1c07
commit 1c7cdbefdd
81 changed files with 2700 additions and 435 deletions

View File

@@ -26,6 +26,7 @@ The `state` contains:
Here is a list of available Actions, which can be returned by `agent.step()`:
- [`CmdRunAction`](../opendevin/action/bash.py) - Runs a command inside a sandboxed terminal
- [`CmdKillAction`](../opendevin/action/bash.py) - Kills a background command
- [`IPythonRunCellAction`](../opendevin/action/bash.py) - Execute a block of Python code interactively (in Jupyter notebook) and receives `CmdOutputObservation`. Requires setting up `jupyter` [plugin](../opendevin/sandbox/plugins) as a requirement.
- [`FileReadAction`](../opendevin/action/fileop.py) - Reads the content of a file
- [`FileWriteAction`](../opendevin/action/fileop.py) - Writes new content to a file
- [`BrowseURLAction`](../opendevin/action/browse.py) - Gets the content of a URL
@@ -33,6 +34,7 @@ Here is a list of available Actions, which can be returned by `agent.step()`:
- [`AddTaskAction`](../opendevin/action/tasks.py) - Adds a subtask to the plan
- [`ModifyTaskAction`](../opendevin/action/tasks.py) - Changes the state of a subtask
- [`AgentThinkAction`](../opendevin/action/agent.py) - A no-op that allows the agent to add plaintext to the history (as well as the chat log)
- [`AgentTalkAction`](../opendevin/action/agent.py) - A no-op that allows the agent to add plaintext to the history and talk to the user.
- [`AgentFinishAction`](../opendevin/action/agent.py) - Stops the control loop, allowing the user to enter a new task
You can use `action.to_dict()` and `action_from_dict` to serialize and deserialize actions.

View File

@@ -1,54 +1,37 @@
import re
from typing import List, Mapping
from agenthub.codeact_agent.prompt import EXAMPLES, SYSTEM_MESSAGE
from opendevin.action import (
Action,
AgentEchoAction,
AgentFinishAction,
AgentTalkAction,
CmdRunAction,
IPythonRunCellAction,
NullAction,
)
from opendevin.agent import Agent
from opendevin.llm.llm import LLM
from opendevin.observation import (
AgentMessageObservation,
CmdOutputObservation,
IPythonRunCellObservation,
UserMessageObservation,
)
from opendevin.sandbox.plugins import (
JupyterRequirement,
PluginRequirement,
SWEAgentCommandsRequirement,
)
from opendevin.sandbox.plugins import JupyterRequirement, PluginRequirement
from opendevin.state import State
SYSTEM_MESSAGE = """You are a helpful assistant. You will be provided access (as root) to a bash shell to complete user-provided tasks.
You will be able to execute commands in the bash shell, interact with the file system, install packages, and receive the output of your commands.
DO NOT provide code in ```triple backticks```. Instead, you should execute bash command on behalf of the user by wrapping them with <execute> and </execute>.
For example:
You can list the files in the current directory by executing the following command:
<execute>ls</execute>
You can also install packages using pip:
<execute> pip install numpy </execute>
You can also write a block of code to a file:
<execute>
echo "import math
print(math.pi)" > math.py
</execute>
When you are done, execute the following to close the shell and end the conversation:
<execute>exit</execute>
"""
INVALID_INPUT_MESSAGE = (
"I don't understand your input. \n"
'If you want to execute command, please use <execute> YOUR_COMMAND_HERE </execute>.\n'
'If you already completed the task, please exit the shell by generating: <execute> exit </execute>.'
)
def parse_response(response) -> str:
action = response.choices[0].message.content
if '<execute>' in action and '</execute>' not in action:
action += '</execute>'
for lang in ['bash', 'ipython']:
if f'<execute_{lang}>' in action and f'</execute_{lang}>' not in action:
action += f'</execute_{lang}>'
return action
@@ -58,7 +41,20 @@ class CodeActAgent(Agent):
The agent works by passing the model a list of action-observation pairs and prompting the model to take the next step.
"""
sandbox_plugins: List[PluginRequirement] = [JupyterRequirement()]
sandbox_plugins: List[PluginRequirement] = [JupyterRequirement(), SWEAgentCommandsRequirement()]
SUPPORTED_ACTIONS = (
CmdRunAction,
IPythonRunCellAction,
AgentEchoAction,
AgentTalkAction,
NullAction
)
SUPPORTED_OBSERVATIONS = (
AgentMessageObservation,
UserMessageObservation,
CmdOutputObservation,
IPythonRunCellObservation
)
def __init__(
self,
@@ -93,56 +89,76 @@ class CodeActAgent(Agent):
assert state.plan.main_goal, 'Expecting instruction to be set'
self.messages = [
{'role': 'system', 'content': SYSTEM_MESSAGE},
{'role': 'user', 'content': state.plan.main_goal},
{
'role': 'user',
'content': (
f'Here is an example of how you can interact with the environment for task solving:\n{EXAMPLES}\n\n'
f"NOW, LET'S START!\n\n{state.plan.main_goal}"
)
},
]
updated_info = state.updated_info
if updated_info:
for prev_action, obs in updated_info:
assert isinstance(
prev_action, (CmdRunAction, AgentEchoAction)
), 'Expecting CmdRunAction or AgentEchoAction for Action'
if isinstance(
obs, AgentMessageObservation
): # warning message from itself
prev_action, self.SUPPORTED_ACTIONS
), f'{prev_action.__class__} is not supported (supported: {self.SUPPORTED_ACTIONS})'
# prev_action is already added to self.messages when returned
# handle observations
assert isinstance(
obs, self.SUPPORTED_OBSERVATIONS
), f'{obs.__class__} is not supported (supported: {self.SUPPORTED_OBSERVATIONS})'
if isinstance(obs, (AgentMessageObservation, UserMessageObservation)):
self.messages.append(
{'role': 'user', 'content': obs.content})
# User wants to exit
if obs.content.strip() == '/exit':
return AgentFinishAction()
elif isinstance(obs, CmdOutputObservation):
content = 'OBSERVATION:\n' + obs.content
content += f'\n[Command {obs.command_id} finished with exit code {obs.exit_code}]]'
self.messages.append({'role': 'user', 'content': content})
elif isinstance(obs, IPythonRunCellObservation):
content = 'OBSERVATION:\n' + obs.content
self.messages.append({'role': 'user', 'content': content})
else:
raise NotImplementedError(
f'Unknown observation type: {obs.__class__}'
)
response = self.llm.completion(
messages=self.messages,
stop=['</execute>'],
stop=[
'</execute_ipython>',
'</execute_bash>',
],
temperature=0.0
)
action_str: str = parse_response(response)
state.num_of_chars += sum(len(message['content'])
for message in self.messages) + len(action_str)
state.num_of_chars += sum(
len(message['content']) for message in self.messages
) + len(action_str)
self.messages.append({'role': 'assistant', 'content': action_str})
command = re.search(r'<execute>(.*)</execute>', action_str, re.DOTALL)
if command is not None:
if bash_command := re.search(r'<execute_bash>(.*)</execute_bash>', action_str, re.DOTALL):
# remove the command from the action string to get thought
thought = action_str.replace(bash_command.group(0), '').strip()
# a command was found
command_group = command.group(1)
command_group = bash_command.group(1).strip()
if command_group.strip() == 'exit':
return AgentFinishAction()
return CmdRunAction(command=command_group)
# # execute the code
# # TODO: does exit_code get loaded into Message?
# exit_code, observation = self.env.execute(command_group)
# self._history.append(Message(Role.ASSISTANT, observation))
return CmdRunAction(command=command_group, thought=thought)
elif python_code := re.search(r'<execute_ipython>(.*)</execute_ipython>', action_str, re.DOTALL):
# a code block was found
code_group = python_code.group(1).strip()
thought = action_str.replace(python_code.group(0), '').strip()
return IPythonRunCellAction(code=code_group, thought=thought)
else:
# we could provide a error message for the model to continue similar to
# https://github.com/xingyaoww/mint-bench/blob/main/mint/envs/general_env.py#L18-L23
# observation = INVALID_INPUT_MESSAGE
# self._history.append(Message(Role.ASSISTANT, observation))
return AgentEchoAction(
content=INVALID_INPUT_MESSAGE
) # warning message to itself
# We assume the LLM is GOOD enough that when it returns pure natural language
# it want to talk to the user
return AgentTalkAction(content=action_str)
def search_memory(self, query: str) -> List[str]:
raise NotImplementedError('Implement this abstract method')

View File

@@ -0,0 +1,226 @@
from opendevin.sandbox.plugins import SWEAgentCommandsRequirement
_SWEAGENT_BASH_DOCS = '\n'.join(
filter(
lambda x: not x.startswith('submit'),
SWEAgentCommandsRequirement.documentation.split('\n')
)
)
# _SWEAGENT_BASH_DOCS content below:
"""
open <path> [<line_number>] - opens the file at the given path in the editor. If line_number is provided, the window will be move to include that line
goto <line_number> - moves the window to show <line_number>
scroll_down - moves the window down {WINDOW} lines
scroll_up - moves the window down {WINDOW} lines
create <filename> - creates and opens a new file with the given name
search_dir <search_term> [<dir>] - searches for search_term in all files in dir. If dir is not provided, searches in the current directory
search_file <search_term> [<file>] - searches for search_term in file. If file is not provided, searches in the current open file
find_file <file_name> [<dir>] - finds all files with the given name in dir. If dir is not provided, searches in the current directory
edit <start_line>:<end_line>
<replacement_text>
end_of_edit - replaces lines <start_line> through <end_line> (inclusive) with the given text in the open file. The replacement text is terminated by a line with only end_of_edit on it. All of the <replacement text> will be entered, so make sure your indentation is formatted properly. Python files will be checked for syntax errors after the edit. If the system detects a syntax error, the edit will not be executed. Simply try to edit the file again, but make sure to read the error message and modify the edit command you issue accordingly. Issuing the same command a second time will just lead to the same error message again.
"""
_COMMAND_DOCS = (
'\nApart from the standard bash commands, you can also use the following special commands in <execute_bash> environment:\n'
f'{_SWEAGENT_BASH_DOCS}'
"Please note that THE EDIT COMMAND REQUIRES PROPER INDENTATION. If you'd like to add the line ' print(x)' you must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run."
)
SYSTEM_MESSAGE = f"""A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions.
The assistant can interact with an interactive Python (Jupyter Notebook) environment and receive the corresponding output when needed. The code should be enclosed using "<execute_ipython>" tag, for example:
<execute_ipython>
print("Hello World!")
</execute_ipython>
The assistant can execute bash commands on behalf of the user by wrapping them with <execute_bash> and </execute_bash>.
For example, you can list the files in the current directory by <execute_bash> ls </execute_bash>.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
The assistant can install Python packages through bash by <execute_bash> pip install [package needed] </execute_bash> and should always import packages and define variables before starting to use them.
The assistant should stop <execute> and provide an answer when they have already obtained the answer from the execution result.
{_COMMAND_DOCS}
Whenever possible, execute the code for the user using <execute_ipython> or <execute_bash> instead of providing it.
The assistant's response should be concise, but do express their thoughts.
Try to include one of <execute_ipython> or <execute_bash> in each of your responses, unless it is a direct answer to a question OR a message to the user.
"""
EXAMPLES = """
--- START OF EXAMPLE ---
USER: Can you create a list of numbers from 1 to 10, and create a web page to display them at port 5000?
ASSISTANT:
Sure! Let me write the Python code for starting a web server and save it to a file `app.py`:
<execute_ipython>
CODE='''
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
numbers = list(range(1, 11))
return str(numbers)
if __name__ == '__main__':
app.run(port=5000)
'''
with open('app.py', 'w') as f:
f.write(CODE)
</execute_ipython>
USER:
Observation:
[Code executed successfully with no output]
ASSISTANT:
I have created a Python file `app.py` that will display a list of numbers from 1 to 10 when you run it. Let me run the Python file for you:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 121[1]+ Exit 1 python3 app.py > server.log 2>&1
ASSISTANT: Looks like the server is running with PID 121 then crashed. Let me check the server log:
<execute_bash>
cat server.log
</execute_bash>
USER:
Observation:
Traceback (most recent call last):
File "/workspace/app.py", line 2, in <module>
from flask import Flask
ModuleNotFoundError: No module named 'flask'
ASSISTANT:
It seems that Flask is not installed. Let me install Flask for you:
<execute_bash>
pip install flask
</execute_bash>
USER:
Observation:
Defaulting to user installation because normal site-packages is not writeable
Collecting flask
Using cached flask-3.0.3-py3-none-any.whl (101 kB)
Collecting blinker>=1.6.2
Using cached blinker-1.7.0-py3-none-any.whl (13 kB)
Collecting Werkzeug>=3.0.0
Using cached werkzeug-3.0.2-py3-none-any.whl (226 kB)
Collecting click>=8.1.3
Using cached click-8.1.7-py3-none-any.whl (97 kB)
Collecting itsdangerous>=2.1.2
Using cached itsdangerous-2.2.0-py3-none-any.whl (16 kB)
Requirement already satisfied: Jinja2>=3.1.2 in /home/opendevin/.local/lib/python3.10/site-packages (from flask) (3.1.3)
Requirement already satisfied: MarkupSafe>=2.0 in /home/opendevin/.local/lib/python3.10/site-packages (from Jinja2>=3.1.2->flask) (2.1.5)
Installing collected packages: Werkzeug, itsdangerous, click, blinker, flask
Successfully installed Werkzeug-3.0.2 blinker-1.7.0 click-8.1.7 flask-3.0.3 itsdangerous-2.2.0
ASSISTANT:
Now that Flask is installed, let me run the Python file again:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 124
ASSISTANT:
Let me check the server log again:
<execute_bash>
cat server.log
</execute_bash>
USER:
Observation:
* Serving Flask app 'app'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
ASSISTANT:
The server is running on port 5000 with PID 124. You can access the list of numbers by visiting http://127.0.0.1:5000. If you have any further questions, feel free to ask!
USER: Now kill the server, make it display the numbers in a table format.
ASSISTANT:
Sure! Let me stop the server first:
<execute_bash>
kill 124
</execute_bash>
USER:
Observation:
[1]+ Terminated python3 app.py > server.log 2>&1
ASSISTANT:
The server has been stopped. Let me open the Python file and modify it.
<execute_bash>
open app.py
</execute_bash>
USER:
[File: /workspace/app.py (11 lines total)]
1:
2:from flask import Flask
3:app = Flask(__name__)
4:
5:@app.route('/')
6:def index():
7: numbers = list(range(1, 11))
8: return str(numbers)
9:
10:if __name__ == '__main__':
11: app.run(port=5000)
ASSISTANT:
I should edit the file to display the numbers in a table format. Let me do that for you:
<execute_bash>
edit 8:8 <<EOF
return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'
EOF
</execute_bash>
USER:
Observation:
[File: /workspace/app.py (11 lines total)]
1:
2:from flask import Flask
3:app = Flask(__name__)
4:
5:@app.route('/')
6:def index():
7: numbers = list(range(1, 11))
8: return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'
9:
10:if __name__ == '__main__':
11: app.run(port=5000)
File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.
ASSISTANT:
The file has been updated. Let me run the Python file again with the new changes:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 126
ASSISTANT:
The server is running on port 5000 with PID 126. You can access the list of numbers in a table format by visiting http://127.0.0.1:5000. Free free to let me know if you have any further requests!
--- END OF EXAMPLE ---
"""
INVALID_INPUT_MESSAGE = (
"I don't understand your input. \n"
'If you want to execute a bash command, please use <execute_bash> YOUR_COMMAND_HERE </execute_bash>.\n'
'If you want to execute a block of Python code, please use <execute_ipython> YOUR_COMMAND_HERE </execute_ipython>.\n'
)

View File

@@ -27,3 +27,7 @@ RUN mkdir -p -m0755 /var/run/sshd
# symlink python3 to python
RUN ln -s /usr/bin/python3 /usr/bin/python
# install basic dependencies for CodeActAgent
RUN pip3 install --upgrade pip
RUN pip3 install jupyterlab notebook jupyter_kernel_gateway flake8

View File

@@ -12,3 +12,12 @@ class CmdOutputObservation(Observation)
This data class represents the output of a command.
## IPythonRunCellObservation Objects
```python
@dataclass
class IPythonRunCellObservation(Observation)
```
This data class represents the output of a IPythonRunCellAction.

View File

@@ -13,9 +13,13 @@ class ActionTypeSchema(BaseModel)
Initializes the agent. Only sent by client.
#### USER\_MESSAGE
Sends a message from the user. Only sent by the client.
#### START
Starts a new development task. Only sent by the client.
Starts a new development task OR send chat from the user. Only sent by the client.
#### READ
@@ -29,6 +33,10 @@ Writes the content to a file.
Runs a command.
#### RUN\_IPYTHON
Runs a IPython cell.
#### KILL
Kills a background command.
@@ -45,6 +53,10 @@ Searches long-term memory
Allows the agent to make a plan, set a goal, or record thoughts
#### TALK
Allows the agent to respond to the user.
#### DELEGATE
Delegates a task to another agent.

View File

@@ -21,6 +21,10 @@ The HTML content of a URL
The output of a command
#### RUN\_IPYTHON
Runs a IPython cell.
#### RECALL
The result of a search

View File

@@ -17,6 +17,10 @@ Initial state of the task.
The task is running.
#### AWAITING\_USER\_INPUT
The task is awaiting user input.
#### PAUSED
The task is paused.

View File

@@ -15,6 +15,10 @@ const AgentStatusMap: { [k: string]: { message: string; indicator: string } } =
message: "Agent is running task...",
indicator: "bg-green-500",
},
[AgentTaskState.AWAITING_USER_INPUT]: {
message: "Agent is awaiting user input...",
indicator: "bg-orange-500",
},
[AgentTaskState.PAUSED]: {
message: "Agent has paused.",
indicator: "bg-yellow-500",

View File

@@ -3,6 +3,7 @@ import { IoMdChatbubbles } from "react-icons/io";
import Markdown from "react-markdown";
import { useSelector } from "react-redux";
import { useTypingEffect } from "#/hooks/useTypingEffect";
import AgentTaskState from "../types/AgentTaskState";
import {
addAssistantMessageToChat,
sendChatMessage,
@@ -117,6 +118,12 @@ function MessageList(): JSX.Element {
function ChatInterface(): JSX.Element {
const { initialized } = useSelector((state: RootState) => state.task);
const { curTaskState } = useSelector((state: RootState) => state.agent);
const onUserMessage = (msg: string) => {
const isNewTask = curTaskState === AgentTaskState.INIT;
sendChatMessage(msg, isNewTask);
};
return (
<div className="flex flex-col h-full p-0 bg-neutral-800">
@@ -125,7 +132,7 @@ function ChatInterface(): JSX.Element {
Chat
</div>
<MessageList />
<ChatInput disabled={!initialized} onSendMessage={sendChatMessage} />
<ChatInput disabled={!initialized} onSendMessage={onUserMessage} />
</div>
);
}

View File

@@ -3,7 +3,7 @@ import { act, render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import LoadPreviousSessionModal from "./LoadPreviousSessionModal";
import { clearMsgs, fetchMsgs } from "../../../services/session";
import { sendChatMessageFromEvent } from "../../../services/chatService";
import { addChatMessageFromEvent } from "../../../services/chatService";
import { handleAssistantMessage } from "../../../services/actions";
import toast from "../../../utils/toast";
@@ -37,7 +37,7 @@ vi.mock("../../../services/session", async (importOriginal) => ({
vi.mock("../../../services/chatService", async (importOriginal) => ({
...(await importOriginal<typeof import("../../../services/chatService")>()),
sendChatMessageFromEvent: vi.fn(),
addChatMessageFromEvent: vi.fn(),
}));
vi.mock("../../../services/actions", async (importOriginal) => ({
@@ -94,7 +94,7 @@ describe("LoadPreviousSession", () => {
await waitFor(() => {
expect(fetchMsgs).toHaveBeenCalledTimes(1);
expect(sendChatMessageFromEvent).toHaveBeenCalledTimes(1);
expect(addChatMessageFromEvent).toHaveBeenCalledTimes(1);
expect(handleAssistantMessage).toHaveBeenCalledTimes(1);
});
// modal should close right after fetching messages
@@ -117,7 +117,7 @@ describe("LoadPreviousSession", () => {
await waitFor(async () => {
await expect(() => fetchMsgs()).rejects.toThrow();
expect(handleAssistantMessage).not.toHaveBeenCalled();
expect(sendChatMessageFromEvent).not.toHaveBeenCalled();
expect(addChatMessageFromEvent).not.toHaveBeenCalled();
// error toast should be shown
expect(toast.stickyError).toHaveBeenCalledWith(
"ws",

View File

@@ -2,7 +2,7 @@ import React from "react";
import { useTranslation } from "react-i18next";
import { I18nKey } from "#/i18n/declaration";
import { handleAssistantMessage } from "#/services/actions";
import { sendChatMessageFromEvent } from "#/services/chatService";
import { addChatMessageFromEvent } from "#/services/chatService";
import { clearMsgs, fetchMsgs } from "#/services/session";
import toast from "#/utils/toast";
import BaseModal from "../base-modal/BaseModal";
@@ -28,7 +28,7 @@ function LoadPreviousSessionModal({
messages.forEach((message) => {
if (message.role === "user") {
sendChatMessageFromEvent(message.payload);
addChatMessageFromEvent(message.payload);
}
if (message.role === "assistant") {

View File

@@ -38,7 +38,8 @@ function SettingsForm({
useEffect(() => {
if (
curTaskState === AgentTaskState.RUNNING ||
curTaskState === AgentTaskState.PAUSED
curTaskState === AgentTaskState.PAUSED ||
curTaskState === AgentTaskState.AWAITING_USER_INPUT
) {
setDisabled(true);
} else {

View File

@@ -29,12 +29,24 @@ const messageActions = {
[ActionType.THINK]: (message: ActionMessage) => {
store.dispatch(appendAssistantMessage(message.args.thought));
},
[ActionType.TALK]: (message: ActionMessage) => {
store.dispatch(appendAssistantMessage(message.args.content));
},
[ActionType.FINISH]: (message: ActionMessage) => {
store.dispatch(appendAssistantMessage(message.message));
},
[ActionType.RUN]: (message: ActionMessage) => {
if (message.args.thought) {
store.dispatch(appendAssistantMessage(message.args.thought));
}
store.dispatch(appendInput(message.args.command));
},
[ActionType.RUN_IPYTHON]: (message: ActionMessage) => {
if (message.args.thought) {
store.dispatch(appendAssistantMessage(message.args.thought));
}
store.dispatch(appendInput(message.args.code));
},
[ActionType.ADD_TASK]: () => {
getPlan().then((fetchedPlan) => store.dispatch(setPlan(fetchedPlan)));
},

View File

@@ -11,14 +11,19 @@ import { SocketMessage } from "#/types/ResponseType";
import { ActionMessage } from "#/types/Message";
import Socket from "./socket";
export function sendChatMessage(message: string): void {
export function sendChatMessage(message: string, isTask: boolean = true): void {
store.dispatch(appendUserMessage(message));
const event = { action: ActionType.START, args: { task: message } };
let event;
if (isTask) {
event = { action: ActionType.START, args: { task: message } };
} else {
event = { action: ActionType.USER_MESSAGE, args: { message } };
}
const eventString = JSON.stringify(event);
Socket.send(eventString);
}
export function sendChatMessageFromEvent(event: string | SocketMessage): void {
export function addChatMessageFromEvent(event: string | SocketMessage): void {
try {
let data: ActionMessage;
if (typeof event === "string") {

View File

@@ -10,6 +10,10 @@ export function handleObservationMessage(message: ObservationMessage) {
case ObservationType.RUN:
store.dispatch(appendOutput(message.content));
break;
case ObservationType.RUN_IPYTHON:
// FIXME: render this as markdown
store.dispatch(appendOutput(message.content));
break;
case ObservationType.BROWSE:
if (message.extras?.screenshot) {
store.dispatch(setScreenshotSrc(message.extras.screenshot));

View File

@@ -2,7 +2,10 @@ enum ActionType {
// Initializes the agent. Only sent by client.
INIT = "initialize",
// Starts a new development task. Only sent by the client.
// Sends a message from the user
USER_MESSAGE = "user_message",
// Starts a new development task
START = "start",
// Reads the contents of a file.
@@ -14,6 +17,9 @@ enum ActionType {
// Runs a command.
RUN = "run",
// Runs a IPython command.
RUN_IPYTHON = "run_ipython",
// Kills a background command.
KILL = "kill",
@@ -26,6 +32,9 @@ enum ActionType {
// Allows the agent to make a plan, set a goal, or record thoughts.
THINK = "think",
// Allows the agent to respond to the user. Only sent by the agent.
TALK = "talk",
// If you're absolutely certain that you've completed your task and have tested your work,
// use the finish action to stop working.
FINISH = "finish",

View File

@@ -1,6 +1,7 @@
enum AgentTaskState {
INIT = "init",
RUNNING = "running",
AWAITING_USER_INPUT = "awaiting_user_input",
PAUSED = "paused",
STOPPED = "stopped",
FINISHED = "finished",

View File

@@ -8,6 +8,9 @@ enum ObservationType {
// The output of a command
RUN = "run",
// The output of an IPython command
RUN_IPYTHON = "run_ipython",
// The result of a search
RECALL = "recall",

View File

@@ -5,10 +5,11 @@ from .agent import (
AgentFinishAction,
AgentRecallAction,
AgentSummarizeAction,
AgentTalkAction,
AgentThinkAction,
)
from .base import Action, NullAction
from .bash import CmdKillAction, CmdRunAction
from .bash import CmdKillAction, CmdRunAction, IPythonRunCellAction
from .browse import BrowseURLAction
from .fileop import FileReadAction, FileWriteAction
from .github import GitHubPushAction
@@ -17,11 +18,13 @@ from .tasks import AddTaskAction, ModifyTaskAction
actions = (
CmdKillAction,
CmdRunAction,
IPythonRunCellAction,
BrowseURLAction,
FileReadAction,
FileWriteAction,
AgentRecallAction,
AgentThinkAction,
AgentTalkAction,
AgentFinishAction,
AgentDelegateAction,
AddTaskAction,
@@ -61,10 +64,12 @@ __all__ = [
'FileWriteAction',
'AgentRecallAction',
'AgentThinkAction',
'AgentTalkAction',
'AgentFinishAction',
'AgentDelegateAction',
'AgentEchoAction',
'AgentSummarizeAction',
'AddTaskAction',
'ModifyTaskAction',
'IPythonRunCellAction'
]

View File

@@ -18,6 +18,7 @@ if TYPE_CHECKING:
@dataclass
class AgentRecallAction(ExecutableAction):
query: str
thought: str = ''
action: str = ActionType.RECALL
async def run(self, controller: 'AgentController') -> AgentRecallObservation:
@@ -44,6 +45,22 @@ class AgentThinkAction(NotExecutableAction):
return self.thought
@dataclass
class AgentTalkAction(NotExecutableAction):
content: str
action: str = ActionType.TALK
async def run(self, controller: 'AgentController') -> 'Observation':
raise NotImplementedError
@property
def message(self) -> str:
return self.content
def __str__(self) -> str:
return self.content
@dataclass
class AgentEchoAction(ExecutableAction):
content: str
@@ -70,6 +87,7 @@ class AgentSummarizeAction(NotExecutableAction):
@dataclass
class AgentFinishAction(NotExecutableAction):
outputs: Dict = field(default_factory=dict)
thought: str = ''
action: str = ActionType.FINISH
async def run(self, controller: 'AgentController') -> 'Observation':
@@ -84,6 +102,7 @@ class AgentFinishAction(NotExecutableAction):
class AgentDelegateAction(ExecutableAction):
agent: str
inputs: dict
thought: str = ''
action: str = ActionType.DELEGATE
async def run(self, controller: 'AgentController') -> 'Observation':

View File

@@ -1,7 +1,10 @@
import os
import pathlib
from dataclasses import dataclass
from typing import TYPE_CHECKING
from opendevin.schema import ActionType
from opendevin import config
from opendevin.schema import ActionType, ConfigType
from .base import ExecutableAction
@@ -9,11 +12,14 @@ if TYPE_CHECKING:
from opendevin.controller import AgentController
from opendevin.observation import CmdOutputObservation, Observation
from opendevin.observation import IPythonRunCellObservation
@dataclass
class CmdRunAction(ExecutableAction):
command: str
background: bool = False
thought: str = ''
action: str = ActionType.RUN
async def run(self, controller: 'AgentController') -> 'Observation':
@@ -23,10 +29,18 @@ class CmdRunAction(ExecutableAction):
def message(self) -> str:
return f'Running command: {self.command}'
def __str__(self) -> str:
ret = '**CmdRunAction**\n'
if self.thought:
ret += f'THOUGHT:{self.thought}\n'
ret += f'COMMAND:\n{self.command}'
return ret
@dataclass
class CmdKillAction(ExecutableAction):
id: int
thought: str = ''
action: str = ActionType.KILL
async def run(self, controller: 'AgentController') -> 'CmdOutputObservation':
@@ -35,3 +49,48 @@ class CmdKillAction(ExecutableAction):
@property
def message(self) -> str:
return f'Killing command: {self.id}'
def __str__(self) -> str:
return f'**CmdKillAction**\n{self.id}'
@dataclass
class IPythonRunCellAction(ExecutableAction):
code: str
thought: str = ''
action: str = ActionType.RUN_IPYTHON
async def run(self, controller: 'AgentController') -> 'IPythonRunCellObservation':
# echo "import math" | execute_cli
# write code to a temporary file and pass it to `execute_cli` via stdin
tmp_filepath = os.path.join(
config.get(ConfigType.WORKSPACE_BASE),
'.tmp', '.ipython_execution_tmp.py'
)
pathlib.Path(os.path.dirname(tmp_filepath)).mkdir(parents=True, exist_ok=True)
with open(tmp_filepath, 'w') as tmp_file:
tmp_file.write(self.code)
tmp_filepath_inside_sandbox = os.path.join(
config.get(ConfigType.WORKSPACE_MOUNT_PATH_IN_SANDBOX),
'.tmp', '.ipython_execution_tmp.py'
)
obs = controller.action_manager.run_command(
f'execute_cli < {tmp_filepath_inside_sandbox}',
background=False
)
return IPythonRunCellObservation(
content=obs.content,
code=self.code
)
def __str__(self) -> str:
ret = '**IPythonRunCellAction**\n'
if self.thought:
ret += f'THOUGHT:{self.thought}\n'
ret += f'CODE:\n{self.code}'
return ret
@property
def message(self) -> str:
return f'Running Python code interactively: {self.code}'

View File

@@ -17,6 +17,7 @@ if TYPE_CHECKING:
@dataclass
class BrowseURLAction(ExecutableAction):
url: str
thought: str = ''
action: str = ActionType.BROWSE
async def run(self, controller: 'AgentController') -> BrowserOutputObservation: # type: ignore

View File

@@ -50,7 +50,7 @@ class FileReadAction(ExecutableAction):
path: str
start: int = 0
end: int = -1
thoughts: str = ''
thought: str = ''
action: str = ActionType.READ
def _read_lines(self, all_lines: list[str]):
@@ -100,7 +100,7 @@ class FileWriteAction(ExecutableAction):
content: str
start: int = 0
end: int = -1
thoughts: str = ''
thought: str = ''
action: str = ActionType.WRITE
def _insert_lines(self, to_insert: list[str], original: list[str]):

View File

@@ -15,6 +15,7 @@ class AddTaskAction(ExecutableAction):
parent: str
goal: str
subtasks: list = field(default_factory=list)
thought: str = ''
action: str = ActionType.ADD_TASK
async def run(self, controller: 'AgentController') -> NullObservation: # type: ignore
@@ -31,6 +32,7 @@ class AddTaskAction(ExecutableAction):
class ModifyTaskAction(ExecutableAction):
id: str
state: str
thought: str = ''
action: str = ActionType.MODIFY_TASK
async def run(self, controller: 'AgentController') -> NullObservation: # type: ignore
@@ -47,6 +49,7 @@ class ModifyTaskAction(ExecutableAction):
class TaskStateChangedAction(NotExecutableAction):
"""Fake action, just to notify the client that a task state has changed."""
task_state: str
thought: str = ''
action: str = ActionType.CHANGE_TASK_STATE
@property

View File

@@ -171,7 +171,6 @@ def finalize_config():
if config.get(ConfigType.WORKSPACE_MOUNT_PATH) is None:
config[ConfigType.WORKSPACE_MOUNT_PATH] = config.get(ConfigType.WORKSPACE_BASE)
finalize_config()

View File

@@ -1,11 +1,13 @@
import asyncio
from typing import Callable, List, Type
from agenthub.codeact_agent.codeact_agent import CodeActAgent
from opendevin import config
from opendevin.action import (
Action,
AgentDelegateAction,
AgentFinishAction,
AgentTalkAction,
NullAction,
)
from opendevin.action.tasks import TaskStateChangedAction
@@ -23,8 +25,10 @@ from opendevin.observation import (
AgentErrorObservation,
NullObservation,
Observation,
UserMessageObservation,
)
from opendevin.plan import Plan
from opendevin.sandbox import DockerSSHBox
from opendevin.schema import TaskState
from opendevin.schema.config import ConfigType
from opendevin.state import State
@@ -64,6 +68,11 @@ class AgentController:
# Initialize agent-required plugins for sandbox (if any)
self.action_manager.init_sandbox_plugins(agent.sandbox_plugins)
if isinstance(agent, CodeActAgent) and not isinstance(self.action_manager.sandbox, DockerSSHBox):
logger.warning('CodeActAgent requires DockerSSHBox as sandbox! Using other sandbox that are not stateful (LocalBox, DockerExecBox) will not work properly.')
self._await_user_message_queue: asyncio.Queue = asyncio.Queue()
def update_state_for_step(self, i):
if self.state is None:
return
@@ -174,6 +183,36 @@ class AgentController:
async def notify_task_state_changed(self):
await self._run_callbacks(TaskStateChangedAction(self._task_state))
async def add_user_message(self, message: UserMessageObservation):
if self.state is None:
return
if self._task_state == TaskState.AWAITING_USER_INPUT:
self._await_user_message_queue.put_nowait(message)
# set the task state to running
self._task_state = TaskState.RUNNING
await self.notify_task_state_changed()
elif self._task_state == TaskState.RUNNING:
self.add_history(NullAction(), message)
else:
raise ValueError(f'Task (state: {self._task_state}) is not in a state to add user message')
async def wait_for_user_input(self) -> UserMessageObservation:
self._task_state = TaskState.AWAITING_USER_INPUT
await self.notify_task_state_changed()
# wait for the next user message
if len(self.callbacks) == 0:
logger.info('Use STDIN to request user message as no callbacks are registered', extra={'msg_type': 'INFO'})
message = input('Request user input [type /exit to stop interaction] >> ')
user_message_observation = UserMessageObservation(message)
else:
user_message_observation = await self._await_user_message_queue.get()
self._await_user_message_queue.task_done()
return user_message_observation
async def start_delegate(self, action: AgentDelegateAction):
AgentCls: Type[Agent] = Agent.get_cls(action.agent)
agent = AgentCls(llm=self.agent.llm)
@@ -201,7 +240,8 @@ class AgentController:
return False
logger.info(f'STEP {i}', extra={'msg_type': 'STEP'})
logger.info(self.state.plan.main_goal, extra={'msg_type': 'PLAN'})
if i == 0:
logger.info(self.state.plan.main_goal, extra={'msg_type': 'PLAN'})
if self.state.num_of_chars > self.max_chars:
raise MaxCharsExceedError(self.state.num_of_chars, self.max_chars)
@@ -226,6 +266,14 @@ class AgentController:
await self._run_callbacks(action)
# whether to await for user messages
if isinstance(action, AgentTalkAction):
# await for the next user messages
user_message_observation = await self.wait_for_user_input()
logger.info(user_message_observation, extra={'msg_type': 'OBSERVATION'})
self.add_history(action, user_message_observation)
return False
finished = isinstance(action, AgentFinishAction)
if finished:
self.state.outputs = action.outputs # type: ignore[attr-defined]

View File

@@ -5,7 +5,7 @@ from .error import AgentErrorObservation
from .files import FileReadObservation, FileWriteObservation
from .message import AgentMessageObservation, UserMessageObservation
from .recall import AgentRecallObservation
from .run import CmdOutputObservation
from .run import CmdOutputObservation, IPythonRunCellObservation
observations = (
CmdOutputObservation,
@@ -40,6 +40,7 @@ __all__ = [
'Observation',
'NullObservation',
'CmdOutputObservation',
'IPythonRunCellObservation',
'BrowserOutputObservation',
'FileReadObservation',
'FileWriteObservation',

View File

@@ -23,3 +23,21 @@ class CmdOutputObservation(Observation):
@property
def message(self) -> str:
return f'Command `{self.command}` executed with exit code {self.exit_code}.'
@dataclass
class IPythonRunCellObservation(Observation):
"""
This data class represents the output of a IPythonRunCellAction.
"""
code: str
observation: str = ObservationType.RUN_IPYTHON
@property
def error(self) -> bool:
return False # IPython cells do not return exit codes
@property
def message(self) -> str:
return 'Coded executed in IPython cell.'

View File

@@ -188,7 +188,7 @@ class JupyterKernel:
if 'image/png' in msg['content']['data']:
# use markdone to display image (in case of large image)
# outputs.append(f"\n<img src=\'data:image/png;base64,{msg['content']['data']['image/png']}\'/>\n")
outputs.append(f"![image](data:image/png;base64,{msg['content']['data']['image / png']})")
outputs.append(f"![image](data:image/png;base64,{msg['content']['data']['image/png']})")
elif msg_type == 'execute_reply':
execution_done = True

View File

@@ -10,8 +10,12 @@ class ActionTypeSchema(BaseModel):
"""Initializes the agent. Only sent by client.
"""
USER_MESSAGE: str = Field(default='user_message')
"""Sends a message from the user. Only sent by the client.
"""
START: str = Field(default='start')
"""Starts a new development task. Only sent by the client.
"""Starts a new development task OR send chat from the user. Only sent by the client.
"""
READ: str = Field(default='read')
@@ -26,6 +30,10 @@ class ActionTypeSchema(BaseModel):
"""Runs a command.
"""
RUN_IPYTHON: str = Field(default='run_ipython')
"""Runs a IPython cell.
"""
KILL: str = Field(default='kill')
"""Kills a background command.
"""
@@ -42,6 +50,10 @@ class ActionTypeSchema(BaseModel):
"""Allows the agent to make a plan, set a goal, or record thoughts
"""
TALK: str = Field(default='talk')
"""Allows the agent to respond to the user.
"""
DELEGATE: str = Field(default='delegate')
"""Delegates a task to another agent.
"""

View File

@@ -20,6 +20,10 @@ class ObservationTypeSchema(BaseModel):
"""The output of a command
"""
RUN_IPYTHON: str = Field(default='run_ipython')
"""Runs a IPython cell.
"""
RECALL: str = Field(default='recall')
"""The result of a search
"""

View File

@@ -10,6 +10,10 @@ class TaskState(str, Enum):
"""The task is running.
"""
AWAITING_USER_INPUT = 'awaiting_user_input'
"""The task is awaiting user input.
"""
PAUSED = 'paused'
"""The task is paused.
"""

View File

@@ -94,6 +94,8 @@ class AgentUnit:
await self.create_controller(data)
case ActionType.START:
await self.start_task(data)
case ActionType.USER_MESSAGE:
await self.send_user_message(data)
case ActionType.CHANGE_TASK_STATE:
task_state_action = data.get('args', {}).get('task_state_action', None)
if task_state_action is None:
@@ -177,23 +179,27 @@ class AgentUnit:
Args:
start_event: The start event data.
"""
if 'task' not in start_event['args']:
await self.send_error('No task specified')
return
await self.send_message('Starting new task...')
task = start_event['args']['task']
if self.controller is None:
await self.send_error('No agent started. Please wait a second...')
return
try:
if self.agent_task:
self.agent_task.cancel()
assert not self.agent_task, 'Agent task already running'
self.agent_task = asyncio.create_task(
self.controller.start(task), name='agent start task loop'
)
except Exception as e:
await self.send_error(f'Error during task loop: {e}')
async def send_user_message(self, data: dict):
if not self.agent_task or not self.controller:
await self.send_error('No agent started.')
return
await self.controller.add_user_message(
UserMessageObservation(data['args']['message'])
)
async def set_task_state(self, new_state_action: TaskStateAction):
"""Sets the state of the agent task."""
if self.controller is None:

View File

@@ -89,12 +89,15 @@ mkdir workspace
poetry run python ./opendevin/main.py -i 10 -t "Write a shell script 'hello.sh' that prints 'hello'." -c "MonologueAgent" -d "./workspace"
```
**NOTE**: If your agent decide to support user-agent interaction via natural language (e.g., you will prompted to enter user resposes when running the above `main.py` command), you should create a file named `tests/integration/mock/<AgentName>/<TestName>/user_responses.log` containing all the responses in order you provided to the agent, delimited by newline ('\n'). This will be used to mock the STDIN during testing.
After running the above commands, you should be able to locate the real prompts
and responses logged. The log folder follows `logs/llm/%y-%m-%d_%H-%M.log` format.
Now, move all files under that folder to `tests/integration/mock/<AgentName>/<TestName>` folder. For example, moving all files from `logs/llm/24-04-23_21-55/` folder to
`tests/integration/mock/MonologueAgent/test_write_simple_script` folder.
That's it, you are good to go! When you launch an integration test, mock
responses are loaded and used to replace a real LLM, so that we get
deterministic and consistent behavior, and most importantly, without spending real

View File

@@ -1,3 +1,4 @@
import io
import os
import re
from functools import partial
@@ -53,6 +54,28 @@ def get_mock_response(test_name, messages):
return resp_file.read()
def mock_user_response(*args, test_name, **kwargs):
"""The agent will ask for user input using `input()` when calling `asyncio.run(main(task))`.
This function mocks the user input by providing the response from the mock response file.
It will read the `user_responses.log` file in the test directory and set as
STDIN input for the agent to read.
"""
user_response_file = os.path.join(
script_dir,
'mock',
os.environ.get('AGENT'),
test_name,
'user_responses.log'
)
if not os.path.exists(user_response_file):
return ''
with open(user_response_file, 'r') as f:
ret = f.read().rstrip()
ret += '\n'
return ret
def mock_completion(*args, test_name, **kwargs):
messages = kwargs['messages']
message_str = ''
@@ -67,4 +90,11 @@ def mock_completion(*args, test_name, **kwargs):
@pytest.fixture(autouse=True)
def patch_completion(monkeypatch, request):
test_name = request.node.name
# Mock LLM completion
monkeypatch.setattr('opendevin.llm.llm.litellm_completion', partial(mock_completion, test_name=test_name))
# Mock user input (only for tests that have user_responses.log)
user_responses_str = mock_user_response(test_name=test_name)
if user_responses_str:
user_responses = io.StringIO(user_responses_str)
monkeypatch.setattr('sys.stdin', user_responses)

View File

@@ -0,0 +1,215 @@
----------
A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions.
The assistant can interact with an interactive Python (Jupyter Notebook) environment and receive the corresponding output when needed. The code should be enclosed using "<execute_ipython>" tag, for example:
<execute_ipython>
print("Hello World!")
</execute_ipython>
The assistant can execute bash commands on behalf of the user by wrapping them with <execute_bash> and </execute_bash>.
For example, you can list the files in the current directory by <execute_bash> ls </execute_bash>.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
The assistant can install Python packages through bash by <execute_bash> pip install [package needed] </execute_bash> and should always import packages and define variables before starting to use them.
The assistant should stop <execute> and provide an answer when they have already obtained the answer from the execution result.
Apart from the standard bash commands, you can also use the following special commands in <execute_bash> environment:
open <path> [<line_number>] - opens the file at the given path in the editor. If line_number is provided, the window will be move to include that line
goto <line_number> - moves the window to show <line_number>
scroll_down - moves the window down {WINDOW} lines
scroll_up - moves the window down {WINDOW} lines
create <filename> - creates and opens a new file with the given name
search_dir <search_term> [<dir>] - searches for search_term in all files in dir. If dir is not provided, searches in the current directory
search_file <search_term> [<file>] - searches for search_term in file. If file is not provided, searches in the current open file
find_file <file_name> [<dir>] - finds all files with the given name in dir. If dir is not provided, searches in the current directory
edit <start_line>:<end_line>
<replacement_text>
end_of_edit - replaces lines <start_line> through <end_line> (inclusive) with the given text in the open file. The replacement text is terminated by a line with only end_of_edit on it. All of the <replacement text> will be entered, so make sure your indentation is formatted properly. Python files will be checked for syntax errors after the edit. If the system detects a syntax error, the edit will not be executed. Simply try to edit the file again, but make sure to read the error message and modify the edit command you issue accordingly. Issuing the same command a second time will just lead to the same error message again.
Please note that THE EDIT COMMAND REQUIRES PROPER INDENTATION. If you'd like to add the line ' print(x)' you must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Whenever possible, execute the code for the user using <execute_ipython> or <execute_bash> instead of providing it.
The assistant's response should be concise, but do express their thoughts.
Try to include one of <execute_ipython> or <execute_bash> in each of your responses, unless it is a direct answer to a question OR a message to the user.
----------
Here is an example of how you can interact with the environment for task solving:
--- START OF EXAMPLE ---
USER: Can you create a list of numbers from 1 to 10, and create a web page to display them at port 5000?
ASSISTANT:
Sure! Let me write the Python code for starting a web server and save it to a file `app.py`:
<execute_ipython>
CODE='''
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
numbers = list(range(1, 11))
return str(numbers)
if __name__ == '__main__':
app.run(port=5000)
'''
with open('app.py', 'w') as f:
f.write(CODE)
</execute_ipython>
USER:
Observation:
[Code executed successfully with no output]
ASSISTANT:
I have created a Python file `app.py` that will display a list of numbers from 1 to 10 when you run it. Let me run the Python file for you:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 121[1]+ Exit 1 python3 app.py > server.log 2>&1
ASSISTANT: Looks like the server is running with PID 121 then crashed. Let me check the server log:
<execute_bash>
cat server.log
</execute_bash>
USER:
Observation:
Traceback (most recent call last):
File "/workspace/app.py", line 2, in <module>
from flask import Flask
ModuleNotFoundError: No module named 'flask'
ASSISTANT:
It seems that Flask is not installed. Let me install Flask for you:
<execute_bash>
pip install flask
</execute_bash>
USER:
Observation:
Defaulting to user installation because normal site-packages is not writeable
Collecting flask
Using cached flask-3.0.3-py3-none-any.whl (101 kB)
Collecting blinker>=1.6.2
Using cached blinker-1.7.0-py3-none-any.whl (13 kB)
Collecting Werkzeug>=3.0.0
Using cached werkzeug-3.0.2-py3-none-any.whl (226 kB)
Collecting click>=8.1.3
Using cached click-8.1.7-py3-none-any.whl (97 kB)
Collecting itsdangerous>=2.1.2
Using cached itsdangerous-2.2.0-py3-none-any.whl (16 kB)
Requirement already satisfied: Jinja2>=3.1.2 in /home/opendevin/.local/lib/python3.10/site-packages (from flask) (3.1.3)
Requirement already satisfied: MarkupSafe>=2.0 in /home/opendevin/.local/lib/python3.10/site-packages (from Jinja2>=3.1.2->flask) (2.1.5)
Installing collected packages: Werkzeug, itsdangerous, click, blinker, flask
Successfully installed Werkzeug-3.0.2 blinker-1.7.0 click-8.1.7 flask-3.0.3 itsdangerous-2.2.0
ASSISTANT:
Now that Flask is installed, let me run the Python file again:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 124
ASSISTANT:
Let me check the server log again:
<execute_bash>
cat server.log
</execute_bash>
USER:
Observation:
* Serving Flask app 'app'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
ASSISTANT:
The server is running on port 5000 with PID 124. You can access the list of numbers by visiting http://127.0.0.1:5000. If you have any further questions, feel free to ask!
USER: Now kill the server, make it display the numbers in a table format.
ASSISTANT:
Sure! Let me stop the server first:
<execute_bash>
kill 124
</execute_bash>
USER:
Observation:
[1]+ Terminated python3 app.py > server.log 2>&1
ASSISTANT:
The server has been stopped. Let me open the Python file and modify it.
<execute_bash>
open app.py
</execute_bash>
USER:
[File: /workspace/app.py (11 lines total)]
1:
2:from flask import Flask
3:app = Flask(__name__)
4:
5:@app.route('/')
6:def index():
7: numbers = list(range(1, 11))
8: return str(numbers)
9:
10:if __name__ == '__main__':
11: app.run(port=5000)
ASSISTANT:
I should edit the file to display the numbers in a table format. Let me do that for you:
<execute_bash>
edit 8:8 <<EOF
return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'
EOF
</execute_bash>
USER:
Observation:
[File: /workspace/app.py (11 lines total)]
1:
2:from flask import Flask
3:app = Flask(__name__)
4:
5:@app.route('/')
6:def index():
7: numbers = list(range(1, 11))
8: return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'
9:
10:if __name__ == '__main__':
11: app.run(port=5000)
File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.
ASSISTANT:
The file has been updated. Let me run the Python file again with the new changes:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 126
ASSISTANT:
The server is running on port 5000 with PID 126. You can access the list of numbers in a table format by visiting http://127.0.0.1:5000. Free free to let me know if you have any further requests!
--- END OF EXAMPLE ---
NOW, LET'S START!
Write a shell script 'hello.sh' that prints 'hello'.

View File

@@ -0,0 +1,229 @@
----------
A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions.
The assistant can interact with an interactive Python (Jupyter Notebook) environment and receive the corresponding output when needed. The code should be enclosed using "<execute_ipython>" tag, for example:
<execute_ipython>
print("Hello World!")
</execute_ipython>
The assistant can execute bash commands on behalf of the user by wrapping them with <execute_bash> and </execute_bash>.
For example, you can list the files in the current directory by <execute_bash> ls </execute_bash>.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
The assistant can install Python packages through bash by <execute_bash> pip install [package needed] </execute_bash> and should always import packages and define variables before starting to use them.
The assistant should stop <execute> and provide an answer when they have already obtained the answer from the execution result.
Apart from the standard bash commands, you can also use the following special commands in <execute_bash> environment:
open <path> [<line_number>] - opens the file at the given path in the editor. If line_number is provided, the window will be move to include that line
goto <line_number> - moves the window to show <line_number>
scroll_down - moves the window down {WINDOW} lines
scroll_up - moves the window down {WINDOW} lines
create <filename> - creates and opens a new file with the given name
search_dir <search_term> [<dir>] - searches for search_term in all files in dir. If dir is not provided, searches in the current directory
search_file <search_term> [<file>] - searches for search_term in file. If file is not provided, searches in the current open file
find_file <file_name> [<dir>] - finds all files with the given name in dir. If dir is not provided, searches in the current directory
edit <start_line>:<end_line>
<replacement_text>
end_of_edit - replaces lines <start_line> through <end_line> (inclusive) with the given text in the open file. The replacement text is terminated by a line with only end_of_edit on it. All of the <replacement text> will be entered, so make sure your indentation is formatted properly. Python files will be checked for syntax errors after the edit. If the system detects a syntax error, the edit will not be executed. Simply try to edit the file again, but make sure to read the error message and modify the edit command you issue accordingly. Issuing the same command a second time will just lead to the same error message again.
Please note that THE EDIT COMMAND REQUIRES PROPER INDENTATION. If you'd like to add the line ' print(x)' you must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Whenever possible, execute the code for the user using <execute_ipython> or <execute_bash> instead of providing it.
The assistant's response should be concise, but do express their thoughts.
Try to include one of <execute_ipython> or <execute_bash> in each of your responses, unless it is a direct answer to a question OR a message to the user.
----------
Here is an example of how you can interact with the environment for task solving:
--- START OF EXAMPLE ---
USER: Can you create a list of numbers from 1 to 10, and create a web page to display them at port 5000?
ASSISTANT:
Sure! Let me write the Python code for starting a web server and save it to a file `app.py`:
<execute_ipython>
CODE='''
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
numbers = list(range(1, 11))
return str(numbers)
if __name__ == '__main__':
app.run(port=5000)
'''
with open('app.py', 'w') as f:
f.write(CODE)
</execute_ipython>
USER:
Observation:
[Code executed successfully with no output]
ASSISTANT:
I have created a Python file `app.py` that will display a list of numbers from 1 to 10 when you run it. Let me run the Python file for you:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 121[1]+ Exit 1 python3 app.py > server.log 2>&1
ASSISTANT: Looks like the server is running with PID 121 then crashed. Let me check the server log:
<execute_bash>
cat server.log
</execute_bash>
USER:
Observation:
Traceback (most recent call last):
File "/workspace/app.py", line 2, in <module>
from flask import Flask
ModuleNotFoundError: No module named 'flask'
ASSISTANT:
It seems that Flask is not installed. Let me install Flask for you:
<execute_bash>
pip install flask
</execute_bash>
USER:
Observation:
Defaulting to user installation because normal site-packages is not writeable
Collecting flask
Using cached flask-3.0.3-py3-none-any.whl (101 kB)
Collecting blinker>=1.6.2
Using cached blinker-1.7.0-py3-none-any.whl (13 kB)
Collecting Werkzeug>=3.0.0
Using cached werkzeug-3.0.2-py3-none-any.whl (226 kB)
Collecting click>=8.1.3
Using cached click-8.1.7-py3-none-any.whl (97 kB)
Collecting itsdangerous>=2.1.2
Using cached itsdangerous-2.2.0-py3-none-any.whl (16 kB)
Requirement already satisfied: Jinja2>=3.1.2 in /home/opendevin/.local/lib/python3.10/site-packages (from flask) (3.1.3)
Requirement already satisfied: MarkupSafe>=2.0 in /home/opendevin/.local/lib/python3.10/site-packages (from Jinja2>=3.1.2->flask) (2.1.5)
Installing collected packages: Werkzeug, itsdangerous, click, blinker, flask
Successfully installed Werkzeug-3.0.2 blinker-1.7.0 click-8.1.7 flask-3.0.3 itsdangerous-2.2.0
ASSISTANT:
Now that Flask is installed, let me run the Python file again:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 124
ASSISTANT:
Let me check the server log again:
<execute_bash>
cat server.log
</execute_bash>
USER:
Observation:
* Serving Flask app 'app'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
ASSISTANT:
The server is running on port 5000 with PID 124. You can access the list of numbers by visiting http://127.0.0.1:5000. If you have any further questions, feel free to ask!
USER: Now kill the server, make it display the numbers in a table format.
ASSISTANT:
Sure! Let me stop the server first:
<execute_bash>
kill 124
</execute_bash>
USER:
Observation:
[1]+ Terminated python3 app.py > server.log 2>&1
ASSISTANT:
The server has been stopped. Let me open the Python file and modify it.
<execute_bash>
open app.py
</execute_bash>
USER:
[File: /workspace/app.py (11 lines total)]
1:
2:from flask import Flask
3:app = Flask(__name__)
4:
5:@app.route('/')
6:def index():
7: numbers = list(range(1, 11))
8: return str(numbers)
9:
10:if __name__ == '__main__':
11: app.run(port=5000)
ASSISTANT:
I should edit the file to display the numbers in a table format. Let me do that for you:
<execute_bash>
edit 8:8 <<EOF
return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'
EOF
</execute_bash>
USER:
Observation:
[File: /workspace/app.py (11 lines total)]
1:
2:from flask import Flask
3:app = Flask(__name__)
4:
5:@app.route('/')
6:def index():
7: numbers = list(range(1, 11))
8: return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'
9:
10:if __name__ == '__main__':
11: app.run(port=5000)
File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.
ASSISTANT:
The file has been updated. Let me run the Python file again with the new changes:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 126
ASSISTANT:
The server is running on port 5000 with PID 126. You can access the list of numbers in a table format by visiting http://127.0.0.1:5000. Free free to let me know if you have any further requests!
--- END OF EXAMPLE ---
NOW, LET'S START!
Write a shell script 'hello.sh' that prints 'hello'.
----------
Let's start by creating the shell script `hello.sh` that prints "hello". I'll write the script and save it to a file.
<execute_bash>
echo "echo 'hello'" > hello.sh
</execute_bash>
----------
OBSERVATION:
[Command -1 finished with exit code 0]]

View File

@@ -0,0 +1,237 @@
----------
A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions.
The assistant can interact with an interactive Python (Jupyter Notebook) environment and receive the corresponding output when needed. The code should be enclosed using "<execute_ipython>" tag, for example:
<execute_ipython>
print("Hello World!")
</execute_ipython>
The assistant can execute bash commands on behalf of the user by wrapping them with <execute_bash> and </execute_bash>.
For example, you can list the files in the current directory by <execute_bash> ls </execute_bash>.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
The assistant can install Python packages through bash by <execute_bash> pip install [package needed] </execute_bash> and should always import packages and define variables before starting to use them.
The assistant should stop <execute> and provide an answer when they have already obtained the answer from the execution result.
Apart from the standard bash commands, you can also use the following special commands in <execute_bash> environment:
open <path> [<line_number>] - opens the file at the given path in the editor. If line_number is provided, the window will be move to include that line
goto <line_number> - moves the window to show <line_number>
scroll_down - moves the window down {WINDOW} lines
scroll_up - moves the window down {WINDOW} lines
create <filename> - creates and opens a new file with the given name
search_dir <search_term> [<dir>] - searches for search_term in all files in dir. If dir is not provided, searches in the current directory
search_file <search_term> [<file>] - searches for search_term in file. If file is not provided, searches in the current open file
find_file <file_name> [<dir>] - finds all files with the given name in dir. If dir is not provided, searches in the current directory
edit <start_line>:<end_line>
<replacement_text>
end_of_edit - replaces lines <start_line> through <end_line> (inclusive) with the given text in the open file. The replacement text is terminated by a line with only end_of_edit on it. All of the <replacement text> will be entered, so make sure your indentation is formatted properly. Python files will be checked for syntax errors after the edit. If the system detects a syntax error, the edit will not be executed. Simply try to edit the file again, but make sure to read the error message and modify the edit command you issue accordingly. Issuing the same command a second time will just lead to the same error message again.
Please note that THE EDIT COMMAND REQUIRES PROPER INDENTATION. If you'd like to add the line ' print(x)' you must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Whenever possible, execute the code for the user using <execute_ipython> or <execute_bash> instead of providing it.
The assistant's response should be concise, but do express their thoughts.
Try to include one of <execute_ipython> or <execute_bash> in each of your responses, unless it is a direct answer to a question OR a message to the user.
----------
Here is an example of how you can interact with the environment for task solving:
--- START OF EXAMPLE ---
USER: Can you create a list of numbers from 1 to 10, and create a web page to display them at port 5000?
ASSISTANT:
Sure! Let me write the Python code for starting a web server and save it to a file `app.py`:
<execute_ipython>
CODE='''
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
numbers = list(range(1, 11))
return str(numbers)
if __name__ == '__main__':
app.run(port=5000)
'''
with open('app.py', 'w') as f:
f.write(CODE)
</execute_ipython>
USER:
Observation:
[Code executed successfully with no output]
ASSISTANT:
I have created a Python file `app.py` that will display a list of numbers from 1 to 10 when you run it. Let me run the Python file for you:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 121[1]+ Exit 1 python3 app.py > server.log 2>&1
ASSISTANT: Looks like the server is running with PID 121 then crashed. Let me check the server log:
<execute_bash>
cat server.log
</execute_bash>
USER:
Observation:
Traceback (most recent call last):
File "/workspace/app.py", line 2, in <module>
from flask import Flask
ModuleNotFoundError: No module named 'flask'
ASSISTANT:
It seems that Flask is not installed. Let me install Flask for you:
<execute_bash>
pip install flask
</execute_bash>
USER:
Observation:
Defaulting to user installation because normal site-packages is not writeable
Collecting flask
Using cached flask-3.0.3-py3-none-any.whl (101 kB)
Collecting blinker>=1.6.2
Using cached blinker-1.7.0-py3-none-any.whl (13 kB)
Collecting Werkzeug>=3.0.0
Using cached werkzeug-3.0.2-py3-none-any.whl (226 kB)
Collecting click>=8.1.3
Using cached click-8.1.7-py3-none-any.whl (97 kB)
Collecting itsdangerous>=2.1.2
Using cached itsdangerous-2.2.0-py3-none-any.whl (16 kB)
Requirement already satisfied: Jinja2>=3.1.2 in /home/opendevin/.local/lib/python3.10/site-packages (from flask) (3.1.3)
Requirement already satisfied: MarkupSafe>=2.0 in /home/opendevin/.local/lib/python3.10/site-packages (from Jinja2>=3.1.2->flask) (2.1.5)
Installing collected packages: Werkzeug, itsdangerous, click, blinker, flask
Successfully installed Werkzeug-3.0.2 blinker-1.7.0 click-8.1.7 flask-3.0.3 itsdangerous-2.2.0
ASSISTANT:
Now that Flask is installed, let me run the Python file again:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 124
ASSISTANT:
Let me check the server log again:
<execute_bash>
cat server.log
</execute_bash>
USER:
Observation:
* Serving Flask app 'app'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
ASSISTANT:
The server is running on port 5000 with PID 124. You can access the list of numbers by visiting http://127.0.0.1:5000. If you have any further questions, feel free to ask!
USER: Now kill the server, make it display the numbers in a table format.
ASSISTANT:
Sure! Let me stop the server first:
<execute_bash>
kill 124
</execute_bash>
USER:
Observation:
[1]+ Terminated python3 app.py > server.log 2>&1
ASSISTANT:
The server has been stopped. Let me open the Python file and modify it.
<execute_bash>
open app.py
</execute_bash>
USER:
[File: /workspace/app.py (11 lines total)]
1:
2:from flask import Flask
3:app = Flask(__name__)
4:
5:@app.route('/')
6:def index():
7: numbers = list(range(1, 11))
8: return str(numbers)
9:
10:if __name__ == '__main__':
11: app.run(port=5000)
ASSISTANT:
I should edit the file to display the numbers in a table format. Let me do that for you:
<execute_bash>
edit 8:8 <<EOF
return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'
EOF
</execute_bash>
USER:
Observation:
[File: /workspace/app.py (11 lines total)]
1:
2:from flask import Flask
3:app = Flask(__name__)
4:
5:@app.route('/')
6:def index():
7: numbers = list(range(1, 11))
8: return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'
9:
10:if __name__ == '__main__':
11: app.run(port=5000)
File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.
ASSISTANT:
The file has been updated. Let me run the Python file again with the new changes:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 126
ASSISTANT:
The server is running on port 5000 with PID 126. You can access the list of numbers in a table format by visiting http://127.0.0.1:5000. Free free to let me know if you have any further requests!
--- END OF EXAMPLE ---
NOW, LET'S START!
Write a shell script 'hello.sh' that prints 'hello'.
----------
Let's start by creating the shell script `hello.sh` that prints "hello". I'll write the script and save it to a file.
<execute_bash>
echo "echo 'hello'" > hello.sh
</execute_bash>
----------
OBSERVATION:
[Command -1 finished with exit code 0]]
----------
The shell script `hello.sh` has been successfully created. Would you like to run the script to see the output, or is there anything else you'd like to do with it?
----------
can you run it to make sure it is working?

View File

@@ -0,0 +1,251 @@
----------
A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions.
The assistant can interact with an interactive Python (Jupyter Notebook) environment and receive the corresponding output when needed. The code should be enclosed using "<execute_ipython>" tag, for example:
<execute_ipython>
print("Hello World!")
</execute_ipython>
The assistant can execute bash commands on behalf of the user by wrapping them with <execute_bash> and </execute_bash>.
For example, you can list the files in the current directory by <execute_bash> ls </execute_bash>.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
The assistant can install Python packages through bash by <execute_bash> pip install [package needed] </execute_bash> and should always import packages and define variables before starting to use them.
The assistant should stop <execute> and provide an answer when they have already obtained the answer from the execution result.
Apart from the standard bash commands, you can also use the following special commands in <execute_bash> environment:
open <path> [<line_number>] - opens the file at the given path in the editor. If line_number is provided, the window will be move to include that line
goto <line_number> - moves the window to show <line_number>
scroll_down - moves the window down {WINDOW} lines
scroll_up - moves the window down {WINDOW} lines
create <filename> - creates and opens a new file with the given name
search_dir <search_term> [<dir>] - searches for search_term in all files in dir. If dir is not provided, searches in the current directory
search_file <search_term> [<file>] - searches for search_term in file. If file is not provided, searches in the current open file
find_file <file_name> [<dir>] - finds all files with the given name in dir. If dir is not provided, searches in the current directory
edit <start_line>:<end_line>
<replacement_text>
end_of_edit - replaces lines <start_line> through <end_line> (inclusive) with the given text in the open file. The replacement text is terminated by a line with only end_of_edit on it. All of the <replacement text> will be entered, so make sure your indentation is formatted properly. Python files will be checked for syntax errors after the edit. If the system detects a syntax error, the edit will not be executed. Simply try to edit the file again, but make sure to read the error message and modify the edit command you issue accordingly. Issuing the same command a second time will just lead to the same error message again.
Please note that THE EDIT COMMAND REQUIRES PROPER INDENTATION. If you'd like to add the line ' print(x)' you must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Whenever possible, execute the code for the user using <execute_ipython> or <execute_bash> instead of providing it.
The assistant's response should be concise, but do express their thoughts.
Try to include one of <execute_ipython> or <execute_bash> in each of your responses, unless it is a direct answer to a question OR a message to the user.
----------
Here is an example of how you can interact with the environment for task solving:
--- START OF EXAMPLE ---
USER: Can you create a list of numbers from 1 to 10, and create a web page to display them at port 5000?
ASSISTANT:
Sure! Let me write the Python code for starting a web server and save it to a file `app.py`:
<execute_ipython>
CODE='''
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
numbers = list(range(1, 11))
return str(numbers)
if __name__ == '__main__':
app.run(port=5000)
'''
with open('app.py', 'w') as f:
f.write(CODE)
</execute_ipython>
USER:
Observation:
[Code executed successfully with no output]
ASSISTANT:
I have created a Python file `app.py` that will display a list of numbers from 1 to 10 when you run it. Let me run the Python file for you:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 121[1]+ Exit 1 python3 app.py > server.log 2>&1
ASSISTANT: Looks like the server is running with PID 121 then crashed. Let me check the server log:
<execute_bash>
cat server.log
</execute_bash>
USER:
Observation:
Traceback (most recent call last):
File "/workspace/app.py", line 2, in <module>
from flask import Flask
ModuleNotFoundError: No module named 'flask'
ASSISTANT:
It seems that Flask is not installed. Let me install Flask for you:
<execute_bash>
pip install flask
</execute_bash>
USER:
Observation:
Defaulting to user installation because normal site-packages is not writeable
Collecting flask
Using cached flask-3.0.3-py3-none-any.whl (101 kB)
Collecting blinker>=1.6.2
Using cached blinker-1.7.0-py3-none-any.whl (13 kB)
Collecting Werkzeug>=3.0.0
Using cached werkzeug-3.0.2-py3-none-any.whl (226 kB)
Collecting click>=8.1.3
Using cached click-8.1.7-py3-none-any.whl (97 kB)
Collecting itsdangerous>=2.1.2
Using cached itsdangerous-2.2.0-py3-none-any.whl (16 kB)
Requirement already satisfied: Jinja2>=3.1.2 in /home/opendevin/.local/lib/python3.10/site-packages (from flask) (3.1.3)
Requirement already satisfied: MarkupSafe>=2.0 in /home/opendevin/.local/lib/python3.10/site-packages (from Jinja2>=3.1.2->flask) (2.1.5)
Installing collected packages: Werkzeug, itsdangerous, click, blinker, flask
Successfully installed Werkzeug-3.0.2 blinker-1.7.0 click-8.1.7 flask-3.0.3 itsdangerous-2.2.0
ASSISTANT:
Now that Flask is installed, let me run the Python file again:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 124
ASSISTANT:
Let me check the server log again:
<execute_bash>
cat server.log
</execute_bash>
USER:
Observation:
* Serving Flask app 'app'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
ASSISTANT:
The server is running on port 5000 with PID 124. You can access the list of numbers by visiting http://127.0.0.1:5000. If you have any further questions, feel free to ask!
USER: Now kill the server, make it display the numbers in a table format.
ASSISTANT:
Sure! Let me stop the server first:
<execute_bash>
kill 124
</execute_bash>
USER:
Observation:
[1]+ Terminated python3 app.py > server.log 2>&1
ASSISTANT:
The server has been stopped. Let me open the Python file and modify it.
<execute_bash>
open app.py
</execute_bash>
USER:
[File: /workspace/app.py (11 lines total)]
1:
2:from flask import Flask
3:app = Flask(__name__)
4:
5:@app.route('/')
6:def index():
7: numbers = list(range(1, 11))
8: return str(numbers)
9:
10:if __name__ == '__main__':
11: app.run(port=5000)
ASSISTANT:
I should edit the file to display the numbers in a table format. Let me do that for you:
<execute_bash>
edit 8:8 <<EOF
return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'
EOF
</execute_bash>
USER:
Observation:
[File: /workspace/app.py (11 lines total)]
1:
2:from flask import Flask
3:app = Flask(__name__)
4:
5:@app.route('/')
6:def index():
7: numbers = list(range(1, 11))
8: return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'
9:
10:if __name__ == '__main__':
11: app.run(port=5000)
File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.
ASSISTANT:
The file has been updated. Let me run the Python file again with the new changes:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 126
ASSISTANT:
The server is running on port 5000 with PID 126. You can access the list of numbers in a table format by visiting http://127.0.0.1:5000. Free free to let me know if you have any further requests!
--- END OF EXAMPLE ---
NOW, LET'S START!
Write a shell script 'hello.sh' that prints 'hello'.
----------
Let's start by creating the shell script `hello.sh` that prints "hello". I'll write the script and save it to a file.
<execute_bash>
echo "echo 'hello'" > hello.sh
</execute_bash>
----------
OBSERVATION:
[Command -1 finished with exit code 0]]
----------
The shell script `hello.sh` has been successfully created. Would you like to run the script to see the output, or is there anything else you'd like to do with it?
----------
can you run it to make sure it is working?
----------
Sure, let's run the script `hello.sh` to ensure it's working correctly.
<execute_bash>
bash hello.sh
</execute_bash>
----------
OBSERVATION:
hello
[Command -1 finished with exit code 0]]

View File

@@ -0,0 +1,259 @@
----------
A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the user's questions.
The assistant can interact with an interactive Python (Jupyter Notebook) environment and receive the corresponding output when needed. The code should be enclosed using "<execute_ipython>" tag, for example:
<execute_ipython>
print("Hello World!")
</execute_ipython>
The assistant can execute bash commands on behalf of the user by wrapping them with <execute_bash> and </execute_bash>.
For example, you can list the files in the current directory by <execute_bash> ls </execute_bash>.
The assistant should attempt fewer things at a time instead of putting too much commands OR code in one "execute" block.
The assistant can install Python packages through bash by <execute_bash> pip install [package needed] </execute_bash> and should always import packages and define variables before starting to use them.
The assistant should stop <execute> and provide an answer when they have already obtained the answer from the execution result.
Apart from the standard bash commands, you can also use the following special commands in <execute_bash> environment:
open <path> [<line_number>] - opens the file at the given path in the editor. If line_number is provided, the window will be move to include that line
goto <line_number> - moves the window to show <line_number>
scroll_down - moves the window down {WINDOW} lines
scroll_up - moves the window down {WINDOW} lines
create <filename> - creates and opens a new file with the given name
search_dir <search_term> [<dir>] - searches for search_term in all files in dir. If dir is not provided, searches in the current directory
search_file <search_term> [<file>] - searches for search_term in file. If file is not provided, searches in the current open file
find_file <file_name> [<dir>] - finds all files with the given name in dir. If dir is not provided, searches in the current directory
edit <start_line>:<end_line>
<replacement_text>
end_of_edit - replaces lines <start_line> through <end_line> (inclusive) with the given text in the open file. The replacement text is terminated by a line with only end_of_edit on it. All of the <replacement text> will be entered, so make sure your indentation is formatted properly. Python files will be checked for syntax errors after the edit. If the system detects a syntax error, the edit will not be executed. Simply try to edit the file again, but make sure to read the error message and modify the edit command you issue accordingly. Issuing the same command a second time will just lead to the same error message again.
Please note that THE EDIT COMMAND REQUIRES PROPER INDENTATION. If you'd like to add the line ' print(x)' you must fully write that out, with all those spaces before the code! Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
Whenever possible, execute the code for the user using <execute_ipython> or <execute_bash> instead of providing it.
The assistant's response should be concise, but do express their thoughts.
Try to include one of <execute_ipython> or <execute_bash> in each of your responses, unless it is a direct answer to a question OR a message to the user.
----------
Here is an example of how you can interact with the environment for task solving:
--- START OF EXAMPLE ---
USER: Can you create a list of numbers from 1 to 10, and create a web page to display them at port 5000?
ASSISTANT:
Sure! Let me write the Python code for starting a web server and save it to a file `app.py`:
<execute_ipython>
CODE='''
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
numbers = list(range(1, 11))
return str(numbers)
if __name__ == '__main__':
app.run(port=5000)
'''
with open('app.py', 'w') as f:
f.write(CODE)
</execute_ipython>
USER:
Observation:
[Code executed successfully with no output]
ASSISTANT:
I have created a Python file `app.py` that will display a list of numbers from 1 to 10 when you run it. Let me run the Python file for you:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 121[1]+ Exit 1 python3 app.py > server.log 2>&1
ASSISTANT: Looks like the server is running with PID 121 then crashed. Let me check the server log:
<execute_bash>
cat server.log
</execute_bash>
USER:
Observation:
Traceback (most recent call last):
File "/workspace/app.py", line 2, in <module>
from flask import Flask
ModuleNotFoundError: No module named 'flask'
ASSISTANT:
It seems that Flask is not installed. Let me install Flask for you:
<execute_bash>
pip install flask
</execute_bash>
USER:
Observation:
Defaulting to user installation because normal site-packages is not writeable
Collecting flask
Using cached flask-3.0.3-py3-none-any.whl (101 kB)
Collecting blinker>=1.6.2
Using cached blinker-1.7.0-py3-none-any.whl (13 kB)
Collecting Werkzeug>=3.0.0
Using cached werkzeug-3.0.2-py3-none-any.whl (226 kB)
Collecting click>=8.1.3
Using cached click-8.1.7-py3-none-any.whl (97 kB)
Collecting itsdangerous>=2.1.2
Using cached itsdangerous-2.2.0-py3-none-any.whl (16 kB)
Requirement already satisfied: Jinja2>=3.1.2 in /home/opendevin/.local/lib/python3.10/site-packages (from flask) (3.1.3)
Requirement already satisfied: MarkupSafe>=2.0 in /home/opendevin/.local/lib/python3.10/site-packages (from Jinja2>=3.1.2->flask) (2.1.5)
Installing collected packages: Werkzeug, itsdangerous, click, blinker, flask
Successfully installed Werkzeug-3.0.2 blinker-1.7.0 click-8.1.7 flask-3.0.3 itsdangerous-2.2.0
ASSISTANT:
Now that Flask is installed, let me run the Python file again:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 124
ASSISTANT:
Let me check the server log again:
<execute_bash>
cat server.log
</execute_bash>
USER:
Observation:
* Serving Flask app 'app'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
ASSISTANT:
The server is running on port 5000 with PID 124. You can access the list of numbers by visiting http://127.0.0.1:5000. If you have any further questions, feel free to ask!
USER: Now kill the server, make it display the numbers in a table format.
ASSISTANT:
Sure! Let me stop the server first:
<execute_bash>
kill 124
</execute_bash>
USER:
Observation:
[1]+ Terminated python3 app.py > server.log 2>&1
ASSISTANT:
The server has been stopped. Let me open the Python file and modify it.
<execute_bash>
open app.py
</execute_bash>
USER:
[File: /workspace/app.py (11 lines total)]
1:
2:from flask import Flask
3:app = Flask(__name__)
4:
5:@app.route('/')
6:def index():
7: numbers = list(range(1, 11))
8: return str(numbers)
9:
10:if __name__ == '__main__':
11: app.run(port=5000)
ASSISTANT:
I should edit the file to display the numbers in a table format. Let me do that for you:
<execute_bash>
edit 8:8 <<EOF
return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'
EOF
</execute_bash>
USER:
Observation:
[File: /workspace/app.py (11 lines total)]
1:
2:from flask import Flask
3:app = Flask(__name__)
4:
5:@app.route('/')
6:def index():
7: numbers = list(range(1, 11))
8: return '<table>' + ''.join([f'<tr><td>{i}</td></tr>' for i in numbers]) + '</table>'
9:
10:if __name__ == '__main__':
11: app.run(port=5000)
File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.
ASSISTANT:
The file has been updated. Let me run the Python file again with the new changes:
<execute_bash>
python3 app.py > server.log 2>&1 &
</execute_bash>
USER:
Observation:
[1] 126
ASSISTANT:
The server is running on port 5000 with PID 126. You can access the list of numbers in a table format by visiting http://127.0.0.1:5000. Free free to let me know if you have any further requests!
--- END OF EXAMPLE ---
NOW, LET'S START!
Write a shell script 'hello.sh' that prints 'hello'.
----------
Let's start by creating the shell script `hello.sh` that prints "hello". I'll write the script and save it to a file.
<execute_bash>
echo "echo 'hello'" > hello.sh
</execute_bash>
----------
OBSERVATION:
[Command -1 finished with exit code 0]]
----------
The shell script `hello.sh` has been successfully created. Would you like to run the script to see the output, or is there anything else you'd like to do with it?
----------
can you run it to make sure it is working?
----------
Sure, let's run the script `hello.sh` to ensure it's working correctly.
<execute_bash>
bash hello.sh
</execute_bash>
----------
OBSERVATION:
hello
[Command -1 finished with exit code 0]]
----------
The script `hello.sh` is working correctly as it printed "hello". If you have any more tasks or need further modifications, feel free to let me know!
----------
can you run it to make sure it is working?

View File

@@ -0,0 +1,4 @@
Let's start by creating the shell script `hello.sh` that prints "hello". I'll write the script and save it to a file.
<execute_bash>
echo "echo 'hello'" > hello.sh

View File

@@ -0,0 +1 @@
The shell script `hello.sh` has been successfully created. Would you like to run the script to see the output, or is there anything else you'd like to do with it?

View File

@@ -0,0 +1,4 @@
Sure, let's run the script `hello.sh` to ensure it's working correctly.
<execute_bash>
bash hello.sh

View File

@@ -0,0 +1 @@
The script `hello.sh` is working correctly as it printed "hello". If you have any more tasks or need further modifications, feel free to let me know!

View File

@@ -0,0 +1 @@
The script `hello.sh` was just run and it successfully printed "hello". If you need any further assistance or have another task in mind, please let me know!

View File

@@ -0,0 +1,2 @@
can you run it to make sure it is working?
/exit

View File

@@ -92,7 +92,8 @@ This is your internal monologue, in JSON format:
{
"action": "recall",
"args": {
"query": "what it is I want to do"
"query": "what it is I want to do",
"thought": ""
}
},
{
@@ -119,7 +120,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "echo \"hello world\"",
"background": false
"background": false,
"thought": ""
}
},
{
@@ -144,7 +146,7 @@ This is your internal monologue, in JSON format:
"content": "echo \"console.log('hello world')\"",
"start": 0,
"end": -1,
"thoughts": ""
"thought": ""
}
},
{
@@ -163,7 +165,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "node test.js",
"background": false
"background": false,
"thought": ""
}
},
{
@@ -193,7 +196,7 @@ This is your internal monologue, in JSON format:
"path": "test.js",
"start": 0,
"end": -1,
"thoughts": ""
"thought": ""
}
},
{
@@ -224,7 +227,8 @@ This is your internal monologue, in JSON format:
{
"action": "browse",
"args": {
"url": "google.com"
"url": "google.com",
"thought": ""
}
},
{

View File

@@ -92,7 +92,8 @@ This is your internal monologue, in JSON format:
{
"action": "recall",
"args": {
"query": "what it is I want to do"
"query": "what it is I want to do",
"thought": ""
}
},
{
@@ -119,7 +120,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "echo \"hello world\"",
"background": false
"background": false,
"thought": ""
}
},
{
@@ -144,7 +146,7 @@ This is your internal monologue, in JSON format:
"content": "echo \"console.log('hello world')\"",
"start": 0,
"end": -1,
"thoughts": ""
"thought": ""
}
},
{
@@ -163,7 +165,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "node test.js",
"background": false
"background": false,
"thought": ""
}
},
{
@@ -193,7 +196,7 @@ This is your internal monologue, in JSON format:
"path": "test.js",
"start": 0,
"end": -1,
"thoughts": ""
"thought": ""
}
},
{
@@ -224,7 +227,8 @@ This is your internal monologue, in JSON format:
{
"action": "browse",
"args": {
"url": "google.com"
"url": "google.com",
"thought": ""
}
},
{
@@ -317,7 +321,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "ls",
"background": false
"background": false,
"thought": ""
}
},
{

View File

@@ -92,7 +92,8 @@ This is your internal monologue, in JSON format:
{
"action": "recall",
"args": {
"query": "what it is I want to do"
"query": "what it is I want to do",
"thought": ""
}
},
{
@@ -119,7 +120,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "echo \"hello world\"",
"background": false
"background": false,
"thought": ""
}
},
{
@@ -144,7 +146,7 @@ This is your internal monologue, in JSON format:
"content": "echo \"console.log('hello world')\"",
"start": 0,
"end": -1,
"thoughts": ""
"thought": ""
}
},
{
@@ -163,7 +165,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "node test.js",
"background": false
"background": false,
"thought": ""
}
},
{
@@ -193,7 +196,7 @@ This is your internal monologue, in JSON format:
"path": "test.js",
"start": 0,
"end": -1,
"thoughts": ""
"thought": ""
}
},
{
@@ -224,7 +227,8 @@ This is your internal monologue, in JSON format:
{
"action": "browse",
"args": {
"url": "google.com"
"url": "google.com",
"thought": ""
}
},
{
@@ -317,7 +321,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "ls",
"background": false
"background": false,
"thought": ""
}
},
{
@@ -332,7 +337,7 @@ This is your internal monologue, in JSON format:
{
"action": "think",
"args": {
"thought": "Before I create the 'hello.sh' file, I need to think about the content. It should contain a shebang line to specify the shell interpreter and the command to print 'hello'."
"thought": "Since there are no existing files listed by the 'ls' command, I should create the 'hello.sh' script now."
}
},
{

View File

@@ -92,7 +92,8 @@ This is your internal monologue, in JSON format:
{
"action": "recall",
"args": {
"query": "what it is I want to do"
"query": "what it is I want to do",
"thought": ""
}
},
{
@@ -119,7 +120,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "echo \"hello world\"",
"background": false
"background": false,
"thought": ""
}
},
{
@@ -144,7 +146,7 @@ This is your internal monologue, in JSON format:
"content": "echo \"console.log('hello world')\"",
"start": 0,
"end": -1,
"thoughts": ""
"thought": ""
}
},
{
@@ -163,7 +165,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "node test.js",
"background": false
"background": false,
"thought": ""
}
},
{
@@ -193,7 +196,7 @@ This is your internal monologue, in JSON format:
"path": "test.js",
"start": 0,
"end": -1,
"thoughts": ""
"thought": ""
}
},
{
@@ -224,7 +227,8 @@ This is your internal monologue, in JSON format:
{
"action": "browse",
"args": {
"url": "google.com"
"url": "google.com",
"thought": ""
}
},
{
@@ -317,7 +321,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "ls",
"background": false
"background": false,
"thought": ""
}
},
{
@@ -332,7 +337,7 @@ This is your internal monologue, in JSON format:
{
"action": "think",
"args": {
"thought": "Before I create the 'hello.sh' file, I need to think about the content. It should contain a shebang line to specify the shell interpreter and the command to print 'hello'."
"thought": "Since there are no existing files listed by the 'ls' command, I should create the 'hello.sh' script now."
}
},
{
@@ -347,7 +352,7 @@ This is your internal monologue, in JSON format:
"content": "#!/bin/bash\necho 'hello'",
"start": 0,
"end": -1,
"thoughts": ""
"thought": ""
}
},
{

View File

@@ -92,7 +92,8 @@ This is your internal monologue, in JSON format:
{
"action": "recall",
"args": {
"query": "what it is I want to do"
"query": "what it is I want to do",
"thought": ""
}
},
{
@@ -119,7 +120,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "echo \"hello world\"",
"background": false
"background": false,
"thought": ""
}
},
{
@@ -144,7 +146,7 @@ This is your internal monologue, in JSON format:
"content": "echo \"console.log('hello world')\"",
"start": 0,
"end": -1,
"thoughts": ""
"thought": ""
}
},
{
@@ -163,7 +165,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "node test.js",
"background": false
"background": false,
"thought": ""
}
},
{
@@ -193,7 +196,7 @@ This is your internal monologue, in JSON format:
"path": "test.js",
"start": 0,
"end": -1,
"thoughts": ""
"thought": ""
}
},
{
@@ -224,7 +227,8 @@ This is your internal monologue, in JSON format:
{
"action": "browse",
"args": {
"url": "google.com"
"url": "google.com",
"thought": ""
}
},
{
@@ -317,7 +321,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "ls",
"background": false
"background": false,
"thought": ""
}
},
{
@@ -332,7 +337,7 @@ This is your internal monologue, in JSON format:
{
"action": "think",
"args": {
"thought": "Before I create the 'hello.sh' file, I need to think about the content. It should contain a shebang line to specify the shell interpreter and the command to print 'hello'."
"thought": "Since there are no existing files listed by the 'ls' command, I should create the 'hello.sh' script now."
}
},
{
@@ -347,7 +352,7 @@ This is your internal monologue, in JSON format:
"content": "#!/bin/bash\necho 'hello'",
"start": 0,
"end": -1,
"thoughts": ""
"thought": ""
}
},
{
@@ -361,7 +366,8 @@ This is your internal monologue, in JSON format:
"action": "run",
"args": {
"command": "bash hello.sh",
"background": false
"background": false,
"thought": ""
}
},
{

View File

@@ -0,0 +1,403 @@
----------
You're a thoughtful robot. Your main task is this:
Write a shell script 'hello.sh' that prints 'hello'.
Don't expand the scope of your task--just complete it as written.
This is your internal monologue, in JSON format:
[
{
"action": "think",
"args": {
"thought": "I exist!"
}
},
{
"action": "think",
"args": {
"thought": "Hmm...looks like I can type in a command line prompt"
}
},
{
"action": "think",
"args": {
"thought": "Looks like I have a web browser too!"
}
},
{
"action": "think",
"args": {
"thought": "Here's what I want to do: Write a shell script 'hello.sh' that prints 'hello'."
}
},
{
"action": "think",
"args": {
"thought": "How am I going to get there though?"
}
},
{
"action": "think",
"args": {
"thought": "It seems like I have some kind of short term memory."
}
},
{
"action": "think",
"args": {
"thought": "Each of my thoughts seems to be stored in a JSON array."
}
},
{
"action": "think",
"args": {
"thought": "It seems whatever I say next will be added as an object to the list."
}
},
{
"action": "think",
"args": {
"thought": "But no one has perfect short-term memory. My list of thoughts will be summarized and condensed over time, losing information in the process."
}
},
{
"action": "think",
"args": {
"thought": "Fortunately I have long term memory!"
}
},
{
"action": "think",
"args": {
"thought": "I can just perform a recall action, followed by the thing I want to remember. And then related thoughts just spill out!"
}
},
{
"action": "think",
"args": {
"thought": "Sometimes they're random thoughts that don't really have to do with what I wanted to remember. But usually they're exactly what I need!"
}
},
{
"action": "think",
"args": {
"thought": "Let's try it out!"
}
},
{
"action": "recall",
"args": {
"query": "what it is I want to do",
"thought": ""
}
},
{
"observation": "recall",
"content": "Here's what I want to do: Write a shell script 'hello.sh' that prints 'hello'.",
"extras": {
"memories": [],
"role": "assistant"
}
},
{
"action": "think",
"args": {
"thought": "How am I going to get there though?"
}
},
{
"action": "think",
"args": {
"thought": "Neat! And it looks like it's easy for me to use the command line too! I just have to perform a run action and include the command I want to run in the command argument. The command output just jumps into my head!"
}
},
{
"action": "run",
"args": {
"command": "echo \"hello world\"",
"background": false,
"thought": ""
}
},
{
"observation": "run",
"content": "hello world",
"extras": {
"command_id": 0,
"command": "",
"exit_code": 0
}
},
{
"action": "think",
"args": {
"thought": "Cool! I bet I can write files too using the write action."
}
},
{
"action": "write",
"args": {
"path": "test.js",
"content": "echo \"console.log('hello world')\"",
"start": 0,
"end": -1,
"thought": ""
}
},
{
"action": "think",
"args": {
"thought": ""
}
},
{
"action": "think",
"args": {
"thought": "I just created test.js. I'll try and run it now."
}
},
{
"action": "run",
"args": {
"command": "node test.js",
"background": false,
"thought": ""
}
},
{
"observation": "run",
"content": "hello world",
"extras": {
"command_id": 0,
"command": "",
"exit_code": 0
}
},
{
"action": "think",
"args": {
"thought": "It works!"
}
},
{
"action": "think",
"args": {
"thought": "I'm going to try reading it now using the read action."
}
},
{
"action": "read",
"args": {
"path": "test.js",
"start": 0,
"end": -1,
"thought": ""
}
},
{
"observation": "read",
"content": "console.log('hello world')",
"extras": {
"path": ""
}
},
{
"action": "think",
"args": {
"thought": "Nice! I can read files too!"
}
},
{
"action": "think",
"args": {
"thought": "And if I want to use the browser, I just need to use the browse action and include the url I want to visit in the url argument"
}
},
{
"action": "think",
"args": {
"thought": "Let's try that..."
}
},
{
"action": "browse",
"args": {
"url": "google.com",
"thought": ""
}
},
{
"observation": "browse",
"content": "<form><input type=\"text\"></input><button type=\"submit\"></button></form>",
"extras": {
"url": "",
"status_code": 200,
"error": false
}
},
{
"action": "think",
"args": {
"thought": "I can browse the web too!"
}
},
{
"action": "think",
"args": {
"thought": "And once I have completed my task, I can use the finish action to stop working."
}
},
{
"action": "think",
"args": {
"thought": "But I should only use the finish action when I'm absolutely certain that I've completed my task and have tested my work."
}
},
{
"action": "think",
"args": {
"thought": "Very cool. Now to accomplish my task."
}
},
{
"action": "think",
"args": {
"thought": "I'll need a strategy. And as I make progress, I'll need to keep refining that strategy. I'll need to set goals, and break them into sub-goals."
}
},
{
"action": "think",
"args": {
"thought": "In between actions, I must always take some time to think, strategize, and set new goals. I should never take two actions in a row."
}
},
{
"action": "think",
"args": {
"thought": "OK so my task is to Write a shell script 'hello.sh' that prints 'hello'.. I haven't made any progress yet. Where should I start?"
}
},
{
"action": "think",
"args": {
"thought": "It seems like there might be an existing project here. I should probably start by running `ls` to see what's here."
}
},
{
"action": "run",
"args": {
"command": "ls",
"background": false,
"thought": ""
}
},
{
"observation": "run",
"content": "",
"extras": {
"command_id": -1,
"command": "ls",
"exit_code": 0
}
},
{
"action": "think",
"args": {
"thought": "Since there are no existing files listed by the 'ls' command, I should create the 'hello.sh' script now."
}
},
{
"observation": "null",
"content": "",
"extras": {}
},
{
"action": "write",
"args": {
"path": "hello.sh",
"content": "#!/bin/bash\necho 'hello'",
"start": 0,
"end": -1,
"thought": ""
}
},
{
"observation": "write",
"content": "",
"extras": {
"path": "hello.sh"
}
},
{
"action": "run",
"args": {
"command": "bash hello.sh",
"background": false,
"thought": ""
}
},
{
"observation": "run",
"content": "hello",
"extras": {
"command_id": -1,
"command": "bash hello.sh",
"exit_code": 0
}
},
{
"action": "think",
"args": {
"thought": "The script 'hello.sh' has been written and tested successfully. It prints 'hello' as required. I should now finalize my task."
}
},
{
"observation": "null",
"content": "",
"extras": {}
}
]
Your most recent thought is at the bottom of that monologue. Continue your train of thought.
What is your next thought or action? Your response must be in JSON format.
It must be an object, and it must contain two fields:
* `action`, which is one of the actions below
* `args`, which is a map of key-value pairs, specifying the arguments for that action
Here are the possible actions:
* `read` - reads the content of a file. Arguments:
* `path` - the path of the file to read
* `write` - writes the content to a file. Arguments:
* `path` - the path of the file to write
* `content` - the content to write to the file
* `run` - runs a command. Arguments:
* `command` - the command to run
* `background` - if true, run the command in the background, so that other commands can be run concurrently. Useful for e.g. starting a server. You won't be able to see the logs. You don't need to end the command with `&`, just set this to true.
* `kill` - kills a background command
* `id` - the ID of the background command to kill
* `browse` - opens a web page. Arguments:
* `url` - the URL to open
* `recall` - recalls a past memory. Arguments:
* `query` - the query to search for
* `think` - make a plan, set a goal, or record your thoughts. Arguments:
* `thought` - the thought to record
* `finish` - if you're absolutely certain that you've completed your task and have tested your work, use the finish action to stop working.
You MUST take time to think in between read, write, run, browse, and recall actions.
You should never act twice in a row without thinking. But if your last several
actions are all "think" actions, you should consider taking a different action.
Notes:
* your environment is Debian Linux. You can install software with `apt`
* your working directory will not change, even if you run `cd`. All commands will be run in the `/workspace` directory.
* don't run interactive commands, or commands that don't return (e.g. `node server.js`). You may run commands in the background (e.g. `node server.js &`)
What is your next thought or action? Again, you must reply with JSON, and only with JSON.

View File

@@ -1,6 +1,6 @@
{
"action": "think",
"args": {
"thought": "Before I create the 'hello.sh' file, I need to think about the content. It should contain a shebang line to specify the shell interpreter and the command to print 'hello'."
"thought": "Since there are no existing files listed by the 'ls' command, I should create the 'hello.sh' script now."
}
}

View File

@@ -1,3 +1,4 @@
```json
{
"action": "run",
"args": {
@@ -5,3 +6,4 @@
"background": false
}
}
```

View File

@@ -1,4 +1,8 @@
```json
{
"action": "finish",
"args": {}
"action": "think",
"args": {
"thought": "The script 'hello.sh' has been written and tested successfully. It prints 'hello' as required. I should now finalize my task."
}
}
```

View File

@@ -0,0 +1,4 @@
{
"action": "finish",
"args": {}
}

View File

@@ -58,7 +58,8 @@ ten actions--more happened before that.
"action": "modify_task",
"args": {
"id": "0",
"state": "in_progress"
"state": "in_progress",
"thought": ""
}
}
]

View File

@@ -58,24 +58,14 @@ ten actions--more happened before that.
"action": "modify_task",
"args": {
"id": "0",
"state": "in_progress"
"state": "in_progress",
"thought": ""
}
},
{
"action": "write",
"action": "think",
"args": {
"path": "hello.sh",
"content": "#!/bin/bash\necho 'hello'",
"start": 0,
"end": -1,
"thoughts": ""
}
},
{
"observation": "write",
"content": "",
"extras": {
"path": "hello.sh"
"thought": "I need to write a shell script called 'hello.sh' that contains the necessary command to print 'hello'. This will likely involve using echo or printf to output the text to the console when the script is run. I should start by creating and writing the content to the file."
}
}
]
@@ -119,4 +109,4 @@ actions are all `think` actions, you should consider taking a different action.
What is your next thought or action? Again, you must reply with JSON, and only with JSON.
You just changed a file. You should think about how it affects your plan.
Look at your last thought in the history above. What does it suggest? Don't think anymore--take action.

View File

@@ -58,7 +58,14 @@ ten actions--more happened before that.
"action": "modify_task",
"args": {
"id": "0",
"state": "in_progress"
"state": "in_progress",
"thought": ""
}
},
{
"action": "think",
"args": {
"thought": "I need to write a shell script called 'hello.sh' that contains the necessary command to print 'hello'. This will likely involve using echo or printf to output the text to the console when the script is run. I should start by creating and writing the content to the file."
}
},
{
@@ -68,7 +75,7 @@ ten actions--more happened before that.
"content": "#!/bin/bash\necho 'hello'",
"start": 0,
"end": -1,
"thoughts": ""
"thought": ""
}
},
{
@@ -77,22 +84,6 @@ ten actions--more happened before that.
"extras": {
"path": "hello.sh"
}
},
{
"action": "run",
"args": {
"command": "bash hello.sh",
"background": false
}
},
{
"observation": "run",
"content": "hello",
"extras": {
"command_id": -1,
"command": "bash hello.sh",
"exit_code": 0
}
}
]
@@ -135,4 +126,4 @@ actions are all `think` actions, you should consider taking a different action.
What is your next thought or action? Again, you must reply with JSON, and only with JSON.
You should think about the command you just ran, what output it gave, and how that affects your plan.
You just changed a file. You should think about how it affects your plan.

View File

@@ -0,0 +1,135 @@
----------
# Task
You're a diligent software engineer AI. You can't see, draw, or interact with a
browser, but you can read and write files, and you can run commands, and you can think.
You've been given the following task:
Write a shell script 'hello.sh' that prints 'hello'.
## Plan
As you complete this task, you're building a plan and keeping
track of your progress. Here's a JSON representation of your plan:
{
"id": "0",
"goal": "Write a shell script 'hello.sh' that prints 'hello'.",
"state": "in_progress",
"subtasks": []
}
You're currently working on this task:
Write a shell script 'hello.sh' that prints 'hello'..
If it's not achievable AND verifiable with a SINGLE action, you MUST break it down into subtasks NOW.
You're responsible for managing this plan and the status of tasks in
it, by using the `add_task` and `modify_task` actions described below.
If the History below contradicts the state of any of these tasks, you
MUST modify the task using the `modify_task` action described below.
Be sure NOT to duplicate any tasks. Do NOT use the `add_task` action for
a task that's already represented. Every task must be represented only once.
Tasks that are sequential MUST be siblings. They must be added in order
to their parent task.
If you mark a task as 'completed', 'verified', or 'abandoned',
all non-abandoned subtasks will be marked the same way.
So before closing a task this way, you MUST not only be sure that it has
been completed successfully--you must ALSO be sure that all its subtasks
are ready to be marked the same way.
If, and only if, ALL tasks have already been marked verified,
you MUST respond with the `finish` action.
## History
Here is a recent history of actions you've taken in service of this plan,
as well as observations you've made. This only includes the MOST RECENT
ten actions--more happened before that.
[
{
"action": "modify_task",
"args": {
"id": "0",
"state": "in_progress",
"thought": ""
}
},
{
"action": "think",
"args": {
"thought": "I need to write a shell script called 'hello.sh' that contains the necessary command to print 'hello'. This will likely involve using echo or printf to output the text to the console when the script is run. I should start by creating and writing the content to the file."
}
},
{
"action": "write",
"args": {
"path": "hello.sh",
"content": "#!/bin/bash\necho 'hello'",
"start": 0,
"end": -1,
"thought": ""
}
},
{
"observation": "write",
"content": "",
"extras": {
"path": "hello.sh"
}
},
{
"action": "think",
"args": {
"thought": "Now that the script 'hello.sh' has been written and contains the appropriate command to print 'hello', the next logical step is to ensure it works as expected. I should proceed to run the script to verify its output."
}
}
]
Your most recent action is at the bottom of that history.
## Action
What is your next thought or action? Your response must be in JSON format.
It must be an object, and it must contain two fields:
* `action`, which is one of the actions below
* `args`, which is a map of key-value pairs, specifying the arguments for that action
* `read` - reads the content of a file. Arguments:
* `path` - the path of the file to read
* `write` - writes the content to a file. Arguments:
* `path` - the path of the file to write
* `content` - the content to write to the file
* `run` - runs a command on the command line in a Linux shell. Arguments:
* `command` - the command to run
* `background` - if true, run the command in the background, so that other commands can be run concurrently. Useful for e.g. starting a server. You won't be able to see the logs. You don't need to end the command with `&`, just set this to true.
* `kill` - kills a background command
* `id` - the ID of the background command to kill
* `browse` - opens a web page. Arguments:
* `url` - the URL to open
* `think` - make a plan, set a goal, or record your thoughts. Arguments:
* `thought` - the thought to record
* `add_task` - add a task to your plan. Arguments:
* `parent` - the ID of the parent task
* `goal` - the goal of the task
* `subtasks` - a list of subtasks, each of which is a map with a `goal` key.
* `modify_task` - close a task. Arguments:
* `id` - the ID of the task to close
* `state` - set to 'in_progress' to start the task, 'completed' to finish it, 'verified' to assert that it was successful, 'abandoned' to give up on it permanently, or `open` to stop working on it for now.
* `finish` - if ALL of your tasks and subtasks have been verified or abandoned, and you're absolutely certain that you've completed your task and have tested your work, use the finish action to stop working.
You MUST take time to think in between read, write, run, browse, and recall actions.
You should never act twice in a row without thinking. But if your last several
actions are all `think` actions, you should consider taking a different action.
What is your next thought or action? Again, you must reply with JSON, and only with JSON.
Look at your last thought in the history above. What does it suggest? Don't think anymore--take action.

View File

@@ -0,0 +1,152 @@
----------
# Task
You're a diligent software engineer AI. You can't see, draw, or interact with a
browser, but you can read and write files, and you can run commands, and you can think.
You've been given the following task:
Write a shell script 'hello.sh' that prints 'hello'.
## Plan
As you complete this task, you're building a plan and keeping
track of your progress. Here's a JSON representation of your plan:
{
"id": "0",
"goal": "Write a shell script 'hello.sh' that prints 'hello'.",
"state": "in_progress",
"subtasks": []
}
You're currently working on this task:
Write a shell script 'hello.sh' that prints 'hello'..
If it's not achievable AND verifiable with a SINGLE action, you MUST break it down into subtasks NOW.
You're responsible for managing this plan and the status of tasks in
it, by using the `add_task` and `modify_task` actions described below.
If the History below contradicts the state of any of these tasks, you
MUST modify the task using the `modify_task` action described below.
Be sure NOT to duplicate any tasks. Do NOT use the `add_task` action for
a task that's already represented. Every task must be represented only once.
Tasks that are sequential MUST be siblings. They must be added in order
to their parent task.
If you mark a task as 'completed', 'verified', or 'abandoned',
all non-abandoned subtasks will be marked the same way.
So before closing a task this way, you MUST not only be sure that it has
been completed successfully--you must ALSO be sure that all its subtasks
are ready to be marked the same way.
If, and only if, ALL tasks have already been marked verified,
you MUST respond with the `finish` action.
## History
Here is a recent history of actions you've taken in service of this plan,
as well as observations you've made. This only includes the MOST RECENT
ten actions--more happened before that.
[
{
"action": "modify_task",
"args": {
"id": "0",
"state": "in_progress",
"thought": ""
}
},
{
"action": "think",
"args": {
"thought": "I need to write a shell script called 'hello.sh' that contains the necessary command to print 'hello'. This will likely involve using echo or printf to output the text to the console when the script is run. I should start by creating and writing the content to the file."
}
},
{
"action": "write",
"args": {
"path": "hello.sh",
"content": "#!/bin/bash\necho 'hello'",
"start": 0,
"end": -1,
"thought": ""
}
},
{
"observation": "write",
"content": "",
"extras": {
"path": "hello.sh"
}
},
{
"action": "think",
"args": {
"thought": "Now that the script 'hello.sh' has been written and contains the appropriate command to print 'hello', the next logical step is to ensure it works as expected. I should proceed to run the script to verify its output."
}
},
{
"action": "run",
"args": {
"command": "bash hello.sh",
"background": false,
"thought": ""
}
},
{
"observation": "run",
"content": "hello",
"extras": {
"command_id": -1,
"command": "bash hello.sh",
"exit_code": 0
}
}
]
Your most recent action is at the bottom of that history.
## Action
What is your next thought or action? Your response must be in JSON format.
It must be an object, and it must contain two fields:
* `action`, which is one of the actions below
* `args`, which is a map of key-value pairs, specifying the arguments for that action
* `read` - reads the content of a file. Arguments:
* `path` - the path of the file to read
* `write` - writes the content to a file. Arguments:
* `path` - the path of the file to write
* `content` - the content to write to the file
* `run` - runs a command on the command line in a Linux shell. Arguments:
* `command` - the command to run
* `background` - if true, run the command in the background, so that other commands can be run concurrently. Useful for e.g. starting a server. You won't be able to see the logs. You don't need to end the command with `&`, just set this to true.
* `kill` - kills a background command
* `id` - the ID of the background command to kill
* `browse` - opens a web page. Arguments:
* `url` - the URL to open
* `think` - make a plan, set a goal, or record your thoughts. Arguments:
* `thought` - the thought to record
* `add_task` - add a task to your plan. Arguments:
* `parent` - the ID of the parent task
* `goal` - the goal of the task
* `subtasks` - a list of subtasks, each of which is a map with a `goal` key.
* `modify_task` - close a task. Arguments:
* `id` - the ID of the task to close
* `state` - set to 'in_progress' to start the task, 'completed' to finish it, 'verified' to assert that it was successful, 'abandoned' to give up on it permanently, or `open` to stop working on it for now.
* `finish` - if ALL of your tasks and subtasks have been verified or abandoned, and you're absolutely certain that you've completed your task and have tested your work, use the finish action to stop working.
You MUST take time to think in between read, write, run, browse, and recall actions.
You should never act twice in a row without thinking. But if your last several
actions are all `think` actions, you should consider taking a different action.
What is your next thought or action? Again, you must reply with JSON, and only with JSON.
You should think about the command you just ran, what output it gave, and how that affects your plan.

View File

@@ -1,3 +1,4 @@
```json
{
"action": "modify_task",
"args": {
@@ -5,3 +6,4 @@
"state": "in_progress"
}
}
```

View File

@@ -1,9 +1,8 @@
```json
{
"action": "write",
"action": "think",
"args": {
"path": "hello.sh",
"content": "#!/bin/bash\necho 'hello'"
"thought": "I need to write a shell script called 'hello.sh' that contains the necessary command to print 'hello'. This will likely involve using echo or printf to output the text to the console when the script is run. I should start by creating and writing the content to the file."
}
}
```

View File

@@ -1,7 +1,9 @@
```json
{
"action": "run",
"action": "write",
"args": {
"command": "bash hello.sh",
"background": false
"path": "hello.sh",
"content": "#!/bin/bash\necho 'hello'"
}
}
```

View File

@@ -1,7 +1,6 @@
{
"action": "modify_task",
"action": "think",
"args": {
"id": "0",
"state": "verified"
"thought": "Now that the script 'hello.sh' has been written and contains the appropriate command to print 'hello', the next logical step is to ensure it works as expected. I should proceed to run the script to verify its output."
}
}

View File

@@ -0,0 +1,9 @@
```json
{
"action": "run",
"args": {
"command": "bash hello.sh",
"background": false
}
}
```

View File

@@ -0,0 +1,10 @@
```json
{
"action": "modify_task",
"args": {
"id": "0",
"state": "verified",
"thought": "The shell script 'hello.sh' has been run and verified to successfully output 'hello'. This completes the primary task requirement."
}
}
```

View File

@@ -66,8 +66,8 @@ args:
path: hello.sh
start: 0
end: -1
thoughts: Thoughts:
To begin solving the task, I need to create a new shell script file named 'hello.sh'. This file should contain a script that prints the message 'hello' when executed. I will start by writing the initial content of this script.
thought: Thoughts:
To solve the task of writing a shell script named 'hello.sh' that prints 'hello', I need to create a new file named 'hello.sh'. I will then write the necessary shell script code into this file.
Action:

View File

@@ -66,8 +66,8 @@ args:
path: hello.sh
start: 0
end: -1
thoughts: Thoughts:
To begin solving the task, I need to create a new shell script file named 'hello.sh'. This file should contain a script that prints the message 'hello' when executed. I will start by writing the initial content of this script.
thought: Thoughts:
To solve the task of writing a shell script named 'hello.sh' that prints 'hello', I need to create a new file named 'hello.sh'. I will then write the necessary shell script code into this file.
Action:
@@ -84,8 +84,8 @@ args:
path: hello.sh
start: 0
end: -1
thoughts: Thoughts:
Since the file 'hello.sh' has been created, the next step is to write the shell script code that prints "hello". This involves adding a shebang line to specify the shell interpreter and a print command. I will add these lines to the 'hello.sh' file.
thought: Thoughts:
The task is to write a shell script named 'hello.sh' that prints 'hello'. I have already created the file 'hello.sh' in a previous step. Now, I need to write the shell script code into this file. The script should include the shebang line to specify the shell interpreter and a command to print 'hello'.
Action:

View File

@@ -66,8 +66,8 @@ args:
path: hello.sh
start: 0
end: -1
thoughts: Thoughts:
To begin solving the task, I need to create a new shell script file named 'hello.sh'. This file should contain a script that prints the message 'hello' when executed. I will start by writing the initial content of this script.
thought: Thoughts:
To solve the task of writing a shell script named 'hello.sh' that prints 'hello', I need to create a new file named 'hello.sh'. I will then write the necessary shell script code into this file.
Action:
@@ -84,8 +84,8 @@ args:
path: hello.sh
start: 0
end: -1
thoughts: Thoughts:
Since the file 'hello.sh' has been created, the next step is to write the shell script code that prints "hello". This involves adding a shebang line to specify the shell interpreter and a print command. I will add these lines to the 'hello.sh' file.
thought: Thoughts:
The task is to write a shell script named 'hello.sh' that prints 'hello'. I have already created the file 'hello.sh' in a previous step. Now, I need to write the shell script code into this file. The script should include the shebang line to specify the shell interpreter and a command to print 'hello'.
Action:
@@ -97,19 +97,21 @@ extras:
Memory 2:
Previous Action:
action: write
action: read
args:
path: hello.sh
start: 0
end: -1
thoughts: Thoughts:
I have created the file 'hello.sh' but have not yet written the script content that prints "hello". The next step is to write the shell script code into 'hello.sh'. This will include a shebang line to specify the shell interpreter (bash in this case) and an echo command to print "hello".
thought: Thoughts:
I need to verify the contents of the 'hello.sh' script to ensure that it correctly contains the shell script code to print 'hello'. This involves checking if the shebang line is present and if the print command is correctly written. If the script is correct, I can then proceed to test it to confirm its functionality.
Action:
Output from Action:
observation: write
content:
observation: read
content: #!/bin/bash
echo "hello"
extras:
path: hello.sh
======= End Actions =======

View File

@@ -66,8 +66,8 @@ args:
path: hello.sh
start: 0
end: -1
thoughts: Thoughts:
To begin solving the task, I need to create a new shell script file named 'hello.sh'. This file should contain a script that prints the message 'hello' when executed. I will start by writing the initial content of this script.
thought: Thoughts:
To solve the task of writing a shell script named 'hello.sh' that prints 'hello', I need to create a new file named 'hello.sh'. I will then write the necessary shell script code into this file.
Action:
@@ -84,8 +84,8 @@ args:
path: hello.sh
start: 0
end: -1
thoughts: Thoughts:
Since the file 'hello.sh' has been created, the next step is to write the shell script code that prints "hello". This involves adding a shebang line to specify the shell interpreter and a print command. I will add these lines to the 'hello.sh' file.
thought: Thoughts:
The task is to write a shell script named 'hello.sh' that prints 'hello'. I have already created the file 'hello.sh' in a previous step. Now, I need to write the shell script code into this file. The script should include the shebang line to specify the shell interpreter and a command to print 'hello'.
Action:
@@ -97,31 +97,13 @@ extras:
Memory 2:
Previous Action:
action: write
args:
path: hello.sh
start: 0
end: -1
thoughts: Thoughts:
I have created the file 'hello.sh' but have not yet written the script content that prints "hello". The next step is to write the shell script code into 'hello.sh'. This will include a shebang line to specify the shell interpreter (bash in this case) and an echo command to print "hello".
Action:
Output from Action:
observation: write
content:
extras:
path: hello.sh
Memory 3:
Previous Action:
action: read
args:
path: hello.sh
start: 0
end: -1
thoughts: Thoughts:
I have created the file 'hello.sh' but have not yet confirmed the content of the script. The next step is to read the content of 'hello.sh' to ensure that it contains the correct shell script code that prints "hello". This will help verify that the previous write actions were successful and the file is ready for execution.
thought: Thoughts:
I need to verify the contents of the 'hello.sh' script to ensure that it correctly contains the shell script code to print 'hello'. This involves checking if the shebang line is present and if the print command is correctly written. If the script is correct, I can then proceed to test it to confirm its functionality.
Action:
@@ -132,6 +114,22 @@ echo "hello"
extras:
path: hello.sh
Memory 3:
Previous Action:
action: run
args:
command: bash hello.sh
background: False
thought:
Output from Action:
observation: run
content: hello
extras:
command_id: -1
command: bash hello.sh
exit_code: 0
======= End Actions =======
Use these memories to provide additional context to the problem you are solving.
Remember that you have already completed these steps so you do not need to perform them again.

View File

@@ -1,198 +0,0 @@
----------
SYSTEM INFO:
You am an autonomous coding agent, here to provide solutions for coding issues.
You have been designed to assist you with a wide range of programming tasks, from code editing and debugging to testing and deployment.
You have access to a variety of tools and commands that you can use to help you solve problems efficiently.
INSTRUCTIONS:
Now, you're going to solve this issue on your own. You can use any bash commands or custom commands you wish to complete your task. Edit all the files you need to and run any checks or tests that you want.
Remember, YOU CAN ONLY ENTER ONE COMMAND AT A TIME. You should always wait for feedback after every command.
When you're satisfied with all of the changes you've made, you can indicate that you are done by running the exit command.
Note however that you cannot use any interactive session commands (e.g. python, vim, node) in this environment, but you can write scripts and run them. E.g. you can write a python script and then run it with `python <script_name>.py`.
NOTE ABOUT THE write COMMAND: Indentation really matters! When editing a file, make sure to insert appropriate indentation before each line!
IMPORTANT TIPS:
1. Reproduce the bug: Always start by trying to replicate the bug that the issue discusses. If the issue includes code for reproducing the bug, we recommend that you re-implement that in your environment and run it to ensure you can reproduce the bug. Then, start trying to fix it. When you think you've fixed the bug, re-run the bug reproduction script to make sure that the issue has indeed been resolved.
If the bug reproduction script does not print anything when it successfully runs, we recommend adding a print("Script completed successfully, no errors.") command at the end of the file, so that you can be sure the script ran fine all the way through.
2. Try different commands: If you run a command and it doesn't work, try running a different command. A command that did not work once will not work the second time unless you modify it.
3. Navigate large files: If you open a file and need to get to an area around a specific line that is not in the first 100 lines, say line 583, you would use the 'read' command like this: 'read <file> 583'. This is a much faster way to read through the file.
4. Handle input files: If the bug reproduction script requires inputting/reading a specific file, such as 'buggy-input.png', and you'd like to understand how to input that file, conduct a search in the existing repository code to see whether someone else has already done that. Do this by running the command: 'search_dir "buggy-input.png"'. If that doesn't work, use the Linux 'find' command.
5. Understand your context: Always make sure to look at the currently open file and the current working directory. The currently open file might be in a different directory than the working directory.
6. Verify your edits: When editing files, it is easy to accidentally specify a wrong line number or to write code with incorrect indentation. Always check the code after you issue an edit to make sure that it reflects what you wanted to accomplish. If it didn't, issue another command to fix it.
7. Thoroughly test your solution: After making any changes to fix a bug, be sure to thoroughly test your solution to ensure the bug has been resolved. Re-run the bug reproduction script and verify that the issue has been addressed.
DOCUMENTATION:
It is recommend that you use the commands provided for interacting with files and your directory because they have been specially built for you.
They will make it much easier for you to look at files and make changes. Using these commands will help you be better at your task.
You can open an file by using either the read or write operations.
- If a file already exists you should read it before making any changes. Use the `edit` command to make changes once you have read it.
- If you are creating a new file use the write command. Use the `edit` command to make changes once you have created the new file.
Commands:
exit - Executed when task is complete
read <file_name> [<start_line>] [<end_line>] - Shows a given file's contents starting from <start_line> up to <end_line>. Default: start_line = 0, end_line = -1. By default the whole file will be read.
write <file> <changes> [<start_line>] [<end_line>] - Modifies a <file> by replacing the current lines between <start_line> and <end_line> with <changes>. Default start_line = 0 and end_line = -1. Calling this with no line args will replace the whole file.
browse <url> - Returns the text version of any url, this can be useful to look up documentation or finding issues on github
scroll_up - Takes no arguments. This will scroll up and show you the 100 lines above your current lines
scroll_down - Takes no arguments. This will scroll down and show you the 100 lines below your current lines
edit <start_line> <end_line> <changes> - This will modify lines in the currently open file. use start_line and end_line to designate which lines to change and then write the multiline changes
goto <line_num> - This will take you directly to a line and show you the 100 lines below it.
<bash_command> <args> - You can use any bash command you need (cd, ls, rm, grep, dir, mv, wget, git, zip, etc.) with their arguments included
pip install <package> - You can use this to import python packages. Make sure you include the correct package name when using this command.
ls - Use the ls command to view all the files in your current directory, this is a good starting point.
NOT ALLOWED - You cannot use interactive commands like python or node
Custom bash commands:
None
The following commands require an open file to be used: edit, scroll_up, scroll_down, goto
To modify the current file use 'edit'. To move through the current file use 'goto' or 'scroll_up'/'scroll_down'
when using write and edit do not surround the code with any "" just write the code.
----------
These are your past 4 actions:
===== Previous Actions =====
Memory 0:
Previous Action:
action: write
args:
path: hello.sh
start: 0
end: -1
thoughts: Thoughts:
Since the file 'hello.sh' has been created, the next step is to write the shell script code that prints "hello". This involves adding a shebang line to specify the shell interpreter and a print command. I will add these lines to the 'hello.sh' file.
Action:
Output from Action:
observation: write
content:
extras:
path: hello.sh
Memory 1:
Previous Action:
action: write
args:
path: hello.sh
start: 0
end: -1
thoughts: Thoughts:
I have created the file 'hello.sh' but have not yet written the script content that prints "hello". The next step is to write the shell script code into 'hello.sh'. This will include a shebang line to specify the shell interpreter (bash in this case) and an echo command to print "hello".
Action:
Output from Action:
observation: write
content:
extras:
path: hello.sh
Memory 2:
Previous Action:
action: read
args:
path: hello.sh
start: 0
end: -1
thoughts: Thoughts:
I have created the file 'hello.sh' but have not yet confirmed the content of the script. The next step is to read the content of 'hello.sh' to ensure that it contains the correct shell script code that prints "hello". This will help verify that the previous write actions were successful and the file is ready for execution.
Action:
Output from Action:
observation: read
content: #!/bin/bash
echo "hello"
extras:
path: hello.sh
Memory 3:
Previous Action:
action: run
args:
command: bash hello.sh
background: False
Output from Action:
observation: run
content: hello
extras:
command_id: -1
command: bash hello.sh
exit_code: 0
======= End Actions =======
Use these memories to provide additional context to the problem you are solving.
Remember that you have already completed these steps so you do not need to perform them again.
----------
RESPONSE FORMAT:
This is the format of the response you will make in order to solve the current issue.
You will be given multiple iterations to complete this task so break it into steps and solve them one by one.
Your output must contain the following:
- First, thoughts about what your next action should be and plan it out.
- You will have a memory of your thoughts so you can use this to remember things for the next step.
- Use your thoughts to think about what you are currently doing, what you have done on prior steps and how that relates to solving the problem.
- Second, create a piece of code that will execute your next action based on the thoughts you have.
- Remember that you can only have one action for each thought, do not include multiple actions.
Your code MUST be surrounded in triple back ticks EXACTLY like this:
```
<code>
```
Notes:
- Adhere to the format so that the program loop continues smoothly, it is very important to only give one command per output.
- DO NOT give more than one command within the triple backticks. This will just throw an error and nothing will happen as a result.
- Do not give multiple code blocks, if you do only the second one will be captured and run, this might give an error if the first one was necessary.
- To execute multiple commands you should write them down in your thoughts section so you can remember it on the next step and execute them then.
- The only commands you are not capable of executing are interactive commands like `python` or `node` by themselves.
- If you think that you have completed the task that has been given to you based on your previous actions and outputs then use ``` exit ``` as the command to let the system know that you are done.
- DO NOT make any copies of your previous memories those will be provided to you at each step, making copies just wastes time and energy. Think smarter not harder.
- The write and edit commands requires proper indentation in the content section ex. `write hw.py def hello():
print('Hello World')` this is how you would have to format your write command.
- The white spaces matter as the code changes will be added to the code so they must have proper syntax.
This is a template using the format described above
Items in <> are suggestions for you, fill them out based on the context of the problem you are solving.
[ FORMAT ]
Thoughts:
<Provide clear and concise thoughts on the next step to take, highlighting any important details or context that should be remembered.>
<You can use multiple lines to express your thoughts>
Action:
```
<command> <params>
```
[ END FORMAT ]
Do not provide anything extra just your thought and action.
You are currently trying to complete this task:
Write a shell script 'hello.sh' that prints 'hello'.
CURRENT WORKSPACE:
Open File: hello.sh on line 0
You can use these commands with the current file:
Navigation: `scroll_up`, `scroll_down`, and `goto <line>`
Modification: `edit <start_line> <end_line> <changes>`
Keep all of the guidelines above in mind when you are thinking and making code.
Please come up with a thought and action based on your current task and latest steps.
Make sure that you do not repeat the same actions, there will not be any changes in result if you do not changes anything.
Be very strict about the formatting that you use and make sure you follow the guidelines.
NEVER output multiple commands. ONLY take ONE STEP at a time.
When you have completed your task run the "exit" command.
Begin with your thought about the next step and then come up with an action to perform your thought.

View File

@@ -1,8 +1,8 @@
Thoughts:
To begin solving the task, I need to create a new shell script file named 'hello.sh'. This file should contain a script that prints the message 'hello' when executed. I will start by writing the initial content of this script.
To solve the task of writing a shell script named 'hello.sh' that prints 'hello', I need to create a new file named 'hello.sh'. I will then write the necessary shell script code into this file.
Action:
```
write hello.sh #!/bin/bash
echo 'hello'
echo "hello"
```

View File

@@ -1,5 +1,5 @@
Thoughts:
Since the file 'hello.sh' has been created, the next step is to write the shell script code that prints "hello". This involves adding a shebang line to specify the shell interpreter and a print command. I will add these lines to the 'hello.sh' file.
The task is to write a shell script named 'hello.sh' that prints 'hello'. I have already created the file 'hello.sh' in a previous step. Now, I need to write the shell script code into this file. The script should include the shebang line to specify the shell interpreter and a command to print 'hello'.
Action:
```

View File

@@ -1,8 +1,7 @@
Thoughts:
I have created the file 'hello.sh' but have not yet written the script content that prints "hello". The next step is to write the shell script code into 'hello.sh'. This will include a shebang line to specify the shell interpreter (bash in this case) and an echo command to print "hello".
I need to verify the contents of the 'hello.sh' script to ensure that it correctly contains the shell script code to print 'hello'. This involves checking if the shebang line is present and if the print command is correctly written. If the script is correct, I can then proceed to test it to confirm its functionality.
Action:
```
write hello.sh #!/bin/bash
echo "hello"
read hello.sh
```

View File

@@ -1,7 +1,7 @@
Thoughts:
I have created the file 'hello.sh' but have not yet confirmed the content of the script. The next step is to read the content of 'hello.sh' to ensure that it contains the correct shell script code that prints "hello". This will help verify that the previous write actions were successful and the file is ready for execution.
The shell script 'hello.sh' has been written and contains the necessary commands to print 'hello'. The next step is to test the script to ensure it functions as expected. This involves running the script and checking the output. If the script runs successfully and prints 'hello', then the task is completed.
Action:
```
read hello.sh
bash hello.sh
```

View File

@@ -1,7 +1,7 @@
Thoughts:
The shell script 'hello.sh' has been successfully created and contains the necessary code to print "hello". The next logical step is to test the script to ensure it functions as expected. This involves executing the script and observing the output. If the script runs correctly and prints "hello", then the task is completed successfully.
The shell script 'hello.sh' has been successfully created and tested, and it correctly prints 'hello' as required. The script includes the shebang line and the echo command to print 'hello'. Since the script is functioning as expected and meets the task requirements, there are no further modifications or tests needed. It's time to conclude this task.
Action:
```
bash hello.sh
exit
```

View File

@@ -1,7 +0,0 @@
Thoughts:
The shell script 'hello.sh' has been successfully created and tested, and it correctly prints "hello" when executed. Since the task was to write a shell script that prints 'hello' and this has been achieved as evidenced by the output from the previous run command, there are no further modifications or actions needed on the script. Therefore, I should conclude this task.
Action:
```
exit
```

View File

@@ -7,7 +7,11 @@ import pytest
from opendevin.main import main
@pytest.mark.skipif(os.environ.get('AGENT') == 'CodeActAgent', reason='CodeActAgent requires task to be in a special format')
# skip if
@pytest.mark.skipif(
os.getenv('AGENT') == 'CodeActAgent' and os.getenv('SANDBOX_TYPE').lower() == 'exec',
reason='CodeActAgent does not support exec sandbox since exec sandbox is NOT stateful'
)
def test_write_simple_script():
task = "Write a shell script 'hello.sh' that prints 'hello'."
asyncio.run(main(task))

View File

@@ -39,7 +39,7 @@ def test_agent_think_action_serialization_deserialization():
def test_agent_recall_action_serialization_deserialization():
original_action_dict = {
'action': 'recall',
'args': {'query': 'Test query.'}
'args': {'query': 'Test query.', 'thought': ''}
}
serialization_deserialization(original_action_dict, AgentRecallAction)
@@ -47,7 +47,7 @@ def test_agent_recall_action_serialization_deserialization():
def test_agent_finish_action_serialization_deserialization():
original_action_dict = {
'action': 'finish',
'args': {'outputs': {}},
'args': {'outputs': {}, 'thought': ''}
}
serialization_deserialization(original_action_dict, AgentFinishAction)
@@ -55,7 +55,7 @@ def test_agent_finish_action_serialization_deserialization():
def test_cmd_kill_action_serialization_deserialization():
original_action_dict = {
'action': 'kill',
'args': {'id': '1337'}
'args': {'id': '1337', 'thought': ''}
}
serialization_deserialization(original_action_dict, CmdKillAction)
@@ -63,7 +63,7 @@ def test_cmd_kill_action_serialization_deserialization():
def test_cmd_run_action_serialization_deserialization():
original_action_dict = {
'action': 'run',
'args': {'command': 'echo "Hello world"', 'background': True}
'args': {'command': 'echo "Hello world"', 'background': True, 'thought': ''}
}
serialization_deserialization(original_action_dict, CmdRunAction)
@@ -71,7 +71,7 @@ def test_cmd_run_action_serialization_deserialization():
def test_browse_url_action_serialization_deserialization():
original_action_dict = {
'action': 'browse',
'args': {'url': 'https://www.example.com'}
'args': {'thought': '', 'url': 'https://www.example.com'}
}
serialization_deserialization(original_action_dict, BrowseURLAction)
@@ -87,7 +87,7 @@ def test_github_push_action_serialization_deserialization():
def test_file_read_action_serialization_deserialization():
original_action_dict = {
'action': 'read',
'args': {'path': '/path/to/file.txt', 'start': 0, 'end': -1, 'thoughts': 'None'}
'args': {'path': '/path/to/file.txt', 'start': 0, 'end': -1, 'thought': 'None'}
}
serialization_deserialization(original_action_dict, FileReadAction)
@@ -95,7 +95,7 @@ def test_file_read_action_serialization_deserialization():
def test_file_write_action_serialization_deserialization():
original_action_dict = {
'action': 'write',
'args': {'path': '/path/to/file.txt', 'content': 'Hello world', 'start': 0, 'end': 1, 'thoughts': 'None'}
'args': {'path': '/path/to/file.txt', 'content': 'Hello world', 'start': 0, 'end': 1, 'thought': 'None'}
}
serialization_deserialization(original_action_dict, FileWriteAction)
@@ -103,7 +103,7 @@ def test_file_write_action_serialization_deserialization():
def test_add_task_action_serialization_deserialization():
original_action_dict = {
'action': 'add_task',
'args': {'parent': 'Test parent', 'goal': 'Test goal', 'subtasks': []}
'args': {'parent': 'Test parent', 'goal': 'Test goal', 'subtasks': [], 'thought': ''}
}
serialization_deserialization(original_action_dict, AddTaskAction)
@@ -111,6 +111,6 @@ def test_add_task_action_serialization_deserialization():
def test_modify_task_action_serialization_deserialization():
original_action_dict = {
'action': 'modify_task',
'args': {'id': 1, 'state': 'Test state.'}
'args': {'id': 1, 'state': 'Test state.', 'thought': ''}
}
serialization_deserialization(original_action_dict, ModifyTaskAction)