Skip to content

feat(yolo-mode): add YOLO support to web interface#1767

Open
lucaspdude wants to merge 27 commits intoMoonshotAI:mainfrom
lucaspdude:feat/yolo-mode-web
Open

feat(yolo-mode): add YOLO support to web interface#1767
lucaspdude wants to merge 27 commits intoMoonshotAI:mainfrom
lucaspdude:feat/yolo-mode-web

Conversation

@lucaspdude
Copy link
Copy Markdown

@lucaspdude lucaspdude commented Apr 5, 2026

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

  • API: Add GET /api/sessions/{id}/yolo and POST /api/sessions/{id}/yolo endpoints in web/a pi/sessions.py
  • Models: Add YoloStatus and UpdateYoloRequest Pydantic models in web/models.py
  • Wire Protocol: Add set_yolo_mode JSON-RPC method and include yolo_mode in StatusUpdate
    messages
  • Session State: Track YOLO mode state in session_state.py and propagate through KimiSoul
  • Web Runner: Handle YOLO mode in process communication (web/runner/process.py)

Frontend Changes

  • Hook: Add useYoloMode hook for state management and server synchronization
  • UI: Add YOLO mode toggle button in global config controls (global-config-controls.tsx)
  • Composer: Display yellow dashed border on the input composer when YOLO mode is active

Documentation

  • Update English and Chinese Web UI reference docs to document the YOLO mode toggle feature

Tests

  • Add unit tests for YOLO mode wire protocol handling
  • Update E2E tests to cover YOLO mode endpoints and state synchronization

Checklist

  • I have read the [CONTRIBUTING](https://github.com/MoonshotAI/kimi-cli/blob/main/CONTRIBUTING.
    md) document.
  • I have linked the related issue, if any.
  • I have added tests that prove my fix is effective or that my feature works.
  • I have run make gen-changelog to update the changelog.
  • I have run make gen-docs to update the user documentation.

Open with Devin

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
chatgpt-codex-connector[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

lucaspdude and others added 3 commits April 5, 2026 16:03
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
chatgpt-codex-connector[bot]

This comment was marked as resolved.

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.
chatgpt-codex-connector[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

…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
chatgpt-codex-connector[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

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
chatgpt-codex-connector[bot]

This comment was marked as resolved.

…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
lucaspdude and others added 6 commits April 7, 2026 22:16
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
devin-ai-integration[bot]

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

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.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +923 to +925
else:
# Only save directly to disk when the worker is not alive
save_session_state(state, session_dir)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +1762 to +1765
const nextYoloMode = event.payload.yolo_mode;
if (typeof nextYoloMode === "boolean") {
hasReceivedLiveYoloUpdateRef.current = true;
setYoloMode(nextYoloMode);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant