chore: remove unused plugin mixin (#3332)

* remove unused plugin mixin

* remove unused field

* remove unused comments
This commit is contained in:
Xingyao Wang 2024-08-10 08:50:49 +08:00 committed by GitHub
parent ace733cb1f
commit e6fa5b5df0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 1 additions and 1401 deletions

View File

@ -1,19 +1,15 @@
# Requirements
from .agent_skills import AgentSkillsPlugin, AgentSkillsRequirement
from .jupyter import JupyterPlugin, JupyterRequirement
from .mixin import PluginMixin
from .requirement import Plugin, PluginRequirement
from .swe_agent_commands import SWEAgentCommandsRequirement
__all__ = [
'Plugin',
'PluginMixin',
'PluginRequirement',
'AgentSkillsRequirement',
'AgentSkillsPlugin',
'JupyterRequirement',
'JupyterPlugin',
'SWEAgentCommandsRequirement',
]
ALL_PLUGINS = {

View File

@ -1,4 +1,3 @@
import os
from dataclasses import dataclass
from opendevin.runtime.plugins.agent_skills.agentskills import DOCUMENTATION
@ -8,11 +7,6 @@ from opendevin.runtime.plugins.requirement import Plugin, PluginRequirement
@dataclass
class AgentSkillsRequirement(PluginRequirement):
name: str = 'agent_skills'
host_src: str = os.path.dirname(
os.path.abspath(__file__)
) # The directory of this file (opendevin/runtime/plugins/agent_skills)
sandbox_dest: str = '/opendevin/plugins/'
bash_script_path: str = 'setup.sh'
documentation: str = DOCUMENTATION

View File

@ -1,21 +0,0 @@
#!/bin/bash
set -e
OPENDEVIN_PYTHON_INTERPRETER=/opendevin/miniforge3/bin/python
# check if OPENDEVIN_PYTHON_INTERPRETER exists and it is usable
if [ -z "$OPENDEVIN_PYTHON_INTERPRETER" ] || [ ! -x "$OPENDEVIN_PYTHON_INTERPRETER" ]; then
echo "OPENDEVIN_PYTHON_INTERPRETER is not usable. Please pull the latest Docker image!"
exit 1
fi
# add agent_skills to PATH
echo 'export PATH=/opendevin/plugins/agent_skills:$PATH' >> ~/.bashrc
# add agent_skills to PYTHONPATH
echo 'export PYTHONPATH=/opendevin/plugins/agent_skills:$PYTHONPATH' >> ~/.bashrc
source ~/.bashrc
$OPENDEVIN_PYTHON_INTERPRETER -m pip install flake8 python-docx PyPDF2 python-pptx pylatexenc openai opencv-python
$OPENDEVIN_PYTHON_INTERPRETER -m pip install diskcache==5.6.3 grep-ast==0.3.2 tree-sitter==0.21.3 tree-sitter-languages==1.10.2

View File

@ -1,4 +1,3 @@
import os
import subprocess
import time
from dataclasses import dataclass
@ -15,16 +14,6 @@ from .execute_server import JupyterKernel
@dataclass
class JupyterRequirement(PluginRequirement):
name: str = 'jupyter'
host_src: str = os.path.dirname(
os.path.abspath(__file__)
) # The directory of this file (opendevin/runtime/plugins/jupyter)
sandbox_dest: str = '/opendevin/plugins/'
bash_script_path: str = 'setup.sh'
# ================================================================
# Plugin methods, which will ONLY be used in the runtime client
# running inside docker
# ================================================================
class JupyterPlugin(Plugin):

View File

@ -1,4 +0,0 @@
#!/bin/bash
# Run the Python script with the specified interpreter
export JUPYTER_PWD=$(pwd)
$OPENDEVIN_PYTHON_INTERPRETER /opendevin/plugins/jupyter/execute_cli.py

View File

@ -1,45 +0,0 @@
import os
import sys
import time
import traceback
import requests
# Read the Python code from STDIN
code = sys.stdin.read()
def execute_code(code, print_output=True):
PORT = os.environ.get('JUPYTER_EXEC_SERVER_PORT')
POST_URL = f'http://localhost:{PORT}/execute'
# Set the default kernel ID
kernel_id = 'default'
output = ''
for i in range(3):
try:
response = requests.post(
POST_URL, json={'kernel_id': kernel_id, 'code': code}
)
output = response.text
if '500: Internal Server Error' not in output:
if print_output:
print(output)
break
except requests.exceptions.ConnectionError:
if i == 2:
traceback.print_exc()
time.sleep(2)
else:
if not output:
with open('/opendevin/logs/jupyter_execute_server.log', 'r') as f:
output = f.read()
print('Failed to connect to the Jupyter server', output)
if jupyter_pwd := os.environ.get('JUPYTER_PWD'):
execute_code(
f'import os\nos.environ["JUPYTER_PWD"] = "{jupyter_pwd}"\n', print_output=False
)
execute_code(code)

View File

@ -1,87 +0,0 @@
#!/bin/bash
set -e
# Hardcoded to use the Python interpreter from the OpenDevin runtime client
OPENDEVIN_PYTHON_INTERPRETER=/opendevin/miniforge3/bin/python
# check if OPENDEVIN_PYTHON_INTERPRETER exists and it is usable
if [ -z "$OPENDEVIN_PYTHON_INTERPRETER" ] || [ ! -x "$OPENDEVIN_PYTHON_INTERPRETER" ]; then
echo "OPENDEVIN_PYTHON_INTERPRETER is not usable. Please pull the latest Docker image!"
exit 1
fi
# Install dependencies
$OPENDEVIN_PYTHON_INTERPRETER -m pip install jupyterlab notebook jupyter_kernel_gateway
source ~/.bashrc
# ADD /opendevin/plugins to PATH to make `jupyter_cli` available
echo 'export PATH=$PATH:/opendevin/plugins/jupyter' >> ~/.bashrc
export PATH=/opendevin/plugins/jupyter:$PATH
# Temporary add /opendevin/miniforge3/bin to PATH
# will not persist after the end of the script
# This fixes https://github.com/OpenDevin/OpenDevin/pull/2489#issuecomment-2223088169
export PATH=/opendevin/miniforge3/bin:$PATH
# if user name is `opendevin`, add '/home/opendevin/.local/bin' to PATH
if [ "$USER" = "opendevin" ]; then
echo 'export PATH=$PATH:/home/opendevin/.local/bin' >> ~/.bashrc
echo "export OPENDEVIN_PYTHON_INTERPRETER=$OPENDEVIN_PYTHON_INTERPRETER" >> ~/.bashrc
export PATH=$PATH:/home/opendevin/.local/bin
export PIP_CACHE_DIR=$HOME/.cache/pip
fi
# if user name is `root`, add '/root/.local/bin' to PATH
if [ "$USER" = "root" ]; then
echo 'export PATH=$PATH:/root/.local/bin' >> ~/.bashrc
echo "export OPENDEVIN_PYTHON_INTERPRETER=$OPENDEVIN_PYTHON_INTERPRETER" >> ~/.bashrc
export PATH=$PATH:/root/.local/bin
export PIP_CACHE_DIR=$HOME/.cache/pip
fi
# Run background process to start jupyter kernel gateway
# write a bash function that finds a free port
find_free_port() {
local start_port="${1:-20000}"
local end_port="${2:-65535}"
for port in $(seq $start_port $end_port); do
if ! ss -tuln | awk '{print $5}' | grep -q ":$port$"; then
echo $port
return
fi
done
echo "No free ports found in the range $start_port to $end_port" >&2
return 1
}
export JUPYTER_GATEWAY_PORT=$(find_free_port 20000 30000)
$OPENDEVIN_PYTHON_INTERPRETER -m \
jupyter kernelgateway --KernelGatewayApp.ip=0.0.0.0 --KernelGatewayApp.port=$JUPYTER_GATEWAY_PORT > /opendevin/logs/jupyter_kernel_gateway.log 2>&1 &
export JUPYTER_GATEWAY_PID=$!
echo "export JUPYTER_GATEWAY_PID=$JUPYTER_GATEWAY_PID" >> ~/.bashrc
export JUPYTER_GATEWAY_KERNEL_ID="default"
echo "export JUPYTER_GATEWAY_KERNEL_ID=$JUPYTER_GATEWAY_KERNEL_ID" >> ~/.bashrc
echo "JupyterKernelGateway started with PID: $JUPYTER_GATEWAY_PID"
# Start the jupyter_server
export JUPYTER_EXEC_SERVER_PORT=$(find_free_port 30000 40000)
echo "export JUPYTER_EXEC_SERVER_PORT=$JUPYTER_EXEC_SERVER_PORT" >> ~/.bashrc
$OPENDEVIN_PYTHON_INTERPRETER /opendevin/plugins/jupyter/execute_server.py > /opendevin/logs/jupyter_execute_server.log 2>&1 &
export JUPYTER_EXEC_SERVER_PID=$!
echo "export JUPYTER_EXEC_SERVER_PID=$JUPYTER_EXEC_SERVER_PID" >> ~/.bashrc
echo "Execution server started with PID: $JUPYTER_EXEC_SERVER_PID"
# Wait until /opendevin/logs/jupyter_kernel_gateway.log contains "is available"
while ! grep -q "at" /opendevin/logs/jupyter_kernel_gateway.log; do
echo "Waiting for Jupyter kernel gateway to be available..."
sleep 1
done
# Wait until /opendevin/logs/jupyter_execute_server.log contains "Jupyter kernel created for conversation"
while ! grep -q "kernel created" /opendevin/logs/jupyter_execute_server.log; do
echo "Waiting for Jupyter kernel to be created..."
sleep 1
done
echo "Jupyter kernel ready."

View File

@ -1,101 +0,0 @@
import os
from typing import Protocol
from opendevin.core.logger import opendevin_logger as logger
from opendevin.core.schema import CancellableStream
from opendevin.runtime.plugins.requirement import PluginRequirement
class SandboxProtocol(Protocol):
# https://stackoverflow.com/questions/51930339/how-do-i-correctly-add-type-hints-to-mixin-classes
@property
def initialize_plugins(self) -> bool: ...
def execute(
self, cmd: str, stream: bool = False
) -> tuple[int, str | CancellableStream]: ...
def copy_to(self, host_src: str, sandbox_dest: str, recursive: bool = False): ...
def _source_bashrc(sandbox: SandboxProtocol):
exit_code, output = sandbox.execute(
'source /opendevin/bash.bashrc && source ~/.bashrc'
)
if exit_code != 0:
raise RuntimeError(
f'Failed to source /opendevin/bash.bashrc and ~/.bashrc with exit code {exit_code} and output: {output}'
)
logger.info('Sourced /opendevin/bash.bashrc and ~/.bashrc successfully')
class PluginMixin:
"""Mixin for Sandbox to support plugins."""
def init_plugins(self: SandboxProtocol, requirements: list[PluginRequirement]):
"""Load a plugin into the sandbox."""
if hasattr(self, 'plugin_initialized') and self.plugin_initialized:
return
if self.initialize_plugins:
logger.info('Initializing plugins in the sandbox')
# clean-up ~/.bashrc and touch ~/.bashrc
exit_code, output = self.execute('rm -f ~/.bashrc && touch ~/.bashrc')
if exit_code != 0:
logger.warning(
f'Failed to clean-up ~/.bashrc with exit code {exit_code} and output: {output}'
)
for requirement in requirements:
# source bashrc file when plugin loads
_source_bashrc(self)
# copy over the files
self.copy_to(
requirement.host_src, requirement.sandbox_dest, recursive=True
)
logger.info(
f'Copied files from [{requirement.host_src}] to [{requirement.sandbox_dest}] inside sandbox.'
)
# Execute the bash script
abs_path_to_bash_script = os.path.join(
requirement.sandbox_dest,
requirement.name,
requirement.bash_script_path,
)
logger.info(
f'Initializing plugin [{requirement.name}] by executing [{abs_path_to_bash_script}] in the sandbox.'
)
exit_code, output = self.execute(abs_path_to_bash_script, stream=True)
if isinstance(output, CancellableStream):
total_output = ''
for line in output:
# Removes any trailing whitespace, including \n and \r\n
line = line.rstrip()
# logger.debug(line)
# Avoid text from lines running into each other
total_output += line + ' '
_exit_code = output.exit_code()
output.close()
if _exit_code != 0:
raise RuntimeError(
f'Failed to initialize plugin {requirement.name} with exit code {_exit_code} and output: {total_output.strip()}'
)
logger.debug(f'Output: {total_output.strip()}')
else:
if exit_code != 0:
raise RuntimeError(
f'Failed to initialize plugin {requirement.name} with exit code {exit_code} and output: {output}'
)
logger.debug(f'Output: {output}')
logger.info(f'Plugin {requirement.name} initialized successfully')
else:
logger.info('Skipping plugin initialization in the sandbox')
if len(requirements) > 0:
_source_bashrc(self)
self.plugin_initialized = True

View File

@ -29,8 +29,3 @@ class PluginRequirement:
"""Requirement for a plugin."""
name: str
# FOLDER/FILES to be copied to the sandbox
host_src: str
sandbox_dest: str
# NOTE: bash_script_path should be relative to the `sandbox_dest` path
bash_script_path: str

View File

@ -1,71 +0,0 @@
import os
from dataclasses import dataclass, field
from opendevin.runtime.plugins.requirement import PluginRequirement
from opendevin.runtime.plugins.swe_agent_commands.parse_commands import (
parse_command_file,
)
def _resolve_to_cur_dir(filename):
return os.path.join(os.path.dirname(os.path.abspath(__file__)), filename)
def check_and_parse_command_file(filepath) -> str:
if filepath is None:
raise FileNotFoundError(f'File not found: {filepath}')
return parse_command_file(filepath)
DEFAULT_SCRIPT_FILEPATHS = [
_resolve_to_cur_dir('defaults.sh'),
_resolve_to_cur_dir('search.sh'),
_resolve_to_cur_dir('edit_linting.sh'),
]
DEFAULT_DOCUMENTATION = ''.join(
[
check_and_parse_command_file(filepath)
for filepath in DEFAULT_SCRIPT_FILEPATHS
if filepath is not None
]
)
@dataclass
class SWEAgentCommandsRequirement(PluginRequirement):
name: str = 'swe_agent_commands'
host_src: str = os.path.dirname(os.path.abspath(__file__))
sandbox_dest: str = '/opendevin/plugins/'
bash_script_path: str = 'setup_default.sh'
scripts_filepaths: list[str | None] = field(
default_factory=lambda: DEFAULT_SCRIPT_FILEPATHS
)
documentation: str = DEFAULT_DOCUMENTATION
CURSOR_SCRIPT_FILEPATHS = [
_resolve_to_cur_dir('cursors_defaults.sh'),
_resolve_to_cur_dir('cursors_edit_linting.sh'),
_resolve_to_cur_dir('search.sh'),
]
CURSOR_DOCUMENTATION = ''.join(
[
check_and_parse_command_file(filepath)
for filepath in CURSOR_SCRIPT_FILEPATHS
if filepath is not None
]
)
@dataclass
class SWEAgentCursorCommandsRequirement(PluginRequirement):
name: str = 'swe_agent_commands'
host_src: str = os.path.dirname(os.path.abspath(__file__))
sandbox_dest: str = '/opendevin/plugins/swe_agent_commands'
bash_script_path: str = 'setup_cursor_mode.sh'
scripts_filepaths: list[str | None] = field(
default_factory=lambda: CURSOR_SCRIPT_FILEPATHS
)
documentation: str = CURSOR_DOCUMENTATION

View File

@ -1,24 +0,0 @@
# Cursor Mode from SWE-Bench
# https://github.com/princeton-nlp/SWE-agent/blob/ca54d5556b9db4f4f2be21f09530ce69a72c0305/config/configs/default_sys-env_cursors_window100-detailed_cmd_format-last_5_history-1_demos.yaml
export WINDOW=200;
export OVERLAP=2;
export CURRENT_LINE=0;
export CURRENT_FILE='';
export SEARCH_RESULTS=();
export SEARCH_FILES=();
export SEARCH_INDEX=0;
export START_INDEX=0;
export END_INDEX=0;
export START_CURSOR=0;
export END_CURSOR=0;
export START_CURSOR_MARK='"<<<<< START CURSOR >>>>>"'; # these have to use double quotes
export END_CURSOR_MARK='"<<<<< END CURSOR >>>>>"'; # these have to use double quotes
state() {
local working_dir="$PWD";
if [ -z $CURRENT_FILE ]; then
echo '{"open_file": "n/a", "working_dir": "'$working_dir'"}';
else
echo '{"open_file": "'$(realpath $CURRENT_FILE)'", "working_dir": "'$working_dir'"}';
fi
};

View File

@ -1,18 +0,0 @@
# Default Mode from SWE-Bench
# https://github.com/princeton-nlp/SWE-agent/blob/ca54d5556b9db4f4f2be21f09530ce69a72c0305/config/configs/default_sys-env_window100-detailed_cmd_format-last_5_history-1_demos.yaml
export WINDOW=100;
export OVERLAP=2;
export CURRENT_LINE=0;
export CURRENT_FILE='';
export SEARCH_RESULTS=();
export SEARCH_FILES=();
export SEARCH_INDEX=0;
state() {
local working_dir="$PWD";
if [ -z $CURRENT_FILE ]; then
echo '{"open_file": "n/a", "working_dir": "'$working_dir'"}';
else
echo '{"open_file": "'$(realpath $CURRENT_FILE)'", "working_dir": "'$working_dir'"}';
fi
};

View File

@ -1,17 +0,0 @@
#!/usr/bin/env python3
import sys
def print_flake8_output(input_string, show_line_numbers=False):
for value in input_string.split('\n'):
parts = value.split()
if not show_line_numbers:
print(f"- {' '.join(parts[1:])}")
else:
line_nums = ':'.join(parts[0].split(':')[1:])
print(f"- {line_nums} {' '.join(parts[1:])}")
if __name__ == '__main__':
lint_output = sys.argv[1]
print_flake8_output(lint_output)

View File

@ -1,306 +0,0 @@
_reset_cursors() {
export START_CURSOR=1
export END_CURSOR=1
}
_constrain_cursors() {
# constrain the cursors to be within the bounds of the file [0, total_lines+1]
local total_lines=$(awk 'END {print NR}' "$CURRENT_FILE")
total_lines=$((total_lines < 1 ? 1 : total_lines)) # if the file is empty, set total_lines to 1
local start_line=$((CURRENT_LINE - WINDOW / 2))
local end_line=$((CURRENT_LINE + WINDOW / 2))
start_line=$((start_line < 1 ? 1 : start_line))
end_line=$((end_line > total_lines ? total_lines : end_line))
local warning_string=""
if [ "$START_CURSOR" -lt "$start_line" ]; then
warning_string+="START_CURSOR moved to $start_line\n"
START_CURSOR=$start_line
elif [ "$START_CURSOR" -gt "$end_line" ]; then
START_CURSOR=$end_line
warning_string+="START_CURSOR moved to $end_line\n"
fi
if [ "$END_CURSOR" -lt "$start_line" ]; then
warning_string+="END_CURSOR moved to $start_line\n"
END_CURSOR=$start_line
elif [ "$END_CURSOR" -gt "$end_line" ]; then
warning_string+="END_CURSOR moved to $end_line\n"
END_CURSOR=$end_line
fi
export START_CURSOR END_CURSOR
echo "$warning_string"
echo $START_CURSOR $END_CURSOR
}
_print() {
local cursor_warning=$(_constrain_cursors)
local cursor_values=$(echo "$cursor_warning" | tail -n 1)
cursor_warning=$(echo "$cursor_warning" | head -n -1)
export START_CURSOR=$(echo "$cursor_values" | awk '{print $1}')
export END_CURSOR=$(echo "$cursor_values" | awk '{print $2}')
local total_lines=$(awk 'END {print NR}' $CURRENT_FILE)
echo "[File: $(realpath "$CURRENT_FILE") ($total_lines lines total)]"
local start_line=$((CURRENT_LINE - WINDOW / 2))
local end_line=$((CURRENT_LINE + WINDOW / 2))
start_line=$((start_line < 1 ? 1 : start_line))
end_line=$((end_line > total_lines ? total_lines : end_line))
local lines=()
local i=0
while IFS= read -r line; do
lines[i++]="$line"
done < <(awk -v start="$start_line" -v end="$end_line" 'NR>=start && NR<=end {print}' "$CURRENT_FILE")
local num_lines=${#lines[@]}
if [ $start_line -gt 1 ]; then
echo "($((start_line - 1)) more lines above)"
fi
for ((i=0; i<num_lines+1; i++)) do
local line_number=$((start_line + i))
if [ $line_number -eq $START_CURSOR ]
then
echo $START_CURSOR_MARK
fi
# if i in [0, num_lines-1] then print the line number and the line
if [ $i -ge 0 ] && [ $i -lt $num_lines ]
then
echo "$line_number:${lines[i]}"
fi
if [ $line_number -eq $END_CURSOR ]
then
echo $END_CURSOR_MARK
fi
done
lines_below=$(jq -n "$total_lines - $start_line - $num_lines" | jq '[0, .] | max')
if [ $lines_below -gt 0 ]; then
echo "($lines_below more lines below)"
fi
if [ -n "$cursor_warning" ]; then
echo -e "$cursor_warning"
fi
}
_constrain_line() {
if [ -z "$CURRENT_FILE" ]
then
echo "No file open. Use the open command first."
return
fi
local max_line=$(awk 'END {print NR}' $CURRENT_FILE)
local half_window=$(jq -n "$WINDOW/2" | jq 'floor')
export CURRENT_LINE=$(jq -n "[$CURRENT_LINE, $max_line - $half_window] | min")
export CURRENT_LINE=$(jq -n "[$CURRENT_LINE, $half_window] | max")
}
# @yaml
# signature: set_cursors <start_line> <end_line>
# docstring: sets the start and end cursors to the given line numbers
# arguments:
# start_line:
# type: integer
# description: the line number to set the start cursor to
# required: true
# end_line:
# type: integer
# description: the line number to set the end cursor to
# required: true
set_cursors() {
if [ -z "$CURRENT_FILE" ]
then
echo "No file open. Use the open command first."
return
fi
if [ $# -lt 2 ]
then
echo "Usage: set_cursors <start_line> <end_line>"
return
fi
local start_line=$1
local end_line=$2
local re='^[0-9]+$'
if ! [[ $start_line =~ $re ]]
then
echo "Usage: set_cursors <start_line> <end_line>"
echo "Error: start_line must be a number"
return
fi
if ! [[ $end_line =~ $re ]]
then
echo "Usage: set_cursors <start_line> <end_line>"
echo "Error: end_line must be a number"
return
fi
if [ $start_line -gt $end_line ]
then
echo "Usage: set_cursors <start_line> <end_line>"
echo "Error: start_line must be less than or equal to end_line"
return
fi
export START_CURSOR=$start_line
export END_CURSOR=$end_line
_print
}
# @yaml
# signature: open <path> [<line_number>]
# docstring: opens the file at the given path in the editor. If line_number is provided, the window will be centered on that line
# arguments:
# path:
# type: string
# description: the path to the file to open
# required: true
# line_number:
# type: integer
# description: the line number to move the window to (if not provided, the window will start at the top of the file)
# required: false
open() {
if [ -z "$1" ]
then
echo "Usage: open <file>"
return
fi
# Check if the second argument is provided
if [ -n "$2" ]; then
# Check if the provided argument is a valid number
if ! [[ $2 =~ ^[0-9]+$ ]]; then
echo "Usage: open <file> [<line_number>]"
echo "Error: <line_number> must be a number"
return # Exit if the line number is not valid
fi
local max_line=$(awk 'END {print NR}' $1)
if [ $2 -gt $max_line ]; then
echo "Warning: <line_number> ($2) is greater than the number of lines in the file ($max_line)"
echo "Warning: Setting <line_number> to $max_line"
local line_number=$(jq -n "$max_line") # Set line number to max if greater than max
elif [ $2 -lt 1 ]; then
echo "Warning: <line_number> ($2) is less than 1"
echo "Warning: Setting <line_number> to 1"
local line_number=$(jq -n "1") # Set line number to 1 if less than 1
else
local line_number=$(jq -n "$2") # Set line number if valid
fi
else
local line_number=$(jq -n "$WINDOW/2") # Set default line number if not provided
fi
if [ -f "$1" ]; then
export CURRENT_FILE=$(realpath $1)
export CURRENT_LINE=$line_number
_constrain_line
_print
else
echo "File $1 not found"
fi
}
# @yaml
# signature: scroll_down
# docstring: moves the window down {WINDOW} lines
scroll_down() {
if [ -z "$CURRENT_FILE" ]
then
echo "No file open. Use the open command first."
return
fi
export CURRENT_LINE=$(jq -n "$CURRENT_LINE + $WINDOW - $OVERLAP")
_constrain_line
_print
}
# @yaml
# signature: scroll_up
# docstring: moves the window up {WINDOW} lines
scroll_up() {
if [ -z "$CURRENT_FILE" ]
then
echo "No file open. Use the open command first."
return
fi
export CURRENT_LINE=$(jq -n "$CURRENT_LINE - $WINDOW + $OVERLAP")
_constrain_line
_print
}
# @yaml
# signature: goto <line_number>
# docstring: moves the window to show <line_number>
# arguments:
# line_number:
# type: integer
# description: the line number to move the window to
# required: true
goto() {
if [ $# -gt 1 ]; then
echo "goto allows only one line number at a time."
return
fi
if [ -z "$CURRENT_FILE" ]
then
echo "No file open. Use the open command first."
return
fi
if [ -z "$1" ]
then
echo "Usage: goto <line>"
return
fi
if ! [[ $1 =~ ^[0-9]+$ ]]
then
echo "Usage: goto <line>"
echo "Error: <line> must be a number"
return
fi
local max_line=$(awk 'END {print NR}' $CURRENT_FILE)
if [ $1 -gt $max_line ]
then
echo "Error: <line> must be less than or equal to $max_line"
return
fi
local OFFSET=$(jq -n "$WINDOW/6" | jq 'floor')
export CURRENT_LINE=$(jq -n "[$1 + $WINDOW/2 - $OFFSET, 1] | max | floor")
_constrain_line
_print
}
# @yaml
# signature: create <filename>
# docstring: creates and opens a new file with the given name
# arguments:
# filename:
# type: string
# description: the name of the file to create
# required: true
create() {
if [ -z "$1" ]; then
echo "Usage: create <filename>"
return
fi
# Check if the file already exists
if [ -e "$1" ]; then
echo "Error: File '$1' already exists."
open "$1"
return
fi
# Create the file an empty new line
printf "\n" > "$1"
# Use the existing open command to open the created file
open "$1"
}
# @yaml
# signature: submit
# docstring: submits your current code and terminates the session
submit() {
cd $ROOT
# Check if the patch file exists and is non-empty
if [ -s "$SWE_CMD_WORK_DIR/test.patch" ]; then
# Apply the patch in reverse
git apply -R < "$SWE_CMD_WORK_DIR/test.patch"
fi
git add -A
git diff --cached > model.patch
echo "<<SUBMISSION||"
cat model.patch
echo "||SUBMISSION>>"
}

View File

@ -1,100 +0,0 @@
# @yaml
# signature: |-
# edit <<EOF
# <replacement_text>
# EOF
# docstring: replaces *all* of the text between the START CURSOR and the END CURSOR with the replacement_text. The replacement text is delineated using heredoc syntax. All of the <replacement_text> will be entered, so make sure your indentation is formatted properly. To enter text at the beginning of the file, set START CURSOR and END CURSOR to 0. Use set_cursors to move the cursors around. Python files will be checked for syntax errors after the edit.
# arguments:
# replacement_text:
# type: string
# description: the text to replace the current selection with
# required: true
edit() {
if [ -z "$CURRENT_FILE" ]
then
echo 'No file is opened. Use the `open` command first.'
return
fi
local start_line=$((START_CURSOR - 1))
start_line=$((start_line < 0 ? 0 : start_line))
local end_line=$((END_CURSOR))
end_line=$((end_line < 0 ? 0 : end_line))
local replacement=()
while IFS= read -r line
do
replacement+=("$line")
done
local num_lines=${#replacement[@]}
# Create a backup of the current file
cp "$CURRENT_FILE" "$SWE_CMD_WORK_DIR/$(basename "$CURRENT_FILE")_backup"
# Read the file line by line into an array
mapfile -t lines < "$CURRENT_FILE"
local new_lines=("${lines[@]:0:$start_line}" "${replacement[@]}" "${lines[@]:$((end_line))}")
# Write the new stuff directly back into the original file
printf "%s\n" "${new_lines[@]}" >| "$CURRENT_FILE"
# Run linter if enabled
if [[ $CURRENT_FILE == *.py && -n "$ENABLE_AUTO_LINT" ]]; then
lint_output=$(flake8 --isolated --select=F821,F822,F831,E111,E112,E113,E999,E902 "$CURRENT_FILE" 2>&1)
else
# do nothing
lint_output=""
fi
# if there is no output, then the file is good
if [ -z "$lint_output" ]; then
_constrain_line
# set to START + num_lines - 1, unless num_lines is 0, then set to START
export END_CURSOR=$((num_lines == 0 ? START_CURSOR : START_CURSOR + num_lines - 1))
export START_CURSOR=$START_CURSOR
_print
echo "File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary."
else
echo "Your proposed edit has introduced new syntax error(s). Please understand the fixes and retry your edit command."
echo ""
echo "ERRORS:"
_split_string "$lint_output"
echo ""
# Save original values
original_current_line=$CURRENT_LINE
original_window=$WINDOW
original_end_cursor=$END_CURSOR
# Update values
export CURRENT_LINE=$(( (num_lines / 2) + start_line )) # Set to "center" of edit
export WINDOW=$((num_lines + 10)) # Show +/- 5 lines around edit
export END_CURSOR=$((num_lines == 0 ? START_CURSOR : START_CURSOR + num_lines - 1))
echo "This is how your edit would have looked if applied"
echo "-------------------------------------------------"
_constrain_line
_print
echo "-------------------------------------------------"
echo ""
# Restoring CURRENT_FILE to original contents.
cp "$SWE_CMD_WORK_DIR/$(basename "$CURRENT_FILE")_backup" "$CURRENT_FILE"
export CURRENT_LINE=$(( ((end_line - start_line) / 2) + start_line )) # Set to "center" of edit
export WINDOW=$((end_line - start_line + 10))
export END_CURSOR=$original_end_cursor
echo "This is the original code before your edit"
echo "-------------------------------------------------"
_constrain_line
_print
echo "-------------------------------------------------"
# Restore original values
export CURRENT_LINE=$original_current_line
export WINDOW=$original_window
export END_CURSOR=$original_end_cursor
echo "Your changes have NOT been applied. Please fix your edit command and try again."
echo "You either need to 1) Specify the correct start/end line arguments or 2) Correct your edit code."
echo "DO NOT re-run the same failed edit command. Running it again will lead to the same error."
fi
# Remove backup file
rm -f "$SWE_CMD_WORK_DIR/$(basename "$CURRENT_FILE")_backup"
}

View File

@ -1,195 +0,0 @@
_print() {
local total_lines=$(awk 'END {print NR}' $CURRENT_FILE)
echo "[File: $(realpath $CURRENT_FILE) ($total_lines lines total)]"
lines_above=$(jq -n "$CURRENT_LINE - $WINDOW/2" | jq '[0, .] | max | floor')
lines_below=$(jq -n "$total_lines - $CURRENT_LINE - $WINDOW/2" | jq '[0, .] | max | round')
if [ $lines_above -gt 0 ]; then
echo "($lines_above more lines above)"
fi
cat $CURRENT_FILE | grep -n $ | head -n $(jq -n "[$CURRENT_LINE + $WINDOW/2, $WINDOW/2] | max | floor") | tail -n $(jq -n "$WINDOW")
if [ $lines_below -gt 0 ]; then
echo "($lines_below more lines below)"
fi
}
_constrain_line() {
if [ -z "$CURRENT_FILE" ]
then
echo "No file open. Use the open command first."
return
fi
local max_line=$(awk 'END {print NR}' $CURRENT_FILE)
local half_window=$(jq -n "$WINDOW/2" | jq 'floor')
export CURRENT_LINE=$(jq -n "[$CURRENT_LINE, $max_line - $half_window] | min")
export CURRENT_LINE=$(jq -n "[$CURRENT_LINE, $half_window] | max")
}
# @yaml
# signature: open <path> [<line_number>]
# docstring: opens the file at the given path in the editor. If line_number is provided, the window will be move to include that line
# arguments:
# path:
# type: string
# description: the path to the file to open
# required: true
# line_number:
# type: integer
# description: the line number to move the window to (if not provided, the window will start at the top of the file)
# required: false
open() {
if [ -z "$1" ]
then
echo "Usage: open <file>"
return
fi
# Check if the second argument is provided
if [ -n "$2" ]; then
# Check if the provided argument is a valid number
if ! [[ $2 =~ ^[0-9]+$ ]]; then
echo "Usage: open <file> [<line_number>]"
echo "Error: <line_number> must be a number"
return # Exit if the line number is not valid
fi
local max_line=$(awk 'END {print NR}' $1)
if [ $2 -gt $max_line ]; then
echo "Warning: <line_number> ($2) is greater than the number of lines in the file ($max_line)"
echo "Warning: Setting <line_number> to $max_line"
local line_number=$(jq -n "$max_line") # Set line number to max if greater than max
elif [ $2 -lt 1 ]; then
echo "Warning: <line_number> ($2) is less than 1"
echo "Warning: Setting <line_number> to 1"
local line_number=$(jq -n "1") # Set line number to 1 if less than 1
else
local OFFSET=$(jq -n "$WINDOW/6" | jq 'floor')
local line_number=$(jq -n "[$2 + $WINDOW/2 - $OFFSET, 1] | max | floor")
fi
else
local line_number=$(jq -n "$WINDOW/2") # Set default line number if not provided
fi
if [ -f "$1" ]; then
export CURRENT_FILE=$(realpath $1)
export CURRENT_LINE=$line_number
_constrain_line
_print
elif [ -d "$1" ]; then
echo "Error: $1 is a directory. You can only open files. Use cd or ls to navigate directories."
else
echo "File $1 not found"
fi
}
# @yaml
# signature: goto <line_number>
# docstring: moves the window to show <line_number>
# arguments:
# line_number:
# type: integer
# description: the line number to move the window to
# required: true
goto() {
if [ $# -gt 1 ]; then
echo "goto allows only one line number at a time."
return
fi
if [ -z "$CURRENT_FILE" ]
then
echo "No file open. Use the open command first."
return
fi
if [ -z "$1" ]
then
echo "Usage: goto <line>"
return
fi
if ! [[ $1 =~ ^[0-9]+$ ]]
then
echo "Usage: goto <line>"
echo "Error: <line> must be a number"
return
fi
local max_line=$(awk 'END {print NR}' $CURRENT_FILE)
if [ $1 -gt $max_line ]
then
echo "Error: <line> must be less than or equal to $max_line"
return
fi
local OFFSET=$(jq -n "$WINDOW/6" | jq 'floor')
export CURRENT_LINE=$(jq -n "[$1 + $WINDOW/2 - $OFFSET, 1] | max | floor")
_constrain_line
_print
}
# @yaml
# signature: scroll_down
# docstring: moves the window down {WINDOW} lines
scroll_down() {
if [ -z "$CURRENT_FILE" ]
then
echo "No file open. Use the open command first."
return
fi
export CURRENT_LINE=$(jq -n "$CURRENT_LINE + $WINDOW - $OVERLAP")
_constrain_line
_print
}
# @yaml
# signature: scroll_up
# docstring: moves the window down {WINDOW} lines
scroll_up() {
if [ -z "$CURRENT_FILE" ]
then
echo "No file open. Use the open command first."
return
fi
export CURRENT_LINE=$(jq -n "$CURRENT_LINE - $WINDOW + $OVERLAP")
_constrain_line
_print
}
# @yaml
# signature: create <filename>
# docstring: creates and opens a new file with the given name
# arguments:
# filename:
# type: string
# description: the name of the file to create
# required: true
create() {
if [ -z "$1" ]; then
echo "Usage: create <filename>"
return
fi
# Check if the file already exists
if [ -e "$1" ]; then
echo "Error: File '$1' already exists."
open "$1"
return
fi
# Create the file an empty new line
printf "\n" > "$1"
# Use the existing open command to open the created file
open "$1"
}
# @yaml
# signature: submit
# docstring: submits your current code and terminates the session
submit() {
cd $ROOT
# Check if the patch file exists and is non-empty
if [ -s "$SWE_CMD_WORK_DIR/test.patch" ]; then
# Apply the patch in reverse
git apply -R < "$SWE_CMD_WORK_DIR/test.patch"
fi
git add -A
git diff --cached > model.patch
echo "<<SUBMISSION||"
cat model.patch
echo "||SUBMISSION>>"
}

View File

@ -1,129 +0,0 @@
# @yaml
# signature: |-
# edit <start_line>:<end_line> <<EOF
# <replacement_text>
# EOF
# docstring: replaces lines <start_line> through <end_line> (inclusive) with the given text in the open file. The replacement text is delineated using heredoc syntax. 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. Remember, the file must be open before editing.
# arguments:
# start_line:
# type: integer
# description: the line number to start the edit at
# required: true
# end_line:
# type: integer
# description: the line number to end the edit at (inclusive)
# required: true
# replacement_text:
# type: string
# description: the text to replace the current selection with
# required: true
edit() {
if [ -z "$CURRENT_FILE" ]
then
echo 'No file open. Use the `open` command first.'
return
fi
local start_line="$(echo $1: | cut -d: -f1)"
local end_line="$(echo $1: | cut -d: -f2)"
if [ -z "$start_line" ] || [ -z "$end_line" ]
then
echo "Usage: edit <start_line>:<end_line>"
return
fi
local re='^[0-9]+$'
if ! [[ $start_line =~ $re ]]; then
echo "Usage: edit <start_line>:<end_line>"
echo "Error: start_line must be a number"
return
fi
if ! [[ $end_line =~ $re ]]; then
echo "Usage: edit <start_line>:<end_line>"
echo "Error: end_line must be a number"
return
fi
# Bash array starts at 0, so let's adjust
local start_line=$((start_line - 1))
local end_line=$((end_line))
local line_count=0
local replacement=()
while IFS= read -r line
do
replacement+=("$line")
((line_count++))
done
# Create a backup of the current file
cp "$CURRENT_FILE" "$SWE_CMD_WORK_DIR/$(basename "$CURRENT_FILE")_backup"
# Read the file line by line into an array
mapfile -t lines < "$CURRENT_FILE"
local new_lines=("${lines[@]:0:$start_line}" "${replacement[@]}" "${lines[@]:$((end_line))}")
# Write the new stuff directly back into the original file
printf "%s\n" "${new_lines[@]}" >| "$CURRENT_FILE"
# Run linter if enabled
if [[ $CURRENT_FILE == *.py && -n "$ENABLE_AUTO_LINT" ]]; then
lint_output=$(flake8 --isolated --select=F821,F822,F831,E111,E112,E113,E999,E902 "$CURRENT_FILE" 2>&1)
else
# do nothing
lint_output=""
fi
# if there is no output, then the file is good
if [ -z "$lint_output" ]; then
export CURRENT_LINE=$start_line
_constrain_line
_print
echo "File updated. Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary."
else
echo "Your proposed edit has introduced new syntax error(s). Please understand the fixes and retry your edit command."
echo ""
echo "ERRORS:"
_split_string "$lint_output"
echo ""
# Save original values
original_current_line=$CURRENT_LINE
original_window=$WINDOW
# Update values
export CURRENT_LINE=$(( (line_count / 2) + start_line )) # Set to "center" of edit
export WINDOW=$((line_count + 10)) # Show +/- 5 lines around edit
echo "This is how your edit would have looked if applied"
echo "-------------------------------------------------"
_constrain_line
_print
echo "-------------------------------------------------"
echo ""
# Restoring CURRENT_FILE to original contents.
cp "$SWE_CMD_WORK_DIR/$(basename "$CURRENT_FILE")_backup" "$CURRENT_FILE"
export CURRENT_LINE=$(( ((end_line - start_line + 1) / 2) + start_line ))
export WINDOW=$((end_line - start_line + 10))
echo "This is the original code before your edit"
echo "-------------------------------------------------"
_constrain_line
_print
echo "-------------------------------------------------"
# Restore original values
export CURRENT_LINE=$original_current_line
export WINDOW=$original_window
echo "Your changes have NOT been applied. Please fix your edit command and try again."
echo "You either need to 1) Specify the correct start/end line arguments or 2) Correct your edit code."
echo "DO NOT re-run the same failed edit command. Running it again will lead to the same error."
fi
# Remove backup file
rm -f "$SWE_CMD_WORK_DIR/$(basename "$CURRENT_FILE")_backup"
}

View File

@ -1,62 +0,0 @@
from dataclasses import dataclass
import yaml
@dataclass()
class Command:
name: str
docstring: str | None = None
signature: str | None = None
def parse_command_file(filepath: str) -> str:
content = open(filepath, 'r').read()
lines = content.split('\n')
commands: list[Command] = []
idx = 0
docs: list[str] = []
while idx < len(lines):
line = lines[idx]
idx += 1
if line.startswith('# '):
docs.append(line[2:])
elif line.strip().endswith('() {'):
name = line.split()[0][:-2]
while lines[idx].strip() != '}':
idx += 1
docstring, signature = None, name
docs_dict = yaml.safe_load('\n'.join(docs).replace('@yaml', ''))
if docs_dict is not None:
docstring = docs_dict.get('docstring')
arguments = docs_dict.get('arguments', None)
if 'signature' in docs_dict:
signature = docs_dict['signature']
else:
if arguments is not None:
for param, settings in arguments.items():
if 'required' in settings:
signature += f' <{param}>'
else:
signature += f' [<{param}>]'
command = Command(name, docstring, signature)
commands.append(command)
docs = []
function_docs = ''
for cmd in commands:
if cmd.docstring is not None:
function_docs += f'{cmd.signature or cmd.name} - {cmd.docstring}\n'
return function_docs
if __name__ == '__main__':
import sys
if len(sys.argv) < 2:
print('Usage: python parse_commands.py <file>')
sys.exit(1)
filepath = sys.argv[1]
filepaths = filepath.split(',')
for filepath in filepaths:
docs = parse_command_file(filepath)
print(docs)

View File

@ -1,155 +0,0 @@
# @yaml
# signature: search_dir <search_term> [<dir>]
# docstring: searches for search_term in all files in dir. If dir is not provided, searches in the current directory
# arguments:
# search_term:
# type: string
# description: the term to search for
# required: true
# dir:
# type: string
# description: the directory to search in (if not provided, searches in the current directory)
# required: false
search_dir() {
if [ $# -eq 1 ]; then
local search_term="$1"
local dir="./"
elif [ $# -eq 2 ]; then
local search_term="$1"
if [ -d "$2" ]; then
local dir="$2"
else
echo "Directory $2 not found"
return
fi
else
echo "Usage: search_dir <search_term> [<dir>]"
return
fi
dir=$(realpath "$dir")
local matches=$(find "$dir" -type f ! -path '*/.*' -exec grep -nIH -- "$search_term" {} + | cut -d: -f1 | sort | uniq -c)
# if no matches, return
if [ -z "$matches" ]; then
echo "No matches found for \"$search_term\" in $dir"
return
fi
# Calculate total number of matches
local num_matches=$(echo "$matches" | awk '{sum+=$1} END {print sum}')
# calculate total number of files matched
local num_files=$(echo "$matches" | wc -l | awk '{$1=$1; print $0}')
# if num_files is > 100, print an error
if [ $num_files -gt 100 ]; then
echo "More than $num_files files matched for \"$search_term\" in $dir. Please narrow your search."
return
fi
echo "Found $num_matches matches for \"$search_term\" in $dir:"
echo "$matches" | awk '{$2=$2; gsub(/^\.+\/+/, "./", $2); print $2 " ("$1" matches)"}'
echo "End of matches for \"$search_term\" in $dir"
}
# @yaml
# signature: search_file <search_term> [<file>]
# docstring: searches for search_term in file. If file is not provided, searches in the current open file
# arguments:
# search_term:
# type: string
# description: the term to search for
# required: true
# file:
# type: string
# description: the file to search in (if not provided, searches in the current open file)
# required: false
search_file() {
# Check if the first argument is provided
if [ -z "$1" ]; then
echo "Usage: search_file <search_term> [<file>]"
return
fi
# Check if the second argument is provided
if [ -n "$2" ]; then
# Check if the provided argument is a valid file
if [ -f "$2" ]; then
local file="$2" # Set file if valid
else
echo "Usage: search_file <search_term> [<file>]"
echo "Error: File name $2 not found. Please provide a valid file name."
return # Exit if the file is not valid
fi
else
# Check if a file is open
if [ -z "$CURRENT_FILE" ]; then
echo "No file open. Use the open command first."
return # Exit if no file is open
fi
local file="$CURRENT_FILE" # Set file to the current open file
fi
local search_term="$1"
file=$(realpath "$file")
# Use grep to directly get the desired formatted output
local matches=$(grep -nH -- "$search_term" "$file")
# Check if no matches were found
if [ -z "$matches" ]; then
echo "No matches found for \"$search_term\" in $file"
return
fi
# Calculate total number of matches
local num_matches=$(echo "$matches" | wc -l | awk '{$1=$1; print $0}')
# calculate total number of lines matched
local num_lines=$(echo "$matches" | cut -d: -f1 | sort | uniq | wc -l | awk '{$1=$1; print $0}')
# if num_lines is > 100, print an error
if [ $num_lines -gt 100 ]; then
echo "More than $num_lines lines matched for \"$search_term\" in $file. Please narrow your search."
return
fi
# Print the total number of matches and the matches themselves
echo "Found $num_matches matches for \"$search_term\" in $file:"
echo "$matches" | cut -d: -f1-2 | sort -u -t: -k2,2n | while IFS=: read -r filename line_number; do
echo "Line $line_number:$(sed -n "${line_number}p" "$file")"
done
echo "End of matches for \"$search_term\" in $file"
}
# @yaml
# signature: find_file <file_name> [<dir>]
# docstring: finds all files with the given name in dir. If dir is not provided, searches in the current directory
# arguments:
# file_name:
# type: string
# description: the name of the file to search for
# required: true
# dir:
# type: string
# description: the directory to search in (if not provided, searches in the current directory)
# required: false
find_file() {
if [ $# -eq 1 ]; then
local file_name="$1"
local dir="./"
elif [ $# -eq 2 ]; then
local file_name="$1"
if [ -d "$2" ]; then
local dir="$2"
else
echo "Directory $2 not found"
return
fi
else
echo "Usage: find_file <file_name> [<dir>]"
return
fi
dir=$(realpath "$dir")
local matches=$(find "$dir" -type f -name "$file_name")
# if no matches, return
if [ -z "$matches" ]; then
echo "No matches found for \"$file_name\" in $dir"
return
fi
# Calculate total number of matches
local num_matches=$(echo "$matches" | wc -l | awk '{$1=$1; print $0}')
echo "Found $num_matches matches for \"$file_name\" in $dir:"
echo "$matches" | awk '{print $0}'
}

View File

@ -1,19 +0,0 @@
#!/bin/bash
export PIP_CACHE_DIR=$HOME/.cache/pip
pip install flake8
# Cursor Mode from SWE-Bench
# https://github.com/princeton-nlp/SWE-agent/blob/ca54d5556b9db4f4f2be21f09530ce69a72c0305/config/configs/default_sys-env_cursors_window100-detailed_cmd_format-last_5_history-1_demos.yaml#L108-L111
echo 'source /opendevin/plugins/swe_agent_commands/_setup_cursor_mode_env.sh' >> ~/.bashrc
# make _split_string (py) available
echo 'export PATH=$PATH:/opendevin/plugins/swe_agent_commands' >> ~/.bashrc
echo 'source /opendevin/plugins/swe_agent_commands/cursors_defaults.sh' >> ~/.bashrc
echo 'source /opendevin/plugins/swe_agent_commands/cursors_edit_linting.sh' >> ~/.bashrc
echo 'source /opendevin/plugins/swe_agent_commands/search.sh' >> ~/.bashrc
echo 'export SWE_CMD_WORK_DIR="/opendevin/plugins/swe_agent_commands/workdir"' >> ~/.bashrc
sudo mkdir -p /opendevin/plugins/swe_agent_commands/workdir
sudo chmod 777 /opendevin/plugins/swe_agent_commands/workdir

View File

@ -1,19 +0,0 @@
#!/bin/bash
export PIP_CACHE_DIR=$HOME/.cache/pip
pip install flake8
# Default Mode from SWE-Bench
# https://github.com/princeton-nlp/SWE-agent/blob/ca54d5556b9db4f4f2be21f09530ce69a72c0305/config/configs/default_sys-env_window100-detailed_cmd_format-last_5_history-1_demos.yaml#L103-L106
echo 'source /opendevin/plugins/swe_agent_commands/_setup_default_env.sh' >> ~/.bashrc
# make _split_string (py) available
echo 'export PATH=$PATH:/opendevin/plugins/swe_agent_commands' >> ~/.bashrc
echo 'source /opendevin/plugins/swe_agent_commands/defaults.sh' >> ~/.bashrc
echo 'source /opendevin/plugins/swe_agent_commands/search.sh' >> ~/.bashrc
echo 'source /opendevin/plugins/swe_agent_commands/edit_linting.sh' >> ~/.bashrc
echo 'export SWE_CMD_WORK_DIR="/opendevin/plugins/swe_agent_commands/workdir"' >> ~/.bashrc
sudo mkdir -p /opendevin/plugins/swe_agent_commands/workdir
sudo chmod 777 /opendevin/plugins/swe_agent_commands/workdir

View File

@ -3,10 +3,9 @@ from abc import ABC, abstractmethod
from opendevin.core.config import SandboxConfig
from opendevin.core.schema import CancellableStream
from opendevin.runtime.plugins.mixin import PluginMixin
class Sandbox(ABC, PluginMixin):
class Sandbox(ABC):
_env: dict[str, str] = {}
is_initial_session: bool = True