Commit Graph

831 Commits

  • feat: add X-Code partner provider preset for Claude, Codex and OpenCode
    - Add X-Code provider presets with x-code.cn endpoint
    - Fix ANTHROPIC_API_KEY to ANTHROPIC_AUTH_TOKEN in Claude preset
    - Register x-code icon SVG in icon index
    - Add partnerPromotion.x-code i18n keys for zh, en, ja locales
  • feat: add Micu partner provider preset for Claude, Codex, OpenClaw and OpenCode
    - Add Micu provider presets with openclaudecode.cn endpoint
    - Register micu icon SVG in icon index with namespaced CSS classes
    - Rename miku.svg to micu.svg to match icon key
    - Add partnerPromotion.micu i18n keys for zh, en, ja locales
  • feat: add Ucloud partner provider preset for Claude, Codex and OpenClaw
    - Add Ucloud provider presets with modelverse.cn API endpoint
    - Register ucloud icon SVG in icon index with namespaced gradient IDs
    - Add partnerPromotion.ucloud i18n keys for zh, en, ja locales
  • feat: show failover toggle independently on main page with confirm dialog
    Add enableFailoverToggle setting to control failover toggle visibility
    on the main page, decoupled from proxy takeover state. First-time
    enable shows a ConfirmDialog (same pattern as proxy toggle). The toggle
    row is placed in the Auto Failover accordion section in settings.
  • feat: apply common config as runtime overlay instead of materialized merge
    Common config snippets are now dynamically overlaid when writing live
    files, rather than being pre-merged into provider snapshots at edit time.
    This ensures that updating a snippet immediately takes effect for the
    current provider and automatically propagates to other providers on
    their next switch.
    
    Key changes:
    - Add write_live_with_common_config() overlay pipeline
    - Strip common config from live before backfilling provider snapshots
    - Normalize provider snapshots on save to keep them snippet-free
    - Add explicit commonConfigEnabled flag in ProviderMeta (Option<bool>)
    - Migrate legacy providers on snippet save (infer flag from subset check)
    - Add Codex TOML snippet validation in set_common_config_snippet
    - Stabilize onConfigChange callbacks with useCallback in ProviderForm
  • fix: comprehensive i18n audit - add 69 missing keys and fix hardcoded Chinese
    - Add 69 missing translation keys to zh/en/ja (usage, proxy, sessionManager,
      deeplink, codexConfig, openclaw, circuitBreaker, streamCheck, etc.)
    - Replace 15 hardcoded Chinese strings in CircuitBreakerConfigPanel with t() calls
    - Fix ColorPicker component to use i18n for default label
    - Add i18n interpolation params to ProxyToggle tooltip translations
    - All three language files synchronized at 1838 keys
  • feat: add confirmation dialog for WebDAV auto-sync toggle
    Show a one-time traffic warning when users first enable auto-sync,
    persisted via autoSyncConfirmed flag in settings.
  • feat: add dual-layer versioning to WebDAV sync (protocol v2 + db-v6)
    Separate protocol version from database compatibility version in WebDAV
    sync paths. Upload writes to v2/db-v6/<profile>, download falls back to
    legacy v2/<profile> when current path has no data. Extend manifest with
    optional dbCompatVersion field and add legacy layout detection to UI.
  • feat: add session deletion with per-provider cleanup and path safety
    Add delete_session Tauri command dispatching to provider-specific deletion
    logic for all 5 providers (Claude, Codex, Gemini, OpenCode, OpenClaw).
    Includes path traversal protection via canonicalize + starts_with validation,
    session ID verification against file contents, frontend confirmation dialog
    with optimistic cache updates, i18n keys (zh/en/ja), and component tests.
  • fix: normalize JSON5 slash escaping and add i18n for OpenClaw panels
    - Fix json-five output unescaping forward slashes (\/ → /)
    - Add structured error codes for env validation (EMPTY, INVALID_JSON, OBJECT_REQUIRED)
    - Add i18n keys (zh/en/ja) for health warnings, tool profiles, env editor hints,
      and agents legacy timeout migration
    - Update env validation test to match new error codes
  • feat: overhaul OpenClaw config panels with JSON5 round-trip write engine
    - Add json-five crate for JSON5 serialization preserving comments and formatting
    - Rewrite openclaw_config.rs with comment-preserving JSON5 read/write engine
    - Add Tauri commands: get_openclaw_live_provider, write_openclaw_config_section
    - Redesign EnvPanel as full JSON editor with structured error handling
    - Add tools.profile selection (minimal/coding/messaging/full) to ToolsPanel
    - Add legacy timeout migration support to AgentsDefaultsPanel
    - Add OpenClawHealthBanner component for config validation warnings
    - Add supporting hooks, mutations, utility functions, and unit tests
  • refactor: deduplicate and improve OpenAI Responses API conversion
    - Extract shared map_responses_stop_reason and build_anthropic_usage_from_responses into transform_responses.rs as pub(crate)
    - Align cache token extraction priority: OpenAI nested details as fallback, direct Anthropic fields as override
    - Extract resolve_content_index helper to eliminate 3x copy-paste in streaming_responses.rs
    - Add streaming reasoning/thinking event handlers (response.reasoning.delta/done)
    - Add explanatory comment to transform_response heuristic detection
    - Add openai_responses to api_format doc comment and needs_transform test
    - Add explicit no-op match arms for lifecycle events
    - Add promptCacheKey to TS ProviderMeta type
    - Update toast i18n key to be generic for both OpenAI formats (zh/en/ja)
  • feat: add OpenAI Responses API format conversion (api_format = "openai_responses")
    Support Anthropic ↔ OpenAI Responses API format conversion alongside existing
    Chat Completions conversion. The Responses API uses a flat input/output structure
    with lifted function_call/function_call_output items and named SSE lifecycle events.
  • fix:Add a new vendor page, API endpoint, and model name. (#1155)
    * fix:Add a new vendor page, API endpoint, and model name. Fix the bug where, after entering characters, line breaks cannot be fully deleted.
    
    * fix: add missing i18n key codexConfig.modelNameHint for zh/en/ja
    
    ---------
    
    Co-authored-by: Jason <farion1231@gmail.com>
  • fix: skills count not displaying when adding (#1295)
    * fix: skills count not displaying when adding
    
    * fix: get real skill count by awaiting discovery after adding repo
    
    The previous approach computed count before discovery, so it was always 0.
    Now we await refetchDiscoverable() after the mutation, then filter the
    fresh skills list to get the actual count for the toast message.
    
    Also reverts the SkillRepo.count field — keep the interface clean since
    count is a transient UI concern, not a data model property.
    
    ---------
    
    Co-authored-by: Jason <farion1231@gmail.com>
  • feat: add Bedrock request optimizer (PRE-SEND thinking + cache injection) (#1301)
    * feat: add Bedrock request optimizer (PRE-SEND thinking + cache injection)
    
    Add a PRE-SEND request optimizer that enhances Bedrock API requests
    before forwarding, complementing the existing POST-ERROR rectifier system.
    
    New modules:
    - thinking_optimizer: 3-path model detection (adaptive/legacy/skip)
      - Opus 4.6/Sonnet 4.6: adaptive thinking + effort max + 1M context beta
      - Legacy models: inject extended thinking with max budget
      - Haiku: skip (no modification)
    - cache_injector: auto-inject cache_control breakpoints (max 4)
      - Injects at tools/system/assistant message positions
      - TTL upgrade for existing breakpoints (5m → 1h)
    
    Gate: only activates for Bedrock providers (CLAUDE_CODE_USE_BEDROCK=1)
    Config: stored in SQLite settings table, default OFF, user opt-in
    UI: new Optimizer section in RectifierConfigPanel with 3 toggles + TTL
    
    18 unit tests covering all paths. Verified against live Bedrock API.
    
    * chore: remove docs/plans directory
    
    * fix: address code review findings for Bedrock request optimizer
    
    P0 fixes:
    - Replace hardcoded Chinese with i18n t() calls in optimizer panel,
      add translation keys to zh/en/ja locale files
    - Fix u64 underflow: max_tokens - 1 → max_tokens.saturating_sub(1)
    - Move optimizer from before retry loop to per-provider with body
      cloning, preventing Bedrock fields leaking to non-Bedrock providers
    
    P1 fixes:
    - Replace .map() side-effect pattern with idiomatic if-let (clippy)
    - Fix module alphabetical ordering in mod.rs
    - Add cache_ttl whitelist validation in set_optimizer_config
    - Remove #[allow(unused_assignments)] and dead budget decrement
    
    ---------
    
    Co-authored-by: Keith (via OpenClaw) <keithyt06@users.noreply.github.com>
    Co-authored-by: Jason <farion1231@gmail.com>
  • Add Bailian For Coding preset configuration (#1263)
    问题描述
    bailian 模块使用的请求地址  https://dashscope.aliyuncs.com/apps/anthropic  仅适用于普通订阅用户,订阅 code 的用户调用该地址会无法正常使用
    
    修改内容
    增加bailian For Coding模块提供给 code 订阅用户:
    正确地址:  https://coding.dashscope.aliyuncs.com/apps/anthropic 
    
    测试验证
    测试环境:本地搭建 ccswitch 运行环境,使用 code 订阅的阿里云 DashScope 账号
    测试步骤:
      1. 修改地址前:调用 bailian 接口提示请求失败/无权限
      2. 修改地址后:成功调用接口,返回正常响应结果
    影响范围:仅增加bailian For Coding模块,未改动其他逻辑,不影响非 code 订阅用户的使用
  • fix: use structural TOML merge/subset for Codex common config snippet
    The text-based approach (string append + substring matching) failed to
    detect already-merged snippets when config.toml was reformatted by
    external tools (MCP sync, Codex CLI). Replace with smol-toml parse/
    stringify + existing deepMerge/isSubset/deepRemove for correct
    structural operations. Falls back to text matching on parse failure.
  • feat: replace text inputs with dropdown selects for OpenClaw agent model config
    - Add useOpenClawModelOptions hook to aggregate models from all configured OpenClaw providers
    - Replace read-only primary model display with a searchable Select dropdown
    - Replace comma-separated fallback text input with add/remove Select rows
    - Filter out already-selected models from fallback options
    - Show "(not configured)" marker for values whose provider has been deleted
    - Unify terminology: rename "主模型/Primary Model" to "默认模型/Default Model"
  • feat: add model role badges and reorder presets to prioritize Opus
    - Add Primary/Fallback badge to each model card in OpenClaw form
    - Update modelsHint to explain model ordering semantics
    - Reorder 11 aggregator/third-party presets to put Opus first
  • fix: remove HTTP status code display from endpoint speed test
    The status code from a simple GET request reflects route matching,
    not actual endpoint availability. Users only need latency and
    reachability info, which the latency number already conveys.
  • feat: add first-run confirmation dialog for stream check
    Show an informational dialog when users first click the health check
    button, explaining its limitations (OAuth providers, relay services,
    Bedrock). The dialog persists the confirmation in settings so it only
    appears once per device.
  • feat: restore model health check (stream check) UI
    Re-enable the stream check feature that was hidden in v3.11.0.
    All backend code, database schema, and i18n keys were preserved;
    only the frontend UI needed uncommenting across 4 files.
    OpenCode and OpenClaw are excluded as the backend does not support them.
  • fix: pass app interpolation param to proxy takeover toast messages
    The i18next t() calls for proxy.takeover.enabled/disabled were missing
    the `app` interpolation parameter, causing {{app}} placeholders in
    translation strings to render literally instead of showing the app name.
  • fix: restore flex-1 on toolbarRef to fix compact mode exit
    After moving ProxyToggle/FailoverToggle outside toolbarRef, the flex-1
    class was accidentally left only on the outer wrapper. Without flex-1,
    toolbarRef.clientWidth reflects content width instead of available space,
    causing useAutoCompact's exit condition to never trigger.
  • fix: let "follow system" theme auto-update by delegating to Tauri's native theme tracking
    Pass "system" to set_window_theme instead of explicitly detecting dark/light,
    so Tauri uses window.set_theme(None) and the WebView's prefers-color-scheme
    media query stays in sync with the real OS theme.
  • refactor: move proxy toggle into panel and surface app takeover options
    Move the proxy on/off switch from the accordion header into the panel
    content area, placing it right above the app takeover section. This
    ensures users see the takeover options immediately after enabling the
    proxy, preventing the common pitfall of running the proxy without
    actually taking over any app.
    
    - Simplify accordion trigger to standard style with Badge only
    - Add AnimatePresence animation for takeover section reveal
    - Remove duplicate takeover switches from running info card
    - Update stoppedDescription i18n to reference "above toggle"
    - Add proxy.takeover.hint key in zh/en/ja
  • revert: restore full config overwrite + Common Config Snippet (revert 992dda5c)
    Revert the partial key-field merging refactoring introduced in 992dda5c,
    along with two dependent commits (24fa8a18, 87604b18) that referenced
    the now-removed ClaudeQuickToggles component.
    
    The whitelist-based partial merge approach had critical issues:
    - Non-whitelisted custom fields were lost during provider switching
    - Backfill permanently stripped non-key fields from the database
    - Whitelist required constant maintenance to track upstream changes
    
    This restores the proven "full config overwrite + Common Config Snippet"
    architecture where each provider stores its complete configuration and
    shared settings are managed via a separate snippet mechanism.
    
    Reverted commits:
    - 24fa8a18: context-aware JSON editor hint + hide quick toggles
    - 87604b18: hide ClaudeQuickToggles when creating
    - 992dda5c: partial key-field merging refactoring
    
    Restored:
    - Full config snapshot write (write_live_snapshot) for Claude/Codex/Gemini
    - Full config backfill (settings_config = live_config)
    - Common Config Snippet UI and backend commands
    - 6 frontend components/hooks for common config editing
    - configApi barrel export and DB snippet methods
    
    Removed:
    - ClaudeQuickToggles component
    - write_live_partial / backfill_key_fields / patch_claude_live
    - All KEY_FIELDS constants
  • fix: add import button for OpenCode/OpenClaw empty state and remove auto-import on startup
    Previously OpenCode and OpenClaw auto-imported providers from live config
    on app startup, which could confuse users. Now they follow the same
    pattern as Claude/Codex/Gemini: manual import via the empty state button.
  • fix: treat missing db file as error in manual backup to prevent false success toast
    backup_database_file() returning Ok(None) was silently resolved as null
    on the frontend, bypassing try/catch and showing a success toast without
    actually creating a backup file. Now None is converted to an explicit
    Err so the frontend correctly displays an error toast.
  • feat: show silent startup option only when launch on startup is enabled
    Add conditional rendering with animated transition for the silent startup
    toggle, so it only appears when the launch on startup option is checked.
  • fix: restore API Key input visibility when creating new Claude providers
    The hasApiKeyField() gate added for Bedrock AKSK/API Key distinction
    was incorrectly hiding the API Key input for all new providers with
    empty env config. Scope the gate to cloud_provider category only.
  • fix: merge duplicate openclaw i18n keys to restore provider form translations
    JSON does not support duplicate keys — the second `openclaw` object was
    silently overwriting the first, causing all provider form field translations
    (providerKey, apiProtocol, baseUrl, models, etc.) to be lost at runtime.
  • fix: remove last-provider deletion restriction for OMO/OMO Slim plugins
    OMO and OMO Slim are OpenCode plugins, not standalone apps — users
    should be able to fully remove them. Remove the count-based guard that
    prevented deleting the last active provider, and clean up the now-unused
    provider-count API surface across the full stack.
  • 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)
  • fix: invalidate OMO Slim query cache after provider mutations
    OMO Slim queries (["omo-slim", ...]) were not invalidated alongside
    OMO queries, causing stale UI state when switching/adding/deleting
    OMO Slim providers.
  • fix: sync OMO agent/category recommended models with upstream sources
    Regular agents & categories: align with oh-my-opencode model-requirements.ts
    fallback chains (oracle→gpt-5.2, librarian→gemini-3-flash, etc.)
    
    Slim agents: derive from Regular's design philosophy — match each agent
    to its functional counterpart's first-choice model instead of using
    the outdated Slim defaults. Also fix provider/model format to pure
    model IDs for suffix matching compatibility.