Skip to content

Commit

Permalink
Lint modified files.
Browse files Browse the repository at this point in the history
Signed-off-by: ifuryst <[email protected]>
  • Loading branch information
iFurySt committed May 2, 2024
1 parent c22c237 commit 0623601
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 26 deletions.
20 changes: 20 additions & 0 deletions docs/modules/python/opendevin/controller/agent_controller.md
Expand Up @@ -9,6 +9,26 @@ title: opendevin.controller.agent_controller
class AgentController()
```

#### \_\_init\_\_

```python
def __init__(agent: Agent,
sid: str = 'default',
max_iterations: int = MAX_ITERATIONS,
max_chars: int = MAX_CHARS,
callbacks: List[Callable] = [])
```

Initializes a new instance of the AgentController class.

**Arguments**:

- `agent` - The agent instance to control.
- `sid` - The session ID of the agent.
- `max_iterations` - The maximum number of iterations the agent can run.
- `max_chars` - The maximum number of characters the agent can output.
- `callbacks` - A list of callback functions to run after each action.

#### setup\_task

```python
Expand Down
18 changes: 6 additions & 12 deletions opendevin/controller/action_manager.py
Expand Up @@ -20,28 +20,22 @@ class ActionManager:
sandbox: Sandbox

def __init__(
self,
sid: str = 'default',
self,
sid: str = 'default',
):
sandbox_type = config.get(ConfigType.SANDBOX_TYPE).lower()
if sandbox_type == 'exec':
self.sandbox = DockerExecBox(
sid=(sid or 'default'),
timeout=config.get(ConfigType.SANDBOX_TIMEOUT)
sid=(sid or 'default'), timeout=config.get(ConfigType.SANDBOX_TIMEOUT)
)
elif sandbox_type == 'local':
self.sandbox = LocalBox(
timeout=config.get(ConfigType.SANDBOX_TIMEOUT)
)
self.sandbox = LocalBox(timeout=config.get(ConfigType.SANDBOX_TIMEOUT))
elif sandbox_type == 'ssh':
self.sandbox = DockerSSHBox(
sid=(sid or 'default'),
timeout=config.get(ConfigType.SANDBOX_TIMEOUT)
sid=(sid or 'default'), timeout=config.get(ConfigType.SANDBOX_TIMEOUT)
)
elif sandbox_type == 'e2b':
self.sandbox = E2BBox(
timeout=config.get(ConfigType.SANDBOX_TIMEOUT)
)
self.sandbox = E2BBox(timeout=config.get(ConfigType.SANDBOX_TIMEOUT))
else:
raise ValueError(f'Invalid sandbox type: {sandbox_type}')

Expand Down
52 changes: 38 additions & 14 deletions opendevin/controller/agent_controller.py
Expand Up @@ -76,8 +76,12 @@ def __init__(
# 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.')
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()

Expand Down Expand Up @@ -122,7 +126,10 @@ async def _run(self):
except Exception:
logger.error('Error in loop', exc_info=True)
await self._run_callbacks(
AgentErrorObservation('Oops! Something went wrong while completing your task. You can check the logs for more info.'))
AgentErrorObservation(
'Oops! Something went wrong while completing your task. You can check the logs for more info.'
)
)
await self.set_task_state_to(TaskState.STOPPED)
break

Expand All @@ -142,14 +149,15 @@ async def _run(self):

if self._is_stuck():
logger.info('Loop detected, stopping task')
observation = AgentErrorObservation('I got stuck into a loop, the task has stopped.')
observation = AgentErrorObservation(
'I got stuck into a loop, the task has stopped.'
)
await self._run_callbacks(observation)
await self.set_task_state_to(TaskState.STOPPED)
break

async def setup_task(self, task: str, inputs: dict = {}):
"""Sets up the agent controller with a task.
"""
"""Sets up the agent controller with a task."""
self._task_state = TaskState.RUNNING
await self.notify_task_state_changed()
self.state = State(Plan(task))
Expand Down Expand Up @@ -206,14 +214,19 @@ async def add_user_message(self, message: UserMessageObservation):
self.add_history(NullAction(), message)

else:
raise ValueError(f'Task (state: {self._task_state}) is not in a state to add user message')
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'})
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:
Expand Down Expand Up @@ -315,22 +328,33 @@ def get_state(self):
return self.state

def _is_stuck(self):
if self.state is None or self.state.history is None or len(self.state.history) < 3:
if (
self.state is None
or self.state.history is None
or len(self.state.history) < 3
):
return False

# if the last three (Action, Observation) tuples are too repetitive
# the agent got stuck in a loop
if all(
[self.state.history[-i][0] == self.state.history[-3][0] for i in range(1, 3)]
[
self.state.history[-i][0] == self.state.history[-3][0]
for i in range(1, 3)
]
):
# it repeats same action, give it a chance, but not if:
if (all
(isinstance(self.state.history[-i][1], NullObservation) for i in range(1, 4))):
if all(
isinstance(self.state.history[-i][1], NullObservation)
for i in range(1, 4)
):
# same (Action, NullObservation): like 'think' the same thought over and over
logger.debug('Action, NullObservation loop detected')
return True
elif (all
(isinstance(self.state.history[-i][1], AgentErrorObservation) for i in range(1, 4))):
elif all(
isinstance(self.state.history[-i][1], AgentErrorObservation)
for i in range(1, 4)
):
# (NullAction, AgentErrorObservation): errors coming from an exception
# (Action, AgentErrorObservation): the same action getting an error, even if not necessarily the same error
logger.debug('Action, AgentErrorObservation loop detected')
Expand Down
1 change: 1 addition & 0 deletions opendevin/sandbox/plugins/requirement.py
Expand Up @@ -4,6 +4,7 @@
@dataclass
class PluginRequirement:
"""Requirement for a plugin."""

name: str
# FOLDER/FILES to be copied to the sandbox
host_src: str
Expand Down

0 comments on commit 0623601

Please sign in to comment.