Commit Graph

10 Commits

Author SHA1 Message Date
Jason 8f018a2d45 feat: add project profiles for snapshot-based config switching
Add a profile feature that captures the current provider, MCP,
skills and prompt state for Claude Code and Codex as a named
snapshot, and re-applies it in one click from the header switcher
or the tray Projects submenu.

- New profiles table (schema v12) with current marker in settings
- ProfileService orchestrates the four existing switch primitives
  (provider first, then MCP diff, skills diff, prompt enable)
- Best-effort apply: dangling references become warnings, no rollback
- Header combobox switcher + snapshot-style manage dialog
- Tray Projects submenu shared with the UI apply/event pipeline
- i18n for zh/en/ja/zh-TW under the new profiles domain
- Integration tests covering roundtrip, dangling refs and clear
2026-07-07 10:49:32 +08:00
Jason 5dbea70eb1 feat(providers): seed an official preset on startup for Claude/Codex/Gemini
New and existing users now see a built-in "Claude Official" / "OpenAI
Official" / "Google Official" entry in their provider list, so switching
back to the official endpoint is one click away instead of buried in the
README.

- New providers_seed.rs holds the three seeds (id, name, settings_config,
  icon) keyed by AppType, with a single is_official_seed_id() helper that
  scans OFFICIAL_SEEDS so the id list has one source of truth.
- Database::init_default_official_providers() runs once per database
  (gated by an official_providers_seeded setting flag), appends each seed
  to the end of the sort order, and never touches is_current.
- Startup also auto-imports the live config (settings.json / auth.json /
  .env) as a "default" provider before seeding, so users with an existing
  manual config don't lose it when they click the official preset.
- Database::has_non_official_seed_provider() replaces the get_all_providers
  call in import_default_config's gating check with an id-only scan,
  dropping the N+1 endpoint sub-queries from every startup.
2026-04-09 16:49:14 +08:00
Jason bf40b0138c feat: add usage daily rollups, incremental auto-vacuum, and sync-aware backup
- Add usage_daily_rollups table (schema v6) to aggregate proxy request
  logs into daily summaries, reducing query overhead for statistics
- Add rollup_and_prune DAO that aggregates old detail logs (>N days)
  into rollup rows and deletes the originals
- Update all usage stats queries to UNION detail logs with rollup data
- Introduce incremental auto-vacuum for SQLite, with startup and
  periodic cleanup of old stream_check_logs and request log rollups
- Split backup export/import into full vs sync variants: WebDAV sync
  now skips local-only table data (proxy_request_logs,
  stream_check_logs, provider_health, proxy_live_backup,
  usage_daily_rollups) while preserving them on import
- Add enable_logging guard to skip request log writes when disabled
- Apply cargo fmt formatting fixes across multiple modules
2026-03-08 19:42:18 +08:00
Jason e7766d4d22 refactor: remove OMO common config two-layer merge system
Each OMO provider now stores its complete configuration directly in
settings_config.otherFields instead of relying on a shared OmoGlobalConfig
merged at write time. This simplifies the data flow from a 4-tuple
(agents, categories, otherFields, useCommonConfig) to a 3-tuple and
eliminates an entire DB table, two Tauri commands, and ~1700 lines of
merge/sync code across frontend and backend.

Backend:
- Delete database/dao/omo.rs (OmoGlobalConfig struct + get/save methods)
- Remove get/set_config_snippet from settings DAO
- Remove get/set_common_config_snippet Tauri commands
- Replace merge_config() with build_config() in services/omo.rs
- Simplify OmoVariant (remove config_key, known_keys)
- Simplify import_from_local and build_local_file_data
- Rewrite all OMO service tests

