Feat: add lint frontend and lint all to Makefile. (#1354)

* Feat: add lint frontend and lint all to Makefile.

* style codes.

* Remove redundant target.

---------

Co-authored-by: Jim Su <jimsu@protonmail.com>
Co-authored-by: Robert Brennan <accounts@rbren.io>
This commit is contained in:
Leo 2024-05-02 19:53:57 +08:00 committed by GitHub
parent 836864fa88
commit 95e4ca490f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 86 additions and 31 deletions

View File

@ -148,10 +148,18 @@ install-precommit-hooks:
@poetry run pre-commit install --config $(PRECOMMIT_CONFIG_PATH)
@echo "$(GREEN)Pre-commit hooks installed successfully.$(RESET)"
lint:
lint-backend:
@echo "$(YELLOW)Running linters...$(RESET)"
@poetry run pre-commit run --files $$(git diff --name-only $$(git merge-base main $$(git branch --show-current)) $$(git branch --show-current) | tr '\n' ' ') --show-diff-on-failure --config $(PRECOMMIT_CONFIG_PATH)
lint-frontend:
@echo "$(YELLOW)Running linters for frontend...$(RESET)"
@cd frontend && npm run lint
lint:
@$(MAKE) -s lint-frontend
@$(MAKE) -s lint-backend
build-frontend:
@echo "$(YELLOW)Building frontend...$(RESET)"
@cd frontend && npm run build

View File

@ -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

View File

@ -43,7 +43,7 @@
"preview": "vite preview",
"make-i18n": "node scripts/make-i18n-translations.cjs",
"prelint": "npm run make-i18n",
"lint": "eslint src/**/*.ts* && prettier --check src/**/*.ts*",
"lint": "eslint src --ext .ts,.tsx,.js && prettier --check src/**/*.{ts,tsx}",
"prepare": "cd .. && husky install frontend/.husky"
},
"husky": {
@ -52,7 +52,7 @@
}
},
"lint-staged": {
"src/**/*.ts*": [
"src/**/*.{ts,tsx,js}": [
"eslint --fix",
"prettier --write"
]

View File

@ -20,28 +20,22 @@ class ActionManager:
sandbox: Sandbox
def __init__(
self,
sid: str,
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}')

View File

@ -55,12 +55,20 @@ class AgentController:
def __init__(
self,
agent: Agent,
inputs: dict = {},
sid: str = 'default',
max_iterations: int = MAX_ITERATIONS,
max_chars: int = MAX_CHARS,
callbacks: List[Callable] = [],
):
"""Initializes a new instance of the AgentController class.
Args:
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.
"""
self.id = sid
self.agent = agent
self.max_iterations = max_iterations
@ -73,8 +81,12 @@ class AgentController:
self.browser = BrowserEnv()
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()
@ -119,7 +131,10 @@ class AgentController:
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
@ -139,14 +154,15 @@ class AgentController:
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))
@ -203,14 +219,19 @@ class AgentController:
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:
@ -312,22 +333,33 @@ class AgentController:
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')

View File

@ -4,9 +4,10 @@ from dataclasses import dataclass
@dataclass
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 shoulds be relative to the `sandbox_dest` path
# NOTE: bash_script_path should be relative to the `sandbox_dest` path
bash_script_path: str