Skip to content

feat: auto-save in code-mode and marimo-pair#9191

Merged
mscolnick merged 4 commits intomainfrom
ms/code-mode-auto-save
Apr 16, 2026
Merged

feat: auto-save in code-mode and marimo-pair#9191
mscolnick merged 4 commits intomainfrom
ms/code-mode-auto-save

Conversation

@mscolnick
Copy link
Copy Markdown
Contributor

@mscolnick mscolnick commented Apr 14, 2026

Agent mutations via code_mode / marimo-pair emit kernel document transactions but never hit disk. NotificationListenerExtension now intercepts kernel-sourced transactions and triggers a best-effort save; run mode and unnamed notebooks are skipped, and failures surface as an AlertNotification toast instead of raising.

  • New SerialTaskRunner FIFO-dispatches the blocking save off the event loop so a slow older save can't clobber a newer one, and routes on_error back to the loop thread.
  • AppFileManager gains save_from_cells(cells) plus a reentrant _save_lock serializing every public writer.
  • generate_filecontents normalizes empty cell names to DEFAULT_CELL_NAME (empty names emitted invalid def ():).

Note: the frontend still thinks the UI is not saved (because it was saved in the backend which is a new concept). I think this is ok for now, but something we can track in a follow.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
marimo-docs Ready Ready Preview, Comment Apr 15, 2026 8:32pm

Request Review

@mscolnick mscolnick added the enhancement New feature or request label Apr 15, 2026
@mscolnick mscolnick requested a review from manzt April 15, 2026 18:44
@mscolnick mscolnick marked this pull request as ready for review April 15, 2026 18:44
Copilot AI review requested due to automatic review settings April 15, 2026 18:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds backend-driven auto-save so kernel-sourced notebook document transactions (from code_mode / marimo-pair) persist to disk, aligning agent-driven edits with the existing frontend save behavior.

Changes:

  • Intercept kernel-sourced NotebookDocumentTransactionNotifications in NotificationListenerExtension and trigger best-effort autosave (skip run mode + unnamed notebooks; surface failures as an AlertNotification).
  • Introduce SerialTaskRunner to FIFO-dispatch blocking saves off the asyncio event loop and route on_error back to the loop thread.
  • Add AppFileManager.save_from_cells() plus a re-entrant write lock; normalize empty cell names during codegen to avoid generating invalid def ():.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
marimo/_session/extensions/extensions.py Intercepts kernel document transactions and schedules autosave + failure toast.
marimo/_utils/serial_task_runner.py New single-worker FIFO executor helper with loop-thread error routing.
marimo/_session/notebook/file_manager.py Adds save_from_cells() and serializes write paths under an RLock.
marimo/_ast/codegen.py Normalizes empty cell names to DEFAULT_CELL_NAME during file generation.
tests/_utils/test_serial_task_runner.py Unit tests for sync/async runner behavior, FIFO ordering, and shutdown semantics.
tests/_session/extensions/test_notification_listener_autosave.py Tests autosave behavior, skip conditions, and failure-to-toast behavior (incl. HTML escaping).
tests/_code_mode/test_context_autosave.py End-to-end tests from real code_mode mutations through interceptor to disk writes.
tests/_server/test_file_manager.py Tests save_from_cells() behavior and lock serialization under concurrent writes.

Comment thread marimo/_session/extensions/extensions.py Outdated
Comment thread marimo/_utils/serial_task_runner.py
Comment thread tests/_server/test_file_manager.py
Comment on lines +62 to +67
Offloads to the executor when called from the event loop;
otherwise runs inline on the caller thread (e.g. the
``QueueDistributor`` worker thread). ``on_error`` is invoked
with any exception raised by ``work`` — posted back to the event
loop when off-loop, inline otherwise. A failing ``on_error`` is
logged and swallowed.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

cool

Comment on lines +352 to +359
assert not t1.is_alive(), (
"frontend save thread did not terminate within 10s "
"(likely deadlock in AppFileManager write lock)"
)
assert not t2.is_alive(), (
"autosave thread did not terminate within 10s "
"(likely deadlock in AppFileManager write lock)"
)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

wierd copilot didn't see this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

those are old comments

persist=request.persist,
)

def save_from_cells(self, cells: Sequence[NotebookCell]) -> str:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm guessing we can improve our "save" paths overall in the future to derive from our NotebookDocument, for a followup.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yep, definitely

@mscolnick mscolnick merged commit d4ccc43 into main Apr 16, 2026
43 checks passed
@mscolnick mscolnick deleted the ms/code-mode-auto-save branch April 16, 2026 14:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants