mirror of
https://github.com/zyycn/codex-proxy-rs.git
synced 2026-11-06 16:06:08 +00:00
16 KiB
16 KiB
Implementation Status
Update this file before each feature commit.
| Area | Status | Commit | Verification | Notes |
|---|---|---|---|---|
| Scaffold | Completed | fc47967 |
cargo fmt --check; cargo test; cargo clippy --all-targets --all-features --locked -- -D warnings |
Rust crate, lint policy, pinned TLS-sensitive dependencies, .gitignore, and minimal entry points are in place. |
| API contract docs | Completed | fc47967 |
cargo fmt --check; cargo test; cargo clippy --all-targets --all-features --locked -- -D warnings |
/v1/* OpenAI-compatible body, /admin/* frontend envelope, body codes, camelCase, and request ID policy are documented. |
| Configuration | Completed | 9ed8579 + e0680bf + cfec8ba |
cargo test default_config_keeps_only_codex_backend; cargo test config_loader_merges_default_local_and_cprs_env_overrides; full fmt/test/clippy before commit |
Defines Codex-only config, default/local/env loading, default YAML, Arc<AppServices> state shell, gpt-5.5 default model, and in-scope model/auth/quota/usage/logging settings fields without proxy/Ollama/provider/OpenAI-key knobs. |
| SQLite storage | Completed | ffec8b5 + b0c10f2 |
cargo test sqlite_schema_creates_accounts_and_event_tables; cargo test connect_sqlite_creates_parent_directory_for_file_database; full fmt/test/clippy before commit |
Creates SQLite WAL connector, parent directory bootstrap, sqlx-managed schema for accounts/API keys/sessions/cookies/fingerprints/events, and event/account indexes. |
| Admin auth and client API keys | Partial | 24d5799 + 4e0d1e5 + e9fdea0 |
cargo test client_api_key_has_proxy_prefix_and_verifies_against_hash; cargo test admin_password_hash_is_not_a_client_api_key; cargo test --test admin_login_route_test; cargo test --test admin_api_keys_route_test; full fmt/test/clippy before commit |
Admin passwords use Argon2id, client API keys use cpr_ prefix plus HMAC-SHA256 with server-side pepper; /admin/login issues HttpOnly sessions and rejects client API keys as admin credentials. /admin/api-keys can create/list local client keys, and /v1/* now verifies enabled keys against SQLite instead of accepting any cpr_ string. Still missing delete/batch-delete/label/status/export/import key management. |
| Secret encryption | Completed | 105aa58 + 228febd |
cargo test secret_box_encrypts_and_decrypts_without_storing_plaintext; cargo test secret_box_load_or_create_should_reuse_existing_master_key_file; full fmt/test/clippy before commit |
AES-256-GCM SecretBox stores upstream secrets as v1:<nonce>:<ciphertext> without plaintext and can load/create the runtime master key file used by repositories. |
| Logging and pagination | Completed | eb0341e + fc16c48 + b0c10f2 + ee0ed90 + fdb9374 + 5bf012c |
cargo test event_logs_are_cursor_paginated; cargo test admin_logs_are_cursor_paginated_and_include_request_id; cargo test rotating_writer_splits_files_when_size_limit_is_reached; cargo test --test admin_usage_stats_route_test; cargo test --test v1_upstream_route_test; full fmt/test/clippy before commit |
Adds cursor pagination, Page<T> camelCase serialization, admin /admin/logs query API, admin /admin/usage-stats and /admin/usage-stats/summary, event log repository, runtime tracing initialization, HTTP trace layer, date/size-based file rotation, v1 response lifecycle events with request/account/route/model/status/latency/non-secret metadata, and non-secret account.refresh events for upstream-401 refresh failures. |
| TLS headers and fingerprint | Completed | 1bdd08c |
cargo test codex_headers_include_desktop_identity_and_turn_state; cargo tree | rg 'reqwest|rustls'; full fmt/test/clippy before commit |
Adds Codex Desktop fingerprint model, exact identity/request headers, and pinned reqwest/rustls client builder. |
| Cookie persistence | Completed | 4710926 + 5d3cc6e |
cargo test cookie_jar_captures_and_replays_account_scoped_cookies; cargo test cookie_repository_encrypts_and_replays_account_scoped_cookies; full fmt/test/clippy before commit |
Adds account-scoped in-memory Cookie jar and encrypted SQLite Cookie repository; Cookies are replayed only for the same account/domain. |
| Account pool and refresh | Partial | 0f97c5c + 2f25db8 + 4dc0c9a + c2cf7a6 + 636fa79 + fdb9374 + 3ecd5b6 + 3960a35 |
cargo test account_pool_skips_expired_disabled_banned_and_quota_exhausted_accounts; cargo test --test account_pool_scheduling_test; cargo test --test account_refresh_test; cargo test --test oauth_refresh_test; cargo test --test v1_upstream_route_test; cargo test --test account_pool_startup_test; Task 5 targeted cargo test --test v1_upstream_route_test, cargo test --test chat_completions_route_test, and cargo test --test account_pool_scheduling_test; full fmt/test/clippy before commit |
Implements base account status filtering, refresh scheduler semantics, real OpenAI OAuth refresh-token exchange, 401-triggered refresh and single retry for /v1/responses, max concurrent slots, stale slot cleanup, least-used/round-robin/sticky strategies, tier priority, quota-cache filtering, Cloudflare cooldown skip, request staggering metadata, preferred account selection, exclude IDs, capacity summary, settings-backed pool construction, same-process import-to-pool sync, startup pool snapshots from SQLite with usage-based last-used metadata, in-memory 429 quota cooldown marking, Cloudflare cooldown mutation, pool status mutation for upstream fallback, and shared fallback acquisition for non-streaming Responses, HTTP SSE Responses setup, and Chat Completions. Still missing durable release-time slot state, WebSocket/history fallback policy, durable quota cooldown persistence, and admin account CRUD. |
| Account repository | Completed | 14fe706 |
cargo test --test account_repository_test; cargo fmt --check; cargo clippy --all-targets --all-features --locked -- -D warnings; cargo test |
Adds encrypted SQLite account token storage, decrypting reads, cursor pagination, status/label updates, release-time usage counter persistence, and refresh-token-preserving token updates. |
| Translation | Completed | eff182e + b9c30ba |
cargo test --test routes_chat_test; cargo test --test chat_completions_route_test; full cargo fmt --check && cargo test && cargo clippy --all-targets --all-features --locked -- -D warnings before b9c30ba |
Adds OpenAI Chat request types, expanded Codex Responses request type, OpenAI Chat to Codex translation for system/developer instructions, multimodal content, tool/function calls, response formats, reasoning effort, service tier, and parallel tool calls. Codex SSE now converts back to OpenAI chat completions and chat chunks with text deltas, reasoning content, tool calls, usage details, and OpenAI-compatible error bodies. |
| HTTP routes | Partial | ab0ad8f + 3830b21 + 6179d44 + cfec8ba + 6341336 + 228febd + c2cf7a6 + e9fdea0 + ee0ed90 + fdb9374 + 9ca5c7d + b9c30ba + 350ffbe + 3ecd5b6 + 3960a35 + 1738f24 + 0b6cc7e + pending |
cargo test v1_requires_client_api_key_not_admin_cookie; cargo test models_route_returns_openai_compatible_codex_model_list; cargo test --test admin_settings_route_test; cargo test --test model_catalog_test; cargo test --test admin_accounts_route_test; cargo test --test admin_api_keys_route_test; cargo test --test admin_usage_stats_route_test; cargo test --test v1_upstream_route_test; cargo test --test chat_completions_route_test; cargo test --test codex_websocket_test; full cargo fmt --check && cargo test && cargo clippy --all-targets --all-features --locked -- -D warnings before b9c30ba and 350ffbe; Task 5 targeted verification before 3ecd5b6 and 3960a35; full fmt/test/clippy before 1738f24; full fmt/test/clippy plus real-file smoke before 0b6cc7e; Task 6 refresh targeted tests before pending |
Adds Axum router, health route, /v1/models, /v1/models/catalog, /v1/models/{id}, /v1/models/{id}/info, /debug/models, /admin/accounts, /admin/accounts/import, /admin/api-keys, /admin/usage-stats, /admin/usage-stats/summary, /admin/refresh-models, /v1/responses HTTP SSE collection with output item/delta reconstruction plus output_text sync for non-streaming clients, default streaming Responses passthrough when stream is omitted, WebSocket-backed Responses streaming for previous_response_id, non-streaming and HTTP SSE setup fallback to another imported account after 429/402/403 account-state failures, Responses field parity for service tier, tool choice, parallel tool calls, text format, prompt cache key, include, client metadata, reasoning include default, and Codex context headers, plus a dedicated /v1/chat/completions route backed by imported Codex accounts with fallback for buffered non-streaming and client-streaming output conversion. /v1 unauthorized and model errors remain OpenAI-compatible, cached backend model snapshots are used by /v1/models* when present, global request-id response headers are preserved, gpt-5.5 remains the default/test model baseline, and /admin/settings is read-only with admin-session auth and lower camelCase envelope. /admin/accounts reads metadata only and does not decrypt tokens for list views. /admin/accounts/import accepts native and Sub2API OpenAI OAuth account exports, returns sourceFormat, and ignores proxy-only metadata. /admin/refresh-models fetches backend model lists through imported accounts only and stores plan snapshots. Still missing OAuth/device/CLI account login flows, admin account mutation/health/quota/Cookie routes, full admin API-key mutation/export/import routes, settings mutation/persistence, diagnostics, live Chat streaming transform, and WebSocket/history fallback policy. |
| Admin/frontend response contract | Completed | 1c34ea7 + b0c10f2 |
cargo test admin_envelope_serializes_lower_camel_case_request_id; cargo test admin_logs_reject_missing_admin_session_cookie; cargo test v1_response_has_request_id_header_without_admin_body_field; full fmt/test/clippy before commit |
Adds reusable admin envelopes with body codes, lower camelCase JSON, paginated list shape, requestId bodies, admin session cookie enforcement, and keeps /v1/* OpenAI-compatible. |
| HTTP auth boundary | Completed | cec4607 + e9fdea0 |
cargo test --test http_auth_test; cargo test --test routes_responses_test; cargo test --test admin_api_keys_route_test; cargo test --test admin_logs_route_test; cargo fmt --check; cargo clippy --all-targets --all-features --locked -- -D warnings; cargo test |
Adds a real src/http/auth.rs boundary for client API key and admin session cookie parsing. /v1/* accepts only enabled local Bearer cpr_... client API keys verified from SQLite, admin session parsing ignores client API keys, and route handlers no longer own ad hoc credential parsing. |
| Model catalog | Partial | 6341336 + 1738f24 + pending |
cargo test --test model_catalog_test; cargo test model_catalog_route_returns_codex_metadata_without_alias_entries; cargo test --test storage_schema_test; cargo test --test routes_responses_test model_catalog_route_returns_cached_backend_models; cargo test --test admin_models_route_test; full fmt/test/clippy before 1738f24; Task 6 refresh targeted tests before pending |
Adds a native static Codex model catalog with gpt-5.5 default, configured aliases, reasoning/service-tier suffix parsing including none and minimal, OpenAI-compatible /v1/models, extended catalog/detail/info routes, debug summary, SQLite-backed backend model snapshots by plan, cached backend catalog merge, model-to-plan allowlist derivation, and an admin refresh route that probes Codex model endpoints with one imported account per plan. Still missing runtime pool allowlist refresh from fetched models and full model metadata parity. |
| Upstream lifecycle | Partial | 88cad87 + 225fbff + c2cf7a6 + 636fa79 + ee0ed90 + fdb9374 + 5bf012c + 9ca5c7d + b9c30ba + 350ffbe + 3ecd5b6 + 3960a35 |
cargo test responses_route_rejects_non_codex_provider_models; cargo test v1_requires_client_api_key_not_admin_cookie; cargo test --test codex_sse_usage_test; cargo test --test codex_client_test; cargo test --test oauth_refresh_test; cargo test --test v1_upstream_route_test; cargo test --test account_pool_startup_test; cargo test --test codex_websocket_test; Task 5 targeted cargo test --test v1_upstream_route_test, cargo test --test chat_completions_route_test, and cargo test --test account_pool_scheduling_test; full cargo fmt --check && cargo test && cargo clippy --all-targets --all-features --locked -- -D warnings before b9c30ba and 350ffbe |
/v1 enforces client API key shape, rejects non-Codex provider models through the model catalog, returns OpenAI-compatible errors, includes reusable SSE/usage helpers, sends Codex Desktop HTTP SSE requests through imported accounts, sends WebSocket response.create requests when previous_response_id requires upstream history, replays/captures encrypted Cookies, forwards Codex request context headers, normalizes service_tier: fast to upstream priority, collects response.completed, reconstructs missing assistant output from response.output_item.done or text deltas, synchronizes output_text for non-streaming clients, passes through Responses streaming SSE by default, adapts Chat Completions responses/chunks, refreshes and retries once after upstream 401 when a refresh token is stored, parses Retry-After plus Codex reset metadata from upstream errors, records 429 request attempts, classifies upstream 429/402/403 into account cooldown/quota/banned/Cloudflare state changes, retries non-streaming /v1/responses, HTTP SSE /v1/responses setup, and /v1/chat/completions with another imported account when available, records token usage, writes v1 lifecycle event logs, records refresh failure classification for upstream 401, and restores the account pool from SQLite on startup. Still missing SSE error/failed mapping, successful rate-limit header capture, WebSocket/history retry policy, durable 429 quota cooldown persistence, previous-response account affinity, and live Chat streaming transform. |
| Codex WebSocket boundary | Completed | cc0516d + b9c30ba + 350ffbe |
cargo test --test codex_websocket_test; cargo test --test v1_upstream_route_test v1_responses_should_use_websocket_for_previous_response_id_streaming; full cargo fmt --check && cargo test && cargo clippy --all-targets --all-features --locked -- -D warnings before b9c30ba and 350ffbe |
Adds src/codex/websocket.rs with tested transport classification for HTTP SSE versus WebSocket-only requests. previous_response_id and explicit WebSocket requests use typed transport selection, local-only use_websocket is not serialized into upstream JSON, WebSocket response.create carries Codex headers and parity fields, incoming WebSocket messages are emitted as SSE-compatible events, and /v1/responses returns WebSocket-backed text/event-stream output for previous_response_id streaming requests. |
| Fingerprint updates | Partial | dd26d31 + e32220a |
cargo test update_manifest_updates_app_version_and_build_number; cargo test fingerprint_updater_fetches_manifest_and_persists_history; full fmt/test/clippy before commit |
Parses a JSON update manifest and persists app version/build number history to SQLite. Still missing original appcast XML polling, update-state persistence, runtime header fingerprint selection from the latest stored fingerprint, and optional local Codex.app Chromium extraction. |
| Runtime docs and packaging | Completed | 33b63f3 |
cargo fmt --check; cargo clippy --all-targets --all-features --locked -- -D warnings; cargo test; cargo run; curl -s -i http://127.0.0.1:8080/health |
README scope, .env.example, Dockerfile, compose file, and health smoke test are complete. |