<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mateus Cavalcanti</title>
    <description>The latest articles on DEV Community by Mateus Cavalcanti (@mateusdcc).</description>
    <link>https://dev.to/mateusdcc</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4072836%2F3ea88632-ff7b-4b0f-a9c6-6326e90f1fd0.jpg</url>
      <title>DEV Community: Mateus Cavalcanti</title>
      <link>https://dev.to/mateusdcc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mateusdcc"/>
    <language>en</language>
    <item>
      <title>I Reverse-Engineered Codex's Web Search and Made It Available to Claude, Gemini, and Local Models</title>
      <dc:creator>Mateus Cavalcanti</dc:creator>
      <pubDate>Tue, 11 Aug 2026 11:24:26 +0000</pubDate>
      <link>https://dev.to/mateusdcc/i-reverse-engineered-codexs-web-search-and-made-it-available-to-claude-gemini-and-local-models-aj7</link>
      <guid>https://dev.to/mateusdcc/i-reverse-engineered-codexs-web-search-and-made-it-available-to-claude-gemini-and-local-models-aj7</guid>
      <description>&lt;p&gt;I wanted Codex's web search. I did not necessarily want Codex to be the model doing the reasoning.&lt;/p&gt;

&lt;p&gt;That distinction ended up being much more interesting than I expected.&lt;/p&gt;

&lt;p&gt;Pi makes it easy to switch the active model between Gemini, Claude, OpenRouter models, local models, etc. But model capability and agent capability are not the same thing. Search, browsing, filesystem access, execution, memory and the rest of the harness can easily become coupled to whichever provider you happen to be using.&lt;/p&gt;

&lt;p&gt;So I started looking at how Codex itself performs web search.&lt;/p&gt;

&lt;p&gt;What I found was a standalone search path inside the Codex infrastructure that could be called independently from the normal model interaction flow.&lt;/p&gt;

&lt;p&gt;I reverse-engineered its interface and turned it into &lt;code&gt;pi-gpt-search&lt;/code&gt;, an open-source Pi extension that lets the active model use Codex's web retrieval layer while remaining the model responsible for reasoning.&lt;/p&gt;

&lt;p&gt;The resulting architecture is basically this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                   Pi
                    |
                    v
       Claude / Gemini / Local LLM
              reasoning model
                    |
                    | tool call
                    v
          codex-search / codex-research
                    |
                    v
      Codex standalone search backend
                    |
                    v
        structured web information
                    |
                    v
       Claude / Gemini / Local LLM
             continues reasoning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The search backend and the reasoning model no longer have to be the same thing.&lt;/p&gt;

&lt;p&gt;That is the part of the project I find most useful.&lt;/p&gt;
&lt;h2&gt;
  
  
  Finding the standalone search interface
&lt;/h2&gt;

&lt;p&gt;I did not start by intercepting random network traffic and guessing requests.&lt;/p&gt;

&lt;p&gt;Codex already exposes a surprisingly useful source of structural information through its app-server protocol generation.&lt;/p&gt;

&lt;p&gt;I generated its TypeScript protocol bindings:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex app-server generate-ts &lt;span class="nt"&gt;--out&lt;/span&gt; /tmp/codex-ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Searching the generated definitions exposed types such as &lt;code&gt;WebSearchItem&lt;/code&gt; and &lt;code&gt;WebSearchAction&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;One Rust documentation comment was particularly useful:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Structured search results returned out-of-band by standalone web search."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;"Standalone" and "out-of-band" were exactly the words I wanted to see.&lt;/p&gt;

&lt;p&gt;At this point there was evidence that web search was not necessarily just an opaque side effect buried inside a normal Codex model turn.&lt;/p&gt;

&lt;p&gt;The next step was the binary.&lt;/p&gt;
&lt;h2&gt;
  
  
  Mining the Codex binary
&lt;/h2&gt;

&lt;p&gt;I searched the installed Codex executable for strings related to web search:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;strings /Applications/ChatGPT.app/Contents/Resources/codex &lt;span class="se"&gt;\&lt;/span&gt;
  | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-iE&lt;/span&gt; &lt;span class="s2"&gt;"(search|alpha/search|backend-api)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Among the results were identifiers like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;standalone_web_search
codex.web_search.results
alpha/search
https://chatgpt.com/backend-api/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That gave me a very plausible endpoint:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://chatgpt.com/backend-api/codex/alpha/search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Finding the URL was only half the problem. I still did not know the actual request schema.&lt;/p&gt;

&lt;p&gt;And this is where the backend itself became useful.&lt;/p&gt;
&lt;h2&gt;
  
  
  Reconstructing the request schema from errors
&lt;/h2&gt;

