playwright-python icon indicating copy to clipboard operation
playwright-python copied to clipboard

[Feature]: add snapshotForAI support

Open wangzhe0912 opened this issue 7 months ago • 18 comments

🚀 Feature Request

add snapshotForAI support. base Python version inplement PlayWright MCP Server。

Example

No response

Motivation

base Python version inplement PlayWright MCP Server。

wangzhe0912 avatar May 27 '25 12:05 wangzhe0912

Now many users use AI driving browser by playwright, add snapshotForAI in python version is important. I support this feature.

Fly-Playgroud avatar May 29 '25 09:05 Fly-Playgroud

What would snapshotForAI do?

neoncube2 avatar Jun 05 '25 05:06 neoncube2

https://github.com/microsoft/playwright/blob/bd5a23f88f3c54b6fd15ff1cde0693babfc86285/packages/protocol/src/channels.d.ts#L2095 The JS version of Playwright provides a snapshotForAI method, which converts a Page into a snapshot format. In this format, each page element is assigned a ref-id, enabling models to understand the page and perform actions based on the ref-id.

Currently, the Python version does not expose this method and only supports a snapshot method based on a specified locator. This method differs from snapshotForAI, as some elements (e.g., text elements) are not assigned a ref-id, making it unsuitable for AI to identify elements and perform intelligent operations.

wangzhe0912 avatar Jun 05 '25 06:06 wangzhe0912

Any updates on this? I have a use case not satisfied by the MCP so I'd like to use the python library directly, but I want to make use of snapshotForAI.

latifboubyan avatar Jun 10 '25 10:06 latifboubyan

@latifboubyan Could you give me some examples for mcp

changshuo08 avatar Jun 11 '25 06:06 changshuo08

Or exposing the forAI parameter in the ariaSnapshot method in the Node version would also work.

Attached is the ariaSnapshot definition from Node version 1.53:

ariaSnapshot:
  title: Aria snapshot
  parameters:
    selector: string
    forAI: boolean?
    timeout: number
  returns:
    snapshot: string
  flags:
    snapshot: true

https://github.com/microsoft/playwright/blob/main/packages/protocol/src/protocol.yml#L2108

wangzhe0912 avatar Jun 13 '25 08:06 wangzhe0912

I'd like to drive playwright using custom tools in my LLM agent. Being able to use snapshotForAI directly would be awesome instead of through playwright-mcp.

zia1138 avatar Jun 16 '25 02:06 zia1138

The Python Playwright 1.53.0 has been released. Can the for_ai parameter be added to the aria_snapshot method now?

wangzhe0912 avatar Jun 26 '25 00:06 wangzhe0912

The Python Playwright 1.53.0 has been released. Can the for_ai parameter be added to the aria_snapshot method now?

I have hacked this in Playwright-Python 1.53.0. It's ran prefectly. But I still hope offical support this.

Fly-Playgroud avatar Jun 26 '25 04:06 Fly-Playgroud

The Python Playwright 1.53.0 has been released. Can the for_ai parameter be added to the aria_snapshot method now?

I have hacked this in Playwright-Python 1.53.0. It's ran prefectly. But I still hope offical support this.

@Fly-Playground, how did you achieve this? Can you help me set it up the same?

HitSakhavala avatar Jul 01 '25 05:07 HitSakhavala

@Fly-Playgroud @HitSakhavala I assume the hack is via the channel, to send the aisnapshot command directly ?

Gby56 avatar Aug 14 '25 07:08 Gby56

await page._impl_obj._channel.send('snapshotForAI', None, {'timeout': 5000})

argszero avatar Aug 26 '25 06:08 argszero

For those who want to get the aria snapshot for a locator with refs (which is not possible via locator.aria_snapshot()):

await locator._impl_obj._frame._channel.send(
    "ariaSnapshot",
    locator._impl_obj._frame._timeout,
    {
        "selector": locator._impl_obj._selector,
        "timeout": 5000,
        "forAI": True,  # this param does the magic
    },
)

idiotWu avatar Aug 29 '25 03:08 idiotWu

Sharing another example in case it is helpful for others:

from playwright.async_api import async_playwright

URL = "https://www.businesswire.com/news/home/20250829814571/en/Merck-Provides-New-Results-for-VERQUVO-vericiguat-in-Patients-with-Chronic-Heart-Failure-and-Reduced-Ejection-Fraction"
async def grab_snapshot(url: str):
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()
        await page.goto(url, timeout=60000)

        snapshot = await page._impl_obj._channel.send(
            "snapshotForAI", None, {"timeout": 5000}
        )

        await browser.close()
        return snapshot
    
snapshot = await grab_snapshot(URL)

zia1138 avatar Oct 18 '25 18:10 zia1138

Sharing another example in case it is helpful for others:分享另一个例子,以防对其他人有帮助:

from playwright.async_api import async_playwright

URL = "https://www.businesswire.com/news/home/20250829814571/en/Merck-Provides-New-Results-for-VERQUVO-vericiguat-in-Patients-with-Chronic-Heart-Failure-and-Reduced-Ejection-Fraction" async def grab_snapshot(url: str): async with async_playwright() as p: browser = await p.chromium.launch(headless=False) page = await browser.new_page() await page.goto(url, timeout=60000)

    snapshot = await page._impl_obj._channel.send(
        "snapshotForAI", None, {"timeout": 5000}
    )

    await browser.close()
    return snapshot

snapshot = await grab_snapshot(URL)

Hi, I used your method and got a ref, but I don’t see any ref attribute on the actual page. How exactly can I use this ref to locate the element?

baijiu-in-my-cup avatar Oct 26 '25 16:10 baijiu-in-my-cup

@baijiu-in-my-cup Not 100 sure. I think you need to keep the session open and use the refs in the output snapshot. I think that's how the playwright MCP server does it, but I didn't explore this extensively.

zia1138 avatar Oct 26 '25 21:10 zia1138

@zia1138 Thanks♪(・ω・)ノ I'm all set now ! It turns out I made a mistake earlier,I thought it was a CSS-style selector, but it's actually a register selector. So I need to do is use locator(f"aria-ref={ref}"). Thank you to all the developers,amazing!

baijiu-in-my-cup avatar Oct 27 '25 10:10 baijiu-in-my-cup

Hello @mxschmitt 👋 I was thinking back on this ticket, I'm waiting on this to be officially supported in order to update my version of PW, is this planned any time soon?

If the complexity isn't too bad I could try to make a PR for it !

Gby56 avatar Dec 08 '25 08:12 Gby56