Commit Graph

226 Commits

  • 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
  • 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
  • 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>
  • 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.
  • 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: 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: 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)
  • chore: pre-release cleanup — remove debug logs, fix clippy warning, add missing ja translations, and format code
    - Remove 2 console.log statements from DeepLinkImportDialog
    - Fix clippy unnecessary_map_or: use is_some_and in live.rs
    - Add 17 missing Japanese i18n keys (skills, proxy, circuitBreaker, universalProvider)
    - Run prettier and cargo fmt to fix pre-existing formatting drift
  • fix: show context-aware JSON editor hint and hide quick toggles for non-active providers
    The hint text and ClaudeQuickToggles were misleading when editing
    non-current providers or creating new ones, since the editor only
    contains a config snippet rather than the full live settings.json.
  • fix: hide ClaudeQuickToggles when creating a new provider
    The quick toggles (hide AI attribution, extended thinking, teammates
    mode) patch the live config of the currently active provider, which
    is incorrect during provider creation. Only show them in edit mode.
  • fix(opencode): add missing omo-slim category checks across add/form/mutation paths
    Several code paths only checked for "omo" category but missed "omo-slim",
    causing OMO Slim providers to be treated as regular OpenCode providers
    (triggering invalid write_live_snapshot, requiring manual provider key,
    and showing wrong form fields).
  • feat: Add AWS Bedrock Provider Support (AKSK & API Key) (#1047)
    * Add AWS Bedrock provider integration design document
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * Add AWS Bedrock provider implementation plan
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * Update implementation plan: add OpenCode Bedrock support
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: add cloud_provider category to ProviderCategory type
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: add AWS Bedrock (AKSK) Claude Code provider preset with tests
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: add AWS Bedrock (API Key) Claude Code provider preset with tests
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: add AWS Bedrock OpenCode provider preset with @ai-sdk/amazon-bedrock
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * docs: add AWS Bedrock provider feature summary for PR
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * chore: remove internal planning documents
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * docs: add AWS Bedrock support to README (EN/ZH/JA)
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * Add AWS Bedrock UI merge design document
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * Add AWS Bedrock UI merge implementation plan
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: skip optional template values in validation
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: support isSecret template fields and hide base URL for Bedrock
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: add Bedrock validation, cleanup, and isBedrock prop in ProviderForm
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * feat: extend TemplateValueConfig and merge Bedrock presets
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: mask Bedrock API Key as secret and support GovCloud regions
    
    - Add isSecret: true to BEDROCK_API_KEY template value
    - Update region regex to support multi-segment regions (us-gov-west-1)
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * style: replace AWS icon with updated logo
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * style: replace AWS icon with updated logo
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * style: replace AWS icon with new PNG image
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix: address code review findings
    
    - Fix AWS icon: use SVG with embedded <image> instead of raw <img> tag
    - Hide duplicate ApiKeySection for Bedrock (auth via template fields only)
    - Guard settingsConfig cleanup against unresolved template placeholders
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * chore: remove planning documents
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * refactor: address PR review - split Bedrock into two presets, restore SVG icon
    
    Based on maintainer review feedback on PR #1047:
    
    1. Split merged "AWS Bedrock" back into two separate presets:
       - "AWS Bedrock (AKSK)": uses AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY
       - "AWS Bedrock (API Key)": uses top-level apiKey field via standard UI input
    
    2. Restore aws.svg to pure vector SVG (was PNG-in-SVG)
    
    3. Remove all Bedrock-specific logic from shared components:
       - Remove isBedrock prop from ClaudeFormFields
       - Remove Bedrock validation/cleanup blocks from ProviderForm
       - Remove optional/isSecret from TemplateValueConfig
       - Remove optional skip from useTemplateValues
    
    4. Add cloud_provider category handling:
       - Skip API Key/Base URL required validation
       - Hide Speed Test and Base URL for cloud_provider
       - Hide API format selector for cloud_provider (always Anthropic)
       - Show API Key input only when config has apiKey field
    
    5. Fix providerConfigUtils to support top-level apiKey:
       - getApiKeyFromConfig: check config.apiKey before env fields
       - setApiKeyInConfig: write to config.apiKey when present
       - hasApiKeyField: detect top-level apiKey property
    
    6. Add OpenClaw Bedrock preset (bedrock-converse-stream protocol)
    
    7. Update model IDs:
       - Sonnet: global.anthropic.claude-sonnet-4-6
       - Opus: global.anthropic.claude-opus-4-6-v1
       - Haiku: global.anthropic.claude-haiku-4-5-20251001-v1:0
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    * fix(test): align Bedrock API Key test assertions with preset implementation
    
    The API Key preset was refactored to use standard UI input (apiKey: "")
    instead of template variables, but the tests were not updated accordingly.
    
    ---------
    
    Co-authored-by: root <root@ip-10-0-11-189.ap-northeast-1.compute.internal>
    Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
    Co-authored-by: Jason <farion1231@gmail.com>
  • refactor(provider): switch from full config overwrite to partial key-field merging (#1098)
    * refactor(provider): switch from full config overwrite to partial key-field merging
    
    Replace the provider switching mechanism for Claude/Codex/Gemini from
    full settings_config overwrite to partial key-field replacement, preserving
    user's non-provider settings (plugins, MCP, permissions, etc.) across switches.
    
    - Add write_live_partial() with per-app implementations for Claude (JSON env
      merge), Codex (auth replace + TOML partial merge), and Gemini (env merge)
    - Add backfill_key_fields() to extract only provider-specific fields when
      saving live config back to provider entries
    - Update switch_normal, sync_current_to_live, add, update to use partial merge
    - Remove common config snippet feature for Claude/Codex/Gemini (no longer
      needed with partial merging); preserve OMO common config
    - Delete 6 frontend files (3 components + 3 hooks), clean up 11 modified files
    - Remove backend extract_common_config_* methods, 3 Tauri commands,
      CommonConfigSnippets struct, and related migration code
    - Update integration tests to validate key-field-only backfill behavior
    
    * refactor(cleanup): remove dead code and redundant MCP sync after partial-merge refactor
    
    - Remove ConfigService legacy full-overwrite sync methods (~150 lines)
    - Remove redundant McpService::sync_all_enabled from switch_normal
    - Switch proxy fallback recovery from write_live_snapshot to write_live_partial
    - Remove dead ProviderService::write_gemini_live wrapper
    - Update tests to reflect partial-merge behavior (MCP preserved, not re-synced)
    
    * feat(claude): add Quick Toggles for common Claude Code preferences
    
    Add checkbox toggles for hideAttribution, alwaysThinking, and
    enableTeammates that write directly to the live settings file via
    RFC 7396 JSON Merge Patch. Mirror changes to the form editor using
    form.watch for reactive updates.
    
    * fix(provider): add missing key fields to partial-merge constants
    
    Add provider-specific fields verified against official docs to prevent
    key residue or loss during provider switching:
    
    - Claude: CLAUDE_CODE_SUBAGENT_MODEL (env), model (top-level)
    - Codex: review_model, plan_mode_reasoning_effort
    - Gemini: GOOGLE_API_KEY (official alternative to GEMINI_API_KEY)
    
    * fix(provider): expand partial-merge key fields for Bedrock, Vertex, Foundry and behavior settings
    
    Add missing env/top-level fields to CLAUDE_KEY_ENV_FIELDS and
    CLAUDE_KEY_TOP_LEVEL so that provider switching correctly replaces
    (and clears) credentials and flags for AWS Bedrock, Google Vertex AI,
    Microsoft Foundry, and provider behavior overrides like max output
    tokens and prompt caching.
    
    * feat(provider): add auth field selector for Claude providers (AUTH_TOKEN / API_KEY)
    
    Allow users to choose between ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY
    when creating or editing custom Claude providers, persisted in meta.apiKeyField.
    
    * refactor(preset): remove AiHubMix hardcoded API_KEY in favor of generic auth selector
    
    AiHubMix was the only preset that hardcoded ANTHROPIC_API_KEY before the
    generic auth field selector was introduced. Now that users can freely
    choose between AUTH_TOKEN and API_KEY via the UI, remove the special-case
    and default AiHubMix to the standard ANTHROPIC_AUTH_TOKEN.
  • refactor(provider): replace startup auto-import with manual import button
    Remove the startup loop in lib.rs that auto-imported default providers
    for Claude/Codex/Gemini. Move config snippet extraction logic into the
    import_default_config command so it works when triggered manually.
    
    Add an "Import Current Config" button to ProviderEmptyState, wired via
    useMutation in ProviderList (shown only for standard apps). Update i18n
    keys (zh/en/ja) with new button labels and revised empty state text.
  • fix(i18n): clarify OpenClaw default model button labels
    Rename "Enable/Default" to "Set Default/Current Default" across
    zh/en/ja locales and widen button to fit longer text.
  • chore(ui): hide stream check / model test config panels
    The stream check feature is unreliable due to diverse provider request
    formats. Comment out the model test config UI in settings page, provider
    advanced config, and the test button in provider actions. Backend code
    and i18n keys are preserved for future restoration.
  • refactor(omo): deduplicate OMO/OMO Slim via OmoVariant parameterization
    Introduce OmoVariant struct with STANDARD/SLIM constants to eliminate
    ~250 lines of copy-pasted code across DAO, service, commands, and
    frontend layers. Adding a new OMO variant now requires only a single
    const declaration instead of duplicating ~400 lines.
  • feat(omo): add OMO Slim (oh-my-opencode-slim) support
    Implement full OMO Slim profile management to align with ai-toolbox:
    - Backend: Slim service methods, DAO, Tauri commands, plugin conflict handling
    - Frontend: types, API, query hooks, form integration with isSlim parameterization
    - Slim variant: 6 agents (no categories), separate config file and plugin name
    - Mutual exclusion: standard OMO and Slim cannot coexist as plugins
    - i18n: zh/en/ja translations for all Slim agent descriptions
  • refactor(forms): extract OpenCode/OMO/OpenClaw state from ProviderForm into dedicated hooks
    Split ProviderForm.tsx (2227 → 1526 lines) by extracting:
    - opencodeFormUtils.ts: pure functions and default config constants
    - useOmoModelSource: OMO model source collection from OpenCode providers
    - useOpencodeFormState: OpenCode provider form state and handlers
    - useOmoDraftState: OMO profile draft editing state
    - useOpenclawFormState: OpenClaw provider form state and handlers
  • feat(ui): add quick config toggles to Claude config editor (#1012)
    Add 3 quick-toggle checkboxes above the JSON editor in Claude provider settings:
    - Hide AI Attribution (sets attribution.commit/pr to empty string)
    - Extended Thinking (sets alwaysThinkingEnabled to true)
    - Teammates Mode (sets env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS to "1")
    
    Uses local state to keep toggles and JsonEditor in sync without
    triggering ProviderForm re-renders. Includes i18n for zh/en/ja.
    
    Co-authored-by: Jason <farion1231@gmail.com>
  • refactor(openclaw): move model detail fields into advanced options
    Keep only model ID and display name visible by default,
    collapse context window, max tokens, reasoning, and cost
    fields into the advanced options section.
  • fix(openclaw): address code review findings across P0-P3 issues
    - Add 25 missing i18n keys for OpenClawFormFields in all 3 locales (P0)
    - Replace key={index} with stable crypto.randomUUID() keys in EnvPanel,
      ToolsPanel, and OpenClawFormFields to prevent list state bugs (P1)
    - Exclude openclaw from ProxyToggle/FailoverToggle in App.tsx (P1)
    - Add merge_additive_config() for openclaw/opencode deep link imports (P1)
    - Normalize serde(flatten) field naming to `extra` + HashMap (P2)
    - Add directory existence check in remove_openclaw_provider_from_live (P2)
    - Remove dead code in import_default_config and openclaw API methods (P2)
    - Add duplicate key validation in EnvPanel before save (P2)
    - Add openclawConfigDir to Settings type (P2)
    - Add staleTime to OpenClaw query hooks (P3)
    - Fix type-unsafe delete via destructuring in mutations.ts (P3)
  • refactor(openclaw): migrate config panels to TanStack Query hooks
    Centralize query keys and extract reusable hooks (useOpenClaw.ts),
    replacing manual useState/useEffect load/save patterns in Env, Tools,
    and AgentsDefaults panels for consistency with MCP/Skills modules.
  • feat(openclaw): add default model button and fix sessionsApi export
    - Add "Enable as Default" button to OpenClaw provider cards
    - Place enable button before add/remove button for better UX
    - Disable remove button when provider is set as default
    - Add sessionsApi re-export from api barrel file to fix white screen
    - Add i18n keys for default model feature (zh/en/ja)
  • feat(openclaw): register suggested models to allowlist on provider add
    When adding an OpenClaw provider with suggestedDefaults, automatically
    merge its model catalog into the allowlist and set the default model
    if not already configured.
  • feat(openclaw): add providerKey input field with validation
    - Add providerKey input field in ProviderForm for OpenClaw
    - Implement duplicate key detection by querying existing providers
    - Add format validation (lowercase letters, numbers, hyphens only)
    - Disable field in edit mode (key cannot be changed after creation)
    - Update mutations.ts to support OpenClaw providerKey
    - Add i18n translations for zh/en/ja
  • fix(openclaw): pass providerKey in AddProviderDialog submit handler
    The providerKey was only being passed for opencode, causing openclaw
    provider creation to fail with "Provider key is required" error.
  • feat(openclaw): add provider form fields and UI components
    - Add OpenClawFormFields component for provider configuration
    - Add Collapsible UI component (radix-ui dependency)
    - Update ProviderForm with OpenClaw-specific handlers and preset logic
    - Extend OpenClawModel type with reasoning, input, maxTokens fields
    - Exclude OpenClaw from universal provider tab in AddProviderDialog
  • feat(openclaw): add additive mode frontend support
    - Add getOpenClawLiveProviderIds() API for querying live config
    - Update ProviderList to query OpenClaw live IDs
    - Rename isOpenCodeMode to isAdditiveMode (covers OpenCode + OpenClaw)
    - Update ProviderCard shouldAutoQuery and isActiveProvider logic
    - Update App.tsx onRemoveFromConfig and invalidateQueries for OpenClaw
  • feat(ui): add OpenClaw support to frontend components
    - Update App.tsx with openclaw visibility and skills fallback
    - Add OpenClaw to AppSwitcher icon and display name maps
    - Update McpFormModal with openclaw in enabled apps
    - Update PromptFormModal/Panel with openclaw filename map
    - Update EndpointSpeedTest with openclaw timeout
    - Update AppVisibilitySettings with openclaw toggle
    - Update test state with openclaw defaults
  • feat(omo): improve agent model selection UX and fix lowercase keys (#1004)
    * fix(omo): use lowercase keys for builtin agent definitions
    
    OMO config schema expects all agent keys to be lowercase.
    Updated OMO_BUILTIN_AGENTS keys (Sisyphus → sisyphus, Hephaestus →
    hephaestus, etc.) and aligned Rust test fixtures accordingly.
    
    * feat(omo): add i18n support and tooltips for agent/category descriptions
    
    * feat(omo): add preset model variants for thinking level support
    
    Add OPENCODE_PRESET_MODEL_VARIANTS constant with variant definitions
    for Google, OpenAI, and Anthropic models. The omoModelVariantsMap
    builder now falls back to presets when config-defined variants are
    absent, enabling the variant selector for supported models.
    
    * feat(omo): replace model select with searchable combobox and improve fallback handling
    
    * feat(omo): enrich preset model defaults and metadata fallback
    
    * fix(omo): preserve custom fields and align otherFields import/validation
    
    * fix: resolve omo clippy warnings and include app update
  • 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
  • fix(opencode): reject save when no models configured (#932)
    Add validation to require at least one model before saving an OpenCode
    provider. Shows a localized toast error when models are empty.
  • feat(ui): hide provider test button
    Provider request formats are complex and varied, making it difficult
    to create a unified test mechanism. Users may incorrectly assume
    request format issues indicate provider unavailability.
    
    Code is commented out (not deleted) for easy restoration if needed.
  • feat(ui): dynamic endpoint hint based on API format selection (#860)
    - Add apiHintOAI i18n key for OpenAI Chat Completions format hint
    - Update ClaudeFormFields to show format-specific endpoint hints
    - When API format is "openai_chat", show OAI-specific hint
    - Maintains consistency between hint and selected API format
    
    Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
  • chore: bump version to 3.10.3
    - Update version in package.json, Cargo.toml, and tauri.conf.json
    - Add missing changelog entries for OpenCode API key link and AICodeMirror preset
    - Fix Prettier formatting for new hook files
  • feat(opencode): add API key link support for OpenCode provider form
    Enable API key link feature for OpenCode app, allowing users to access
    provider websites for key registration directly from the form.
  • feat(claude): add apiFormat support for provider presets
    Allow preset providers to specify API format (anthropic or openai_chat),
    enabling third-party proxy services that use OpenAI Chat Completions format.
  • refactor(claude): migrate api_format from settings_config to meta
    Move api_format storage from settings_config to ProviderMeta to prevent
    polluting ~/.claude/settings.json when switching providers.
    
    - Add api_format field to ProviderMeta (Rust + TypeScript)
    - Update ProviderForm to read/write apiFormat from meta
    - Maintain backward compatibility for legacy settings_config.api_format
      and openrouter_compat_mode fields (read-only fallback)
    - Strip api_format from settings_config before writing to live config