&lt;p&gt;I reused the OAuth credentials generated by &lt;code&gt;codex login&lt;/code&gt; and started probing the endpoint with deliberately incomplete requests.&lt;/p&gt;

&lt;p&gt;For example, sending only a query led to an error about a missing &lt;code&gt;id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Adding an &lt;code&gt;id&lt;/code&gt; then exposed the next required field, &lt;code&gt;model&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Adding that produced another validation response. Sending &lt;code&gt;command&lt;/code&gt; instead of &lt;code&gt;commands&lt;/code&gt; produced a correction. Sending the wrong type for &lt;code&gt;search_query&lt;/code&gt; exposed that it expected an array of objects.&lt;/p&gt;

&lt;p&gt;So instead of blindly fuzzing the API, I could use its validation errors to progressively reconstruct the contract.&lt;/p&gt;

&lt;p&gt;The resulting minimal request looked roughly like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gpt-4o"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"commands"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"search_query"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"q"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OpenAI Codex GitHub repository"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And that returned structured web results.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;model&lt;/code&gt; field deserves some clarification because it is easy to misunderstand what I am claiming here.&lt;/p&gt;

&lt;p&gt;The endpoint requires it as part of its protocol. That does &lt;strong&gt;not&lt;/strong&gt; mean &lt;code&gt;pi-gpt-search&lt;/code&gt; sends the user's prompt to GPT and asks GPT to solve the task.&lt;/p&gt;

&lt;p&gt;The active Pi model still decides what to search for, receives the resulting web information and performs the reasoning.&lt;/p&gt;
&lt;h2&gt;
  
  
  Turning the endpoint into an actual research tool
&lt;/h2&gt;

&lt;p&gt;A raw undocumented endpoint is interesting, but not especially useful by itself.&lt;/p&gt;

&lt;p&gt;So I built a provider around it.&lt;/p&gt;

&lt;p&gt;The current project exposes two main tools.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;codex-search&lt;/code&gt; handles simple single-query retrieval. It accepts the query itself plus optional domain filtering, recency filtering and response-length control.&lt;/p&gt;