Frontend:
- Delete OmoCommonConfigEditor.tsx and OmoGlobalConfigFields.tsx
- Delete src/lib/api/config.ts
- Remove OmoGlobalConfig type and merge preview functions
- Remove useGlobalConfig/useSaveGlobalConfig query hooks
- Simplify useOmoDraftState (remove all common config state)
- Replace OmoCommonConfigEditor with read-only JsonEditor preview
- Clean i18n keys (zh/en/ja)
2026-02-26 19:31:43 +08:00
Dex Miller ed47480fc7 feat(omo): integrate Oh My OpenCode profile management (#972)
* feat(omo): integrate Oh My OpenCode profile management into Provider system

Adds full-stack OMO support: backend config read/write/import, OMO-specific
provider CRUD with exclusive switching, frontend profile editor with
agent/category/model configuration, global config management, and i18n support.

* feat(omo): add model/variant dropdowns from enabled providers

Replace model text inputs with Select dropdowns sourced from enabled
OpenCode providers, add thinking-level variant selection, and prevent
auto-enabling newly added OMO providers.

* fix(omo): use standard provider action styles for OMO switch button

* fix(omo): replace hardcoded isZh strings with proper i18n t() calls
2026-02-09 12:18:20 +08:00
Calcium-Ion 8fe5c1041a feat: add Universal Provider feature (#348)
* feat: add Universal Provider feature

- Add Universal Provider data structures and type definitions
- Implement backend CRUD operations and sync functionality
- Add frontend UI components (UniversalProviderPanel, Card, FormModal)
- Add NewAPI icon and preset configuration
- Support cross-app (Claude/Codex/Gemini) configuration sync
- Add website URL field for providers
- Implement real-time refresh via event notifications
- Add i18n support (Chinese/English/Japanese)

* feat: integrate universal provider presets into add provider dialog

- Add universal provider presets (NewAPI, Custom Gateway) to preset selector
- Show universal presets with Layers icon badge in preset selector
- Open UniversalProviderFormModal when universal preset is clicked
- Pass initialPreset to auto-fill form when opened from add dialog
- Add i18n keys for addSuccess/addFailed messages
- Keep separate universal provider panel for management

* refactor: move universal provider management to add dialog

- Remove Layers button from main navigation header
- Add 'Manage' button next to universal provider presets
- Open UniversalProviderPanel from within add provider dialog
- Add i18n keys for 'manage' in all locales

* style: display universal provider presets on separate line

- Move universal provider section to a new row with border separator
- Add label '统一供应商:' to clarify the section

* style: unify universal provider label style with preset label

- Use FormLabel component for consistent styling
- Add background to 'Manage' button matching preset buttons
- Update icon size and button padding for consistency

* feat: add sync functionality and JSON preview for Universal Provider

* fix: add missing in_failover_queue field to Provider structs

After rebasing to main, the Provider struct gained a new
`in_failover_queue` field. This fix adds the missing field
to the three to_*_provider() methods in UniversalProvider.

* refactor: redesign AddProviderDialog with tab-based layout

- Add tabs to separate app-specific providers and universal providers
- Move "Add Universal Provider" button from panel header to footer
- Remove unused handleAdd callback and clean up imports
- Update emptyHint i18n text to reference the footer button

* fix: append /v1 suffix to Codex base_url in Universal Provider

Codex uses OpenAI-compatible API which requires the /v1 endpoint suffix.
The Universal Provider now automatically appends /v1 to base_url when
generating Codex provider config if not already present.

- Handle trailing slashes to avoid double slashes
- Apply fix to both backend (to_codex_provider) and frontend preview

* feat: auto-sync universal provider to apps on creation

Previously, users had to manually click sync after adding a universal
provider. Now it automatically syncs to Claude/Codex/Gemini on creation,
providing a smoother user experience.

---------

Co-authored-by: Jason <farion1231@gmail.com>
2025-12-26 22:47:24 +08:00
Jason 5d424b1383 feat(proxy): implement independent failover queue management
Add a new failover queue system that operates independently from provider
sortIndex, allowing users to configure failover order per app type.

Backend changes:
- Add failover_queue table to schema.rs for persistent storage
- Create dao/failover.rs with CRUD operations for queue management
- Add Tauri commands for queue operations (get, add, remove, reorder, toggle)
- Refactor provider_router.rs select_providers() to use failover queue:
  - Current provider always takes first priority
  - Queue providers ordered by queue_order as fallback
  - Only providers with open circuit breakers are included

Frontend changes:
- Add FailoverQueueItem type to proxy.ts
- Extend failover.ts API with queue management methods
- Add React Query hooks for queue data fetching and mutations
- Create FailoverQueueManager component with drag-and-drop reordering
- Integrate queue management into SettingsPage under "Auto Failover"
- Add i18n translations for zh and en locales
2025-12-12 16:13:07 +08:00
YoVinchen 395783e22a Feat/provider icon color (#385)
* feat(ui): add color prop support to ProviderIcon component

* feat(health): add stream check core functionality

Add new stream-based health check module to replace model_test:
- Add stream_check command layer with single and batch provider checks
- Add stream_check DAO layer for config and log persistence
- Add stream_check service layer with retry mechanism and health status evaluation
- Add frontend HealthStatusIndicator component
- Add frontend useStreamCheck hook

This provides more comprehensive health checking capabilities.

* refactor(health): replace model_test with stream_check

Replace model_test module with stream_check across the codebase:
- Remove model_test command and service modules
- Update command registry in lib.rs to use stream_check commands
- Update module exports in commands/mod.rs and services/mod.rs
- Remove frontend useModelTest hook
- Update stream_check command implementation

This refactoring provides clearer naming and better separation of concerns.

* refactor(db): clean up unused database tables and optimize schema

Remove deprecated and unused database tables:
- Remove proxy_usage table (replaced by proxy_request_logs)
- Remove usage_daily_stats table (aggregation done on-the-fly)
- Rename model_test_logs to stream_check_logs with updated schema
- Remove related DAO methods for proxy_usage
- Update usage_stats service to use proxy_request_logs only
- Refactor usage_script to work with new schema

This simplifies the database schema and removes redundant data storage.

* refactor(ui): update frontend components for stream check

Update frontend components to use stream check API:
- Refactor ModelTestConfigPanel to use stream check config
- Update API layer to use stream_check commands
- Add HealthStatus type and StreamCheckResult interface
- Update ProviderList to use new health check integration
- Update AutoFailoverConfigPanel with stream check references
- Improve UI layout and configuration options

This completes the frontend migration from model_test to stream_check.

* feat(health): add configurable test models and reasoning effort support

Enhance stream check service with configurable test models:
- Add claude_model, codex_model, gemini_model to StreamCheckConfig
- Support reasoning effort syntax (model@level or model#level)
- Parse and apply reasoning_effort for OpenAI-compatible models
- Remove hardcoded model names from check functions
- Add unit tests for model parsing logic
- Remove obsolete model_test source files

This allows users to customize which models are used for health checks.
2025-12-11 17:20:44 +08:00
YoVinchen b1103c8a59 Feat/proxy server (#355)
* feat(proxy): implement local HTTP proxy server with multi-provider failover

Add a complete HTTP proxy server implementation built on Axum framework,
enabling local API request forwarding with automatic provider failover
and load balancing capabilities.

Backend Implementation (Rust):
- Add proxy server module with 7 core components:
  * server.rs: Axum HTTP server lifecycle management (start/stop/status)
  * router.rs: API routing configuration for Claude/OpenAI/Gemini endpoints
  * handlers.rs: Request/response handling and transformation
  * forwarder.rs: Upstream forwarding logic with retry mechanism (652 lines)
  * error.rs: Comprehensive error handling and HTTP status mapping
  * types.rs: Shared types (ProxyConfig, ProxyStatus, ProxyServerInfo)
  * health.rs: Provider health check infrastructure

Service Layer:
- Add ProxyService (services/proxy.rs, 157 lines):
  * Manage proxy server lifecycle
  * Handle configuration updates
  * Track runtime status and metrics

Database Layer:
- Add proxy configuration DAO (dao/proxy.rs, 242 lines):
  * Persist proxy settings (listen address, port, timeout)
  * Store provider priority and availability flags
- Update schema with proxy_config table (schema.rs):
  * Support runtime configuration persistence

Tauri Commands:
- Add 6 command endpoints (commands/proxy.rs):
  * start_proxy_server: Launch proxy server
  * stop_proxy_server: Gracefully shutdown server
  * get_proxy_status: Query runtime status
  * get_proxy_config: Retrieve current configuration
  * update_proxy_config: Modify settings without restart
  * is_proxy_running: Check server state

Frontend Implementation (React + TypeScript):
- Add ProxyPanel component (222 lines):
  * Real-time server status display
  * Start/stop controls
  * Provider availability monitoring
- Add ProxySettingsDialog component (420 lines):
  * Configuration editor (address, port, timeout)
  * Provider priority management
  * Settings validation
- Add React hooks:
  * useProxyConfig: Manage proxy configuration state
  * useProxyStatus: Poll and display server status
- Add TypeScript types (types/proxy.ts):
  * Define ProxyConfig, ProxyStatus interfaces

Provider Integration:
- Extend Provider model with availability field (providers.rs):
  * Track provider health for failover logic
- Update ProviderCard UI to display proxy status
- Integrate proxy controls in Settings page

Dependencies:
- Add Axum 0.7 (async web framework)
- Add Tower 0.4 (middleware and service abstractions)
- Add Tower-HTTP (CORS layer)
- Add Tokio sync primitives (oneshot, RwLock)

Technical Details:
- Graceful shutdown via oneshot channel
- Shared state with Arc<RwLock<T>> for thread-safe config updates
- CORS enabled for cross-origin frontend access
- Request/response streaming support
- Automatic retry with exponential backoff (forwarder)
- API key extraction from multiple config formats (Claude/Codex/Gemini)

File Statistics:
- 41 files changed
- 3491 insertions(+), 41 deletions(-)
- Core modules: 1393 lines (server + forwarder + handlers)
- Frontend UI: 642 lines (ProxyPanel + ProxySettingsDialog)
- Database/DAO: 326 lines

This implementation provides the foundation for advanced features like:
- Multi-provider load balancing
- Automatic failover on provider errors
- Request logging and analytics
- Usage tracking and cost monitoring

* fix(proxy): resolve UI/UX issues and database constraint error

Simplify proxy control interface and fix database persistence issues:

Backend Fixes:
- Fix NOT NULL constraint error in proxy_config.created_at field
  * Use COALESCE to preserve created_at on updates
  * Ensure proper INSERT OR REPLACE behavior
- Remove redundant enabled field validation on startup
  * Auto-enable when user clicks start button
  * Persist enabled state after successful start
- Preserve enabled state during config updates
  * Prevent accidental service shutdown on config save

Frontend Improvements:
- Remove duplicate proxy enable switch from settings dialog
  * Keep only runtime toggle in ProxyPanel
  * Simplify user experience with single control point
- Hide proxy target button when proxy service is stopped
  * Add isProxyRunning prop to ProviderCard
  * Conditionally render proxy controls based on service status
- Update form schema to omit enabled field
  * Managed automatically by backend

Files: 5 changed, 81 insertions(+), 94 deletions(-)

* fix(proxy): improve URL building and Gemini request handling

- Refactor URL construction with version path deduplication (/v1, /v1beta)
- Preserve query parameters for Gemini API requests
- Support GOOGLE_GEMINI_API_KEY field name (with fallback)
- Change default proxy port from 5000 to 15721
- Fix test: use Option type for is_proxy_target field

* refactor(proxy): remove unused request handlers and routes

- Remove unused GET/DELETE request forwarding methods
- Remove count_tokens, get/delete response handlers
- Simplify router by removing unused endpoints
- Keep only essential routes: /v1/messages, /v1/responses, /v1beta/*

* Merge branch 'main' into feat/proxy-server

* fix(proxy): resolve clippy warnings for dead code and uninlined format args

- Add #[allow(dead_code)] to unused ProviderUnhealthy variant
- Inline format string arguments in handlers.rs and codex.rs log macros
- Refactor error response handling to properly pass through upstream errors
- Add URL deduplication logic for /v1/v1 paths in CodexAdapter

* feat(proxy): implement provider adapter pattern with OpenRouter support

This major refactoring introduces a modular provider adapter architecture
to support format transformation between different AI API formats.

New features:
- Add ProviderAdapter trait for unified provider abstraction
- Implement Claude, Codex, and Gemini adapters with specific logic
- Add Anthropic ↔ OpenAI format transformation for OpenRouter compatibility
- Support model mapping from provider configuration (ANTHROPIC_MODEL, etc.)
- Add OpenRouter preset to Claude provider presets

Refactoring:
- Extract authentication logic into auth.rs with AuthInfo and AuthStrategy
- Move URL building and request transformation to individual adapters
- Simplify ProviderRouter to only use proxy target providers
- Refactor RequestForwarder to use adapter-based request/response handling
- Use whitelist mode for header forwarding (only pass necessary headers)

Architecture:
- providers/adapter.rs: ProviderAdapter trait definition
- providers/auth.rs: AuthInfo, AuthStrategy types
- providers/claude.rs: Claude adapter with OpenRouter detection
- providers/codex.rs: Codex (OpenAI) adapter
- providers/gemini.rs: Gemini (Google) adapter
- providers/models/: Anthropic and OpenAI API data models
- providers/transform.rs: Bidirectional format transformation

* feat(proxy): add streaming SSE transform and thinking parameter support

New features:
- Add OpenAI → Anthropic SSE streaming response transformation
- Support thinking parameter detection for reasoning model selection
- Add ANTHROPIC_REASONING_MODEL config option for extended thinking

Changes:
- streaming.rs: Implement SSE event parsing and Anthropic format conversion
- transform.rs: Add thinking detection logic and reasoning model mapping
- handlers.rs: Integrate streaming transform for OpenRouter compatibility
- Cargo.toml: Add async-stream and bytes dependencies

* feat(db): add usage tracking schema and types

Add database tables for proxy request logs and model pricing.
Extend Provider and error types to support usage statistics.

* feat(proxy): implement usage tracking subsystem

Add request logger with automatic cost calculation.
Implement token parser for Claude/OpenAI/Gemini responses.
Add cost calculator based on model pricing configuration.

* feat(proxy): integrate usage logging into request handlers

Add usage logging to forwarder and streaming handlers.
Track token usage and costs for each proxy request.

* feat(commands): add usage statistics Tauri commands

Register usage commands for summary, trends, logs, and pricing.
Expose usage stats service through Tauri command layer.

* feat(api): add frontend usage API and query hooks

Add TypeScript types for usage statistics.
Implement usage API with Tauri invoke calls.
Add TanStack Query hooks for usage data fetching.

* feat(ui): add usage dashboard components

Add UsageDashboard with summary cards, trend chart, and data tables.
Implement model pricing configuration panel.
Add request log viewer with filtering and detail panel.

* fix(ui): integrate usage dashboard and fix type errors

Add usage dashboard tab to settings page.
Fix UsageScriptModal TypeScript type annotations.

* deps: add recharts for charts and rust_decimal/uuid for usage tracking

- recharts: Chart visualization for usage trends
- rust_decimal: Precise cost calculations
- uuid: Request ID generation

* feat(proxy): add ProviderType enum for fine-grained provider detection

Introduce ProviderType enum to distinguish between different provider
implementations (Claude, ClaudeAuth, Codex, Gemini, GeminiCli, OpenRouter).
This enables proper authentication handling and request transformation
based on the actual provider type rather than just AppType.

- Add ProviderType enum with detection logic from config
- Enhance Claude adapter with OpenRouter detection
- Enhance Gemini adapter with CLI mode detection
- Add helper methods for provider type inference

* feat(database): extend schema with streaming and timing fields

Add new columns to proxy_request_logs table for enhanced usage tracking:
- first_token_ms and duration_ms for performance metrics
- provider_type and is_streaming for request classification
- cost_multiplier for flexible pricing

Update model pricing with accurate rates for Claude/GPT/Gemini models.
Add ensure_model_pricing_seeded() call on database initialization.
Add test for model pricing auto-seeding verification.

* feat(proxy/usage): enhance token parser and logger for multi-format support

Parser enhancements:
- Add OpenAI Chat Completions format parsing (prompt_tokens/completion_tokens)
- Add model field to TokenUsage for actual model name extraction
- Add from_codex_response_adjusted() for proper cache token handling
- Add debug logging for better stream event tracing

Logger enhancements:
- Add first_token_ms, provider_type, is_streaming, cost_multiplier fields
- Extend RequestLog struct with full metadata tracking
- Update log_with_calculation() signature for new fields

Calculator: Update tests with model field in TokenUsage.

* feat(proxy): enhance proxy server with session tracking and OpenAI route

Error handling:
- Add StreamIdleTimeout and AuthError variants for better error classification

Module exports:
- Export ResponseType, StreamHandler, NonStreamHandler from response_handler
- Export ProxySession, ClientFormat from session module

Server routing:
- Add /v1/chat/completions route for OpenAI Chat Completions API

Handlers:
- Add log_usage_with_session() for enhanced usage tracking with session context
- Add first_token_ms timing measurement for streaming responses
- Use SseUsageCollector with start_time for accurate latency calculation
- Track is_streaming flag in usage logs

* feat(services): add pagination and enhanced filtering for request logs

Usage stats service:
- Change get_request_logs() from limit/offset to page/page_size pagination
- Return PaginatedLogs with total count, page, and page_size
- Add appType and providerName filters with LIKE search
- Add is_streaming, first_token_ms, duration_ms to RequestLogDetail
- Join with providers table for provider name lookup

Commands:
- Update get_request_logs command signature for pagination params

Module exports:
- Export PaginatedLogs struct

* feat(frontend): update usage types and API for pagination support

Types (usage.ts):
- Add isStreaming, firstTokenMs, durationMs to RequestLog
- Add PaginatedLogs interface with data, total, page, pageSize
- Change LogFilters: providerId -> appType + providerName

API (usage.ts):
- Change getRequestLogs params from limit/offset to page/pageSize
- Return PaginatedLogs instead of RequestLog[]
- Pass filters object directly to backend

Query (usage.ts):
- Update usageKeys.logs key generation for pagination
- Update useRequestLogs hook signature

* refactor(ui): enhance RequestLogTable with filtering and pagination

UI improvements:
- Add filter bar with app type, provider name, model, status selectors
- Add date range picker (startDate/endDate)
- Add search/reset/refresh buttons

Pagination:
- Implement proper page-based pagination with page info display
- Show total count and current page range
- Add prev/next navigation buttons

Features:
- Default to last 24 hours filter
- Streamlined table columns layout
- Query invalidation on refresh

* style(config): format mcpPresets code style

Apply consistent formatting to createNpxCommand function and
sequential-thinking server configuration.

* fix(ui): update SettingsPage tab styles for improved appearance (#342)

* feat(model-test): add provider model availability testing

Implement standalone model testing feature to verify provider API connectivity:
- Add ModelTestService for Claude/Codex/Gemini endpoint testing
- Create model_test_logs table for test result persistence
- Add test button to ProviderCard with loading state
- Include ModelTestConfigPanel for customizing test parameters

* fix(proxy): resolve token parsing for OpenRouter streaming responses

Problem:
- OpenRouter and similar third-party services return streaming responses
  where input_tokens appear in message_delta instead of message_start
- The previous implementation only extracted input_tokens from message_start,
  causing input_tokens to be recorded as 0 for these providers

Changes:
- streaming.rs: Add prompt_tokens field to Usage struct and include
  input_tokens in the transformed message_delta event when converting
  OpenAI format to Anthropic format
- parser.rs: Update from_claude_stream_events() to handle input_tokens
  from both message_start (native Claude API) and message_delta (OpenRouter)
  - Use if-let pattern instead of direct unwrap for safer parsing
  - Only update input_tokens from message_delta if not already set
- logger.rs: Adjust test parameters to match updated function signature

Tests:
- Add test_openrouter_stream_parsing() for OpenRouter format validation
- Add test_native_claude_stream_parsing() for native Claude API validation

* fix(pricing): standardize model ID format for pricing lookup

Normalize model IDs by removing vendor prefixes and converting dots to hyphens to ensure consistent pricing lookups across different API response formats.

Changes:
- Update seed data to use hyphen format (e.g., gpt-5-1, gemini-2-5-pro)
- Add normalize_model_id() function to strip vendor prefixes (anthropic/, openai/)
- Convert dots to hyphens in model IDs (claude-haiku-4.5 → claude-haiku-4-5)
- Try both original and normalized IDs for exact matching
- Use normalized ID for suffix-based fallback matching
- Add comprehensive test cases for prefix and dot handling
- Add warning log when no pricing found

This ensures pricing lookups work correctly for:
- Models with vendor prefixes: anthropic/claude-haiku-4.5
- Models with dots in version: claude-sonnet-4.5
- Models with date suffixes: claude-haiku-4-5-20240229

* style(rust): apply clippy formatting suggestions

Apply automatic clippy fixes for uninlined_format_args warnings across Rust codebase. Replace format string placeholders with inline variable syntax for improved readability.

Changes:
- Convert format!("{}", var) to format!("{var}")
- Apply to model_test.rs, parser.rs, and usage_stats.rs
- Fix line length issues by breaking long function calls
- Improve code formatting consistency

All changes are automatic formatting with no functional impact.

* fix(ui): restore card borders in usage statistics panels

Restore proper card styling for ModelTestConfigPanel and PricingConfigPanel by adding back border and rounded-lg classes. The transparent background styling was causing visual inconsistency.

Changes:
- Replace border-none bg-transparent shadow-none with border rounded-lg
- Apply to both loading and error states for consistency
- Format TypeScript code for better readability
- Break long function signatures across multiple lines

This ensures the usage statistics panels have consistent visual appearance with proper borders and rounded corners.

* feat(pricing): add GPT-5 Codex model pricing presets

Add pricing configuration for GPT-5 Codex variants to support cost tracking for Codex-specific models.

Changes:
- Add gpt-5-codex model with standard GPT-5 pricing
- Add gpt-5-1-codex model with standard GPT-5.1 pricing
- Input: $1.25/M tokens, Output: $10/M tokens
- Cache read: $0.125/M tokens, Cache creation: $0

This ensures accurate cost calculation for Codex API requests using GPT-5 Codex models.
2025-12-05 11:26:41 +08:00
Jason c3f2f0798d refactor(database): split monolithic database.rs into modular structure
Split the 1788-line database.rs into a well-organized module directory:

- mod.rs (142 lines): Database struct and initialization
- schema.rs (341 lines): Table creation and schema migrations
- backup.rs (324 lines): SQL import/export and snapshot backup
- migration.rs (240 lines): JSON to SQLite data migration
- tests.rs (280 lines): Unit tests
- dao/providers.rs (254 lines): Provider CRUD operations
- dao/mcp.rs (97 lines): MCP server CRUD operations
- dao/prompts.rs (88 lines): Prompt CRUD operations
- dao/skills.rs (124 lines): Skills CRUD operations
- dao/settings.rs (65 lines): Settings key-value storage

Benefits:
- Max file size reduced from 1788 to 341 lines
- Clear separation of concerns (schema, backup, migration, DAOs)
- Easier to navigate and maintain
- All 107 tests passing with zero API changes
2025-11-25 11:56:08 +08:00