Studio: spoof-aware Codex availability probe + autouse fixture

When ``UNSLOTH_CODEX_SPOOF=1`` is exported (the credit-free dev / CI
path the previous commit added), the in-process spoof IS the Codex
SDK and a real ``codex`` CLI is irrelevant. The status endpoint at
``/api/codex/status`` used to gate ``installed`` on the real CLI +
real SDK only, which made the frontend hide the Codex provider in
the connections dropdown even when the spoof was active. Now both
``_sdk_importable`` and ``probe_codex_availability`` short-circuit on
``codex_spoof.is_spoof_enabled()`` so the provider becomes visible
under the spoof. ``installed=True``, ``cli_path="<spoof>"``,
``logged_in=True``, ``version="spoof"`` -- a sentinel that lets devs
read off "yes I am under the spoof" at a glance.

Real production code path (no spoof flag) is unchanged: still gates
on bool(cli_path) AND sdk_ok the same as round 6.

Tests: added an autouse fixture in ``test_codex_provider.py`` that
clears ``UNSLOTH_CODEX_SPOOF`` before every test so the existing
availability / import gating tests are not polluted when a dev runs
the suite with the flag exported. The spoof-targeted tests still
call ``monkeypatch.setenv(...)`` to flip it back on inside their own
scope. 69/69 pass with and without the env flag.
This commit is contained in:
Daniel Han 2026-05-27 14:44:15 +00:00
commit 6403846bbe
2 changed files with 39 additions and 4 deletions

View file

@ -146,7 +146,19 @@ def _sdk_importable() -> bool:
Probes both ``openai_codex`` (the canonical upstream package name
at ``openai/codex/sdk/python``) and ``codex_app_server`` (the Rust
crate name, kept as a forward-compat alias).
When ``UNSLOTH_CODEX_SPOOF=1`` is set we report importable=True so
the frontend exposes the Codex provider in dev / CI without a real
SDK install. The spoof module gets swapped into ``sys.modules`` on
first ``_import_codex`` call, so any downstream consumer that
actually imports also succeeds.
"""
try:
from core.inference import codex_spoof
if codex_spoof.is_spoof_enabled():
return True
except Exception:
pass
for name in _SDK_MODULE_NAMES:
try:
if importlib.util.find_spec(name) is not None:
@ -338,17 +350,28 @@ async def probe_codex_availability() -> dict[str, Any]:
cli_path = _which_codex()
sdk_ok = _sdk_importable()
# Spoof mode also fakes the CLI half of the install signal so the
# frontend stops hiding the Codex provider in dev / CI. ``installed``
# gates on the spoof being explicitly opted in, so production hosts
# without the flag still see the real CLI / SDK gating intact.
spoof_active = False
try:
from core.inference import codex_spoof
spoof_active = codex_spoof.is_spoof_enabled()
except Exception:
pass
payload: dict[str, Any] = {
# Gate on BOTH because the login flow shells out to `codex`.
# Round 5 briefly set this to `sdk_ok` alone, but round 6
# caught that the login route would then fail with
# `codex CLI not found on PATH` after the user clicked
# Sign in, leaving them with an unusable provider row.
"installed": bool(cli_path) and sdk_ok,
"cli_path": cli_path,
"installed": (bool(cli_path) and sdk_ok) or spoof_active,
"cli_path": cli_path or ("<spoof>" if spoof_active else None),
"sdk_importable": sdk_ok,
"logged_in": False,
"version": None,
"logged_in": spoof_active,
"version": "spoof" if spoof_active else None,
"supported_models": list(_DEFAULT_SUPPORTED_MODELS),
}

View file

@ -34,6 +34,18 @@ from typing import Any
import pytest
@pytest.fixture(autouse = True)
def _no_spoof_by_default(monkeypatch):
"""Tests in this file assume the real-SDK gating path unless they
explicitly re-enable the spoof. The dev environment sometimes has
UNSLOTH_CODEX_SPOOF=1 exported for the live UI; clearing it here
keeps the existing availability + import tests deterministic.
Tests that exercise the spoof use ``monkeypatch.setenv(...)`` to
flip it back on inside their own scope.
"""
monkeypatch.delenv("UNSLOTH_CODEX_SPOOF", raising = False)
_backend = os.path.join(os.path.dirname(__file__), "..")
if _backend not in sys.path:
sys.path.insert(0, _backend)