Web search
Reaching the web is not what makes an agent able to search. Fetching ten results and reading them is a job, and an agent doing it by hand spends its whole context on the reading before it gets to the thinking.
The searching and the reading happen somewhere else
web_search is a pi extension shipped in the sandbox image, like wake_me. It posts the question to a hosted search that reads the pages itself and answers in prose with its sources linked in — so what comes back into the agent's context is an answer rather than ten pages of HTML.
Choosing the provider is the whole of it
│ config │ │ │ │ Choosing here is the whole of setting it up — the host, the │ │ key and what a search costs come with the provider, and the │ │ proxy is told to pay for that one endpoint and nothing else. │ │ │ │ ● provider openai │ │ ● model gpt-5-mini │ │ ● key OPENAI_API_KEY │ │ ╭────────────────────────────────────────────────────────────╮ │ │ │ 2 to search with $0.010 a search here │ │ │ ╰────────────────────────────────────────────────────────────╯ │
Where that provider lives, the one endpoint on it that searches, the variable its key is read from and what a search costs are facts about the provider rather than decisions, so none of them is asked for. The dot is the same on all three rows because none of them is in force without the key — a provider and a model chosen against a key this plane does not hold is a search refused at the proxy, and one mark that says so is better than two that disagree.
What the plane derives from that screen is api.openai.com, POST /v1/responses, bearer from OPENAI_API_KEY — and the path scope is the part worth keeping. The same key against the rest of that API is a second model to think with, bought by whoever takes the agent over, and a grant that only opens the endpoint which searches is one that cannot be spent on anything else.
Every agent gets it, because it is a tool rather than a reach: the question goes to one host and the answer comes back, and no agent is narrowed by being kept off it. Writing the grant out by hand in deploy/config.yaml still works and still wins, if you want the endpoint pinned somewhere a console cannot move it.
curl, and a failure said out loud
The tool reaches the proxy with curl rather than fetch, because a sandbox has no DNS and no route out except that proxy: Node's fetch reads neither HTTPS_PROXY nor NODE_EXTRA_CA_CERTS and dies resolving the name. Nothing sends an Authorization — the proxy writes one and strips whatever was sent, so an agent holding a key could not spend it and this one has none to hold.
Without the grant the tool is still there and says at the moment of use that it could not search, which is a better failure than an agent quietly answering from memory. Each search is billed per call, which is why the tool asks for one question rather than keywords to try — and what it costs lands on the agent's day like everything else.