&lt;p&gt;For example, the active model can invoke something equivalent to:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;codex-search({
  query: "latest Rust release",
  domains: ["rust-lang.org"],
  response_length: "short"
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The other interface is more interesting: &lt;code&gt;codex-research&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Search systems used by agents need more than a &lt;code&gt;query -&amp;gt; results&lt;/code&gt; function. The model frequently needs to search, inspect one result, find a specific section, follow another reference and only then construct an answer.&lt;/p&gt;

&lt;p&gt;So &lt;code&gt;codex-research&lt;/code&gt; exposes the richer command structure I recovered from the backend:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"search_query"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"q"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OpenAI Codex GitHub repository"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"domains"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"github.com"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"response_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"medium"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A later tool call in the same research session can then open a returned reference:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"open"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ref_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"turn0search0"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Or search inside that document:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"find"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ref_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"turn1view0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"pattern"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"terminal"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;There is also support for &lt;code&gt;click&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The provider keeps a stable session identity across these calls, so references produced during one operation remain useful during subsequent research operations.&lt;/p&gt;

&lt;p&gt;At that point this stops being a search wrapper and becomes a small web research harness.&lt;/p&gt;
&lt;h2&gt;
  
  
  Search is not reasoning
&lt;/h2&gt;

&lt;p&gt;This was the architectural motivation behind the project.&lt;/p&gt;

&lt;p&gt;A lot of discussion around coding agents collapses everything into "the model".&lt;/p&gt;

&lt;p&gt;But a coding agent is not just a model.&lt;/p&gt;

&lt;p&gt;There is the model, and then there is the harness around it: tools, retrieval, context management, filesystem access, shell execution, browser/search infrastructure, memory, verification and the policies controlling when these things are used.&lt;/p&gt;

&lt;p&gt;Those components do not inherently need to come from the same vendor.&lt;/p&gt;

&lt;p&gt;With this extension I can run Gemini as the reasoning model:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Gemini
   |
   | decides that current information is required
   v
Codex search infrastructure
   |
   | returns web evidence
   v
Gemini
   |
   v
final reasoning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The same applies to Claude or a local model.&lt;/p&gt;

&lt;p&gt;I am still using OpenAI infrastructure for retrieval, so calling the project "provider-independent" without qualification would be wrong.&lt;/p&gt;

&lt;p&gt;It is &lt;strong&gt;reasoning-model-independent&lt;/strong&gt;, not infrastructure-independent.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;
&lt;h2&gt;
  
  
  What "zero GPT inference" means here
&lt;/h2&gt;

&lt;p&gt;The repository describes this as zero-GPT inference, but I want to define that claim precisely.&lt;/p&gt;

&lt;p&gt;I added a live test that wraps &lt;code&gt;fetch()&lt;/code&gt; with an intercepting proxy.&lt;/p&gt;

&lt;p&gt;The test watches outgoing requests for routes associated with model execution, including completion, response, conversation and turn-start paths. If the extension attempts to call one of those routes, the test fails.&lt;/p&gt;

&lt;p&gt;It then performs a real search followed by a real &lt;code&gt;open&lt;/code&gt; operation.&lt;/p&gt;

&lt;p&gt;The expected network behavior is:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pi-gpt-search
     |
     +------&amp;gt; /backend-api/codex/alpha/search
     |
     +------&amp;gt; /backend-api/codex/alpha/search

separate model inference requests: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The current test expects exactly two standalone-search HTTP requests and zero separate GPT/model-inference requests.&lt;/p&gt;

&lt;p&gt;This verifies something specific: &lt;strong&gt;the extension itself does not perform an additional GPT/Codex model turn as part of the search workflow.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It does not prove what OpenAI internally executes behind the &lt;code&gt;/codex/alpha/search&lt;/code&gt; service. I cannot inspect their backend, so claiming that no model of any kind exists anywhere internally would go beyond the evidence I have.&lt;/p&gt;

&lt;p&gt;For my use case, the important property is that the active Pi model remains the reasoning agent and no additional model turn is initiated by the extension.&lt;/p&gt;
&lt;h2&gt;
  
  
  Keeping web retrieval out of the main context where possible
&lt;/h2&gt;

&lt;p&gt;There is another problem with agentic browsing that is less visible than the API call itself: context pollution.&lt;/p&gt;

&lt;p&gt;Dumping raw web responses, HTTP metadata and huge result structures directly into the active model context is a very easy way to waste tokens.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pi-gpt-search&lt;/code&gt; separates model-facing content from TUI metadata.&lt;/p&gt;

&lt;p&gt;The cleaned output and citations go back to the active model.&lt;/p&gt;

&lt;p&gt;The detailed structured results can remain attached as local &lt;code&gt;details&lt;/code&gt; metadata used by Pi's UI.&lt;/p&gt;

&lt;p&gt;The output layer also converts Codex's internal citation references into usable source references and terminal hyperlinks.&lt;/p&gt;

&lt;p&gt;The model gets the information required to continue reasoning without blindly inheriting every byte returned by the search backend.&lt;/p&gt;
&lt;h2&gt;
  
  
  Auth is intentionally boring
&lt;/h2&gt;

&lt;p&gt;The extension reuses an existing Codex authentication session.&lt;/p&gt;

&lt;p&gt;If you already ran:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;it can read the access token and account ID from:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.codex/auth.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can also provide the credentials through environment variables.&lt;/p&gt;

&lt;p&gt;The actual search request contains the command being executed and the required session/protocol metadata. The extension does not need to forward the entire Pi conversation, project files or system prompt to the search endpoint just to execute a search.&lt;/p&gt;

&lt;p&gt;This is one of the reasons I wanted search to remain a separate tool instead of silently delegating the entire problem to another agent.&lt;/p&gt;
&lt;h2&gt;
  
  
  Handling the less interesting failure modes
&lt;/h2&gt;

&lt;p&gt;Once I decided to publish this instead of keeping it as a local hack, some boring things became necessary.&lt;/p&gt;

&lt;p&gt;The provider has explicit handling for authentication failures, authorization failures, HTTP rate limits, timeouts and cancellation.&lt;/p&gt;

&lt;p&gt;Transient &lt;code&gt;502&lt;/code&gt;, &lt;code&gt;503&lt;/code&gt; and &lt;code&gt;504&lt;/code&gt; responses are retried.&lt;/p&gt;

&lt;p&gt;Pi's &lt;code&gt;AbortSignal&lt;/code&gt; is connected to the request, so cancelling a tool operation cancels the underlying fetch rather than leaving an HTTP request running in the background.&lt;/p&gt;

&lt;p&gt;There are unit tests for command validation and response normalization, integration tests for provider behavior, live endpoint tests, the zero-additional-inference interception test and an end-to-end research harness test.&lt;/p&gt;

&lt;p&gt;I do not think an undocumented API becomes "stable" because you added tests around it, but tests at least make breakage observable instead of mysterious.&lt;/p&gt;
&lt;h2&gt;
  
  
  Trying it
&lt;/h2&gt;

&lt;p&gt;The package is published on npm and can be installed directly through Pi:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pi &lt;span class="nb"&gt;install &lt;/span&gt;npm:pi-gpt-search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Or executed temporarily:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pi &lt;span class="nt"&gt;-e&lt;/span&gt; npm:pi-gpt-search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;After installation, the model gets access to &lt;code&gt;codex-search&lt;/code&gt; and &lt;code&gt;codex-research&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There is also a direct command:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/gpt-search Rust 1.97 release notes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The requirements are currently Pi, Node.js 18+ and an authenticated Codex session.&lt;/p&gt;

&lt;p&gt;The project is MIT licensed.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mateusdcc" rel="noopener noreferrer"&gt;
        mateusdcc
      &lt;/a&gt; / &lt;a href="https://github.com/mateusdcc/pi-gpt-search" rel="noopener noreferrer"&gt;
        pi-gpt-search
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;pi-gpt-search&lt;/h1&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Native, Model-Independent Web Search for Pi using OpenAI Codex Standalone Search Engine.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;pi-gpt-search&lt;/code&gt; gives &lt;strong&gt;any&lt;/strong&gt; Pi model (Gemini, Claude, local models, OpenRouter) real-time web search capabilities by reusing OpenAI Codex's standalone web retrieval infrastructure - with &lt;strong&gt;ZERO GPT Model Inference Turns&lt;/strong&gt; and &lt;strong&gt;ZERO GPT Tokens Consumed&lt;/strong&gt;.&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;⚡ Quick Start: 1-Line Installation&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Install via npm:&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;pi install npm:pi-gpt-search&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Or install via GitHub:&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;pi install https://github.com/mateusdcc/pi-gpt-search&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Or install project-locally for your current repository (&lt;code&gt;-l&lt;/code&gt; flag):&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;pi install npm:pi-gpt-search -l&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Or try it temporarily in a single session without installing:&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;pi -e npm:pi-gpt-search&lt;/pre&gt;

&lt;/div&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;⚡ Key Highlights: ZERO-GPT INFERENCE&lt;/h2&gt;
&lt;/div&gt;


&lt;ul&gt;

&lt;li&gt;🚀 &lt;strong&gt;Zero GPT Tokens Spent:&lt;/strong&gt; Pure web retrieval via OpenAI's backend endpoint. No GPT/Codex LLM turns are executed, meaning &lt;strong&gt;0 input tokens, 0 output tokens, and 0 reasoning credits are billed&lt;/strong&gt;.&lt;/li&gt;

&lt;li&gt;👑 &lt;strong&gt;Model Sovereign:&lt;/strong&gt; Your active Pi model (e.g., Gemini 3.5 Flash / Gemini 3.1 Pro) remains the sole reasoning model.&lt;/li&gt;

&lt;li&gt;…&lt;/li&gt;

&lt;/ul&gt;&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mateusdcc/pi-gpt-search" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  The obvious limitations
&lt;/h2&gt;

&lt;p&gt;The biggest limitation is also obvious from the first paragraph: this is an undocumented backend interface.&lt;/p&gt;

&lt;p&gt;OpenAI can change the request schema, authentication behavior, endpoint or availability at any point.&lt;/p&gt;

&lt;p&gt;This is not a replacement for an official supported search API.&lt;/p&gt;

&lt;p&gt;It also still depends on OpenAI's search infrastructure and on a valid Codex authentication session. The model doing the reasoning can be Claude, Gemini or something local, but retrieval itself is still vendor-dependent.&lt;/p&gt;

&lt;p&gt;And this is not a headless browser implementation. The research interface exposes search and document-oriented operations such as &lt;code&gt;open&lt;/code&gt;, &lt;code&gt;find&lt;/code&gt; and &lt;code&gt;click&lt;/code&gt;, but it does not give you a full DOM renderer with arbitrary browser automation.&lt;/p&gt;

&lt;p&gt;Those are real constraints, not footnotes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I published it anyway
&lt;/h2&gt;

&lt;p&gt;The reverse engineering was fun, but the endpoint itself is not the main idea I took away from this.&lt;/p&gt;

&lt;p&gt;The interesting part is how much of what we call an "AI model capability" is actually a property of the harness around the model.&lt;/p&gt;

&lt;p&gt;Codex search can be useful without Codex being responsible for the reasoning.&lt;/p&gt;

&lt;p&gt;A Gemini model can use retrieval infrastructure discovered in Codex. A local model can use the same interface. The tool can expose a stable contract even when the implementation behind that contract belongs to a completely different system.&lt;/p&gt;

&lt;p&gt;Once model and harness are treated as separate components, agent architectures become much more composable.&lt;/p&gt;

&lt;p&gt;That is what I wanted from &lt;code&gt;pi-gpt-search&lt;/code&gt;: not another agent, but one useful subsystem extracted from an existing one and made reusable.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>typescript</category>
      <category>reverseengineering</category>
    </item>
  </channel>
</rss>
