Skip to content

feat(ai): let Bob edit other pages and create new ones - #1083

Open
surajshetty3416 wants to merge 4 commits into
frappe:developfrom
surajshetty3416:feat/bob-multi-page-edits
Open

surajshetty3416 wants to merge 4 commits into
frappe:developfrom
surajshetty3416:feat/bob-multi-page-edits

Conversation

@surajshetty3416

@surajshetty3416 surajshetty3416 commented Nov 13, 2026 •

Copy link
Copy Markdown
Member

Summary

Bob could only change the page open in the editor. Now it can change the site's other pages and propose new ones. Nothing outside the open page lands until the user confirms, and the chat follows the user to the pages it changed.

turn on Home
  edit_page(ops)                     applies live, as before
  edit_page(page="about", ops)       checked against About, held
  create_page(title, route, brief)   held
  end of turn                        reply, then one card: a row per page, ticked, its changes folded under a count

Apply (the ticked rows)
  create the new pages, then replay each held edit on the page as it is now
    a page that fails (its block is gone, another AI turn holds it, no permission) is left alone; the rest apply
  the card shows how each page came out, and the pages it changed now list this chat
  build each new page in its own turn: one line in this chat, canvas events go only to that page
builder/ai/agent/page_changes.py              holds other-page edits and new pages; applies the ticked rows of a card
builder/ai/agent/tools/pages.py               create_page
builder/ai/agent/loop.py                      edit_page(page=…), the end-of-turn card, off-screen build turns
builder/ai/api.py                             confirm_page_changes, queue_page_build
builder/ai/session.py                         the pages a chat is on, and which page each message came from
frontend/src/components/ai/AIPageCard.vue     the card, before and after it is answered
frontend/src/components/ai/AIPageBuild.vue    the one line for a page built off-screen

A held edit is checked inside a savepoint that is rolled back, so checking never writes. Apply replays the checked ops rather than the markup, so blocks Bob added keep their ids and later edits to them still land.

A chat across pages. A chat used to belong to the page it started on, so opening a page Bob had just changed showed an empty panel. A chat now records every page it was used on or changed (child table Builder AI Session Page) and shows in the chat list of each. Opening a page from the chat carries the chat there. Each user message keeps the page it was sent from, shown as a chip and given to the model as "Sent from the page …". Lovable, v0, Bolt, Replit, Copilot and Claude Code all scope a conversation to the project and attach the open file to each message; this does the same within Builder's per-page chat list.

Also fixed: Builder's dark-mode .bg-surface-base override (index.css) painted over the fill of a ticked checkbox, so every ticked frappe-ui Checkbox looked empty in dark mode.

Evidence

  • Before: the prompt told Bob "You cannot create, open, or edit other pages", so it refused.
    After: driven in the editor against a scripted model that renames the studio on 12 pages and proposes a Careers page:
Card for 12 pages, two left out Careers building, one line After apply, on reload Opened About from the card

builder/ai/test_page_changes.py covers checking, replay on a changed page, per-page failures, the card, Apply and Skip, and the build hand-off. Not yet tried with a real model.

Merge Danger

Door: two-way

One new child DocType, Builder AI Session Page, which migrate creates; no patch. Existing chats keep working through their page. Held changes live in the card message's metadata, and every applied page gets an AI snapshot to restore from.

Blast Radius: Bob, and checkboxes in dark mode

The system prompt no longer says Bob works on one page, and create_page plus edit_page.page add schema tokens to every round. Reads of other pages now print short refs, and the per-turn page-read cap goes from 3 to 6. A chat's page now moves to the page it was last used from, and deleting a page drops it from other chats' page lists. An editor that has the target page open in another tab picks up the change only if its Bob panel has been opened; otherwise its autosave can still write its older copy back. The index.css change reaches every ticked checkbox in dark mode.

Bob could only change the page open in the editor. Now edit_page takes a
`page`: an edit to another page is checked against that page right away,
held, and shown with any new page Bob proposes (create_page) on one confirm
card when the turn ends. Apply replays the checked edits on each page as it
is then, page by page, and builds each approved new page in a turn of its
own that never touches the open canvas.

Co-Authored-By: Claude <noreply@anthropic.com>
@mergify

mergify Bot commented Nov 13, 2026

Copy link
Copy Markdown
Contributor

Tick the box to add this pull request to the merge queue (same as @mergifyio queue). If it does not match the queue conditions yet, it enters the queue once it does.

  • Queue this pull request

@codecov

codecov Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.42%. Comparing base (86b6975) to head (01b4f0f).

Additional details and impacted files
@@           Coverage Diff            @@
##           develop    #1083   +/-   ##
========================================
  Coverage    81.42%   81.42%           
========================================
  Files           70       70           
  Lines         7541     7542    +1     
========================================
+ Hits          6140     6141    +1     
  Misses        1401     1401           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

surajshetty3416 and others added 3 commits November 13, 2026 11:09
Semgrep's string-concat-in-list rule flagged the implicitly joined
f-strings inside the list literal.

Co-Authored-By: Claude <noreply@anthropic.com>
The confirm card listed every change line for every page with an Open
button per row, and an applied card was repeated by a second result list
with Open buttons of its own. The card now asks one question, gives each
page a single row with a tick to leave it out and its changes folded
under a count, folds past six pages, and once answered shows how each
page came out in place. Page names are links.

A page Bob builds off-screen is one line that moves with the build
("Building Careers, Section 2: Open roles") and ends as "Built Careers",
with its steps and summary behind a chevron. Edits held for several
pages read as one step, and reading a skill names the skill.

A chat was tied to the page it started on, so opening a page Bob had
changed showed an empty panel. A chat now records each page it was used
on or changed (Builder AI Session Page) and shows on all of them;
opening a page from the chat carries the chat there, and each message
keeps the page it was sent from, shown as a chip and given to the model.

Builder's dark-mode surface-base override also painted over the fill of
a ticked checkbox, so every ticked frappe-ui Checkbox looked empty.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
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