Skip to content

Feat: Replay saving functionality added and readme polished.#618

Open
Sameersribot wants to merge 3 commits intonottelabs:mainfrom
Sameersribot:test
Open

Feat: Replay saving functionality added and readme polished.#618
Sameersribot wants to merge 3 commits intonottelabs:mainfrom
Sameersribot:test

Conversation

@Sameersribot
Copy link
Copy Markdown

@Sameersribot Sameersribot commented Nov 9, 2025

🆕 Feature: Replay Saving Functionality Added
Summary

This merge adds support for saving session replays as WebP animations directly through the Session class.
A new argument save_replay_to has been introduced to automatically save the replay when a session ends.
The README has also been refined for clarity and developer guidance.

save_replay_to defines the output path (must end with .webp).
When the session finishes, its entire trajectory (screenshots + actions) is automatically saved to the given file.
If the directory doesn’t exist, it will be created automatically.

Impact

Simplifies recording and debugging of interactive sessions.
Allows developers to store visual replays for sharing, analysis, or QA workflows.

Summary by CodeRabbit

  • Documentation

    • Updated setup guide with required LLM provider configuration steps
    • Clarified SDK switching instructions to enable premium features and hosted browser sessions
  • New Features

    • Implemented session replay recording capability with WebP export
    • Added visual execution highlights showing element interactions during execution
    • Included example demonstrating interactive overlay functionality

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Nov 9, 2025

Walkthrough

This pull request adds replay and execution highlighting features to the Notte browser automation library. The changes introduce three class-level constants and three new methods to NotteSession: a public save_replay() method for persisting sessions as WebP files, and private methods for managing replay persistence and rendering visual highlights during action execution. An example script demonstrates the new replay functionality with local package bootstrapping, and documentation is updated to reflect SDK import changes and environment setup requirements. A minor comment typo is also corrected in tests.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–25 minutes

  • packages/notte-browser/src/notte_browser/session.py: Review the _flash_execution_highlight() method for DOM manipulation correctness, animation timing logic, and error handling; validate integration point in _aexecute_impl for proper call ordering; verify save_replay() and _save_replay_if_requested() file handling and path management.
  • tests/examples/Interaction-overlay.py: Examine the _bootstrap_local_packages() bootstrapping logic for robustness and module reloading correctness; validate integration with actual local packages.
  • Class-level constants: Ensure EXECUTION_HIGHLIGHT_DURATION_MS, EXECUTION_HIGHLIGHT_FADE_MS, and EXECUTION_HIGHLIGHT_PADDING values are appropriate and documented.
  • Constructor parameter: Confirm save_replay_to parameter type handling (string vs. Path) and default behavior.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the two main changes in this PR: adding replay saving functionality and polishing the README documentation.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/examples/Interaction-overlay.py (1)

7-7: Add space after # in comments.

Python style guidelines recommend a space after # in comments for better readability.

Apply this diff:

-#There was a clash with the local session.py file and the virtual env file 
+# There was a clash with the local session.py file and the virtual env file 

And:

-    #Use save_replay_to in Session method to save the screenshots WebP file at the specified location.
+    # Use save_replay_to in Session method to save the screenshots WebP file at the specified location.

Also applies to: 48-48

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 2ff8069 and dc2218c.

📒 Files selected for processing (4)
  • README.md (2 hunks)
  • packages/notte-browser/src/notte_browser/session.py (7 hunks)
  • tests/examples/Interaction-overlay.py (1 hunks)
  • tests/integration/sdk/test_steps.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.14.3)
tests/examples/Interaction-overlay.py

51-51: Local variable response is assigned to but never used

Remove assignment to unused variable response

(F841)

packages/notte-browser/src/notte_browser/session.py

252-252: Do not catch blind exception: Exception

(BLE001)


402-402: Do not catch blind exception: Exception

(BLE001)


488-488: Do not catch blind exception: Exception

(BLE001)

🔇 Additional comments (11)
tests/integration/sdk/test_steps.py (1)

45-45: LGTM! Typo corrected.

The comment typo has been fixed appropriately.

README.md (2)

58-59: LGTM! Helpful setup guidance added.

The preface note about .env.example will help users configure their environment correctly before running examples.


75-75: LGTM! SDK switch instruction clarified.

The updated wording ("replace the notte import with notte_sdk") is clearer and more accurate than the previous "import prefix" phrasing.

tests/examples/Interaction-overlay.py (1)

9-41: LGTM! Bootstrap logic enables local development workflow.

The bootstrap function correctly prioritizes local package sources over virtualenv installations by manipulating sys.path and clearing cached modules. This is a useful pattern for testing local changes.

packages/notte-browser/src/notte_browser/session.py (7)

77-79: LGTM! Well-defined execution highlight constants.

The class-level constants provide clear configuration for the visual highlight feature with reasonable default values.


92-92: LGTM! Replay save path parameter added correctly.

The save_replay_to parameter is properly typed, documented through the PR context, and safely converted to a Path object when provided.

Also applies to: 114-114


160-163: LGTM! Safer teardown pattern with replay persistence.

Using a local variable for the window reference before closing is a defensive practice. The replay save happens after window closure, ensuring all trajectory data is captured.


227-242: LGTM! Well-implemented replay persistence.

The method has a clear docstring, automatically creates parent directories, and returns the saved path for confirmation.


244-254: LGTM! Robust error handling for best-effort replay saving.

The method appropriately catches specific ValueError for empty trajectories and uses a broad exception handler for unexpected failures during the optional replay save. The logging provides useful feedback without disrupting the session close flow.


392-504: LGTM! Comprehensive visual highlight implementation.

The method is well-structured with:

  • Early returns for non-applicable cases (lines 393-399)
  • Robust error handling for element location and evaluation (lines 400-409, 488-495)
  • Defensive sleep cap using min() (line 498)
  • Clean JavaScript overlay with proper lifecycle management (scroll, render, fade, cleanup)

The broad exception handlers at lines 402 and 488 are appropriate for this non-critical visual feature, ensuring execution continues even if highlighting fails.


560-560: LGTM! Highlight integrated at the right execution point.

Calling _flash_execution_highlight immediately after action resolution ensures the visual feedback appears before the action executes, which is the correct user experience.

Comment on lines +46 to +54
def main() -> None:
load_dotenv()
#Use save_replay_to in Session method to save the screenshots WebP file at the specified location.
with notte.Session(headless=False, save_replay_to=r".\replays\rp.webp") as session:
agent = notte.Agent(session=session, reasoning_model="gemini/gemini-2.5-flash", max_steps=30)
response = agent.run(task="go to google and search for plujss and select the second dropdown suggestion")

if __name__ == "__main__":
main()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove unused variable assignment.

The response variable is assigned but never used. Either utilize it or remove the assignment to clean up the code.

Apply this diff to remove the unused assignment:

-        response = agent.run(task="go to google and search for plujss and select the second dropdown suggestion")
+        _ = agent.run(task="go to google and search for plujss and select the second dropdown suggestion")
🧰 Tools
🪛 Ruff (0.14.3)

51-51: Local variable response is assigned to but never used

Remove assignment to unused variable response

(F841)

🤖 Prompt for AI Agents
In tests/examples/Interaction-overlay.py around lines 46 to 54, the local
variable `response` is assigned the result of `agent.run(...)` but never used;
remove the unused assignment or make use of the returned value. Fix by either
deleting the `response =` assignment and calling `agent.run(...)` directly, or
replace it with a short use (for example logging/printing or passing it to an
assertion) so the value is consumed.

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