mirror of
https://github.com/openai/codex.git
synced 2026-05-25 05:24:37 +00:00
## Why Users and support need a single command that captures the local Codex runtime, configuration, auth, terminal, network, and state shape without asking the user to know which diagnostic depth to choose first. `codex doctor` now runs the useful checks by default and makes the detailed human output the default because the command is usually run when someone already needs context. The command also targets concrete support failure modes we have seen while iterating on the design: - update-target mismatches like #21956, where the installed package manager target can differ from the running executable - terminal and multiplexer issues that depend on `TERM`, tmux/zellij state, color handling, and TTY metadata - provider-specific HTTP/WebSocket connectivity, including ChatGPT WebSocket handshakes and API-key/provider endpoint reachability - local state/log SQLite integrity problems and large rollout directories - feedback reports that need an attached, redacted diagnostic snapshot without asking the user to run a second command ## What Changed - Adds `codex doctor` as a grouped CLI diagnostic report with default detailed output and `--summary` for the compact view. - Adds stable report sections for Environment, Configuration, Updates, Connectivity, and Background Server, plus a top Notes block that promotes anomalies such as available updates, large rollout directories, optional MCP issues, and mixed auth signals. - Adds runtime provenance, install consistency, bundled/system search readiness, terminal/multiplexer metadata, `config.toml` parse status, auth mode details, sandbox details, feature flag summaries, update cache/latest-version state, app-server daemon state, SQLite integrity checks, rollout statistics, and provider-aware network diagnostics. - Adds ChatGPT WebSocket diagnostics that report the negotiated HTTP upgrade as `HTTP 101 Switching Protocols` and include timeout, DNS, auth, and provider context in detailed output. - Makes reachability provider-aware: API-key OpenAI setups check the API endpoint, ChatGPT auth checks the ChatGPT path, and custom/AWS/local providers check configured HTTP endpoints when available. - Adds structured, redacted JSON output where `checks` is keyed by check id and `details` is a key/value object for support tooling. - Integrates doctor with feedback uploads by attaching a best-effort `codex-doctor-report.json` report and adding derived Sentry tags for overall status and failing/warning checks. - Updates the TUI feedback consent copy so users can see that the doctor report is included when logs/diagnostics are uploaded. - Updates the CLI bug issue template to ask reporters for `codex doctor --json` and render pasted reports as JSON. ## Example Output The examples below are sanitized from local smoke runs with `--no-color` so the structure is reviewable in plain text. ### `codex doctor` ```text Codex Doctor v0.0.0 · macos-aarch64 Notes ↑ updates 0.130.0 available (current 0.0.0, dismissed 0.128.0) ⚠ rollouts 1,526 active files · 2.53 GB on disk ⚠ mcp MCP configuration has optional issues ⚠ auth mixed auth signals: ChatGPT login plus API key env var; HTTP reachability uses API-key mode ───────────────────────────────────────────────────────────── Environment ✓ runtime local debug build version 0.0.0 install method other commit unknown executable ~/code/codex.fcoury-doct…x-rs/target/debug/codex ✓ install consistent context other managed by npm: no · bun: no · package root — PATH entries (2) ~/.local/share/mise/installs/node/24/bin/codex ~/.local/share/mise/shims/codex ✓ search ripgrep 15.1.0 (system, `rg`) ✓ terminal Ghostty 1.3.2-main-+b0f827665 · tmux 3.6a · TERM=xterm-256color terminal Ghostty TERM_PROGRAM ghostty terminal version 1.3.2-main-+b0f827665 TERM xterm-256color multiplexer tmux 3.6a tmux extended-keys on tmux allow-passthrough on tmux set-clipboard on ✓ state databases healthy CODEX_HOME ~/.codex (dir) state DB ~/.codex/state_5.sqlite (file) · integrity ok log DB ~/.codex/logs_2.sqlite (file) · integrity ok active rollouts 1,526 files · 2.53 GB (avg 1.70 MB) archived rollouts 8 files · 3.84 MB (avg 491.11 KB) Configuration ✓ config loaded model gpt-5.5 · openai cwd ~/code/codex.fcoury-doctor/codex-rs config.toml ~/.codex/config.toml config.toml parse ok MCP servers 1 feature flags 36 enabled · 7 overridden (full list with --all) overrides code_mode, code_mode_only, memories, chronicle, goals, remote_control, prevent_idle_sleep ✓ auth auth is configured auth storage mode File auth file ~/.codex/auth.json auth env vars present OPENAI_API_KEY stored auth mode chatgpt stored API key false stored ChatGPT tokens true stored agent identity false ⚠ mcp MCP configuration has optional issues — Set the missing MCP env vars or disable the affected server. configured servers 1 disabled servers 0 streamable_http servers 1 optional reachability openaiDeveloperDocs: https://developers.openai.com/mcp (HEAD connect failed; GET connect failed) ✓ sandbox restricted fs + restricted network · approval OnRequest approval policy OnRequest filesystem sandbox restricted network sandbox restricted Connectivity ✓ network network-related environment looks readable ✓ websocket connected (HTTP 101 Switching Protocols) · 15s timeout model provider openai provider name OpenAI wire API responses supports websockets true connect timeout 15000 ms auth mode chatgpt endpoint wss://chatgpt.com/backend-api/<redacted> DNS 2 IPv4, 2 IPv6, first IPv6 handshake result HTTP 101 Switching Protocols ✗ reachability one or more required provider endpoints are unreachable over HTTP — Check proxy, VPN, firewall, DNS, and custom CA configuration. reachability mode API key auth openai API https://api.openai.com/v1 connect failed (required) Background Server ○ app-server not running (ephemeral mode) ───────────────────────────────────────────────────────────── 11 ok · 1 idle · 4 notes · 1 warn · 1 fail failed --summary compact output --all expand truncated lists --json redacted report ``` ### `codex doctor --summary` ```text Codex Doctor v0.0.0 · macos-aarch64 Notes ↑ updates 0.130.0 available (current 0.0.0, dismissed 0.128.0) ⚠ rollouts 1,526 active files · 2.53 GB on disk ⚠ mcp MCP configuration has optional issues ⚠ auth mixed auth signals: ChatGPT login plus API key env var; HTTP reachability uses API-key mode ───────────────────────────────────────────────────────────── Environment ✓ runtime local debug build ✓ install consistent ✓ search ripgrep 15.1.0 (system, `rg`) ✓ terminal Ghostty 1.3.2-main-+b0f827665 · tmux 3.6a · TERM=xterm-256color ✓ state databases healthy Configuration ✓ config loaded ✓ auth auth is configured ⚠ mcp MCP configuration has optional issues — Set the missing MCP env vars or disable the affected server. ✓ sandbox restricted fs + restricted network · approval OnRequest Updates ✓ updates update configuration is locally consistent Connectivity ✓ network network-related environment looks readable ✓ websocket connected (HTTP 101 Switching Protocols) · 15s timeout ✗ reachability one or more required provider endpoints are unreachable over HTTP — Check proxy, VPN, firewall, DNS, and custom CA configuration. Background Server ○ app-server not running (ephemeral mode) ───────────────────────────────────────────────────────────── 11 ok · 1 idle · 4 notes · 1 warn · 1 fail failed Run codex doctor without --summary for detailed diagnostics. --all expand truncated lists --json redacted report ``` ### `codex doctor --json` shape ```json { "schema_version": 1, "overall_status": "fail", "checks": { "runtime.provenance": { "id": "runtime.provenance", "category": "Environment", "status": "ok", "summary": "local debug build", "details": { "version": "0.0.0", "install method": "other", "commit": "unknown" } }, "sandbox.helpers": { "id": "sandbox.helpers", "category": "Configuration", "status": "ok", "summary": "restricted fs + restricted network · approval OnRequest", "details": { "approval policy": "OnRequest", "filesystem sandbox": "restricted", "network sandbox": "restricted" } } } } ``` ### `/feedback` new sentry attachment <img width="938" height="798" alt="CleanShot 2026-05-13 at 15 36 14" src="https://github.com/user-attachments/assets/715e62e0-d7b4-4fea-a35a-fd5d5d33c4c0" /> ### New section in CLI issue template <img width="1164" height="435" alt="CleanShot 2026-05-13 at 15 47 24" src="https://github.com/user-attachments/assets/9081dc25-a28c-4afa-8ba1-e299c2b4031d" /> ## How to Test 1. Run `cargo run --bin codex -- doctor --no-color`. 2. Confirm the detailed report is the default and includes promoted Notes, grouped sections, terminal details, state DB integrity, rollout stats, provider reachability, WebSocket diagnostics, and app-server status. 3. Run `cargo run --bin codex -- doctor --summary --no-color`. 4. Confirm the compact view keeps the same sections and summary counts but omits detailed key/value rows. 5. Run `cargo run --bin codex -- doctor --json`. 6. Confirm the output is redacted JSON, `checks` is an object keyed by check id, and each check's `details` is a key/value object. 7. Preview the CLI bug issue template and confirm the `Codex doctor report` field appears after the terminal field, asks for `codex doctor --json`, and renders pasted output as JSON. 8. Start a feedback flow that includes logs. 9. Confirm the upload consent copy lists `codex-doctor-report.json` alongside the log attachments. Targeted tests: - `cargo test -p codex-cli doctor` - `cargo test -p codex-app-server doctor_report_tags_summarize_status_counts` - `cargo test -p codex-feedback` - `cargo test -p codex-tui feedback_view` - `just argument-comment-lint` - `git diff --check`
519 lines
25 KiB
Rust
519 lines
25 KiB
Rust
use crate::bespoke_event_handling::apply_bespoke_event_handling;
|
|
use crate::bespoke_event_handling::maybe_emit_hook_prompt_item_completed;
|
|
use crate::command_exec::CommandExecManager;
|
|
use crate::command_exec::StartCommandExecParams;
|
|
use crate::config_manager::ConfigManager;
|
|
use crate::error_code::INPUT_TOO_LARGE_ERROR_CODE;
|
|
use crate::error_code::invalid_params;
|
|
use crate::models::supported_models;
|
|
use crate::outgoing_message::ConnectionId;
|
|
use crate::outgoing_message::ConnectionRequestId;
|
|
use crate::outgoing_message::OutgoingMessageSender;
|
|
use crate::outgoing_message::RequestContext;
|
|
use crate::outgoing_message::ThreadScopedOutgoingMessageSender;
|
|
use crate::skills_watcher::SkillsWatcher;
|
|
use crate::thread_status::ThreadWatchManager;
|
|
use crate::thread_status::resolve_thread_status;
|
|
use chrono::Duration as ChronoDuration;
|
|
use chrono::SecondsFormat;
|
|
use codex_analytics::AnalyticsEventsClient;
|
|
use codex_analytics::AnalyticsJsonRpcError;
|
|
use codex_analytics::InputError;
|
|
use codex_analytics::TurnSteerRequestError;
|
|
use codex_app_server_protocol::Account;
|
|
use codex_app_server_protocol::AccountLoginCompletedNotification;
|
|
use codex_app_server_protocol::AccountUpdatedNotification;
|
|
use codex_app_server_protocol::AddCreditsNudgeCreditType;
|
|
use codex_app_server_protocol::AddCreditsNudgeEmailStatus;
|
|
use codex_app_server_protocol::AppInfo;
|
|
use codex_app_server_protocol::AppListUpdatedNotification;
|
|
use codex_app_server_protocol::AppSummary;
|
|
use codex_app_server_protocol::AppsListParams;
|
|
use codex_app_server_protocol::AppsListResponse;
|
|
use codex_app_server_protocol::AskForApproval;
|
|
use codex_app_server_protocol::AuthMode;
|
|
use codex_app_server_protocol::CancelLoginAccountParams;
|
|
use codex_app_server_protocol::CancelLoginAccountResponse;
|
|
use codex_app_server_protocol::CancelLoginAccountStatus;
|
|
use codex_app_server_protocol::ClientInfo;
|
|
use codex_app_server_protocol::ClientRequest;
|
|
use codex_app_server_protocol::ClientResponsePayload;
|
|
use codex_app_server_protocol::CodexErrorInfo;
|
|
use codex_app_server_protocol::CollaborationModeListParams;
|
|
use codex_app_server_protocol::CollaborationModeListResponse;
|
|
use codex_app_server_protocol::CommandExecParams;
|
|
use codex_app_server_protocol::CommandExecResizeParams;
|
|
use codex_app_server_protocol::CommandExecTerminateParams;
|
|
use codex_app_server_protocol::CommandExecWriteParams;
|
|
use codex_app_server_protocol::ConfigWarningNotification;
|
|
use codex_app_server_protocol::ConversationGitInfo;
|
|
use codex_app_server_protocol::ConversationSummary;
|
|
use codex_app_server_protocol::DeprecationNoticeNotification;
|
|
use codex_app_server_protocol::DynamicToolSpec as ApiDynamicToolSpec;
|
|
use codex_app_server_protocol::EnvironmentAddParams;
|
|
use codex_app_server_protocol::EnvironmentAddResponse;
|
|
use codex_app_server_protocol::ExperimentalFeature as ApiExperimentalFeature;
|
|
use codex_app_server_protocol::ExperimentalFeatureListParams;
|
|
use codex_app_server_protocol::ExperimentalFeatureListResponse;
|
|
use codex_app_server_protocol::ExperimentalFeatureStage as ApiExperimentalFeatureStage;
|
|
use codex_app_server_protocol::FeedbackUploadParams;
|
|
use codex_app_server_protocol::FeedbackUploadResponse;
|
|
use codex_app_server_protocol::GetAccountParams;
|
|
use codex_app_server_protocol::GetAccountRateLimitsResponse;
|
|
use codex_app_server_protocol::GetAccountResponse;
|
|
use codex_app_server_protocol::GetAuthStatusParams;
|
|
use codex_app_server_protocol::GetAuthStatusResponse;
|
|
use codex_app_server_protocol::GetConversationSummaryParams;
|
|
use codex_app_server_protocol::GetConversationSummaryResponse;
|
|
use codex_app_server_protocol::GitDiffToRemoteParams;
|
|
use codex_app_server_protocol::GitDiffToRemoteResponse;
|
|
use codex_app_server_protocol::GitInfo as ApiGitInfo;
|
|
use codex_app_server_protocol::HookMetadata;
|
|
use codex_app_server_protocol::HooksListParams;
|
|
use codex_app_server_protocol::HooksListResponse;
|
|
use codex_app_server_protocol::InitializeParams;
|
|
use codex_app_server_protocol::InitializeResponse;
|
|
use codex_app_server_protocol::JSONRPCErrorError;
|
|
use codex_app_server_protocol::ListMcpServerStatusParams;
|
|
use codex_app_server_protocol::ListMcpServerStatusResponse;
|
|
use codex_app_server_protocol::LoginAccountParams;
|
|
use codex_app_server_protocol::LoginAccountResponse;
|
|
use codex_app_server_protocol::LoginApiKeyParams;
|
|
use codex_app_server_protocol::LogoutAccountResponse;
|
|
use codex_app_server_protocol::MarketplaceAddParams;
|
|
use codex_app_server_protocol::MarketplaceAddResponse;
|
|
use codex_app_server_protocol::MarketplaceInterface;
|
|
use codex_app_server_protocol::MarketplaceRemoveParams;
|
|
use codex_app_server_protocol::MarketplaceRemoveResponse;
|
|
use codex_app_server_protocol::MarketplaceUpgradeErrorInfo;
|
|
use codex_app_server_protocol::MarketplaceUpgradeParams;
|
|
use codex_app_server_protocol::MarketplaceUpgradeResponse;
|
|
use codex_app_server_protocol::McpResourceReadParams;
|
|
use codex_app_server_protocol::McpResourceReadResponse;
|
|
use codex_app_server_protocol::McpServerOauthLoginCompletedNotification;
|
|
use codex_app_server_protocol::McpServerOauthLoginParams;
|
|
use codex_app_server_protocol::McpServerOauthLoginResponse;
|
|
use codex_app_server_protocol::McpServerRefreshResponse;
|
|
use codex_app_server_protocol::McpServerStatus;
|
|
use codex_app_server_protocol::McpServerStatusDetail;
|
|
use codex_app_server_protocol::McpServerToolCallParams;
|
|
use codex_app_server_protocol::McpServerToolCallResponse;
|
|
use codex_app_server_protocol::MemoryResetResponse;
|
|
use codex_app_server_protocol::MockExperimentalMethodParams;
|
|
use codex_app_server_protocol::MockExperimentalMethodResponse;
|
|
use codex_app_server_protocol::ModelListParams;
|
|
use codex_app_server_protocol::ModelListResponse;
|
|
use codex_app_server_protocol::PermissionProfileModificationParams;
|
|
use codex_app_server_protocol::PermissionProfileSelectionParams;
|
|
use codex_app_server_protocol::PluginDetail;
|
|
use codex_app_server_protocol::PluginInstallParams;
|
|
use codex_app_server_protocol::PluginInstallResponse;
|
|
use codex_app_server_protocol::PluginInterface;
|
|
use codex_app_server_protocol::PluginListMarketplaceKind;
|
|
use codex_app_server_protocol::PluginListParams;
|
|
use codex_app_server_protocol::PluginListResponse;
|
|
use codex_app_server_protocol::PluginMarketplaceEntry;
|
|
use codex_app_server_protocol::PluginReadParams;
|
|
use codex_app_server_protocol::PluginReadResponse;
|
|
use codex_app_server_protocol::PluginShareCheckoutParams;
|
|
use codex_app_server_protocol::PluginShareCheckoutResponse;
|
|
use codex_app_server_protocol::PluginShareContext;
|
|
use codex_app_server_protocol::PluginShareDeleteParams;
|
|
use codex_app_server_protocol::PluginShareDeleteResponse;
|
|
use codex_app_server_protocol::PluginShareDiscoverability;
|
|
use codex_app_server_protocol::PluginShareListItem;
|
|
use codex_app_server_protocol::PluginShareListParams;
|
|
use codex_app_server_protocol::PluginShareListResponse;
|
|
use codex_app_server_protocol::PluginSharePrincipal;
|
|
use codex_app_server_protocol::PluginSharePrincipalType;
|
|
use codex_app_server_protocol::PluginShareSaveParams;
|
|
use codex_app_server_protocol::PluginShareSaveResponse;
|
|
use codex_app_server_protocol::PluginShareTarget;
|
|
use codex_app_server_protocol::PluginShareUpdateDiscoverability;
|
|
use codex_app_server_protocol::PluginShareUpdateTargetsParams;
|
|
use codex_app_server_protocol::PluginShareUpdateTargetsResponse;
|
|
use codex_app_server_protocol::PluginSkillReadParams;
|
|
use codex_app_server_protocol::PluginSkillReadResponse;
|
|
use codex_app_server_protocol::PluginSource;
|
|
use codex_app_server_protocol::PluginSummary;
|
|
use codex_app_server_protocol::PluginUninstallParams;
|
|
use codex_app_server_protocol::PluginUninstallResponse;
|
|
use codex_app_server_protocol::RequestId;
|
|
use codex_app_server_protocol::ReviewDelivery as ApiReviewDelivery;
|
|
use codex_app_server_protocol::ReviewStartParams;
|
|
use codex_app_server_protocol::ReviewStartResponse;
|
|
use codex_app_server_protocol::ReviewTarget as ApiReviewTarget;
|
|
use codex_app_server_protocol::SandboxMode;
|
|
use codex_app_server_protocol::SendAddCreditsNudgeEmailParams;
|
|
use codex_app_server_protocol::SendAddCreditsNudgeEmailResponse;
|
|
use codex_app_server_protocol::ServerNotification;
|
|
use codex_app_server_protocol::ServerRequestResolvedNotification;
|
|
use codex_app_server_protocol::SkillSummary;
|
|
use codex_app_server_protocol::SkillsConfigWriteParams;
|
|
use codex_app_server_protocol::SkillsConfigWriteResponse;
|
|
use codex_app_server_protocol::SkillsListParams;
|
|
use codex_app_server_protocol::SkillsListResponse;
|
|
use codex_app_server_protocol::SortDirection;
|
|
use codex_app_server_protocol::Thread;
|
|
use codex_app_server_protocol::ThreadApproveGuardianDeniedActionParams;
|
|
use codex_app_server_protocol::ThreadApproveGuardianDeniedActionResponse;
|
|
use codex_app_server_protocol::ThreadArchiveParams;
|
|
use codex_app_server_protocol::ThreadArchiveResponse;
|
|
use codex_app_server_protocol::ThreadArchivedNotification;
|
|
use codex_app_server_protocol::ThreadBackgroundTerminalsCleanParams;
|
|
use codex_app_server_protocol::ThreadBackgroundTerminalsCleanResponse;
|
|
use codex_app_server_protocol::ThreadClosedNotification;
|
|
use codex_app_server_protocol::ThreadCompactStartParams;
|
|
use codex_app_server_protocol::ThreadCompactStartResponse;
|
|
use codex_app_server_protocol::ThreadDecrementElicitationParams;
|
|
use codex_app_server_protocol::ThreadDecrementElicitationResponse;
|
|
use codex_app_server_protocol::ThreadForkParams;
|
|
use codex_app_server_protocol::ThreadForkResponse;
|
|
use codex_app_server_protocol::ThreadGoal;
|
|
use codex_app_server_protocol::ThreadGoalClearParams;
|
|
use codex_app_server_protocol::ThreadGoalClearResponse;
|
|
use codex_app_server_protocol::ThreadGoalClearedNotification;
|
|
use codex_app_server_protocol::ThreadGoalGetParams;
|
|
use codex_app_server_protocol::ThreadGoalGetResponse;
|
|
use codex_app_server_protocol::ThreadGoalSetParams;
|
|
use codex_app_server_protocol::ThreadGoalSetResponse;
|
|
use codex_app_server_protocol::ThreadGoalStatus;
|
|
use codex_app_server_protocol::ThreadGoalUpdatedNotification;
|
|
use codex_app_server_protocol::ThreadHistoryBuilder;
|
|
use codex_app_server_protocol::ThreadIncrementElicitationParams;
|
|
use codex_app_server_protocol::ThreadIncrementElicitationResponse;
|
|
use codex_app_server_protocol::ThreadInjectItemsParams;
|
|
use codex_app_server_protocol::ThreadInjectItemsResponse;
|
|
use codex_app_server_protocol::ThreadItem;
|
|
use codex_app_server_protocol::ThreadListCwdFilter;
|
|
use codex_app_server_protocol::ThreadListParams;
|
|
use codex_app_server_protocol::ThreadListResponse;
|
|
use codex_app_server_protocol::ThreadLoadedListParams;
|
|
use codex_app_server_protocol::ThreadLoadedListResponse;
|
|
use codex_app_server_protocol::ThreadMemoryModeSetParams;
|
|
use codex_app_server_protocol::ThreadMemoryModeSetResponse;
|
|
use codex_app_server_protocol::ThreadMetadataGitInfoUpdateParams;
|
|
use codex_app_server_protocol::ThreadMetadataUpdateParams;
|
|
use codex_app_server_protocol::ThreadMetadataUpdateResponse;
|
|
use codex_app_server_protocol::ThreadNameUpdatedNotification;
|
|
use codex_app_server_protocol::ThreadReadParams;
|
|
use codex_app_server_protocol::ThreadReadResponse;
|
|
use codex_app_server_protocol::ThreadRealtimeAppendAudioParams;
|
|
use codex_app_server_protocol::ThreadRealtimeAppendAudioResponse;
|
|
use codex_app_server_protocol::ThreadRealtimeAppendTextParams;
|
|
use codex_app_server_protocol::ThreadRealtimeAppendTextResponse;
|
|
use codex_app_server_protocol::ThreadRealtimeListVoicesResponse;
|
|
use codex_app_server_protocol::ThreadRealtimeStartParams;
|
|
use codex_app_server_protocol::ThreadRealtimeStartResponse;
|
|
use codex_app_server_protocol::ThreadRealtimeStartTransport;
|
|
use codex_app_server_protocol::ThreadRealtimeStopParams;
|
|
use codex_app_server_protocol::ThreadRealtimeStopResponse;
|
|
use codex_app_server_protocol::ThreadResumeParams;
|
|
use codex_app_server_protocol::ThreadResumeResponse;
|
|
use codex_app_server_protocol::ThreadRollbackParams;
|
|
use codex_app_server_protocol::ThreadSetNameParams;
|
|
use codex_app_server_protocol::ThreadSetNameResponse;
|
|
use codex_app_server_protocol::ThreadShellCommandParams;
|
|
use codex_app_server_protocol::ThreadShellCommandResponse;
|
|
use codex_app_server_protocol::ThreadSortKey;
|
|
use codex_app_server_protocol::ThreadSourceKind;
|
|
use codex_app_server_protocol::ThreadStartParams;
|
|
use codex_app_server_protocol::ThreadStartResponse;
|
|
use codex_app_server_protocol::ThreadStartedNotification;
|
|
use codex_app_server_protocol::ThreadStatus;
|
|
use codex_app_server_protocol::ThreadTurnsItemsListParams;
|
|
use codex_app_server_protocol::ThreadTurnsListParams;
|
|
use codex_app_server_protocol::ThreadTurnsListResponse;
|
|
use codex_app_server_protocol::ThreadUnarchiveParams;
|
|
use codex_app_server_protocol::ThreadUnarchiveResponse;
|
|
use codex_app_server_protocol::ThreadUnarchivedNotification;
|
|
use codex_app_server_protocol::ThreadUnsubscribeParams;
|
|
use codex_app_server_protocol::ThreadUnsubscribeResponse;
|
|
use codex_app_server_protocol::ThreadUnsubscribeStatus;
|
|
use codex_app_server_protocol::Turn;
|
|
use codex_app_server_protocol::TurnEnvironmentParams;
|
|
use codex_app_server_protocol::TurnError;
|
|
use codex_app_server_protocol::TurnInterruptParams;
|
|
use codex_app_server_protocol::TurnInterruptResponse;
|
|
use codex_app_server_protocol::TurnItemsView;
|
|
use codex_app_server_protocol::TurnStartParams;
|
|
use codex_app_server_protocol::TurnStartResponse;
|
|
use codex_app_server_protocol::TurnStatus;
|
|
use codex_app_server_protocol::TurnSteerParams;
|
|
use codex_app_server_protocol::TurnSteerResponse;
|
|
use codex_app_server_protocol::UserInput as V2UserInput;
|
|
use codex_app_server_protocol::WindowsSandboxReadiness;
|
|
use codex_app_server_protocol::WindowsSandboxReadinessResponse;
|
|
use codex_app_server_protocol::WindowsSandboxSetupCompletedNotification;
|
|
use codex_app_server_protocol::WindowsSandboxSetupMode;
|
|
use codex_app_server_protocol::WindowsSandboxSetupStartParams;
|
|
use codex_app_server_protocol::WindowsSandboxSetupStartResponse;
|
|
use codex_arg0::Arg0DispatchPaths;
|
|
use codex_backend_client::AddCreditsNudgeCreditType as BackendAddCreditsNudgeCreditType;
|
|
use codex_backend_client::Client as BackendClient;
|
|
use codex_chatgpt::connectors;
|
|
use codex_chatgpt::workspace_settings;
|
|
use codex_config::CloudRequirementsLoadError;
|
|
use codex_config::CloudRequirementsLoadErrorCode;
|
|
use codex_config::ConfigLayerStack;
|
|
use codex_config::loader::project_trust_key;
|
|
use codex_config::types::McpServerTransportConfig;
|
|
use codex_core::CodexThread;
|
|
use codex_core::CodexThreadTurnContextOverrides;
|
|
use codex_core::ExternalGoalPreviousStatus;
|
|
use codex_core::ExternalGoalSet;
|
|
use codex_core::ForkSnapshot;
|
|
use codex_core::NewThread;
|
|
#[cfg(test)]
|
|
use codex_core::SessionMeta;
|
|
use codex_core::StartThreadOptions;
|
|
use codex_core::SteerInputError;
|
|
use codex_core::ThreadConfigSnapshot;
|
|
use codex_core::ThreadManager;
|
|
use codex_core::config::Config;
|
|
use codex_core::config::ConfigOverrides;
|
|
use codex_core::config::NetworkProxyAuditMetadata;
|
|
use codex_core::config::edit::ConfigEdit;
|
|
use codex_core::config::edit::ConfigEditsBuilder;
|
|
use codex_core::exec::ExecCapturePolicy;
|
|
use codex_core::exec::ExecExpiration;
|
|
use codex_core::exec::ExecParams;
|
|
use codex_core::exec_env::create_env;
|
|
use codex_core::path_utils;
|
|
#[cfg(test)]
|
|
use codex_core::read_head_for_summary;
|
|
use codex_core::sandboxing::SandboxPermissions;
|
|
use codex_core::windows_sandbox::WindowsSandboxLevelExt;
|
|
use codex_core::windows_sandbox::WindowsSandboxSetupMode as CoreWindowsSandboxSetupMode;
|
|
use codex_core::windows_sandbox::WindowsSandboxSetupRequest;
|
|
use codex_core::windows_sandbox::sandbox_setup_is_complete;
|
|
use codex_core_plugins::OPENAI_CURATED_MARKETPLACE_NAME;
|
|
use codex_core_plugins::PluginInstallError as CorePluginInstallError;
|
|
use codex_core_plugins::PluginInstallRequest;
|
|
use codex_core_plugins::PluginLoadOutcome;
|
|
use codex_core_plugins::PluginReadRequest;
|
|
use codex_core_plugins::PluginUninstallError as CorePluginUninstallError;
|
|
use codex_core_plugins::loader::load_plugin_apps;
|
|
use codex_core_plugins::loader::load_plugin_mcp_servers;
|
|
use codex_core_plugins::loader::plugin_telemetry_metadata_from_root;
|
|
use codex_core_plugins::manifest::PluginManifestInterface;
|
|
use codex_core_plugins::marketplace::MarketplaceError;
|
|
use codex_core_plugins::marketplace::MarketplacePluginSource;
|
|
use codex_core_plugins::marketplace_add::MarketplaceAddError;
|
|
use codex_core_plugins::marketplace_add::MarketplaceAddRequest;
|
|
use codex_core_plugins::marketplace_add::add_marketplace as add_marketplace_to_codex_home;
|
|
use codex_core_plugins::marketplace_remove::MarketplaceRemoveError;
|
|
use codex_core_plugins::marketplace_remove::MarketplaceRemoveRequest as CoreMarketplaceRemoveRequest;
|
|
use codex_core_plugins::marketplace_remove::remove_marketplace;
|
|
use codex_core_plugins::remote::RemoteMarketplace;
|
|
use codex_core_plugins::remote::RemoteMarketplaceSource;
|
|
use codex_core_plugins::remote::RemotePluginCatalogError;
|
|
use codex_core_plugins::remote::RemotePluginDetail as RemoteCatalogPluginDetail;
|
|
use codex_core_plugins::remote::RemotePluginServiceConfig;
|
|
use codex_core_plugins::remote::RemotePluginShareContext as RemoteCatalogPluginShareContext;
|
|
use codex_core_plugins::remote::RemotePluginShareSummary as RemoteCatalogPluginShareSummary;
|
|
use codex_core_plugins::remote::RemotePluginSummary as RemoteCatalogPluginSummary;
|
|
use codex_exec_server::EnvironmentManager;
|
|
use codex_exec_server::LOCAL_FS;
|
|
use codex_features::FEATURES;
|
|
use codex_features::Feature;
|
|
use codex_features::Stage;
|
|
use codex_feedback::CodexFeedback;
|
|
use codex_feedback::FeedbackAttachmentPath;
|
|
use codex_feedback::FeedbackUploadOptions;
|
|
use codex_git_utils::git_diff_to_remote;
|
|
use codex_git_utils::resolve_root_git_project_for_trust;
|
|
use codex_login::AuthManager;
|
|
use codex_login::CLIENT_ID;
|
|
use codex_login::CodexAuth;
|
|
use codex_login::ServerOptions as LoginServerOptions;
|
|
use codex_login::ShutdownHandle;
|
|
use codex_login::auth::login_with_chatgpt_auth_tokens;
|
|
use codex_login::complete_device_code_login;
|
|
use codex_login::login_with_api_key;
|
|
use codex_login::request_device_code;
|
|
use codex_login::run_login_server;
|
|
use codex_mcp::McpRuntimeEnvironment;
|
|
use codex_mcp::McpServerStatusSnapshot;
|
|
use codex_mcp::McpSnapshotDetail;
|
|
use codex_mcp::collect_mcp_server_status_snapshot_with_detail;
|
|
use codex_mcp::discover_supported_scopes;
|
|
use codex_mcp::effective_mcp_servers;
|
|
use codex_mcp::read_mcp_resource as read_mcp_resource_without_thread;
|
|
use codex_mcp::resolve_oauth_scopes;
|
|
use codex_memories_write::clear_memory_roots_contents;
|
|
use codex_model_provider::ProviderAccountError;
|
|
use codex_model_provider::create_model_provider;
|
|
use codex_models_manager::collaboration_mode_presets::builtin_collaboration_mode_presets;
|
|
use codex_protocol::ThreadId;
|
|
use codex_protocol::config_types::CollaborationMode;
|
|
use codex_protocol::config_types::ForcedLoginMethod;
|
|
use codex_protocol::config_types::Personality;
|
|
use codex_protocol::config_types::TrustLevel;
|
|
use codex_protocol::config_types::WindowsSandboxLevel;
|
|
use codex_protocol::dynamic_tools::DynamicToolSpec as CoreDynamicToolSpec;
|
|
use codex_protocol::error::CodexErr;
|
|
use codex_protocol::error::Result as CodexResult;
|
|
#[cfg(test)]
|
|
use codex_protocol::items::TurnItem;
|
|
use codex_protocol::models::ResponseItem;
|
|
use codex_protocol::permissions::FileSystemSandboxPolicy;
|
|
use codex_protocol::protocol::AgentStatus;
|
|
use codex_protocol::protocol::ConversationAudioParams;
|
|
use codex_protocol::protocol::ConversationStartParams;
|
|
use codex_protocol::protocol::ConversationStartTransport;
|
|
use codex_protocol::protocol::ConversationTextParams;
|
|
use codex_protocol::protocol::EventMsg;
|
|
#[cfg(test)]
|
|
use codex_protocol::protocol::GitInfo as CoreGitInfo;
|
|
use codex_protocol::protocol::InitialHistory;
|
|
use codex_protocol::protocol::McpAuthStatus as CoreMcpAuthStatus;
|
|
use codex_protocol::protocol::Op;
|
|
use codex_protocol::protocol::RateLimitSnapshot as CoreRateLimitSnapshot;
|
|
use codex_protocol::protocol::RealtimeVoicesList;
|
|
use codex_protocol::protocol::ResumedHistory;
|
|
use codex_protocol::protocol::ReviewDelivery as CoreReviewDelivery;
|
|
use codex_protocol::protocol::ReviewRequest;
|
|
use codex_protocol::protocol::ReviewTarget as CoreReviewTarget;
|
|
use codex_protocol::protocol::RolloutItem;
|
|
use codex_protocol::protocol::SessionConfiguredEvent;
|
|
#[cfg(test)]
|
|
use codex_protocol::protocol::SessionMetaLine;
|
|
use codex_protocol::protocol::TurnEnvironmentSelection;
|
|
use codex_protocol::protocol::USER_MESSAGE_BEGIN;
|
|
use codex_protocol::protocol::W3cTraceContext;
|
|
use codex_protocol::user_input::MAX_USER_INPUT_TEXT_CHARS;
|
|
use codex_protocol::user_input::UserInput as CoreInputItem;
|
|
use codex_rmcp_client::perform_oauth_login_return_url;
|
|
use codex_rollout::EventPersistenceMode;
|
|
use codex_rollout::is_persisted_rollout_item;
|
|
use codex_rollout::state_db::StateDbHandle;
|
|
use codex_rollout::state_db::reconcile_rollout;
|
|
use codex_state::ThreadMetadata;
|
|
use codex_state::log_db::LogDbLayer;
|
|
use codex_thread_store::ArchiveThreadParams as StoreArchiveThreadParams;
|
|
use codex_thread_store::GitInfoPatch as StoreGitInfoPatch;
|
|
use codex_thread_store::ListThreadsParams as StoreListThreadsParams;
|
|
use codex_thread_store::LocalThreadStore;
|
|
use codex_thread_store::ReadThreadByRolloutPathParams as StoreReadThreadByRolloutPathParams;
|
|
use codex_thread_store::ReadThreadParams as StoreReadThreadParams;
|
|
use codex_thread_store::SortDirection as StoreSortDirection;
|
|
use codex_thread_store::StoredThread;
|
|
use codex_thread_store::ThreadMetadataPatch as StoreThreadMetadataPatch;
|
|
use codex_thread_store::ThreadSortKey as StoreThreadSortKey;
|
|
use codex_thread_store::ThreadStore;
|
|
use codex_thread_store::ThreadStoreError;
|
|
use codex_utils_absolute_path::AbsolutePathBuf;
|
|
use codex_utils_pty::DEFAULT_OUTPUT_BYTES_CAP;
|
|
use std::collections::HashMap;
|
|
use std::collections::HashSet;
|
|
use std::io::Error as IoError;
|
|
use std::path::Path;
|
|
use std::path::PathBuf;
|
|
use std::result::Result;
|
|
use std::sync::Arc;
|
|
use std::time::Duration;
|
|
use std::time::Instant;
|
|
use tokio::sync::Mutex;
|
|
use tokio::sync::Semaphore;
|
|
use tokio::sync::SemaphorePermit;
|
|
use tokio::sync::broadcast;
|
|
use tokio::sync::oneshot;
|
|
use tokio::sync::watch;
|
|
use tokio_util::sync::CancellationToken;
|
|
use tokio_util::task::TaskTracker;
|
|
use toml::Value as TomlValue;
|
|
use tracing::Instrument;
|
|
use tracing::error;
|
|
use tracing::info;
|
|
use tracing::warn;
|
|
use uuid::Uuid;
|
|
|
|
#[cfg(test)]
|
|
use codex_app_server_protocol::ServerRequest;
|
|
|
|
mod account_processor;
|
|
mod apps_processor;
|
|
mod catalog_processor;
|
|
mod command_exec_processor;
|
|
mod config_processor;
|
|
mod environment_processor;
|
|
mod external_agent_config_processor;
|
|
mod feedback_doctor_report;
|
|
mod feedback_processor;
|
|
mod fs_processor;
|
|
mod git_processor;
|
|
mod initialize_processor;
|
|
mod marketplace_processor;
|
|
mod mcp_processor;
|
|
mod plugins;
|
|
mod process_exec_processor;
|
|
mod search;
|
|
mod thread_processor;
|
|
mod token_usage_replay;
|
|
mod turn_processor;
|
|
mod windows_sandbox_processor;
|
|
|
|
pub(crate) use account_processor::AccountRequestProcessor;
|
|
pub(crate) use apps_processor::AppsRequestProcessor;
|
|
pub(crate) use catalog_processor::CatalogRequestProcessor;
|
|
pub(crate) use command_exec_processor::CommandExecRequestProcessor;
|
|
pub(crate) use config_processor::ConfigRequestProcessor;
|
|
pub(crate) use environment_processor::EnvironmentRequestProcessor;
|
|
pub(crate) use external_agent_config_processor::ExternalAgentConfigRequestProcessor;
|
|
pub(crate) use feedback_processor::FeedbackRequestProcessor;
|
|
pub(crate) use fs_processor::FsRequestProcessor;
|
|
pub(crate) use git_processor::GitRequestProcessor;
|
|
pub(crate) use initialize_processor::InitializeRequestProcessor;
|
|
pub(crate) use marketplace_processor::MarketplaceRequestProcessor;
|
|
pub(crate) use mcp_processor::McpRequestProcessor;
|
|
pub(crate) use plugins::PluginRequestProcessor;
|
|
pub(crate) use process_exec_processor::ProcessExecRequestProcessor;
|
|
pub(crate) use search::SearchRequestProcessor;
|
|
pub(crate) use thread_goal_processor::ThreadGoalRequestProcessor;
|
|
pub(crate) use thread_processor::ThreadRequestProcessor;
|
|
pub(crate) use turn_processor::TurnRequestProcessor;
|
|
pub(crate) use windows_sandbox_processor::WindowsSandboxRequestProcessor;
|
|
|
|
use crate::error_code::internal_error;
|
|
use crate::error_code::invalid_request;
|
|
use crate::filters::compute_source_filters;
|
|
use crate::filters::source_kind_matches;
|
|
use crate::thread_state::ConnectionCapabilities;
|
|
use crate::thread_state::ThreadListenerCommand;
|
|
use crate::thread_state::ThreadState;
|
|
use crate::thread_state::ThreadStateManager;
|
|
use token_usage_replay::latest_token_usage_turn_id_from_rollout_items;
|
|
use token_usage_replay::send_thread_token_usage_update_to_connection;
|
|
|
|
mod config_errors;
|
|
mod request_errors;
|
|
mod thread_goal_processor;
|
|
mod thread_lifecycle;
|
|
mod thread_resume_redaction;
|
|
mod thread_summary;
|
|
|
|
use self::config_errors::*;
|
|
use self::request_errors::*;
|
|
use self::thread_goal_processor::api_thread_goal_from_state;
|
|
use self::thread_lifecycle::*;
|
|
use self::thread_resume_redaction::*;
|
|
use self::thread_summary::*;
|
|
|
|
pub(crate) use self::thread_lifecycle::populate_thread_turns_from_history;
|
|
pub(crate) use self::thread_processor::thread_from_stored_thread;
|
|
#[cfg(test)]
|
|
pub(crate) use self::thread_summary::read_summary_from_rollout;
|
|
#[cfg(test)]
|
|
pub(crate) use self::thread_summary::summary_to_thread;
|
|
|
|
pub(crate) fn build_api_turns_from_rollout_items(items: &[RolloutItem]) -> Vec<Turn> {
|
|
let mut builder = ThreadHistoryBuilder::new();
|
|
for item in items {
|
|
if is_persisted_rollout_item(item, EventPersistenceMode::Limited) {
|
|
builder.handle_rollout_item(item);
|
|
}
|
|
}
|
|
builder.finish()
|
|
}
|