Skip to content

feat(agent): free DeepSeek Codex path via control plane (ENG-4785)#264

Merged
LarsenCundric merged 4 commits into
mainfrom
larsen/eng-4785-codex-free-config
May 26, 2026
Merged

feat(agent): free DeepSeek Codex path via control plane (ENG-4785)#264
LarsenCundric merged 4 commits into
mainfrom
larsen/eng-4785-codex-free-config

Conversation

@LarsenCundric
Copy link
Copy Markdown
Contributor

@LarsenCundric LarsenCundric commented May 25, 2026

What

Box side of the "no Codex subscription → free DeepSeek" option. Pairs with cloud PR browser-use/cloud#4551 (the setup choice + codex_use_free WS command) and browser-use/cloud#4542 (the control-plane proxy).

Codex (CLI on box)  →  CP /api/codex/v1/chat/completions  →  OpenRouter  →  DeepSeek V4

How

bootstrap.sh — writes, on every box, an inert Codex provider/profile:

  • [model_providers.browser-use-free]: base_url at the control plane (derived from BUX_CLOUD_URL, wss://https://, + /api/codex/v1), wire_api = "chat", auth.command = /usr/local/bin/bu-cp-token.
  • [profiles.browser-use-free]: model = "deepseek/deepseek-v4-flash".
  • bu-cp-token helper: prints $BUX_BOX_TOKEN from /etc/bux/env so Codex authenticates to the CP with the box token (read at call time → token rotation just works). The CP holds the OpenRouter key; the box never sees it.
  • Idempotent (grep-guarded), non-fatal on failure — same pattern as the existing [features] goals writer right above it.

Why inert, not default: codex exec (how the box runs Codex) reads the default provider in config.toml and ignores --profile. Making the free provider the global default would silently route own-sub users through us. So bootstrap only ships the block; selecting it is per-box and explicit.

box_agent.py — handles the codex_use_free WS command:

  • Sets the top-level profile = "browser-use-free" line (idempotent awk/prepend), making the free profile this box's default.
  • check_codex_authed() now treats an active browser-use-free profile as authed — the free path has no codex login (the CP holds the credential), so this is what flips codex_authed and completes the setup wizard. Nudges the auth poll loop so it reports immediately.

Gates

  • ruff check agent/ (what CI runs) — clean.
  • bash -n agent/bootstrap.sh — valid.
  • Style matches the file (tabs, single quotes); deliberately did not run ruff format since the repo isn't formatted with it and CI doesn't gate on it.

🤖 Generated with Claude Code


Summary by cubic

Adds an opt-in free DeepSeek path for Codex via the control plane for boxes without a Codex subscription (ENG-4785). Uses the CP PrivateLink endpoint (BUX_CP_CODEX_URL) and treats the active free profile as authed with no login.

  • New Features

    • bootstrap.sh: writes inert [model_providers.browser-use-free] and [profiles.browser-use-free] to ~/.codex/config.toml with base "$BUX_CP_CODEX_URL/api/codex/v1", wire_api = "chat", auth.command /usr/local/bin/bu-cp-token, model deepseek/deepseek-v4-flash; not default; idempotent; skip if BUX_CP_CODEX_URL is unset.
    • Adds /usr/local/bin/bu-cp-token to emit $BUX_BOX_TOKEN from /etc/bux/env; CP holds the OpenRouter key.
    • box_agent.py: handles codex_use_free to set the top‑level profile = "browser-use-free" for bux; treats an active free profile as authed and wakes the auth poll loop.
  • Bug Fixes

    • bootstrap.sh and bu-cp-token: do not source /etc/bux/env as root; grep only BUX_CP_CODEX_URL and BUX_BOX_TOKEN.
    • box_agent.py: ensure codex_use_free always sets the top‑level profile (single awk pass + verify). Tighten _codex_free_profile_active() to match the exact top‑level profile key.
    • bootstrap.sh: normalize BUX_CP_CODEX_URL to an absolute https:// base_url (handle bare host and ws/wss) to prevent invalid routing.

Written for commit c12e854. Summary will update on new commits. Review in cubic

Wire the box side of the 'no Codex sub' option. The cloud PR adds the
setup choice + the codex_use_free WS command; this makes the box honor it.

- bootstrap.sh: write an INERT [model_providers.browser-use-free] +
  [profiles.browser-use-free] block in ~/.codex/config.toml (base_url at
  the control plane, wire_api=chat, auth.command=bu-cp-token), plus the
  bu-cp-token helper that hands codex the box token. Not the default —
  codex exec reads the default provider and ignores --profile, so making
  it default would route own-sub users through us. Idempotent.
- box_agent.py: handle the codex_use_free WS command — set the top-level
  profile line so the free profile becomes this box's default, then nudge
  the auth poll loop. check_codex_authed() now treats an active
  browser-use-free profile as authed (the free path has no codex login;
  the control plane holds the credential), so codex_authed flips and the
  setup wizard completes.

Pairs with cloud PR #4551.
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 2 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread agent/bootstrap.sh Outdated
Comment thread agent/box_agent.py Outdated
- P0 (bootstrap.sh): don't source /etc/bux/env as root — sourcing executes
  the file as shell, so a tampered line would run as root. grep only the
  BUX_CLOUD_URL / BUX_BOX_TOKEN values we need (URL/token, no shell metachars).
  Applied to both the provider-config block and the bu-cp-token helper.
- P2 (box_agent.py): the grep gate matched any 'profile =' (incl. inside a
  table) but the awk only rewrote a top-level one, so codex_use_free could
  report success without setting the default profile. Replace with a single
  awk pass that always sets the top-level key (replace-in-place or insert
  above the first table), plus a verify step that fails if it isn't set.
…ublic host (ENG-4785)

The CP is internal-only and reachable from the box VPC only over PrivateLink;
the public BUX_CLOUD_URL host has no /api/codex route. So bootstrap now reads
BUX_CP_CODEX_URL (the PrivateLink endpoint DNS the provisioner writes into
/etc/bux/env) as Codex's base_url, instead of deriving it from BUX_CLOUD_URL.
Empty (not set / not staging) -> skip writing the free-Codex provider block.

Also: tighten _codex_free_profile_active() to match the top-level 'profile'
key exactly (not startswith), so 'profile_dir'/'profiles' can't be mistaken
for the default-profile selector.

Pairs with cloud #4561 (writes BUX_CP_CODEX_URL, staging-gated).
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 2 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread agent/bootstrap.sh
…l (Cubic, ENG-4785)

Coerce the value to an absolute https:// base_url: tolerate a bare host or a
stray ws/wss value rather than emitting a scheme-less base_url that silently
breaks Codex routing.
@LarsenCundric LarsenCundric merged commit dd86997 into main May 26, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant