Spaces:
Paused
Paused
Commit History
-
update Dockerfile for HF spaces
bok922af7d -
Update README.md
Verified signature8dd2cbc -
add Dockerfile for HF spaces
bok52d4317
-
Add CODEOWNERS file for @Mirrowel
MirrowelUnverified signatureSet @Mirrowel as the code owner for all files.bb3d31f -
fix(antigravity): add propertyNames to incompatible schema keywords (#52)
mirrobot-agent[bot] +1: mirrobot-agent[bot]Unverified signatureAdds 'propertyNames' to the list of JSON Schema validation keywords that are stripped from tool schemas when converting for Claude via the Antigravity provider. This keyword is not supported by Google's Proto-based API and was causing 400 Bad Request errors with nested object schemas. Closes #48 Co-authored-by: mirrobot-agent[bot] <2140342+mirrobot-agent@users.noreply.github.com>92db52f
-
fix(antigravity): 🐛 propagate usage stats in streaming auto-recovery
MirrowelThe streaming wrapper relies on `completion_tokens > 0` in the usage dictionary to correctly detect final chunks and terminate the stream. Previously, auto-recovery responses lacked this data, causing streams to hang. - Add `_build_malformed_fallback_chunk` to generate compliant streaming error responses when retries are exhausted. - Extract and propagate `last_usage` from the response accumulator during malformed function call exceptions. - Ensure fixed tool call chunks and fallback chunks include valid usage data (forcing `completion_tokens` to 1 if necessary) to properly signal stream completion.9c5dbdf -
feat(antigravity): ✨Gemini auto-unfuck: implement auto-recovery for malformed function calls
MirrowelThis commit introduces a comprehensive handling mechanism for `MALFORMED_FUNCTION_CALL` errors occasionally produced by Gemini models, allowing the system to recover from invalid JSON tool arguments. - **Auto-Fix Logic**: Implements a heuristic JSON repair engine (`_analyze_json_error`) to locally correct common syntax errors like unquoted keys, single quotes, and trailing commas. - **Retry Strategy**: Adds a retry loop that injects corrective error messages and schema hints back into the conversation if local auto-fix fails. - **System Prompt**: Updates model instructions to explicitly emphasize strict JSON syntax requirements (double quotes). - **Logging**: Adds dedicated logging methods to track malformed requests, retry payloads, and auto-fix results for debugging. - **Configuration**: Introduces `MALFORMED_CALL_MAX_RETRIES` and `MALFORMED_CALL_RETRY_DELAY` settings.a9943e6 -
fix(antigravity): 🐛 implement schema-aware JSON string parsing for tools
MirrowelThis change addresses parsing issues where Gemini models (particularly Gemini 3) return stringified JSON for certain parameters, while preventing corruption of actual string arguments that resemble JSON. - Enable `ANTIGRAVITY_ENABLE_JSON_STRING_PARSING` by default. - Add `_build_tool_schema_map` to extract and normalize tool parameter schemas. - Update `_extract_tool_call` to use schemas for intelligent argument parsing. - Propagate tool schemas through both streaming and non-streaming completion flows.50ee93b
-
fix(antigravity): 🐛 TLDR: Huge ass pass fixing things + Gemini 3 Flash addition
Mirrowele4ee46f -
refactor(antigravity): 🔨 improve additionalProperties handling in schema cleaning
MirrowelFor Claude schema cleaning: - Preserve permissive `additionalProperties` (true or {}) for pass-through objects - Normalize permissive values to `true` for consistency - Pass through explicit `false` values unchanged - Skip complex schema definitions that aren't supported For Gemini enforcement: - Only add `additionalProperties: false` when not already set - Respect explicit `additionalProperties` values (true or false) - Avoid enforcing strictness on pass-through objects with empty `properties1ec1463 -
fix(antigravity): 🐛 preserve property names matching validation keywords
MirrowelFix schema cleaning to preserve user-defined property names that coincidentally match JSON Schema validation keywords. Previously, properties named "pattern", "format", or "default" would be incorrectly removed. - Separate meta/structural keywords from validation keywords - Preserve property names in "properties" objects even when matching validation keywords - Add debug logging for property names that match validation keywords740e192 -
Merge remote-tracking branch 'origin/feature/filtering-tool' into dev
Mirrowelcfa8697
-
Merge branch 'quota-viewer' into main
Mirrowel475234c -
feat(quota): ✨ improve aggregation with tier priorities and fix double-counting
Mirrowel- Adds tier priority metadata for proper sorting of credential tiers in the UI - Fixes double-counting when models share quota groups by using aggregated group totals - Enhances reset time display to show expiration for low/exhausted quotas - Implements provider-specific stats merging to preserve cache during partial updates - Recalculates summary statistics on-demand instead of full cache replacement90d4836 -
feat(quota): restructure quota aggregation with cumulative counts and tier registry
MirrowelRemove averaged percentage calculations in favor of summing actual request counts across all credentials in a group. Introduce per-tier credential registries that distinguish active from exhausted allocations. Simplify viewer presentation to show absolute usage totals alongside compact tier status markers, deprecating the previous exhaustion counting approach.06b3f7d -
refactor(quota-viewer): 🔨 enhance credential sorting and cooldown display
MirrowelAdd natural/numeric sorting for credentials to ensure proper ordering (e.g., proj-1, proj-2, proj-10 instead of proj-1, proj-10, proj-2). Improve cooldown display in quota viewer by grouping cooldowns by quota groups when available, providing clearer visibility into rate limiting status for grouped models. Also in this commit: - refactor(client): improve model stats lookup with alias support - feat(usage-manager): add quota display formatting for logging1af1879 -
refactor(usage): 🔨 sync request_count across quota group models
MirrowelRefactor quota group handling to synchronize request_count across all models in a quota group instead of recalculating it on each access. This improves performance and ensures consistency. The previous implementation iterated through all models in a group to sum request counts and find baselines on each quota check. The new implementation proactively syncs these values when requests are recorded. Changes: - Sync request_count to all models in quota group when recording successes, failures, or updating quota baselines - Quota estimation now reads values from any representative model since all models in the group are guaranteed to have synchronized data - Add credential filename parsing support for OAuth files without paths Also in this commit: - chore(gitignore): ignore quota_viewer_config.json1ac7bd0 -
feat(quota-viewer): ✨ add intelligent URL scheme detection for local and private hosts
MirrowelPrevious implementation used https for any host containing a dot, which incorrectly applied https to private IP addresses. The new logic properly detects local hosts and private networks (localhost, 127.0.0.1, 192.168.x.x, 10.x.x.x, 172.16-31.x.x) and uses http for them while maintaining https for external domains and port 443.65fe549 -
feat(usage): ✨ use request count for credential selection when failed requests consume quota
MirrowelFor providers like antigravity where failed requests also consume quota, credential selection now uses `request_count` instead of `success_count`. This ensures proper credential rotation when quota is consumed by failed requests. - Add `_REQUEST_COUNT_PROVIDERS` set to identify affected providers - Update `_get_grouped_usage_count` to dynamically select usage field based on provider - Extend `_get_usage_count` signature to support configurable usage fields48b6b15 -
feat(quota-viewer): ✨ add quota and usage statistics viewer system
MirrowelThis introduces a comprehensive quota and usage statistics monitoring system with API endpoints and a rich terminal UI for real-time credential consumption visibility. Key components: - Add GET/POST /v1/quota-stats API endpoints to main proxy for retrieving and refreshing statistics - Implement full-featured TUI viewer (quota_viewer.py) with provider summaries, credential details, progress bars, and remote management - Add configuration system (quota_viewer_config.py) supporting multiple remote proxies with API key management - Extend RotatingClient with get_quota_stats(), reload_usage_from_disk(), and force_refresh_quota() methods - Enhance usage_manager with get_stats_for_endpoint() for aggregated statistics - Integrate viewer into launcher TUI as new menu option 5 Features include toggle between current and global/lifetime stats, token formatting, cooldown timers, quota group visualization, and estimated cost tracking. Supports Antigravity quota group enrichment and live API refre…8b4ff52 -
feat(antigravity): ✨ add initial full quota baseline fetch on startup
MirrowelOn first run, fetch quota baselines for all credentials to establish accurate usage tracking. Subsequent runs only refresh credentials used since the last refresh interval, improving efficiency. - add _initial_quota_fetch_done flag to track initial fetch state - modify refresh_quota_baselines to conditionally fetch all or active credentials846c165 -
Merge pull request #41 from Mirrowel/antigravity-usage-tracking
MirrowelUnverified signatureAntigravity-usage-trackingf812e17 -
docs(background): reduce default background job interval from 15min to 5min
Mirroweld7c643f -
docs(antigravity): 📚 document quota tracking, background jobs, and error handling
MirrowelAdds comprehensive documentation for recently implemented Antigravity provider features: - Provider-specific background jobs system with independent timers - Antigravity quota tracker with API baseline fetching and request counting - TransientQuotaError for handling bare 429 responses without retry info - Quota groups configuration for models sharing usage limits - Parallel tool usage instruction injection for Claude and Gemini 3 - Quota cost constants and model name mappings Documents both the architecture and implementation details to help developers understand the advanced usage tracking capabilities.2eb0cb6 -
feat(antigravity): ✨ add parallel tool usage instruction injection for claude and gemini 3
MirrowelAdds configurable instruction injection to encourage parallel tool usage for models that support it. Parallel tool calls reduce round-trips and improve efficiency when multiple independent operations are needed. - Separate environment variable toggles for Claude (default: enabled) and Gemini 3 (default: disabled) - Allows model-specific optimization based on capability and behavior09eea32 -
feat(antigravity): ✨ add credential availability tracking for models
MirrowelAdd get_available_credentials_for_model method to filter credentials not on cooldown. Update client logging to display available credentials count alongside total count.818ba14 -
feat(antigravity): ✨ add TransientQuotaError for bare 429 responses
MirrowelIntroduces a new TransientQuotaError exception to handle 429 responses without retry timing information. The antigravity provider now detects bare 429 errors and retries them internally like empty responses. After exhausting retries, it raises TransientQuotaError to trigger credential rotation. 429 responses with retry information continue to be treated as quota exhaustion for cooldown periods. This distinction improves handling of transient rate limits versus true quota exhaustion.543f871 -
feat(antigravity): ✨ add quota tracking with independent background jobs
MirrowelImplement comprehensive quota tracking for the Antigravity provider with automated background refresh. The system fetches quota baselines from the API, tracks request counts locally, and estimates remaining quota per credential/model. - Add AntigravityQuotaTracker mixin for quota management, cost learning, and verification methods - Extend BackgroundRefresher to support provider-specific background jobs with independent asyncio task timers - Add provider interface methods get_background_job_config() and run_background_job() for periodic task integration - Integrate UsageManager with quota baseline storage and aggregated tracking fields (request_count, failure_count) - Implement quota cost learning that persists empirical costs to learned_quota_costs.json - Define model quota groups for thinking variants (claude, gemini-2.5-flash, gemini-3-pro-preview) - Disable flawed key lockout logic that incorrectly triggered when a single quota group was exhausted2be7535 -
fix(timeout): 🐛 increase streaming read timeout to 5 minutes - 3 minute timeouts failed sometimes
Mirrowel0a45558 -
fix(retry): 🐛 parse millisecond durations and avoid immediate retry loops
Mirrowel- Add explicit support for millisecond format (e.g., '290.979975ms') in duration parsing - Fix misinterpretation where 'ms' suffix was incorrectly parsed as minutes using negative lookahead - Ensure sub-second duration values round up to at least 1 second to prevent immediate retry loops - Properly handle zero-second delays and distinguish them from missing valuesbb812a7 -
refactor(iflow): 🔨 reorganize model registry and integrate new LLM options
MirrowelNew model integrations: - minimax-m2: added to expand provider capabilities - kimi-k2-thinking: reasoning-focused variant now available - deepseek-v3.2-chat: latest conversational model version included Model removals: - qwen3-coder: removed from supported models list690ec60
-
refactor(cache): 🔨 decouple memory cleanup from disk persistence lifecycle
MirrowelReorganize the cache to treat memory and disk as independent storage tiers with distinct expiration policies. Memory cleanup now operates in isolation without affecting disk state, while disk operations implement a merge strategy that reconciles both layers during write operations. - Memory entry removal no longer sets dirty flag or forces disk synchronization - Disk write procedure loads existing file contents and filters by disk_ttl before merging with current memory state - Cleanup routine explicitly targets memory-only expiration using memory_ttl threshold - Default disk retention window doubled from 24h to 48h (172800 seconds) - Enhanced statistics capture layer-specific metrics including disk-preserved entry counts - Logging differentiation between memory cleanup events and disk merge operations9bfc01f -
refactor(antigravity): 🔨 clarify empty response retry configuration and logic
MirrowelRenames `EMPTY_RESPONSE_MAX_RETRIES` to `EMPTY_RESPONSE_MAX_ATTEMPTS` and updates the retry logic to be more intuitive and correct. - Renamed constant to better reflect that it represents total attempts, not retries - Updated environment variable from `ANTIGRAVITY_EMPTY_RESPONSE_RETRIES` to `ANTIGRAVITY_EMPTY_RESPONSE_ATTEMPTS` - Changed default from 3 to 4 attempts with minimum enforcement via `max(1, ...)` - Fixed off-by-one errors in loop conditions: now using `range(EMPTY_RESPONSE_MAX_ATTEMPTS)` instead of `range(EMPTY_RESPONSE_MAX_RETRIES + 1)` - Corrected retry condition from `attempt < EMPTY_RESPONSE_MAX_RETRIES` to `attempt < EMPTY_RESPONSE_MAX_ATTEMPTS - 1` - Removed redundant error logging on final attempt failure (caller handles error logging) - Updated all related comments and log messages to reflect "attempts" terminology - Applied changes consistently to both streaming and non-streaming handlers BREAKING CHANGE: The environment variable `ANTIGRAVITY_EMPTY_RESPONSE_RETRI…3876001 -
refactor(tui): 🔨 enhance clear_screen with optional header display
MirrowelThe `clear_screen()` function in both launcher_tui.py and settings_tool.py has been enhanced to accept an optional subtitle parameter that displays a consistent header panel when provided. - Add `subtitle` parameter to `clear_screen()` function - Display formatted header panel with subtitle when provided - Update function calls to use new subtitle feature in settings tool (e.g., "Save Changes", "Exit Without Saving") - Remove redundant clear_screen call in launcher after startup message - Improve code reuse and consistency across TUI interfacesd5acbd4 -
refactor(credentials): 🔨 separate view and manage credential menus
MirrowelThis commit refactors the credential management interface by separating view-only and management operations into distinct menus, improving user experience and code organization. - Add new `view_credentials_menu()` function that provides read-only credential viewing with drill-down capability from summary to provider-specific details - Create dedicated detail view functions `_view_api_keys_detail()` and `_view_oauth_credentials_detail()` for displaying comprehensive credential information - Modify `manage_credentials_submenu()` to focus solely on management operations (delete, edit) - Enhance `clear_screen()` function to accept an optional subtitle parameter, providing contextual headers throughout the application - Update all credential-related functions to use the new `clear_screen()` signature with descriptive subtitles for better navigation clarity - Add "View Credentials" as option 4 and "Manage Credentials" as option 5 in main menu - Improve visual hierarchy in detail views with …ef8f78e -
feat(credentials): ✨ add comprehensive credential management interface
MirrowelImplement a new credential management submenu that provides a unified view and control panel for all credentials (API keys and OAuth). This significantly improves the user experience for managing credentials across all providers. Key additions: - New credentials summary dashboard displaying API keys and OAuth credentials side-by-side with tier breakdowns - Delete functionality for both API keys and OAuth credentials with safety confirmations - Edit capability for OAuth credential email fields (particularly useful for Qwen Code) - Tier counting and display for OAuth providers that support tier information - Numeric sorting for API keys (properly handles KEY_1, KEY_10, etc.) - Safety mechanisms for API key deletion with backup/restore on unexpected changes - Improved visual presentation using Rich tables and columns The credential tool now provides complete CRUD operations for all credential types through an intuitive menu system, with proper error handling and user confirmations for d…8eb4988 -
feat(antigravity): ✨ add automatic retry logic for empty API responses
MirrowelImplements robust handling for cases where the Antigravity provider returns empty responses (no content, no tool calls) due to transient server-side issues. - Introduces new `EmptyResponseError` exception class to represent empty response failures - Classifies empty responses as rotatable server errors (HTTP 503 equivalent) to trigger credential rotation - Adds configurable retry mechanism with `ANTIGRAVITY_EMPTY_RESPONSE_RETRIES` (default: 3) and `ANTIGRAVITY_EMPTY_RESPONSE_RETRY_DELAY` (default: 2s) - Implements separate retry logic for streaming and non-streaming requests to preserve true streaming behavior - Refactors request handling to use a URL fallback loop with nested empty response retry logic - Tracks whether any chunks were yielded in streaming mode to avoid emitting synthetic final chunks for empty responses - Moves helper functions (`_env_bool`, `_env_int`) earlier in the file for use in configuration constants - Stores last received usage metadata for proper final chunk…c5dfecd
-
fix(oauth): 🐛 prevent deadlock and token desync for rotating refresh tokens
MirrowelThis commit fixes critical issues in OAuth providers (Google, iFlow, Qwen) that use rotating refresh tokens, where each token refresh invalidates the previous token. **Problems Fixed:** 1. **Deadlock Prevention**: Removed inline re-authentication from `refresh_token()` method that was called while holding a lock. When refresh failed with HTTP 400/401/403, the method would call `initialize_token()` directly, which would try to acquire the same lock, causing a deadlock. Now, invalid token errors are caught and queued for background re-authentication via `asyncio.create_task()`. 2. **Token Desync**: Changed `_save_credentials()` to write to disk FIRST, then update cache. Previously, cache was updated first with `buffer_on_failure=True`, which could leave stale tokens on disk if the write failed. For rotating tokens, this caused the old refresh_token on disk to become invalid after a successful API call, requiring re-auth on restart. 3. **Stale Cache Usage**: Modified `refresh_token()`…8ed4f52 -
fix(antigravity): 🐛 add platform/architecture to User-Agent header
MirrowelThe User-Agent header was previously only including the antigravity version number. This update appends platform and architecture information (windows/amd64) to improve server-side request tracking and debugging capabilities.a68d8d0 -
feat(model-info): ✨ add provider priority system and enhanced model metadata
MirrowelThis commit significantly improves the model lookup and metadata capabilities of the ModelInfoService: - Introduces a provider priority system that prefers native/authoritative providers (anthropic, openai, google) over proxy/aggregator providers (openrouter, azure, requesty) when multiple sources exist for the same model - Adds provider alias mapping to support custom provider names (e.g., nvidia_nim -> nvidia, gemini_cli -> google) for direct model ID resolution - Extends ModelMetadata with new ModelInfo dataclass containing family, description, knowledge_cutoff, release_date, open_weights, status, tokenizer, and huggingface_id fields - Adds extended capabilities support: structured_output, temperature, attachments, and interleaved content - Implements version pattern normalization to handle different version formats (e.g., claude-opus-4-5 matches claude-opus-4.5) - Refactors data merger to use best-source selection instead of averaging multiple sources, preserving queried model ide…c4e297f -
Merge branch 'dev' into main
Mirroweled4dd55 -
feat(filter): ✨ add full glob pattern support for model filtering
MirrowelThis commit upgrades the model filtering system to support complete glob/fnmatch pattern syntax, replacing the previous limited wildcard implementation. - Migrate from custom prefix-only wildcard matching to full fnmatch support - Add support for suffix wildcards (*-preview), contains wildcards (*-preview*), single character matching (gpt-?), and character sets (gpt-[45]*) - Implement cross-platform mouse wheel scrolling with normalized delta calculation for Windows, macOS, and Linux - Update help documentation with comprehensive pattern examples - Refactor duplicate model filtering logic in both GUI (FilterEngine) and client (RotatingClient) to use unified fnmatch approach - Add traceback printing for better debugging of .env save errors - Fix clipboard copy logic to properly include models without explicit status - Improve code formatting with consistent line breaks and spacing - Add pyinstaller to requirements and remove tkinter from build exclusions - Bump rotator_library version …b7df2fe -
refactor(antigravity): 🔨 inline JSON schema references before sanitization
MirrowelIntroduced `_inline_schema_refs()` function to resolve local $ref definitions in JSON schemas before applying Claude-specific sanitization. This ensures that schema references are properly expanded and circular references are handled gracefully. - Added new helper function to recursively resolve $ref pointers from $defs and definitions - Circular reference detection prevents infinite loops by tracking seen references - Applied inlining step before `_clean_claude_schema()` in both tool transformation flows - Updated docstring to reflect the new two-step sanitization process (inline, then clean) - Removed extraneous `$schema` pop that was no longer needed This change improves schema compatibility with Antigravity/Gemini's Proto-based API by ensuring all references are resolved before unsupported JSON Schema keywords are stripped.c745d73 -
docs: 📚 restructure README with quick start guide and improved navigation
MirrowelComplete overhaul of the README to improve first-time user experience and discoverability of features. - Reorganize content with prominent "Quick Start" section at the top - Add clear "Connecting to the Proxy" guide with model format explanation - Group features into collapsible sections for better readability - Consolidate credential management documentation with TUI and CLI instructions - Add comprehensive usage examples for Python, curl, and popular chat UIs - Move advanced configuration into collapsible details sections - Improve OAuth provider documentation with per-provider setup guides - Add troubleshooting table with common issues and solutions - Restructure technical documentation links into organized table - Emphasize universal compatibility and zero-code-change deploymente4bf852 -
refactor(startup): 🔨 reorganize import sequence to eliminate blocking dependencies
Mirrowelb6116f7 -
feat(settings): ✨ add real-time pending changes preview across all settings menus
MirrowelThis commit introduces a comprehensive pending changes system that displays live previews of all staged modifications before they are committed to the .env file. - Add sentinel value `_NOT_FOUND` to distinguish between "no pending change" and "pending change to None" - Implement helper methods in `AdvancedSettings` class: - `get_pending_value()` - retrieve pending value for a key - `get_original_value()` - get current .env value before changes - `get_change_type()` - categorize changes as 'add', 'edit', or 'remove' - `get_pending_keys_by_pattern()` - filter pending changes by prefix/suffix - `get_changes_summary()` - get categorized summary of all pending changes - `get_pending_counts()` - count pending changes by type - Add `_format_item()` method to display list items with visual change indicators (+ for adds, ~ for edits, - for removals) - Implement `_get_pending_status_text()` to show detailed pending changes count in main menu - Add `_show_changes_summary()` to displa…352d879 -
fix(env): 🐛 use explicit .env path for PyInstaller compatibility
MirrowelReplaced hardcoded `Path.cwd() / ".env"` references with centralized `_get_env_file()` helper function across launcher_tui.py, main.py, and settings_tool.py. - Adds `_get_env_file()` helper that detects PyInstaller frozen state - When running as EXE, resolves .env relative to executable directory - When running as script, resolves .env relative to current working directory - Updates all `load_dotenv()` calls to use explicit path instead of relying on implicit cwd resolution - Ensures consistent .env file location regardless of execution context This fixes issues where the application couldn't locate the .env file when running as a PyInstaller bundle and the working directory differed from the executable location.682bbea -
fix(gemini): 🐛 add robust JSON parsing and tool response grouping for Gemini CLI
MirrowelThis commit addresses multiple issues in the Gemini CLI provider related to malformed tool responses and conversation history management: - Add `_recursively_parse_json_strings()` to handle JSON-stringified tool arguments and malformed double-encoded JSON - Implement selective control character unescaping (preserving intentional escapes like \" and \\) - Add `_fix_tool_response_grouping()` to properly pair function calls with their responses - Implement ID-based pairing with fallback recovery strategies (name matching, order-based matching, placeholder insertion) - Add comprehensive logging for debugging ID mismatches and orphaned responses - Parse tool response content as JSON before wrapping in result object - Add fallback handling for missing tool_call_id mappings (can occur after context compaction) The grouping fix prevents API errors caused by linear tool response format and ensures responses are correctly matched to their corresponding function calls even when IDs are lost dur…f925da4 -
fix(antigravity): 🐛 add fallback retry logic for RESOURCE_EXHAUSTED errors without timing details
MirrowelPreviously, the error parsing logic would return None if the API response didn't include explicit retry timing details, even when the error clearly indicated resource exhaustion (HTTP 429 or RESOURCE_EXHAUSTED status). This caused the retry mechanism to fail silently. - Removed the early return when details array is empty, allowing further error processing - Added detection for bare RESOURCE_EXHAUSTED errors (status code or HTTP 429) - Set a sensible 60-second default retry_after when timing details are missing - Ensures retry mechanism engages even with minimal error response data This improves resilience when the Antigravity API returns resource exhaustion errors without structured retry timing information.b9d9895 -
refactor(core): 🔨 centralize path management for PyInstaller compatibility
MirrowelIntroduce a new `paths.py` utility module that provides centralized path resolution for all data files (logs, cache, OAuth credentials, usage data) with support for both PyInstaller EXE and script/library runtime modes. - Add `get_default_root()` to auto-detect EXE directory when frozen, otherwise uses CWD - Add `get_logs_dir()`, `get_cache_dir()`, `get_oauth_dir()`, and `get_data_file()` helpers - Update `RotatingClient` to accept optional `data_dir` parameter for override capability - Refactor all hardcoded path calculations to use centralized utilities - Update `CredentialManager` to accept `oauth_dir` parameter - Convert `failure_logger` to lazy initialization with configurable logs directory - Migrate `UsageManager` to accept optional `file_path` with automatic defaults - Update all provider-specific logging directories to use centralized helpers - Refactor credential tool and settings tool to use path utilities - Update main.py to load .env files from correct root directory in b…467f294