unsloth/studio/backend/core/inference
Daniel Han fd8f25f507 Studio: scrub Codex subprocess env, guard partial-stream replay, abort login on unmount
Third reviewer.py pass found three remaining sharp edges. Each fix
is small and paired with a regression test where applicable.

* Codex subprocess env is now scrubbed to a safe-list before spawn.
  Both `_run_cli` in codex_availability and the device-auth spawn
  in stream_codex_device_login switch from `env=os.environ.copy()`
  to `env=_codex_subprocess_env()`, which forwards only PATH /
  HOME / USER / Windows-equivalents / CODEX_HOME / OPENAI_API_KEY /
  OPENAI_BASE_URL. Other-provider secrets like HF_TOKEN, GH_TOKEN,
  WANDB_API_KEY, ANTHROPIC_API_KEY no longer reach the local codex
  binary, so a shimmed `codex` earlier on PATH cannot harvest them.

* `_stream_thread_run` now tracks `emitted_any` and refuses to fall
  through to the buffered `await thread.run(prompt)` after either
  streaming helper has already yielded text. Previously a network
  glitch mid-stream re-executed the same Codex turn, which can
  duplicate file writes, shell commands, and other Codex side
  effects. The buffered path is now reserved for the zero-output
  case (no streaming helper resolved, or streaming returned empty).

* `CodexLoginButton` now aborts the SSE reader on unmount via a
  useEffect cleanup that calls `abortRef.current?.abort()`. The
  underlying `codex login --device-auth` subprocess no longer
  keeps streaming (and holding a device-auth session) after the
  dialog closes.

Two new pytest cases pin the behaviour: `test_codex_subprocess_env_scrubbed`
sets HF/GH/WANDB/ANTHROPIC keys and asserts none reach the codex
env while OPENAI_API_KEY / CODEX_HOME survive; and
`test_partial_stream_failure_does_not_replay_turn` injects a fake
`turn().stream()` that yields "partial output " then raises, and
asserts `thread.run()` is never called. 28/28 codex_provider tests
pass; `tsc --noEmit` clean.
2026-05-24 15:16:38 +00:00
..
__init__.py Final cleanup 2026-03-12 18:28:04 +00:00
_html_to_md.py fix: studio web search SSL failures and empty page content (#4754) 2026-04-01 06:12:02 -07:00
anthropic_compat.py Studio: Claude Code Anthropic API tool compatibility (#5390) 2026-05-21 16:45:05 +04:00
audio_codecs.py Add native GGUF intake to Studio (#5246) 2026-05-04 11:46:18 +02:00
chat_template_helpers.py Studio: tools, thinking blocks, code execution and web search for safetensors (#5520) 2026-05-19 06:30:17 -07:00
codex_availability.py Studio: scrub Codex subprocess env, guard partial-stream replay, abort login on unmount 2026-05-24 15:16:38 +00:00
codex_provider.py Studio: scrub Codex subprocess env, guard partial-stream replay, abort login on unmount 2026-05-24 15:16:38 +00:00
defaults.py studio: engage draft-mtp on vision MTP GGUFs (drop incorrect vision gate) (#5560) 2026-05-18 08:42:55 -07:00
external_provider.py wip: anthropic citation helper 2026-05-23 14:00:31 +00:00
inference.py Studio: tools, thinking blocks, code execution and web search for safetensors (#5520) 2026-05-19 06:30:17 -07:00
key_exchange.py studio: API external provider support for chat (OpenAI, Mistral, Gemini, Cohere, Anthropic, OpenRouter, DeepSeek, custom providers) (#4706) 2026-05-14 16:13:59 +04:00
llama_cpp.py studio: settle GPU VRAM after killing llama-server before the next reload (#5693) 2026-05-22 05:50:39 -07:00
llama_server_args.py studio: add --spec-draft-n-max toggle for MTP speculative decoding (#5582) 2026-05-19 06:17:04 -07:00
mlx_inference.py Studio: tools, thinking blocks, code execution and web search for safetensors (#5520) 2026-05-19 06:30:17 -07:00
orchestrator.py Studio: tools, thinking blocks, code execution and web search for safetensors (#5520) 2026-05-19 06:30:17 -07:00
pricing.py Studio: per-session cost calculator + /api/providers/pricing endpoint (#5690) 2026-05-22 06:03:43 -07:00
providers.py Studio: name the actual PyPI package in the Codex install hint 2026-05-24 14:25:04 +00:00
safetensors_agentic.py Studio: tools, thinking blocks, code execution and web search for safetensors (#5520) 2026-05-19 06:30:17 -07:00
tool_call_parser.py Revert "studio: tool calling for Llama-3, Mistral, Gemma 4 on safetensors + MLX (#5615)" (#5619) 2026-05-19 07:26:39 -07:00
tools.py studio: tighten sandbox blocklist precision (bash, hf upload, NOFILE) (#5487) 2026-05-18 00:01:17 -07:00
worker.py Studio: tools, thinking blocks, code execution and web search for safetensors (#5520) 2026-05-19 06:30:17 -07:00