[{"data":1,"prerenderedAt":801},["ShallowReactive",2],{"navigation_docs":3,"-providers-openai-codex":104,"-providers-openai-codex-surround":796},[4,44],{"title":5,"path":6,"stem":7,"children":8,"icon":43},"Guide","\u002Fguide","1.guide\u002F1.index",[9,11,15,19,23,27,31,35,39],{"title":10,"path":6,"stem":7},"Getting Started",{"title":12,"path":13,"stem":14},"Searching","\u002Fguide\u002Fsearch","1.guide\u002F2.search",{"title":16,"path":17,"stem":18},"Fan-out","\u002Fguide\u002Ffanout","1.guide\u002F3.fanout",{"title":20,"path":21,"stem":22},"Reading","\u002Fguide\u002Fread","1.guide\u002F4.read",{"title":24,"path":25,"stem":26},"Reverse Image Search","\u002Fguide\u002Fimage","1.guide\u002F5.image",{"title":28,"path":29,"stem":30},"CLI","\u002Fguide\u002Fcli","1.guide\u002F6.cli",{"title":32,"path":33,"stem":34},"Agents","\u002Fguide\u002Fagents","1.guide\u002F7.agents",{"title":36,"path":37,"stem":38},"Custom Providers","\u002Fguide\u002Fcustom","1.guide\u002F8.custom",{"title":40,"path":41,"stem":42},"Explorer","\u002Fguide\u002Fexplorer","1.guide\u002F9.explorer","i-lucide-book-open",{"title":45,"path":46,"stem":47,"children":48,"icon":103},"Providers","\u002Fproviders","2.providers\u002F0.index",[49,51,55,59,63,67,71,75,79,83,87,91,95,99],{"title":50,"path":46,"stem":47},"Overview",{"title":52,"path":53,"stem":54},"Brave","\u002Fproviders\u002Fbrave","2.providers\u002F01.brave",{"title":56,"path":57,"stem":58},"Context.dev","\u002Fproviders\u002Fcontext","2.providers\u002F02.context",{"title":60,"path":61,"stem":62},"Exa","\u002Fproviders\u002Fexa","2.providers\u002F03.exa",{"title":64,"path":65,"stem":66},"Firecrawl","\u002Fproviders\u002Ffirecrawl","2.providers\u002F04.firecrawl",{"title":68,"path":69,"stem":70},"Jina","\u002Fproviders\u002Fjina","2.providers\u002F05.jina",{"title":72,"path":73,"stem":74},"Mojeek","\u002Fproviders\u002Fmojeek","2.providers\u002F06.mojeek",{"title":76,"path":77,"stem":78},"SearXNG","\u002Fproviders\u002Fsearxng","2.providers\u002F07.searxng",{"title":80,"path":81,"stem":82},"SerpAPI","\u002Fproviders\u002Fserpapi","2.providers\u002F08.serpapi",{"title":84,"path":85,"stem":86},"SerpBase","\u002Fproviders\u002Fserpbase","2.providers\u002F09.serpbase",{"title":88,"path":89,"stem":90},"Tavily","\u002Fproviders\u002Ftavily","2.providers\u002F10.tavily",{"title":92,"path":93,"stem":94},"TinyFish","\u002Fproviders\u002Ftinyfish","2.providers\u002F11.tinyfish",{"title":96,"path":97,"stem":98},"OpenAI Codex","\u002Fproviders\u002Fopenai-codex","2.providers\u002F12.openai-codex",{"title":100,"path":101,"stem":102},"Marginalia","\u002Fproviders\u002Fmarginalia","2.providers\u002F13.marginalia","i-lucide-library",{"id":105,"title":96,"body":106,"description":789,"extension":790,"links":791,"meta":792,"navigation":360,"path":97,"seo":794,"stem":98,"__hash__":795},"docs\u002F2.providers\u002F12.openai-codex.md",{"type":107,"value":108,"toc":784},"minimark",[109,113,122,127,130,164,167,170,264,271,303,326,329,477,480,550,569,578,582,599,617,697,708,712,766,780],[110,111],"provider-facts",{"provider":112},"openai-codex",[114,115,116,117,121],"p",{},"This is the search available through a Codex login, not the separately billed OpenAI API. The adapter calls the ChatGPT backend with the hosted ",[118,119,120],"code",{},"web_search"," tool. A model answer without a completed search is an error, not a search result.",[123,124,126],"h2",{"id":125},"credentials","Credentials",[114,128,129],{},"Log in with Pi, OMP, Codex or OpenCode, then search. No manual token export:",[131,132,137],"pre",{"className":133,"code":134,"language":135,"meta":136,"style":136},"language-bash shiki shiki-themes web web web","web search \"Node.js release notes\" --provider openai-codex --json\n","bash","",[118,138,139],{"__ignoreMap":136},[140,141,144,148,152,155,158,161],"span",{"class":142,"line":143},"line",1,[140,145,147],{"class":146},"sK71F","web",[140,149,151],{"class":150},"shU9J"," search",[140,153,154],{"class":150}," \"Node.js release notes\"",[140,156,157],{"class":150}," --provider",[140,159,160],{"class":150}," openai-codex",[140,162,163],{"class":150}," --json\n",[114,165,166],{},"Pi tools resolve credentials through the host's model registry. Pi owns expiry-based refresh, but its extension API can't force renewal of a revoked token. OMP's auth broker supports forced refresh and keeps the calling session's account affinity. Listing providers doesn't resolve a token, and concurrent calls don't share accounts.",[114,168,169],{},"Outside a host, automatic discovery reads saved logins in this order:",[171,172,173,189],"table",{},[174,175,176],"thead",{},[177,178,179,183,186],"tr",{},[180,181,182],"th",{},"Client",[180,184,185],{},"Default store",[180,187,188],{},"Overrides",[190,191,192,208,223,249],"tbody",{},[177,193,194,198,203],{},[195,196,197],"td",{},"Codex",[195,199,200],{},[118,201,202],{},"~\u002F.codex\u002Fauth.json",[195,204,205],{},[118,206,207],{},"CODEX_HOME",[177,209,210,213,218],{},[195,211,212],{},"Pi",[195,214,215],{},[118,216,217],{},"~\u002F.pi\u002Fagent\u002Fauth.json",[195,219,220],{},[118,221,222],{},"PI_CODING_AGENT_DIR",[177,224,225,228,237],{},[195,226,227],{},"OMP",[195,229,230,233,234],{},[118,231,232],{},"~\u002F.omp\u002Fagent\u002Fagent.db",", then legacy ",[118,235,236],{},"auth.json",[195,238,239,241,242,245,246],{},[118,240,222],{},", ",[118,243,244],{},"OMP_PROFILE"," or legacy ",[118,247,248],{},"PI_PROFILE",[177,250,251,254,259],{},[195,252,253],{},"OpenCode",[195,255,256],{},[118,257,258],{},"~\u002F.local\u002Fshare\u002Fopencode\u002Fauth.json",[195,260,261],{},[118,262,263],{},"XDG_DATA_HOME",[114,265,266,267,270],{},"Only OAuth access tokens are used. API keys, disabled OMP accounts and expired tokens are skipped. Discovery never writes login files, creates a database or rotates saved refresh tokens. Standalone callers need a usable saved access token; if it expired, open the owning client and let it refresh. Codex logins held only in an OS keyring are not read. OMP SQLite requires Node's optional ",[118,268,269],{},"node:sqlite"," builtin; the native OMP host resolver does not.",[114,272,273,274,277,278,281,282,285,286,241,289,241,292,241,295,298,299,302],{},"Choose a store with ",[118,275,276],{},"codex.authSource"," or ",[118,279,280],{},"OPENAI_CODEX_AUTH_SOURCE",": ",[118,283,284],{},"auto"," (default), ",[118,287,288],{},"codex",[118,290,291],{},"pi",[118,293,294],{},"omp",[118,296,297],{},"opencode",", or ",[118,300,301],{},"none"," to disable local and host discovery. A named source bypasses other stores and the invoking host.",[114,304,305,306,309,310,313,314,317,318,321,322,325],{},"Explicit ",[118,307,308],{},"codex.credentials"," wins over environment overrides, which win over automatic discovery. ",[118,311,312],{},"OPENAI_CODEX_ACCESS_TOKEN"," can still supply a bearer; ",[118,315,316],{},"OPENAI_CODEX_ACCOUNT_ID"," is optional when its JWT contains ",[118,319,320],{},"chatgpt_account_id",". A partial environment override does not silently switch to a different account. ",[118,323,324],{},"OPENAI_API_KEY"," does not configure this provider.",[114,327,328],{},"In application code, explicit credentials remain an optional override:",[131,330,334],{"className":331,"code":332,"language":333,"meta":136,"style":136},"language-ts shiki shiki-themes web web web","import { createSearchProvider } from \"@agntn\u002Fweb\";\n\nconst search = createSearchProvider(\"openai-codex\", {\n  codex: {\n    credentials: {\n      accessToken: \"your-oauth-access-token\",\n      accountId: \"your-chatgpt-account-id\",\n    },\n    model: \"gpt-5.5\",\n  },\n});\nconst results = await search.search(\"Node.js release notes\", { maxResults: 5 });\n","ts",[118,335,336,355,362,386,392,398,410,421,427,438,444,450],{"__ignoreMap":136},[140,337,338,342,346,349,352],{"class":142,"line":143},[140,339,341],{"class":340},"skH_V","import",[140,343,345],{"class":344},"s38Sx"," { createSearchProvider } ",[140,347,348],{"class":340},"from",[140,350,351],{"class":150}," \"@agntn\u002Fweb\"",[140,353,354],{"class":344},";\n",[140,356,358],{"class":142,"line":357},2,[140,359,361],{"emptyLinePlaceholder":360},true,"\n",[140,363,365,368,371,374,377,380,383],{"class":142,"line":364},3,[140,366,367],{"class":340},"const",[140,369,370],{"class":344}," search ",[140,372,373],{"class":340},"=",[140,375,376],{"class":146}," createSearchProvider",[140,378,379],{"class":344},"(",[140,381,382],{"class":150},"\"openai-codex\"",[140,384,385],{"class":344},", {\n",[140,387,389],{"class":142,"line":388},4,[140,390,391],{"class":344},"  codex: {\n",[140,393,395],{"class":142,"line":394},5,[140,396,397],{"class":344},"    credentials: {\n",[140,399,401,404,407],{"class":142,"line":400},6,[140,402,403],{"class":344},"      accessToken: ",[140,405,406],{"class":150},"\"your-oauth-access-token\"",[140,408,409],{"class":344},",\n",[140,411,413,416,419],{"class":142,"line":412},7,[140,414,415],{"class":344},"      accountId: ",[140,417,418],{"class":150},"\"your-chatgpt-account-id\"",[140,420,409],{"class":344},[140,422,424],{"class":142,"line":423},8,[140,425,426],{"class":344},"    },\n",[140,428,430,433,436],{"class":142,"line":429},9,[140,431,432],{"class":344},"    model: ",[140,434,435],{"class":150},"\"gpt-5.5\"",[140,437,409],{"class":344},[140,439,441],{"class":142,"line":440},10,[140,442,443],{"class":344},"  },\n",[140,445,447],{"class":142,"line":446},11,[140,448,449],{"class":344},"});\n",[140,451,453,455,458,460,463,466,469,471,474],{"class":142,"line":452},12,[140,454,367],{"class":340},[140,456,457],{"class":344}," results ",[140,459,373],{"class":340},[140,461,462],{"class":340}," await",[140,464,465],{"class":344}," search.",[140,467,468],{"class":146},"search",[140,470,379],{"class":344},[140,472,473],{"class":150},"\"Node.js release notes\"",[140,475,476],{"class":344},", { maxResults: 5 });\n",[114,478,479],{},"For refresh, pass a callback instead of the fixed pair. Your login service owns token storage and concurrent refresh coordination:",[131,481,483],{"className":331,"code":482,"language":333,"meta":136,"style":136},"import { createSearchProvider, type CodexCredentialProvider } from \"@agntn\u002Fweb\";\n\nexport function createCodexSearch(credentials: CodexCredentialProvider) {\n  return createSearchProvider(\"openai-codex\", { codex: { credentials } });\n}\n",[118,484,485,504,508,531,545],{"__ignoreMap":136},[140,486,487,489,492,495,498,500,502],{"class":142,"line":143},[140,488,341],{"class":340},[140,490,491],{"class":344}," { createSearchProvider, ",[140,493,494],{"class":340},"type",[140,496,497],{"class":344}," CodexCredentialProvider } ",[140,499,348],{"class":340},[140,501,351],{"class":150},[140,503,354],{"class":344},[140,505,506],{"class":142,"line":357},[140,507,361],{"emptyLinePlaceholder":360},[140,509,510,513,516,519,522,525,528],{"class":142,"line":364},[140,511,512],{"class":340},"export",[140,514,515],{"class":340}," function",[140,517,518],{"class":146}," createCodexSearch",[140,520,521],{"class":344},"(credentials",[140,523,524],{"class":340},":",[140,526,527],{"class":146}," CodexCredentialProvider",[140,529,530],{"class":344},") {\n",[140,532,533,536,538,540,542],{"class":142,"line":388},[140,534,535],{"class":340},"  return",[140,537,376],{"class":146},[140,539,379],{"class":344},[140,541,382],{"class":150},[140,543,544],{"class":344},", { codex: { credentials } });\n",[140,546,547],{"class":142,"line":394},[140,548,549],{"class":344},"}\n",[114,551,552,553,556,557,560,561,564,565,568],{},"The callback receives ",[118,554,555],{},"{ refresh, signal }"," and returns ",[118,558,559],{},"{ accessToken, accountId? }",", directly or through a promise. The account ID is derived from the access token when omitted. It runs before each search with ",[118,562,563],{},"refresh: false",". After an authentication rejection it runs once more with ",[118,566,567],{},"refresh: true",". The adapter retries once only if the bearer or account changed. If the host returns the rejected pair unchanged, search stops and asks for a fresh login. Check expiry even on the first call. The library never handles a refresh token itself.",[114,570,571,572,277,574,577],{},"Explicit credentials and model take precedence over the environment. Instance configuration is local to that instance, it does not enroll a callback in the global ",[118,573,284],{},[118,575,576],{},"all"," flows.",[123,579,581],{"id":580},"endpoint-and-results","Endpoint and results",[114,583,584,587,588,241,591,594,595,598],{},[118,585,586],{},"POST https:\u002F\u002Fchatgpt.com\u002Fbackend-api\u002Fcodex\u002Fresponses",", with Bearer auth, ",[118,589,590],{},"chatgpt-account-id",[118,592,593],{},"store: false",", streaming enabled and ",[118,596,597],{},"tool_choice: { type: \"web_search\" }",".",[114,600,601,602,605,606,241,609,612,613,616],{},"Results come only from structured search sources and ",[118,603,604],{},"url_citation"," annotations. They have ",[118,607,608],{},"url",[118,610,611],{},"title"," and an empty ",[118,614,615],{},"snippet",". Generated prose is not a page excerpt. URLs that appear only in prose never become results.",[131,618,620],{"className":331,"code":619,"language":333,"meta":136,"style":136},"import { searchProviderDetailed } from \"@agntn\u002Fweb\";\n\nconst response = await searchProviderDetailed(\"openai-codex\", \"Node.js release notes\", {\n  maxResults: 5,\n  summary: true,\n});\nconsole.log(response.results);\nconsole.log(response.metadata?.answer);\n",[118,621,622,635,639,663,668,673,677,688],{"__ignoreMap":136},[140,623,624,626,629,631,633],{"class":142,"line":143},[140,625,341],{"class":340},[140,627,628],{"class":344}," { searchProviderDetailed } ",[140,630,348],{"class":340},[140,632,351],{"class":150},[140,634,354],{"class":344},[140,636,637],{"class":142,"line":357},[140,638,361],{"emptyLinePlaceholder":360},[140,640,641,643,646,648,650,653,655,657,659,661],{"class":142,"line":364},[140,642,367],{"class":340},[140,644,645],{"class":344}," response ",[140,647,373],{"class":340},[140,649,462],{"class":340},[140,651,652],{"class":146}," searchProviderDetailed",[140,654,379],{"class":344},[140,656,382],{"class":150},[140,658,241],{"class":344},[140,660,473],{"class":150},[140,662,385],{"class":344},[140,664,665],{"class":142,"line":388},[140,666,667],{"class":344},"  maxResults: 5,\n",[140,669,670],{"class":142,"line":394},[140,671,672],{"class":344},"  summary: true,\n",[140,674,675],{"class":142,"line":400},[140,676,449],{"class":344},[140,678,679,682,685],{"class":142,"line":412},[140,680,681],{"class":344},"console.",[140,683,684],{"class":146},"log",[140,686,687],{"class":344},"(response.results);\n",[140,689,690,692,694],{"class":142,"line":423},[140,691,681],{"class":344},[140,693,684],{"class":146},[140,695,696],{"class":344},"(response.metadata?.answer);\n",[114,698,699,700,703,704,707],{},"The detailed helper uses the same automatic login discovery and explicit environment overrides. ",[118,701,702],{},"summary: true"," includes the generated answer in ",[118,705,706],{},"metadata.answer","; it stays absent otherwise. Metadata also carries the returned model, request ID and token usage when available.",[123,709,711],{"id":710},"limits-and-traps","Limits and traps",[713,714,715,719,733,739,742,750,753,756,763],"ul",{},[716,717,718],"li",{},"This is an experimental adapter for the Codex backend, not a stable public search API. Model access and subscription limits still apply.",[716,720,721,722,725,726,277,729,732],{},"The default model is ",[118,723,724],{},"gpt-5.5",". Override it with ",[118,727,728],{},"codex.model",[118,730,731],{},"OPENAI_CODEX_MODEL"," if your account needs another model that supports hosted web search. There is no hidden model fallback.",[716,734,735,738],{},[118,736,737],{},"maxResults"," caps collected sources locally, not upstream search work. Default 10, maximum 100. It does not promise that many sources.",[716,740,741],{},"No paging, domain\u002Fdate\u002Fcategory filters, highlights, full page text, reverse image search or URL reading. Detailed helpers report ignored filters.",[716,743,744,746,747,749],{},[118,745,284],{}," tries Codex after the existing API providers, before custom providers and SearXNG. ",[118,748,576],{}," includes it when a usable saved login, a native host resolver or explicit environment credentials are available. Discovery does not check subscription status or refresh tokens.",[716,751,752],{},"A search has a 90-second ceiling, including credential resolution and its one possible refresh. Caller cancellation and earlier deadlines still win. The transport rejects streams above 8 MiB and events above 1 MiB.",[716,754,755],{},"The adapter does not retry metered requests after HTTP 429 or server errors. Automatic search may move to another configured provider under the library's normal fallback rules.",[716,757,758,759,762],{},"OAuth credentials can only go to the fixed ChatGPT endpoint. Custom ",[118,760,761],{},"baseURL"," values and HTTP redirects are refused. Error messages omit upstream bodies and credential callback diagnostics.",[716,764,765],{},"Do not put personal subscription credentials on a public explorer worker. Local configuration is enough to use the library and its tools.",[114,767,768,769,772,773,598],{},"Implementation: ",[118,770,771],{},"src\u002Fproviders\u002Fopenai-codex.ts",". Protocol reference: the Codex search adapter in ",[774,775,779],"a",{"href":776,"rel":777},"https:\u002F\u002Fgithub.com\u002Fcan1357\u002Foh-my-pi\u002Fblob\u002Fmain\u002Fpackages\u002Fcoding-agent\u002Fsrc\u002Fweb\u002Fsearch\u002Fproviders\u002Fcodex.ts",[778],"nofollow","oh-my-pi",[781,782,783],"style",{},"html pre.shiki code .sK71F, html code.shiki .sK71F{--shiki-light:var(--shiki-token-function);--shiki-default:var(--shiki-token-function);--shiki-dark:var(--shiki-token-function)}html pre.shiki code .shU9J, html code.shiki .shU9J{--shiki-light:var(--shiki-token-string);--shiki-default:var(--shiki-token-string);--shiki-dark:var(--shiki-token-string)}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .skH_V, html code.shiki .skH_V{--shiki-light:var(--shiki-token-keyword);--shiki-default:var(--shiki-token-keyword);--shiki-dark:var(--shiki-token-keyword)}html pre.shiki code .s38Sx, html code.shiki .s38Sx{--shiki-light:var(--ui-text-highlighted);--shiki-default:var(--ui-text-highlighted);--shiki-dark:var(--ui-text-highlighted)}",{"title":136,"searchDepth":357,"depth":357,"links":785},[786,787,788],{"id":125,"depth":357,"text":126},{"id":580,"depth":357,"text":581},{"id":710,"depth":357,"text":711},"Web search through your existing Pi, OMP, Codex or OpenCode login.","md",null,{"icon":793},"i-lucide-search",{"title":96,"description":789},"Bssj0TvAjLCIDGJ75JoYBG17eNVGqMe6TqKvivBfgTI",[797,799],{"title":92,"path":93,"stem":94,"description":798,"children":-1},"TinyFish Search for news and research results with publisher metadata, and TinyFish Fetch for reading pages.",{"title":100,"path":101,"stem":102,"description":800,"children":-1},"Marginalia Search, an independent index of small personal sites and plain text pages, usable without a key when you name it.",1791287748510]