Skip to content

feat: route GPT-5.6 Pro through standard ChatGPT - #757

Closed
fede-oss wants to merge 2 commits into
lidge-jun:devfrom
fede-oss:feat/gpt-5.6-pro
Closed

feat: route GPT-5.6 Pro through standard ChatGPT#757
fede-oss wants to merge 2 commits into
lidge-jun:devfrom
fede-oss:feat/gpt-5.6-pro

Conversation

@fede-oss

@fede-oss fede-oss commented Jul 30, 2026

Copy link
Copy Markdown

Closes #650.

Summary

Adds an experimental, explicit chatgpt-browser/gpt-5.6-pro provider that routes through the standard ChatGPT browser surface using Oracle 0.16.1+, rather than the Codex/Work backend or OpenAI API.

  • forces browser mode, standard chatgpt.com, and explicit Pro selection;
  • never falls back to another model, account, Codex route, or API billing;
  • serializes Responses conversations and validated client tools through a nonce-bound protocol;
  • compacts prose-only tool-schema annotations while preserving callable names and validation-relevant JSON Schema;
  • retains local previous_response_id replay when Codex sends store:false;
  • preflights browser failures before committing response headers, preventing automatic duplicate Pro submissions;
  • disables native vision/search sidecars and paid media bridges for this route;
  • adds a static provider preset, readiness probe, GUI/catalog metadata, documentation, and regression tests.

Why

GPT-5.6 Pro is available through standard ChatGPT limits, while Codex and Work share a separate agentic usage pool. This provider is deliberately namespaced and isolated so bare GPT model IDs continue to use the canonical OpenAI provider.

Validation

  • live full-inventory Codex response with the user's real skills/plugins and 398-tool surface;
  • live Codex shell-tool round trip: GPT-5.6 Pro requested exec_command, Codex executed pwd, and the next browser turn returned the exact result;
  • live store:false continuation through previous_response_id;
  • live routed compaction with a decoded ocx1: checkpoint;
  • 6,044 repository tests passed, 1 platform skip, 0 failures;
  • TypeScript typecheck, GUI lint, privacy scan, GUI doctor, documentation build, and git diff --check passed.

Limitations

  • Browser UI automation is experimental and can break when ChatGPT changes.
  • Oracle 0.16.1+ and a locally signed-in eligible ChatGPT account are required.
  • The route is text-only and does not advertise hosted search, WebSockets, vision, reasoning selection, or parallel tool calls.
  • Browser turns are one-shot and non-streaming until Oracle captures the result.

AI assistance disclosure

This PR was created with the assistance of GPT-5.6 Sol Ultra.

Summary by CodeRabbit

  • New Features

    • Added an experimental ChatGPT Browser provider for GPT-5.6 Pro using a signed-in browser session.
    • Added Oracle executable configuration and readiness checks.
    • Added strict text-only support with fail-closed handling for authentication, quota, timeout, model, and protocol errors.
    • Disabled web search, vision sidecars, and parallel tool calls for this provider.
  • Bug Fixes

    • Improved provider classification so only loopback addresses are treated as local runtimes.
  • Documentation

    • Updated adapter and architecture references across supported languages.
    • Updated the built-in provider preset count from 53 to 61.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds an experimental Oracle-backed ChatGPT Browser adapter for GPT-5.6 Pro, integrates provider routing and readiness checks, disables incompatible sidecars, narrows local-provider classification, and updates tests and multilingual documentation.

Changes

ChatGPT Browser route

