feat(chatgpt-ui): profile pool hardening — slot health, safe Chromium cleanup, telemetry#679
Conversation
… cleanup, and telemetry Per-slot health/quarantine keeps a single broken login or crashed browser from stalling every GPT Pro mission: auth and launch failures quarantine a slot immediately, repeated compatibility failures quarantine after three strikes, and a fully quarantined pool fails open so missions never deadlock. Leftover Chromium Singleton files are now removed only when provably safe (same-host dead pid, or pool-owned via an ownership marker that survives container hostname churn); regular files and live-process locks are never touched. Driver error codes map to structured failure classes, composer selectors prefer stable data-testids with anchored role fallbacks, and diagnostics stay on a fixed-string allowlist. Slot state is exposed at GET /api/backends/chatgpt_ui/profile-pool (basenames only) with a read-only dashboard panel.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@codex review |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_e5682541-c6b4-4751-ac93-752731a94ef6) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2d0ee1b9bc
ℹ️ 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".
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_faedec25-a199-49f0-996f-6a694dc16ff6) |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cb22bddcc5
ℹ️ 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".
| if let Some(kind) = slot_failure { | ||
| profile_pool::record_slot_failure(&profile_dir, kind); | ||
| } | ||
| terminate_child_tree(&mut child).await; | ||
| return AgentResult::failure(format!("chatgpt_ui: {message}"), 0) |
There was a problem hiding this comment.
Retry another slot after a slot-local driver failure
When the selected profile emits auth_required or compatibility while another configured profile is healthy, this records the bad slot but immediately returns the failed turn instead of reacquiring from the pool. The main and parallel mission controllers only auto-resume failures classified as TransportError, whereas these codes are classified as AuthError and ProviderError, so the advertised different-slot retry never occurs and the mission fails until the user manually resumes it. Retry once through acquire_profile after recording these slot-local failures so the healthy profile can serve the current mission.
Useful? React with 👍 / 👎.
Summary
src/api/runners/chatgpt_ui/profile_pool.rs): auth failures quarantine a slot 30 min, launch failures 5 min, compatibility failures 10 min after 3 consecutive strikes; success resets. A fully quarantined pool fails open so missions never deadlock. Existing lease/wait/cancel semantics preserved.src/api/runners/chatgpt_ui/chromium_cleanup.rs):SingletonLock/SingletonCookie/SingletonSocketare removed only when provably safe — same-host + dead pid, or pool-owned via an ownership marker (.{name}.sandboxed-chatgpt-ui.owner, stored outside the profile) that survives container hostname churn. Live-process locks, foreign unowned locks, and regular files are never touched; unlaunchable profiles fail fast with a structured error instead of a browser crash loop.TerminalReason/FailureClass(auth_required→AuthError,rate_limited→RateLimited,browser_launch→TransportError,compatibility→ProviderError) and feed slot health.scripts/chatgpt_ui_driver.py): send/stop controls resolve via stabledata-testids first, falling back to composer-form-scoped anchored accessible-name regexes; fallback use emits one fixed-string diagnostic.GET /api/backends/chatgpt_ui/profile-poolreturns slot state (available/in_use/quarantined), failure counts, and quarantine countdown — profile basenames only, never full paths or contents. Diagnostics remain on the fixed-string allowlist.Baseline:
17bbf178(current origin/master, includes #677 — no overlap: #677 covered watchdog/liveness, this covers pool health/cleanup/telemetry).Verification
cargo fmt --all/cargo fmt --all --check— cleancargo check --all-targets— cleancargo clippy --all-targets -- -D warnings— cleancargo test— 1513 passed / 1 ignored / 1 failed:api::remote_build::tests::wrapper_resumes_an_interrupted_async_job_without_resubmitting, pre-existing (reproduced identically on pristine17bbf178), unrelated to this changecargo test --lib chatgpt_ui— 27/27 (pool quarantine, fail-open, concurrency lease exclusivity, Singleton judgment, ownership marker, error-code classification, diagnostics allowlist)unittestinscripts/— 17/17 (selector fallback matrix, anchored names, download safety)vitest254/254 (incl. new pool-panel test),eslint0 errors (no findings in touched files),next buildproduction build passesTest plan
Note
Medium Risk
Changes the ChatGPT UI mission path (profile selection, on-disk browser profile cleanup, and failure classification); cleanup is conservative but incorrect judgment could affect live browser processes or profile locks.
Overview
Hardens the ChatGPT UI browser profile pool so missions skip bad slots, recover from crashed Chromium state, and expose operator-friendly status.
Runner / pool: Profile leasing moves into
profile_poolwith per-slot health: auth and launch failures quarantine slots for timed cooldowns; compatibility failures quarantine after repeated strikes; successes reset health. Acquisition prefers cleaner slots over ones with recent failures. Driver error codes map to terminal reasons and, where appropriate, slot-local failure records (browser_launchdeliberately does not quarantine a slot).Chromium: Before/after each Chromium turn, conservative cleanup of
SingletonLock/ cookie / socket entries runs only under the profile lock, with pool ownership markers so container hostname changes do not strand profiles. Unlaunchable singleton states fail fast with structured errors instead of looping launches.Driver: Send/stop controls resolve via
data-testidfirst, then composer-scoped anchored button names, with one-shot fallback diagnostics.API & dashboard:
GET /api/backends/chatgpt_ui/profile-poolreturns basename-only slot telemetry (state, failures, quarantine countdown). The ChatGPT UI backends tab polls this when runtime paths are configured and shows a read-only pool status panel.Reviewed by Cursor Bugbot for commit cb22bdd. Bugbot is set up for automated code reviews on this repo. Configure here.