Your agent is paying to look at the screen. Twice.
More than half of the web is no longer people. Staying visible as yourself has quietly become a daily job — and every machine offering to help first has to look at the screen, which is where the bill starts.
More than half of the web is no longer people. Automated traffic passed 53% in 2025 — the seventh year in a row it has grown — and somewhere in that majority is a rack of second-hand phones with fifty screens and one operator.
The cost of that lands on a person. Staying visible as yourself now takes the kind of daily effort that used to be a job: the same message shaped five ways, the replies nobody else can write, the fifteen tabs you open to find the three things that actually needed you.
This is not an argument for adding one more machine to the pile. It is an argument for the one machine that works for you — and asks before it speaks in your name. What follows is what that machine costs to run.
Every agent that operates real software has the same hidden bill: before it can do anything, it has to look. And the two ways it usually looks are both expensive in a way nobody puts on the invoice.
Look one: take a picture. Screenshot the window, hand it to a vision model, ask where the button is. The picture is cheap in tokens and useless as an address — the model can say “the Send button is bottom-right”, but nothing in that sentence can be clicked. So the agent guesses coordinates, clicks, takes another picture to find out what happened, and pays again. Every act costs two looks, and a wrong guess costs three.
Look two: dump the page. Serialize the DOM, or an accessibility snapshot, and paste it into the context. Now the model has addresses — and a bill.
The measurement
One machine, one Chrome, one page: a public LinkedIn job posting, foreground tab, nothing cached
away. Playwright 1.62 attached to that same browser over CDP, so every tool below looked at exactly
the same pixels and the same DOM. Medians of five runs, one tool at a time on an otherwise idle
machine — a measurement taken while something else is measuring is a measurement of the
machine. Token estimates: text at 3.7 characters per token, images by the standard
width × height / 750.
| how the agent looks | into the model | time |
|---|---|---|
| HTML dump | 133 887 tokens | 98 ms |
| a11y snapshot | 23 559 tokens | 147 ms |
| screenshot | ~896 tokens, no element addresses | 1.5 s |
| kovavue map | 6 774 tokens | 300 ms cold, ~50 ms warm |
| form_state | 240 tokens | ~320 ms |
Read the first row again: a single look at one job posting costs more than a hundred thousand tokens. That is not a page an agent reads once — it reads it after every click, because the page changed. At current API prices that one look is real money, and the agent will take hundreds of them before it finishes a form.
Note what the time column does not say. On an idle machine every structured read is fast, and the honest summary is that none of them is the bottleneck. The slow one is the picture, at a second and a half — and it is also the only one that hands back nothing you can address.
So the difference that matters is the bill: 3.5× against the accessibility snapshot, 20× against the HTML.
Not because of a compression trick — because the map answers a different question. The dump answers “what is on this page”. The map answers “what can be acted on, and how do I address it”. This job page carries 1 718 nodes worth of structure and about 300 lines worth of things you can actually do.
And when the agent is about to do the one thing that matters — press Submit — it doesn't need the page at all. It needs to know what is written in the form right now: every field, its label, its current value, and every complaint the page is making. That is 240 tokens — 98 times leaner than the accessibility snapshot of the same page, and 558 times leaner than its HTML.
Why a map and not a picture
The picture-and-OCR approach has one honest advantage: it works on anything, because everything has pixels. It also has one dishonest cost: the model is guessing. It infers a control from a rectangle of colour, infers a state from a shade, and hands you a coordinate that was right when the screenshot was taken.
A map is built from what the software already publishes about itself — the same information a screen reader uses — and the pixels are used to fill the holes, not to carry the whole load. Every node in the map has an identity you can act on. When the page re-renders and that identity goes stale, the act re-binds by what the target meant instead of failing, or it says plainly that it could not.
The part browser tools cannot reach
Everything above is a web page. But a working day is not a browser. It is Telegram, Slack, a desktop mail client, a PDF viewer — native windows that no browser automation tool can see, because there is no DOM to attach to.
Same measurement, native Telegram Desktop, its main window — sidebar, chat list, search, composer:
| how the agent looks | into the model | time |
|---|---|---|
| kovavue map | 844 tokens | 3.1 s first read, ~26 ms after |
| screenshot | ~700 tokens, no addresses | 147 ms |
844 tokens for a running chat client, every control of it addressable. The first read is the expensive one — a Qt tree has to be walked rather than asked — and it is paid once per window, not per look.
That same path has opened a channel by deep link, read 29 posts out of it, pasted a 1 614-character message into the composer and read the field back to confirm what was actually in it. No screenshots involved, no OCR, no guessing.
An ack that means something
There is a failure mode specific to agents that nobody talks about: the green tick that means nothing. The click was delivered, the API returned OK, and nothing happened. The agent reports success and moves on, and you find out three steps later.
So the acknowledgement is about the effect, not the call. A press that reported success but moved nothing in the app comes back as UNCERTAIN and falls back to the pixel floor. A fill reads the field back — and reads it again half a second later, so if the field emptied because you hit Enter yourself, the record says “the field emptied after the fill — something submitted it, not this action”. That sentence exists because I once concluded the opposite from a screenshot.
Nothing irreversible without your yes
Send, Submit, Apply, Connect — the actions that reach a live human — are held by a gate that returns the exact text of what would happen and does nothing until you say yes. It is not a setting to remember; it is the default, and it fires against my own agent every day.
The gate matches on what a control is called, so a button labelled
save can slip past a rule written for send. And a click by raw coordinates
goes around the gate altogether, which is why coordinate clicks are not used near a live submit
button. Both are filed; neither is fixed today.
What did get fixed this week is next door to them, and worth naming because it is the same disease: an act could land in the wrong window. Two windows of one application answer to the same name, and the code that picked one took the first match — so a screenshot could show the neighbouring window, and a keystroke could go to whichever window happened to hold the focus. Now a name that fits two windows is refused rather than resolved, the target window is raised and the raise is confirmed before anything is typed, and the acknowledgement says which window it acted in. I would rather publish that than a clean story.
What's coming
The next thing is presence: an agent that checks your messengers and the sites you care about on a schedule, keeps your accounts alive, drafts the replies, and brings you the three things that actually need a human — without you opening fifteen tabs to find them. The hard parts are already in place: it can read the native apps, it can act in them, and it will not send anything on your behalf without your word.
Bring your own model
kovavue is not a model and not a subscription to one. It speaks MCP, so any agent that speaks MCP can drive it — Claude, Kimi, GPT, a local Llama, whatever you prefer or whatever your compliance department permits. The eye and the hand live on your machine, and the model is a parameter, not a lock-in.
Numbers above were measured on 18 August 2026 on a single machine (Ubuntu 24.04, X11/KDE, Chrome 151), one page and one window, medians of five runs on an idle box, and are reproducible: Playwright attaches to the same browser over CDP, and the kovavue figures come from its MCP bridge. An earlier draft of this piece carried times from the same page taken while the machine was swapping itself to death — the accessibility snapshot “took” 22 seconds there. It did not; the box did. Times are only worth printing when the machine is idle, and that is why every row here was re-taken. Comparisons with other browser agents are deliberately absent — measuring one means putting someone else's extension into a browser that holds live logins, and I will not publish numbers I did not take myself. The traffic figure is from the Imperva/Thales Bad Bot Report 2026, covering 2025.
Building something that has to work in the real world?
I build and run AI systems end to end — the whole stack, solo. If your agents need to act in software that was never designed for them, that is the problem I have been living in.
— naykip —