Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

codex-chatgpt-control Python SDK

Python parity client for controlling visible ChatGPT Chat and Work through the shared Node backend protocol.

Unofficial project: not affiliated with, endorsed by, or sponsored by OpenAI. This is not an OpenAI API wrapper and does not call hidden or private ChatGPT endpoints.

Python SDK -> backend protocol -> Node runtime -> browser bridge -> visible chatgpt.com session

The current browser-control runtime is Node/TypeScript. Python talks to it through a long-lived local stdio backend service. This is intentionally not a pure-Python browser-control runtime yet.

Install

python -m pip install --pre codex-chatgpt-control

The Python package needs a Node backend command for browser-control workflows. Install or build the Node package too:

npm install codex-chatgpt-control@next

Development Install

Build the backend bundle first:

cd ../node
npm ci
npm run bundle:backend

Install the Python package:

cd ../python
python -m pip install -e .[dev]

Sync Usage

from codex_chatgpt_control import Agent, BackendClient, Runner, StdioBackendTransport

backend = BackendClient(StdioBackendTransport(
    command=["node", "../node/dist/codex-chatgpt-control-backend.mjs"]
))
runner = Runner(backend)
agent = Agent(name="reviewer", instructions="Review carefully.")

try:
    result = runner.run_sync(agent, {
        "input": "Reply with hi.",
        "thread": {"type": "new"},
        "response": {"format": "markdown"},
    })
finally:
    backend.close()

print(result.status)
print(result.output_text)

Agents-Style API

The Python SDK exposes OpenAI Agents SDK-inspired names where they fit the visible-session product:

  • Agent
  • Runner.run
  • Runner.run_sync
  • Runner.run_streamed
  • RunResult
  • RunResultStreaming

The semantics are browser-control semantics, not OpenAI API semantics. Instructions are visible by default and are submitted to ChatGPT web as prompt text unless instructions_mode="metadata_only" is used.

Product-Specific API

The ChatGPT facade exposes workflows and primitive command groups:

  • chatgpt.responses.create(...)
  • chatgpt.ask(...), ask_in_thread(...), ask_with_files(...)
  • chatgpt.run_plan({"name": "new-ask-read", ...})
  • chatgpt.doctor(...)
  • chatgpt.reports.create(...)
  • chatgpt.session, experience, configuration, work, threads, messages, artifacts, files, projects.sources, modes, tools, response
  • chatgpt.commands(), describe(...), help(...)
  • chatgpt.explain_blocker(result_or_blocker, ...) and module-level explain_blocker(...)

Unsupported OpenAI API-only Responses fields, such as model, temperature, and previous_response_id, return explicit unsupported responses instead of silently submitting misleading prompts.

Inspect and control Chat or Work with the same sync/async surface:

surface = chatgpt.experience.detect()
capabilities = chatgpt.configuration.inspect(experience="work")

applied = chatgpt.configuration.apply(
    experience="work",
    desired={
        "model": "GPT-5.6 Sol",
        "effort": "High",
        "speed": "Standard",
    },
    strict=True,
)

started = chatgpt.work.start(
    prompt="Produce a decision-ready implementation brief.",
    new_task=True,
    wait=False,
    read=False,
)

Use work.status, work.wait, work.steer, work.read_latest, and work.artifacts after submission. Legacy modes APIs remain available for existing callers.

Blocker Explainability

explain_blocker(...) preserves backend blocker dictionaries and returns structured fields plus Markdown for logs or CLI output:

result = chatgpt.session.bootstrap(existing_tab=True)
if not result.ok:
    explanation = chatgpt.explain_blocker(result, command="session.bootstrap")
    print(explanation["markdown"])

Existing-tab blockers expose only safe metadata: requested target, candidate tab IDs, URLs, titles, conversation IDs, omitted candidate count, and mismatch reason. They do not include page text or chat content.

Host-Local Attachment Paths

The Python client does not normalize attachment paths. It forwards them to the Node backend. Use the path form for the backend host, not necessarily the Python caller host. If Python is running on WSL but the backend is running in Windows, pass a Windows path. If the backend is running in WSL/Linux, pass a Linux path such as /home/you/file.pdf.

Validate local file metadata without opening ChatGPT:

preflight = chatgpt.files.preflight(paths=["/absolute/host/path/to/report.pdf"])
if not preflight.ok:
    print(preflight.blocker)

Plan append-only ChatGPT Project Sources changes before mutating a project:

plan = chatgpt.projects.sources.plan_add(
    project_url="https://chatgpt.com/g/g-p-example/project",
    files=["/absolute/host/path/to/source.md"],
)

added = chatgpt.projects.sources.add(
    project_url="https://chatgpt.com/g/g-p-example/project",
    files=["/absolute/host/path/to/source.md"],
    confirm_mutation=True,
)

plan_add validates explicit local file metadata without reading file contents or opening ChatGPT. add is append-only and returns needs_confirmation unless confirm_mutation=True is supplied.

Backend And Browser Bridge

Ordinary shells can launch the backend and validate the protocol. Browser-required calls need a compatible browser bridge.

Without a bridge, live browser operations should return:

{
  "kind": "browser_bridge_unavailable"
}

That blocker is expected in ordinary shells. A real live browser pass requires a backend command with bridge access. A plain Python-spawned Node subprocess does not automatically inherit a Codex browser bridge.

Override the backend command when needed:

CHATGPT_BROWSER_BACKEND_COMMAND="node /absolute/path/to/bridge-enabled-backend.mjs" \
python scripts/live_smoke.py --mode browser-bridge

Validation

Run from packages/python:

python -m unittest discover -s tests
python -m compileall -q src examples
python -m pyright src tests
python scripts/live_smoke.py --mode ordinary-shell

The ordinary-shell smoke succeeds when the backend stays alive, backend.health succeeds, command descriptors load, and browser-required calls return browser_bridge_unavailable.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

codex_chatgpt_control-0.5.0a1.tar.gz (62.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

codex_chatgpt_control-0.5.0a1-py3-none-any.whl (37.6 kB view details)

Uploaded Python 3

File details

Details for the file codex_chatgpt_control-0.5.0a1.tar.gz.

File metadata

  • Download URL: codex_chatgpt_control-0.5.0a1.tar.gz
  • Upload date:
  • Size: 62.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for codex_chatgpt_control-0.5.0a1.tar.gz
Algorithm Hash digest
SHA256 3846e083eaf549d2c02906d9413563480eb254a9bad2039fb699fbea33648d02
MD5 b970e4b8214769eb63e40a61c8a98ad0
BLAKE2b-256 d5b9f09fdf63db2ae67f748a8ac3344e71029d15f56b374514b2df1603a4c5cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for codex_chatgpt_control-0.5.0a1.tar.gz:

Publisher: release.yml on adamallcock/codex-chatgpt-control

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file codex_chatgpt_control-0.5.0a1-py3-none-any.whl.

File metadata

File hashes

Hashes for codex_chatgpt_control-0.5.0a1-py3-none-any.whl
Algorithm Hash digest
SHA256 6f1244917e6be597d6f77c75308faa59ce4846f5df61ba1e5fdc09aa36900e46
MD5 068b77aeefa65dc6666dfe1e13dd23ff
BLAKE2b-256 321fc6d5d97a58ccefd5ff3adaa97293f9ef683a968f4f5c6c387bd42c131d96

See more details on using hashes here.

Provenance

The following attestation bundles were made for codex_chatgpt_control-0.5.0a1-py3-none-any.whl:

Publisher: release.yml on adamallcock/codex-chatgpt-control

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page