feat(yolo-mode): add YOLO support to web interface#1767
feat(yolo-mode): add YOLO support to web interface#1767lucaspdude wants to merge 27 commits intoMoonshotAI:mainfrom
Conversation
Add ability to view and toggle YOLO mode from the web UI:
- Add GET/POST /api/sessions/{id}/yolo endpoints
- Add useYoloMode hook for state management
- Add YOLO mode toggle in global config controls
- Add YoloStatus and UpdateYoloRequest models
- Update wire protocol with set_yolo_mode JSON-RPC method
- Update StatusUpdate to include yolo_mode field
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com> Signed-off-by: Lucas Pacheco <lucaspdude@gmail.com>
Integrate useYoloMode hook into useSessionStream to fetch the initial YOLO mode state from the server API. This ensures the UI correctly reflects the default_yolo config setting when a session connects, instead of defaulting to false and waiting for a StatusUpdate event. Changes: - Import useYoloMode hook in useSessionStream.ts - Add yoloStatus fetching and sync to yoloMode state via useEffect
fix(web): initialize YOLO mode from server config on session connect
The separate useEffect that synced sessionIdRef.current was updating the ref BEFORE the load effect could compare them. This caused the guard condition to always be true after first mount, skipping refresh() on session switches and displaying stale YOLO data. Remove the ref-sync effect so the load effect can properly compare old vs new sessionId before deciding to fetch.
…nto feat/yolo-mode-web
…ditions Add AbortController to cancel in-flight fetch requests when sessionId changes. This prevents stale YOLO status from overwriting the correct state after a session switch. Changes: - Add abortControllerRef to track the current fetch - Pass signal to fetch call in refresh callback - Check for AbortError in catch block and skip state updates - Add cleanup function in useEffect to abort on session change/unmount
Add previousSessionIdRef to track the last connected session ID. Modify resetState to accept preserveYoloMode parameter. On reconnect to the same session, preserve YOLO mode state to avoid showing the toggle as OFF while approvals are still auto-approved. Changes: - Add previousSessionIdRef to track session changes - Update resetState signature to accept preserveYoloMode - Check if reconnecting to same session in connect() and preserve yoloMode
Only save session state to disk when the worker is NOT alive. When the worker IS alive, skip the disk save and let the worker handle persistence via its notify_change callback. This prevents the REST handler's save from overwriting concurrent worker changes to session state (title, plan mode, todos, etc.). Changes: - Move save_session_state inside else branch - Only save directly when session_process is None or not alive - When worker is alive, rely on set_yolo_mode -> worker persistence
…dates Add hasReceivedLiveYoloUpdateRef to track if we've received a live yolo_mode update from WebSocket. Only apply yoloStatus from HTTP fetch if no live update has been received yet. This prevents stale HTTP responses from overwriting newer real-time state when the user toggles YOLO quickly or another client toggles it. Changes: - Add hasReceivedLiveYoloUpdateRef to track live WebSocket updates - Guard yoloStatus sync useEffect to only apply before live updates - Set flag when StatusUpdate.yolo_mode is received from WebSocket - Reset flag in resetState when switching sessions
Add ability to view and toggle YOLO mode from the web UI:
- Add GET/POST /api/sessions/{id}/yolo endpoints
- Add useYoloMode hook for state management
- Add YOLO mode toggle in global config controls
- Add YoloStatus and UpdateYoloRequest models
- Update wire protocol with set_yolo_mode JSON-RPC method
- Update StatusUpdate to include yolo_mode field
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com> Signed-off-by: Lucas Pacheco <lucaspdude@gmail.com>
Integrate useYoloMode hook into useSessionStream to fetch the initial YOLO mode state from the server API. This ensures the UI correctly reflects the default_yolo config setting when a session connects, instead of defaulting to false and waiting for a StatusUpdate event. Changes: - Import useYoloMode hook in useSessionStream.ts - Add yoloStatus fetching and sync to yoloMode state via useEffect
The separate useEffect that synced sessionIdRef.current was updating the ref BEFORE the load effect could compare them. This caused the guard condition to always be true after first mount, skipping refresh() on session switches and displaying stale YOLO data. Remove the ref-sync effect so the load effect can properly compare old vs new sessionId before deciding to fetch.
…ditions Add AbortController to cancel in-flight fetch requests when sessionId changes. This prevents stale YOLO status from overwriting the correct state after a session switch. Changes: - Add abortControllerRef to track the current fetch - Pass signal to fetch call in refresh callback - Check for AbortError in catch block and skip state updates - Add cleanup function in useEffect to abort on session change/unmount
# Conflicts: # CHANGELOG.md # docs/en/release-notes/changelog.md # docs/zh/release-notes/changelog.md # src/kimi_cli/web/api/sessions.py # web/src/hooks/useSessionStream.ts
The useEffect that syncs initial YOLO mode state from the REST API had an empty body due to a merge conflict resolution error. Add the missing setYoloMode(yoloStatus.enabled) call so the toggle correctly reflects the server state on initial page load and session switch.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8c93973c05
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| else: | ||
| # Only save directly to disk when the worker is not alive | ||
| save_session_state(state, session_dir) |
There was a problem hiding this comment.
Persist stopped-session YOLO changes to wire history
When POST /api/sessions/{id}/yolo runs against a stopped session, this branch only writes session_state.json and does not append a StatusUpdate(yolo_mode=...) record to wire.jsonl. On the next reconnect, replay can emit an older YOLO status from prior history, and the web client treats replayed yolo_mode as a live update, so the toggle can show the wrong safety state until YOLO is toggled again. Please also persist a wire status event (or equivalent replay source of truth) in this path.
Useful? React with 👍 / 👎.
When POST /api/sessions/{id}/yolo runs against a stopped session,
append a StatusUpdate(yolo_mode=...) record to wire.jsonl in addition
to saving session_state.json. This ensures replay emits the correct
YOLO state on reconnect, preventing the toggle from showing stale
values until the next live update.
Add comprehensive tests for the YOLO mode REST API:
- GET /api/sessions/{id}/yolo endpoint tests
- POST /api/sessions/{id}/yolo endpoint tests
- Tests for stopped sessions (saves to disk and wire.jsonl)
- Tests for running sessions (notifies worker via set_yolo_mode)
- Wire replay tests to verify StatusUpdate records are persisted
- StatusUpdate serialization tests with yolo_mode field
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fb6fcf79d5
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const nextYoloMode = event.payload.yolo_mode; | ||
| if (typeof nextYoloMode === "boolean") { | ||
| hasReceivedLiveYoloUpdateRef.current = true; | ||
| setYoloMode(nextYoloMode); |
There was a problem hiding this comment.
Synchronize YOLO state after slash-command toggles
useSessionStream updates yoloMode only from StatusUpdate.yolo_mode, so any toggle path that does not emit that field leaves the UI stale. Fresh evidence for re-raising this class of issue: src/kimi_cli/soul/slash.py still flips YOLO in /yolo by calling approval.set_yolo(...) without emitting StatusUpdate(yolo_mode=...), which means the web toggle can continue showing the previous safety state (including OFF while approvals are actually auto-approved). Please ensure all YOLO mutation paths publish a yolo_mode status event (or trigger an explicit refresh) to keep the web indicator correct.
Useful? React with 👍 / 👎.
Related Issue
N/A - This is a follow-up feature to extend YOLO mode support to the Web UI.
Description
Add YOLO (auto-approve) mode support to the Web UI, allowing users to toggle automatic approval of
operations directly from the web interface.
Backend Changes
GET /api/sessions/{id}/yoloandPOST /api/sessions/{id}/yoloendpoints inweb/a pi/sessions.pyYoloStatusandUpdateYoloRequestPydantic models inweb/models.pyset_yolo_modeJSON-RPC method and includeyolo_modeinStatusUpdatemessages
session_state.pyand propagate throughKimiSoulweb/runner/process.py)Frontend Changes
useYoloModehook for state management and server synchronizationglobal-config-controls.tsx)Documentation
Tests
Checklist
md) document.
make gen-changelogto update the changelog.make gen-docsto update the user documentation.