Layer / File(s) Summary
Oracle transport and response protocol
src/adapters/chatgpt-browser-oracle.ts, src/adapters/chatgpt-browser.ts, src/lib/process-control.ts
Builds nonce-bound prompts, validates text and tool responses, checks Oracle compatibility, captures browser output, handles cancellation, and emits normalized adapter events.
Provider configuration and routing
src/config.ts, src/types.ts, src/providers/*, src/server/adapter-resolve.ts, src/codex/catalog/*, src/codex/subagent-model-fallback.ts
Adds the experimental local provider, oracleCommand, explicit GPT-5.6 Pro routing, restricted capabilities, and fallback preservation.
Server readiness and response integration
src/server/management/*, src/server/auth-cors.ts, src/server/responses*
Adds Oracle readiness probing and validation, suppresses unsupported sidecars, and applies ChatGPT Browser continuation and error-preflight behavior.
Provider workspace classification
gui/src/provider-workspace/*, tests/provider-workspace-data.test.ts
Uses loopback base URLs rather than local authentication alone to classify local and free providers.
Validation and regression coverage
tests/chatgpt-browser-adapter.test.ts, tests/images/*, tests/provider-connection-test.test.ts, tests/config.test.ts, tests/responses-state.test.ts, tests/subagent-model-fallback.test.ts
Covers Oracle contracts, response parsing, routing, readiness, sidecar bypasses, configuration validation, continuation state, and fallback behavior.
Runtime and provider documentation
docs-site/src/content/docs/**, structure/*.md
Documents the eighth adapter, ChatGPT Browser transport, Oracle configuration, protocol constraints, unsupported capabilities, and fail-closed behavior.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Responses
  participant ChatGptBrowserAdapter
  participant Oracle
  Client->>Responses: Submit chatgpt-browser/gpt-5.6-pro request
  Responses->>ChatGptBrowserAdapter: Resolve adapter and run turn
  ChatGptBrowserAdapter->>Oracle: Send nonce-bound prompt
  Oracle-->>ChatGptBrowserAdapter: Return captured text or tool call
  ChatGptBrowserAdapter-->>Responses: Emit response events
  Responses-->>Client: Stream result or fail-closed error
Loading

Possibly related PRs

  • lidge-jun/opencodex#302: Provides related Kiro completion and transport infrastructure extended by this route.
  • lidge-jun/opencodex#366: Uses the same runTurn and response-preflight infrastructure extended for ChatGPT Browser.
  • lidge-jun/opencodex#424: Modifies the shared sidecar and image-bridge planning logic changed for ChatGPT Browser exclusions.

Suggested reviewers: ingwannu, lidge-jun, wibias

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.28% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary change: routing GPT-5.6 Pro through the standard ChatGPT browser interface.
Linked Issues check ✅ Passed The PR implements the opt-in browser route, explicit GPT-5.6 Pro targeting, readiness and failure handling, and no-fallback behavior requested by issue #650.
Out of Scope Changes check ✅ Passed The implementation, configuration, GUI metadata, documentation, process handling, and regression tests all support the linked GPT-5.6 Pro browser-routing objective.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the enhancement New feature or request label Jul 30, 2026
@fede-oss
fede-oss marked this pull request as ready for review July 30, 2026 22:03

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 102f00e7f6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +217 to +218
const required = parsed.options.toolChoice === "required"
|| (isAllowedToolChoice(parsed.options.toolChoice) && parsed.options.toolChoice.mode === "required");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Enforce named tool choices

When a Responses request specifies a named tool_choice, the parser represents it as { name: ... }, which semantically forces that tool, but required only recognizes the string and allowed_tools forms. If the browser model returns a final answer—or the requested tool is absent—this adapter accepts it instead of failing closed, breaking workflows that rely on a guaranteed tool invocation. Treat a named choice as required and reject final responses or an empty matching tool set.

AGENTS.md reference: src/AGENTS.md:L19-L19

Useful? React with 👍 / 👎.

Comment thread src/adapters/chatgpt-browser-oracle.ts Outdated
Comment on lines +389 to +393
try { child?.kill("SIGINT"); } catch { /* best-effort cancellation */ }
if (child && !hardKillTimer) {
hardKillTimer = setTimeout(() => {
try { child?.kill("SIGKILL"); } catch { /* best-effort hard cancellation */ }
}, 5_000);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Kill the Oracle process tree on Windows

On Windows with the documented global npm installation, commandInvocation() resolves oracle.cmd through cmd.exe, so these child.kill() calls terminate only the command wrapper rather than the Node/Oracle descendant. The repository's own process-control.ts uses taskkill /T /F for this reason. After cancellation, Oracle can therefore continue the browser submission for up to 60 minutes, consume allowance, and write into a directory that the finally block has removed; terminate and await the full process tree instead.

AGENTS.md reference: src/AGENTS.md:L17-L19

Useful? React with 👍 / 👎.

Comment on lines +311 to +315
const [exitCode, stdout, stderr] = await Promise.all([
child.exited,
readProcessText(child.stdout),
readProcessText(child.stderr),
]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bound the Oracle version probe

If the configured executable or its --version path hangs, this unbounded Promise.all never settles. runOracleBrowserTurn() does not install its abort listener until after awaiting this probe and only checks the signal afterward, while /api/providers/test has no cancellation path at all, so the first browser request or health check can remain stuck indefinitely and impede shutdown. Apply a deadline/abort handler that terminates and reaps the probe process.

AGENTS.md reference: src/AGENTS.md:L17-L19

Useful? React with 👍 / 👎.

Comment on lines +186 to +190
return [
"Continue the OpenAI Responses conversation encoded as JSON below.",
"Follow the system and developer instructions represented in the conversation.",
"Tools listed in conversation.tools are executed by the client, not by ChatGPT. You may request exactly one listed tool call when needed.",
"Return exactly one JSON object and no surrounding prose or Markdown fence. Copy responseProtocol.nonce exactly.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve instruction-role authority

Every system, developer, user, assistant, and tool message is serialized into one string that Oracle submits as a single ChatGPT user prompt. Consequently, when user input or repository content conflicts with a system/developer instruction, ChatGPT receives both at the same transport-level authority; the prose asking it to simulate the encoded roles does not preserve the Responses API's instruction hierarchy. This permits ordinary prompt injection to override developer constraints on this route, so use a transport that can preserve roles or explicitly reject contexts requiring privileged instructions rather than claiming equivalent Responses behavior.

Useful? React with 👍 / 👎.

Comment on lines +225 to +227
if (value.type !== "tool_call" || typeof value.name !== "string" || !plainRecord(value.arguments)) {
throw new ChatGptBrowserError("protocol_error");
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate browser tool arguments against their schema

A browser answer is accepted as a tool call whenever arguments is merely a JSON object and the name exists; selected.parameters is never evaluated. Unlike a native function-calling response, this value is plain model-generated text, so missing required fields, wrong types, disallowed enum values, and unexpected properties are relayed directly to the client tool and can fail or mis-execute the turn. Validate the arguments against the selected tool schema before emitting the call.

AGENTS.md reference: src/AGENTS.md:L19-L19

Useful? React with 👍 / 👎.

logCtx.providerAdapter = adapter.name;
sealRequestAttemptIdentity(logCtx.activeAttempt, logCtx.provider, adapter.name);
const isPassthrough = "passthrough" in adapter && !!adapter.passthrough;
const isChatGptBrowserRoute = route.provider.adapter === "chatgpt-browser";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fail closed when browser continuation state is missing

When a previous_response_id entry has been evicted from the bounded state cache or the server has restarted, _previousResponseInputExpanded remains false. Unlike Cursor, this adapter has no upstream conversation identifier because every Oracle invocation starts a fresh browser chat, yet after identifying the browser route the server proceeds with only the current delta or tool output. This silently drops the prior conversation and spends another Pro turn on an invalid context; add the same fail-closed replay-miss check used for Kiro before invoking Oracle.

AGENTS.md reference: src/AGENTS.md:L17-L19

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs-site/src/content/docs/guides/providers.md`:
- Around line 26-29: Replace “GPT-5.6 Sol Pro” with “GPT-5.6 Pro” in
docs-site/src/content/docs/guides/providers.md lines 26-29 and
structure/04_transports-and-sidecars.md line 56, keeping the browser route
documented consistently as chatgpt-browser/gpt-5.6-pro.

In `@src/adapters/chatgpt-browser.ts`:
- Around line 105-119: Update the catch block around the error normalization in
the ChatGPT browser adapter to record the original error before converting
non-ChatGptBrowserError values to the generic browser_failed error. Preserve the
existing emitted safe error payload and non-retryable behavior, while ensuring
the original exception message and stack are available through the established
server-side logging mechanism.

In `@src/config.ts`:
- Around line 436-438: Make oracleCommand normalization consistent across the
config schema and management-write path by extracting the raw validation and
trimming logic into a shared helper, then reuse it at both call sites. Preserve
rejection of CR/LF and NUL while trimming valid values identically; add coverage
for surrounding whitespace, line breaks, and NUL input.

In `@src/providers/registry.ts`:
- Around line 445-459: The chatgpt-browser provider must not be rewritten by
subagent model fallback. Add an explicit provider guard in the fallback logic
centered on the relevant symbol in subagent-model-fallback.ts, ensuring
thread-spawn requests preserve the registry’s gpt-5.6-pro and no-fallback
contract before route re-selection in core.ts. Add a regression test covering
thread-spawn behavior for chatgpt-browser.

In `@tests/chatgpt-browser-adapter.test.ts`:
- Around line 279-301: Update the message assertion in the “preserves actionable
fail-closed error categories” test so every error code has a non-empty,
code-specific expected message fragment. Replace the conditional fallback that
produces an empty string with explicit expectations for login_required, timeout,
oracle_missing, and oracle_incompatible, while preserving the existing
model_unavailable and quota_exhausted checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8da3589f-6424-499b-9d01-883cf937beb9

📥 Commits

Reviewing files that changed from the base of the PR and between be177ea and 102f00e.

📒 Files selected for processing (36)
  • docs-site/src/content/docs/guides/providers.md
  • docs-site/src/content/docs/ja/reference/adapters.md
  • docs-site/src/content/docs/ja/reference/architecture.md
  • docs-site/src/content/docs/ko/reference/adapters.md
  • docs-site/src/content/docs/ko/reference/architecture.md
  • docs-site/src/content/docs/reference/adapters.md
  • docs-site/src/content/docs/reference/architecture.md
  • docs-site/src/content/docs/reference/configuration.md
  • docs-site/src/content/docs/ru/reference/adapters.md
  • docs-site/src/content/docs/ru/reference/architecture.md
  • docs-site/src/content/docs/zh-cn/reference/adapters.md
  • docs-site/src/content/docs/zh-cn/reference/architecture.md
  • gui/src/provider-workspace/catalog.ts
  • gui/src/provider-workspace/kind.ts
  • src/adapters/chatgpt-browser-oracle.ts
  • src/adapters/chatgpt-browser.ts
  • src/codex/catalog/parsing.ts
  • src/codex/catalog/provider-fetch.ts
  • src/codex/catalog/sync.ts
  • src/config.ts
  • src/providers/derive.ts
  • src/providers/registry.ts
  • src/server/adapter-resolve.ts
  • src/server/auth-cors.ts
  • src/server/management/context.ts
  • src/server/management/provider-routes.ts
  • src/server/responses.ts
  • src/server/responses/core.ts
  • src/types.ts
  • structure/01_runtime.md
  • structure/04_transports-and-sidecars.md
  • tests/chatgpt-browser-adapter.test.ts
  • tests/images/z-handler-activation.test.ts
  • tests/provider-connection-test.test.ts
  • tests/provider-workspace-data.test.ts
  • tests/responses-state.test.ts

Comment thread docs-site/src/content/docs/guides/providers.md Outdated
Comment thread src/adapters/chatgpt-browser.ts
Comment thread src/config.ts Outdated
Comment thread src/providers/registry.ts
Comment thread tests/chatgpt-browser-adapter.test.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/server/responses/core.ts (1)

2082-2118: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Non-streaming chatgpt-browser turns can't surface fail-closed errors — always return HTTP 200.

The streaming branch (Lines 2025-2039) explicitly runs preflightAdapterEvents for adapterNeedsErrorPreflight(adapter.name) adapters (currently only chatgpt-browser) and converts a leading error event into a real formatErrorResponse(status, errorType, message, {code}). The non-streaming branch below only special-cases options.comboAttempt (Line 2084-2092); for an ordinary non-streaming request it passes every event — including a leading {type:"error", status, errorType, code} from the ChatGPT Browser adapter — straight into buildResponseJSON, then returns:

return new Response(JSON.stringify(json), { headers: { "Content-Type": "application/json" } });

No status is set, so this is always HTTP 200, regardless of whether the browser turn actually failed closed (login required, quota exhausted, Oracle missing/incompatible, etc.). This defeats the PR's "distinct fail-closed errors" objective for any client that sets stream:false against chatgpt-browser/gpt-5.6-pro, and there's no test in this PR covering that path.

🐛 Proposed fix
     await runTurn();
     const events = await queue.collect();
-    if (options.comboAttempt) {
+    if (options.comboAttempt || adapterNeedsErrorPreflight(adapter.name)) {
       const firstMeaningful = events.find(event => event.type !== "heartbeat");
       if (!firstMeaningful || firstMeaningful.type === "error") {
         const message = firstMeaningful?.type === "error"
           ? firstMeaningful.message
           : "Adapter ended before producing a response";
-        return formatErrorResponse(502, "upstream_error", redactSecretString(message));
+        if (options.comboAttempt) {
+          return formatErrorResponse(502, "upstream_error", redactSecretString(message));
+        }
+        return formatErrorResponse(
+          firstMeaningful?.type === "error" ? (firstMeaningful.status ?? 502) : 502,
+          firstMeaningful?.type === "error" ? (firstMeaningful.errorType ?? "upstream_error") : "upstream_error",
+          redactSecretString(message),
+          firstMeaningful?.type === "error" ? { code: firstMeaningful.code } : undefined,
+        );
       }
     }

Please also add a focused regression test near tests/images/z-handler-activation.test.ts covering stream:false against the chatgpt-browser route with a fail-closed adapter error, per the tests/** convention that behavior changes need adjacent regression coverage.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/server/responses/core.ts` around lines 2082 - 2118, Update the
non-streaming turn handling around runTurn, queue.collect, and buildResponseJSON
to preflight adapter events for adapters requiring error preflight, matching the
streaming branch. When a leading fail-closed error is present, return
formatErrorResponse with its status, errorType, message, and code instead of
constructing the normal HTTP 200 response; preserve comboAttempt handling and
successful responses. Add a focused regression test near
z-handler-activation.test.ts covering stream:false on the chatgpt-browser route
with a fail-closed adapter error and asserting the propagated status and error
payload.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/adapters/chatgpt-browser-oracle.ts`:
- Line 5: Add regression tests covering the pinned fromJSONSchema behavior used
by chatgpt-browser-oracle.ts: validate required fields, reject wrong types, and
handle additional properties before arguments reach dispatch. Reuse the existing
adapter test setup and target the schema/parsing flow around the tool-argument
handling symbols near lines 144-156 and 254-256; do not change dependency
versions.

---

Outside diff comments:
In `@src/server/responses/core.ts`:
- Around line 2082-2118: Update the non-streaming turn handling around runTurn,
queue.collect, and buildResponseJSON to preflight adapter events for adapters
requiring error preflight, matching the streaming branch. When a leading
fail-closed error is present, return formatErrorResponse with its status,
errorType, message, and code instead of constructing the normal HTTP 200
response; preserve comboAttempt handling and successful responses. Add a focused
regression test near z-handler-activation.test.ts covering stream:false on the
chatgpt-browser route with a fail-closed adapter error and asserting the
propagated status and error payload.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a7a48685-21c2-43a2-9f60-af0fc186e693

📥 Commits

Reviewing files that changed from the base of the PR and between 102f00e and 19812ae.

📒 Files selected for processing (13)
  • docs-site/src/content/docs/guides/providers.md
  • docs-site/src/content/docs/reference/adapters.md
  • src/adapters/chatgpt-browser-oracle.ts
  • src/adapters/chatgpt-browser.ts
  • src/codex/subagent-model-fallback.ts
  • src/config.ts
  • src/lib/process-control.ts
  • src/server/responses/core.ts
  • structure/04_transports-and-sidecars.md
  • tests/chatgpt-browser-adapter.test.ts
  • tests/config.test.ts
  • tests/images/z-handler-activation.test.ts
  • tests/subagent-model-fallback.test.ts

import { chmod, lstat, mkdtemp, readFile, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fromJSONSchema, type ZodType } from "zod";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Is zod's z.fromJSONSchema() still marked experimental in the latest zod release, and what changed in its behavior across recent versions?

💡 Result:

As of July 30, 2026, the z.fromJSONSchema function in Zod is still officially marked as experimental and is not considered part of Zod's stable API [1][2][3]. It is expected to undergo implementation changes in future releases [1][4][3]. Key aspects of its development and behavior in recent versions include: 1. Initial Implementation and Evolution: The function was introduced in Zod v4.2.0 [5] and refined in subsequent releases like v4.3.0 [6]. 2. Purpose and Support: It is designed to convert JSON Schema definitions (supporting drafts 4, 7, 2020-12, and OpenAPI 3.0) into Zod schemas [7][6]. 3. Metadata Handling: Recent updates, such as those in PR #5586 (included in v4.3.0), added support for capturing JSON Schema metadata (e.g., title, deprecated, examples, and custom extension fields) and storing them in a registry [8]. 4. Limitations: The maintainers note that there is no guarantee of perfect 1:1 round-trip soundness (MySchema > z.toJSONSchema > z.fromJSONSchema) due to fundamental differences between Zod and JSON Schema capabilities [6]. Additionally, the implementation uses a JSON round-trip process to normalize inputs, meaning it will fail on cyclic inputs (unless handled via $defs/$ref) and convert class instances to plain objects [4].

Citations:


🏁 Script executed:

printf '%s\n' '--- dependency declarations ---'
rg -n '"zod"|fromJSONSchema|toolArgumentsMatchSchema' --glob 'package.json' --glob 'bun.lockb' --glob 'bun.lock' --glob 'yarn.lock' --glob 'package-lock.json' --glob 'pnpm-lock.yaml' --glob 'src/adapters/chatgpt-browser-oracle.ts'
printf '%s\n' '--- relevant implementation ---'
sed -n '135,165p' src/adapters/chatgpt-browser-oracle.ts
sed -n '240,260p' src/adapters/chatgpt-browser-oracle.ts

Repository: lidge-jun/opencodex

Length of output: 189


🏁 Script executed:

printf '%s\n' '--- tracked dependency/config files ---'
git ls-files | rg '(^|/)(package\.json|bun\.lockb?|yarn\.lock|package-lock\.json|pnpm-lock\.yaml)$' || true
printf '%s\n' '--- tracked Oracle adapter files ---'
git ls-files | rg 'chatgpt-browser-oracle\.ts$' || true
printf '%s\n' '--- repository references ---'
rg -n 'fromJSONSchema|toolArgumentsMatchSchema|"zod"' . --hidden -g '!node_modules' -g '!dist' -g '!build' || true

Repository: lidge-jun/opencodex

Length of output: 5253


Add regression coverage for the pinned fromJSONSchema contract.

package.json and bun.lock already pin Zod to 4.4.3, so no further pinning is needed. Add tests for required fields, wrong types, and additional properties around src/adapters/chatgpt-browser-oracle.ts:144-156 to catch behavior changes before tool arguments reach dispatch at lines 254-256.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/adapters/chatgpt-browser-oracle.ts` at line 5, Add regression tests
covering the pinned fromJSONSchema behavior used by chatgpt-browser-oracle.ts:
validate required fields, reject wrong types, and handle additional properties
before arguments reach dispatch. Reuse the existing adapter test setup and
target the schema/parsing flow around the tool-argument handling symbols near
lines 144-156 and 254-256; do not change dependency versions.

@lidge-jun

Copy link
Copy Markdown
Owner

Closing this. It is browser automation of the consumer ChatGPT web UI, and this project will not carry that.

What the patch actually does: src/adapters/chatgpt-browser-oracle.ts spawns Oracle with --engine browser --chatgpt-url https://chatgpt.com/, drives the signed-in session's model picker and composer, and scrapes the rendered answer back into a Responses stream. However #650 was framed, that is scripted use of the ChatGPT web interface to serve API-shaped traffic. The PR description states the motivation plainly - "GPT-5.6 Pro is available through standard ChatGPT limits, while Codex and Work share a separate agentic usage pool" - which is agent traffic deliberately moved onto an allowance that was not sold for it. OpenAI's terms prohibit automated or scripted access to the service outside its published APIs, and prohibit circumventing access restrictions and usage limits. The size of the test suite does not change that; the design itself is the blocker, so there is no revision of this branch that becomes mergeable.

Secondary problems, none of which are the reason for closing:

  • The adapter's own documentation concedes that system and developer roles collapse into advisory text inside a single composer message. Instruction-authority isolation is gone, and untrusted repository content on this route becomes prompt-injection-capable by construction.
  • It introduces a hard runtime dependency on a third-party CLI plus a persistent authenticated browser profile holding live session credentials.
  • It breaks on any upstream UI change, which makes it a permanent maintenance liability for a route that should not exist.

The isLocalProvider / isFreeProvider narrowing to loopback-only in gui/src/provider-workspace/ is unrelated to the stated feature and should not have been bundled here. If you want it considered, open it separately against dev.

To be direct: do not open another pull request or issue that automates or scrapes a provider's web UI to obtain model access outside its published API. One more submission of this kind and issue/pull-request access for this account will be blocked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants