feat: Replace terminal dangerous-command block with HITL approval and add Safe Mode in Settings#1310
Conversation
|
@bytecii @Wendong-Fan Could you please review my PR? |
bytecii
left a comment
There was a problem hiding this comment.
IMO we can move this to camel to make a special safe mode such as strict. cc @Wendong-Fan
thanks @bytecii , the idea behind this issue is to implement a human-in-the-loop mechanism for safer code execution, which would involve the HumanToolkit. Since CAMEL serves more as a modular framework, it might be more appropriate to implement this feature in Eigent as an application layer. What do you think? |
|
@Wendong-Fan @bytecii could you please review this pr? Regards |
- Move HitlOptions and ApprovalRequest models from chat.py to app/hitl/__init__.py - Remove unnecessary hasattr guard on auto_approve (always initialized) - Remove issue reference comment and docstring comments - Update all imports across controllers, services, and tests
- Move _request_user_approval from AbstractToolkit to TerminalToolkit (only terminal uses approval today) - Remove debug print statements from shell_exec - Move import time to top-level in terminal_toolkit - Fix approval endpoint docstring - Remove module docstring from terminal_command.py - Add comment for effective executable check - Update test to subclass TerminalToolkit directly
| options.project_id, | ||
| Agents.browser_agent, | ||
| working_directory=working_directory, | ||
| safe_mode=True, |
There was a problem hiding this comment.
remove this as this is not configured. And by default if the HITL not specified, we still use the safe_mode=True for the terminaltoolkit
| return None | ||
| return "Operation rejected by user. The task is being stopped." | ||
|
|
||
| async def shell_exec( |
- Remove unused logger from abstract_toolkit - Move _thread_local from AbstractToolkit to TerminalToolkit - Add missing threading.local() definition - Add Args/Returns to terminal_command.py functions - Use ApprovalAction.reject enum instead of raw string - Fix ApprovalAction and ActionCommandApprovalData docstrings - Add comment for auto_approve reset at task start
| # the HITL approval flow (Camel's upstream shell_exec is | ||
| # sync-only with no async variant available). | ||
| if wrap is not func: | ||
| async_wrapper.__wrapped__ = func |
There was a problem hiding this comment.
Need someone helps to take a look at this
_get_terminal_approval() now reads from task_lock every call instead of caching in __init__, so toggling the setting between tasks takes effect immediately. SupplementChat carries hitl_options to the improve endpoint, and the localStorage key is extracted to a shared constant.
|
Update the PR including backend and ui redesign
tested with and without terminal approval in the HITL + approval / auto approval / reject with & without dark mode |
…L approvals - Replace approval_input Queue with pending_approvals dict of asyncio.Future - Each _request_user_approval call gets a unique approval_id (agent_hex), so concurrent commands from the same agent no longer compete for one slot - Fix str,Enum f-string bug: use concatenation so Agents.developer_agent produces "developer_agent_..." not "Agents.developer_agent_..." - Frontend: replace activeApproval single slot with approvalQueue[] array; pushApproval/shiftApproval/clearAllApprovals manage the queue - Controller routes approve_once by approval_id, auto_approve/reject by agent - Add design comments to resolve_approval and resolve_all_approvals_for_agent - Update all tests; add concurrent same-agent and Enum regression tests
…cstrings and comments
| async def _request_user_approval(self, action_data) -> str | None: | ||
| """Send a command approval request to the frontend and wait. | ||
|
|
||
| Flow:: |


Related issue
Closes #1306
Summary
Replaces the Terminal Toolkit’s hard block of “dangerous” commands with a Human-in-the-Loop (HITL) approval flow and adds a Safe Mode setting so users can opt in.
Changes
HITL for dangerous commands
/chat/{id}/terminal-approvalwith the chosen option; backend enforces approval before running the command and supports “approve all in task” per task.Safe Mode in Settings
“With Safe Mode active, Eigent will pause and seek explicit approval whenever high-risk system operations are detected.”
Backend
sudo,su,reboot,shutdown), file (e.g.rm,chown,mount), disk (e.g.dd,mkfs,fdisk), process (e.g.service,systemctl), network (e.g.iptables,ifconfig), cron (e.g.crontab,at), user/kernel (e.g.useradd,modprobe), and related commands as specified.cdis validated so the agent cannot leave the designatedworking_directory.approved_all_dangerous_commandsand a queue for terminal approval; reset on new task.Frontend
localStorageand sent assafe_modein the start-task request.Other
uvis not installed so commits succeed withoutuv(message suggests installing uv for backend checks).Testing
cdoutsideworking_directoryin non-Docker mode is rejected.