Commit Graph

127 Commits

Author SHA1 Message Date
jgor20
7ed9305b5b fix: remove unused weight from quota config
The quota scoring weight is managed in HybridStrategy's DEFAULT_WEIGHTS,
not in the config.quota block. Removed to avoid confusion.
2026-01-21 20:52:14 +00:00
jgor20
2f5babba99 feat(strategy): add quota-awareness to hybrid account selection
The hybrid strategy now considers account quota levels when selecting
accounts, preventing any single account from being drained to 0%.

- Add QuotaTracker class to track per-account quota levels
- Exclude accounts with critical quota (<5%) from selection
- Add quota component to scoring formula (weight: 3)
- Fall back to critical accounts when no alternatives exist
- Add 18 new tests for quota-aware selection

Scoring formula: Health×2 + Tokens×5 + Quota×3 + LRU×0.1

An attempt at resolving  badrisnarayanan/antigravity-claude-proxy#171
2026-01-21 11:15:38 +00:00
jgor20
e51e3ff56a feat(config): add configurable max accounts limit (#156)
Adds `maxAccounts` configuration parameter to control the maximum number of Google accounts.

**Changes:**
- New config field `maxAccounts` (default: 10, range: 1-100)
- Settings page: slider control for adjusting limit
- Accounts page: counter badge (e.g., "8/10") with visual feedback
- Add button disabled when limit reached
- Server-side validation on account creation

**Breaking Changes:** None
2026-01-21 04:34:57 +08:00
Badri Narayanan S
11f135ef32 fix: simplify 403/404 endpoint fallback log messages
Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-20 23:41:17 +05:30
Badri Narayanan S
8d8f170f18 fix: add explicit logging for 403/404 endpoint fallback
Adds logging when 403/404 errors trigger endpoint fallback (daily → prod).
The retry behavior was already working but silently - now it's visible.
Matches opencode-antigravity-auth error handling behavior.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-20 23:33:44 +05:30
Badri Narayanan S
c8fbf37be9 fix: replace pickNext() with selectAccount() in /v1/models endpoint
Fixes regression where /v1/models returned 500 error because
pickNext() method was removed in v2.2.x refactor.

Fixes #164

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-20 21:03:03 +05:30
Badri Narayanan S
b0c3a61130 fix: use allowedTiers only for onboarding (not paidTier)
paidTier values like g1-pro-tier and g1-ultra-tier are rejected by
the onboardUser API with 400 INVALID_ARGUMENT. This matches the
opencode-antigravity-auth reference which only uses allowedTiers.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-19 20:19:40 +05:30
Badri Narayanan S
2175118f9f feat: align project discovery with opencode-antigravity-auth reference
- Store project IDs in composite refresh token format (refreshToken|projectId|managedProjectId)
- Add parseRefreshParts() and formatRefreshParts() for token handling
- Extract and persist subscription tier during project discovery
- Fetch subscription in blocking mode when missing from cached accounts
- Fix conditional duetProject setting to match reference implementation
- Export parseTierId() for reuse across modules

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-19 14:21:30 +05:30
Badri Narayanan S
9311c6fdf7 Merge pull request #151 from pedrofariasx/fix/windows-oauth-url
fix: Escape OAuth URL parameters for Windows CLI
2026-01-19 11:43:29 +05:30
Pedro Farias
a8ca1b79f3 fix: escape ampersands in OAuth URL on Windows 2026-01-19 02:26:55 -03:00
Badri Narayanan S
c8c7a5a8aa refactor: move STRATEGY_LABELS to constants.js and make banner dynamic
Consolidate strategy configuration by moving STRATEGY_LABELS from
strategies/index.js to constants.js. Update startup banner to
dynamically display strategy options from SELECTION_STRATEGIES.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-18 12:59:33 +05:30
Badri Narayanan S
5ae19a5b72 feat: add configurable account selection strategies
Refactor account selection into a strategy pattern with three options:
- Sticky: cache-optimized, stays on same account until rate-limited
- Round-robin: load-balanced, rotates every request
- Hybrid (default): smart distribution using health scores, token buckets, and LRU

The hybrid strategy uses multiple signals for optimal account selection:
health tracking for reliability, client-side token buckets for rate limiting,
and LRU freshness to prefer rested accounts.

Includes WebUI settings for strategy selection and unit tests.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-18 03:48:43 +05:30
Badri Narayanan S
973234372b chore: remove unused code and suppress noisy Claude Code logs
- Delete unused files: retry.js, app-init.js, model-manager.js
- Remove duplicate error helpers from helpers.js (exist in errors.js)
- Remove unused exports from signature-cache.js, logger.js
- Remove unused frontend code: ErrorHandler methods, validators, canDelete, destroy
- Make internal functions private in thinking-utils.js
- Remove commented-out code from constants.js
- Remove deprecated .glass-panel CSS class
- Add silent handler for Claude Code event logging (/api/event_logging/batch)
- Suppress logging for /v1/messages/count_tokens (501 responses)
- Fix catch-all to use originalUrl (wildcard strips req.path)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-18 01:36:24 +05:30
Badri Narayanan S
c52d32572a Merge pull request #141 from jgor20/fix/spawn-browser-launch
refactor(cli): use spawn instead of exec for browser launch
2026-01-18 01:01:59 +05:30
Pedro Farias
6a6c4829ca feat: server reliability and observability improvements 2026-01-17 13:21:15 -03:00
jgor20
cbade78e86 Merge branch 'badrisnarayanan:main' into fix/spawn-browser-launch 2026-01-17 13:31:21 +00:00
jgor20
71a808ed31 refactor(cli): use spawn instead of exec for browser launch
Replace shell command execution with spawn for cleaner process handling.

Uses array arguments instead of string interpolation.
2026-01-17 13:13:49 +00:00
Badri Narayanan S
ed68f4b21e fix: enable strict tool parameter validation for Claude models
Set functionCallingConfig.mode = 'VALIDATED' when using Claude models
to ensure strict parameter validation, matching opencode-antigravity-auth.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-17 14:47:48 +05:30
Marvin
480b4a0bc1 fix: preserve whitespace-only chunks in SSE stream (#139)
* fix: preserve whitespace-only chunks in SSE stream

Fixes issue #138 where Claude models would swallow spaces between words because whitespace-only chunks (e.g., " ") were being filtered out as empty.

Changes:
- Modified sse-streamer.js to only skip truly empty strings (""), preserving strings that contain only whitespace.
- Added regression test case in tests/test-streaming-whitespace.cjs to verify whitespace preservation.

* test: add streaming whitespace regression test to main suite

---------

Co-authored-by: walczak <walczak@ial.ruhr>
2026-01-17 12:16:28 +05:30
Badri Narayanan S
2516e90d06 Revert "fix: check allowedTiers when paidTier is free for tier detection"
This reverts commit 11a1879fc7.
2026-01-15 21:26:08 +05:30
Badri Narayanan S
11a1879fc7 fix: check allowedTiers when paidTier is free for tier detection
Some accounts have paidTier.id = "free-tier" but allowedTiers includes
"standard-tier", meaning they can use Pro-level quotas even though their
Google One subscription doesn't grant Antigravity benefits.

New priority:
1. paidTier - if Pro/Ultra, use immediately
2. allowedTiers - if paidTier is free, check for higher tiers
3. currentTier - fallback if still unknown
4. allowedTiers default - final fallback

This fixes accounts that show as "free" but actually have Pro access
through programs other than Google One AI.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-15 21:23:19 +05:30
Badri Narayanan S
9ffb83ab74 fix: improve onboarding flow for non-free tier accounts
- Use raw API tier IDs (e.g., 'free-tier', 'g1-pro-tier') consistently
- Pass DEFAULT_PROJECT_ID for non-free tiers during onboarding
- Fix free tier detection to use .includes('free') instead of exact match
- Upgrade onboarding error logs from debug to warn for visibility
- Add debug logging for onboarding request parameters

Fixes onboarding failures for Pro/Ultra accounts that were previously
failing because the API requires a project ID for paid tier onboarding.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-15 20:25:10 +05:30
Badri Narayanan S
9809337190 fix: improve subscription tier detection with paidTier priority and verbose logging
- Use parseTierId() consistently for all tier sources (paidTier, currentTier, allowedTiers)
- Add tierSource tracking to identify which field tier was detected from
- Add verbose debug logging to show all tier-related fields from loadCodeAssist API
- Fix onboarding to prioritize paidTier > currentTier > allowedTiers (consistent with model-api.js)

This helps diagnose issues where Pro/Ultra accounts are incorrectly detected as free.
Fixes #128

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-15 20:08:30 +05:30
Badri Narayanan S
2a0c110f9b fix: try model fallback before throwing RESOURCE_EXHAUSTED error
When all accounts are rate-limited for > 2 minutes, now attempts
model fallback (if enabled) before throwing the error. This allows
quota-exhausted accounts to gracefully fall back to alternate models.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-15 16:41:02 +05:30
Badri Narayanan S
77363c679e fix: accurate quota reporting with project ID and improved rate limit handling
- Pass project ID to fetchAvailableModels for accurate per-project quota
- Treat missing remainingFraction with resetTime as 0% (exhausted)
- Fix double-escaped regex in rate-limit-parser.js (\\d -> \d)
- Use ANTIGRAVITY_HEADERS for loadCodeAssist consistency
- Store actual reset time from API instead of capping at default
- Add getRateLimitInfo() for detailed rate limit state
- Handle disabled accounts in rate limit checks

Fixes issue where free tier accounts showed 100% quota but were actually exhausted.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-15 16:18:13 +05:30
Badri Narayanan S
a20cba90ee Merge pull request #125 from IrvanFza/feat/webui-notif
docs: update startup message to mention WebUI
2026-01-15 12:46:42 +05:30
Irvan Fauziansyah
915ee88e80 docs: update startup message to mention WebUI
- Changed "Server running at" to "Server and WebUI running at"
- Clarifies that the web interface is available at the same port
2026-01-15 14:10:27 +07:00
Badri Narayanan S
44632dc301 feat: add automatic user onboarding for accounts without projects
When loadCodeAssist returns no project, automatically call onboardUser API
to provision a managed project. This handles first-time setup for new accounts.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-15 12:27:37 +05:30
Badri Narayanan S
896bf81a36 revert: remove count_tokens endpoint (caused regression)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-14 23:43:16 +05:30
Badri Narayanan S
fa29de7183 fix: handle unsigned thinking blocks in tool loops (#120)
When Claude Code strips thinking signatures it doesn't recognize,
the proxy would drop unsigned thinking blocks, causing the error
"Expected thinking but found text". This fix detects unsigned
thinking blocks and triggers recovery to close the tool loop.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-14 23:01:13 +05:30
Badri Narayanan S
dee7512bd8 fix: improve subscription tier detection for Pro accounts
The tier detection was incorrectly showing Pro accounts as "free" due to:
1. paidTier field being flaky/missing from some API responses
2. standard-tier not being recognized as a Pro tier
3. No fallback to allowedTiers when currentTier is missing

Changes:
- Add parseTierId() helper to centralize tier ID parsing
- Recognize "standard-tier" as Pro (Gemini Code Assist paid tier)
- Add fallback chain: paidTier > currentTier > allowedTiers
- Return "unknown" instead of incorrectly defaulting to "free"

Fixes #121

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-14 21:27:24 +05:30
Badri Narayanan S
772dabe7e4 fix: defer inlineData parts to end of array for parallel tool calls (#91)
When multiple tool_results contain images, the inlineData parts were
being interleaved between functionResponse parts, breaking Claude's API
requirement that functionResponse parts be consecutive.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-14 21:04:36 +05:30
behemoth-phucnm
d33de409d4 docs: fix misleading tokenizer comments 2026-01-14 19:31:43 +07:00
minhphuc429
7da7e887bf feat: use official tokenizers for 99.99% accuracy
Replace gpt-tokenizer with model-specific official tokenizers:
- Claude models: @anthropic-ai/tokenizer (official Anthropic tokenizer)
- Gemini models: @lenml/tokenizer-gemini (GemmaTokenizer)

Changes:
- Add @anthropic-ai/tokenizer and @lenml/tokenizer-gemini dependencies
- Remove gpt-tokenizer dependency
- Update count-tokens.js with model-aware tokenization
- Use getModelFamily() to select appropriate tokenizer
- Lazy-load Gemini tokenizer (138MB) on first use
- Default to local estimation for all content types (no API calls)

Tested with all supported models:
- claude-sonnet-4-5, claude-opus-4-5-thinking, claude-sonnet-4-5-thinking
- gemini-3-flash, gemini-3-pro-low, gemini-3-pro-high
2026-01-14 16:04:13 +07:00
minhphuc429
2bdecf6e96 fix: ensure account manager initialized for count_tokens
- Add ensureInitialized() call before count_tokens handler
- Use hybrid approach: local estimation for text, API for images/docs
- This prevents "No accounts available" error on first request
2026-01-14 15:43:25 +07:00
minhphuc429
df81ba5632 feat: use API-based token counting for 100% accuracy
Switch from local estimation (gpt-tokenizer) to API-based counting
via Google Cloud Code API for accurate token counts. Falls back to
local estimation if API call fails.
2026-01-14 15:36:47 +07:00
minhphuc429
acc228b920 feat: implement /v1/messages/count_tokens endpoint
Add Anthropic-compatible token counting endpoint using hybrid approach:
- Local estimation with gpt-tokenizer for text content (~95% accuracy)
- API-based counting for complex content (images, documents)
- Automatic fallback to local estimation on API errors

This resolves warnings in LiteLLM and other clients that rely on
pre-request token counting.
2026-01-14 15:32:27 +07:00
Badri Narayanan S
12d196f6a0 refactor: centralize TEST_MODELS and DEFAULT_PRESETS in constants.js
- Move TEST_MODELS and DEFAULT_PRESETS to src/constants.js as single source of truth
- Update test-models.cjs helper to use dynamic import from constants
- Make getTestModels() and getModels() async functions
- Update all test files to await async model config loading
- Remove duplicate THINKING_MODELS and getThinkingModels() from test helper
- Make thinking tests more lenient for Gemini (doesn't always produce thinking blocks)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-13 19:20:57 +05:30
Badri Narayanan S
632536e2d7 fix: use configured cooldown as cap for rate limit wait times
- Cooldown now caps API-provided reset times instead of being a fallback
- Fixed misleading UI descriptions for cooldown settings
- Removed unused cooldownDurationMs from settings object
- Updated default fallback values in frontend to 10s

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-13 18:28:52 +05:30
Badri Narayanan S
49e536e9a9 fix: reduce default cooldown from 60s to 10s
Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-13 18:16:30 +05:30
Badri Narayanan S
70fd1baaa8 fix: improve loadCodeAssist for Google One AI Pro accounts
- Add separate LOAD_CODE_ASSIST_ENDPOINTS (prod first) and
  LOAD_CODE_ASSIST_HEADERS (google-api-nodejs-client User-Agent)
- Add duetProject to metadata for project discovery
- Silent fallback when API returns success but no project
  (matches opencode-antigravity-auth behavior)
- Only warn when all endpoints fail with actual errors

Fixes #114, addresses discussion #113

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-13 18:11:45 +05:30
Badri Narayanan S
99a06632ea Merge pull request #102 from liuwuyu118/fix/image-response-and-ui-performance
fix: add image response support
2026-01-13 17:17:39 +05:30
董飞祥
6172f5ef10 feat: add API key authentication for /v1/* endpoints 2026-01-13 16:46:31 +08:00
liuwuyu118
860c0d6c2d fix: add image response support
Convert Google's inlineData format to Anthropic's image format:
- response-converter.js: Handle inlineData in non-streaming responses
- sse-parser.js: Parse inlineData for thinking models
- sse-streamer.js: Stream inlineData as image content blocks

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-13 11:17:17 +08:00
simon-ami
e24dff279c feat(webui): add configuration presets for Claude CLI
- Add backend storage logic in `src/utils/claude-config.js` to save/load/delete presets
- Add API endpoints (`GET`, `POST`, `DELETE`) for presets in `src/webui/index.js`
- Update `public/views/settings.html` with new Presets UI card and modals
- Update `public/js/components/claude-config.js` with auto-load logic and unsaved changes protection
- Add translations (EN/ZH) for new UI elements in `public/js/store.js`
- Add integration tests in `tests/frontend/test-frontend-settings.cjs`
- Update compiled CSS

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-12 11:59:32 +01:00
copilot-swe-agent[bot]
cd594f6e82 Address code review: use constant array for proxy env vars and clean empty env
Co-authored-by: simon-ami <102378134+simon-ami@users.noreply.github.com>
2026-01-11 11:56:01 +00:00
copilot-swe-agent[bot]
8eba68e47a Add Restore Default Claude CLI button to settings page
Co-authored-by: simon-ami <102378134+simon-ami@users.noreply.github.com>
2026-01-11 11:54:13 +00:00
Badri Narayanan S
325acdba8c fix: preserve tool_use stop reason from being overwritten by finishReason
When a tool call is made, stopReason is set to 'tool_use'. However, when
finishReason: STOP arrives later, it was overwriting stopReason back to
'end_turn', breaking multi-turn tool conversations in clients like OpenCode.

Fix: Initialize stopReason to null and only set it from finishReason if
not already set. This ensures tool_use is preserved once detected.

Fixes #96

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-11 11:52:35 +05:30
Wha1eChai
14ef814c1a merge: sync with upstream/main (5xx error fallback feature) 2026-01-11 02:57:59 +08:00
Wha1eChai
bda9623f3a feat(webui): optimize CSS build system and enhance UI quality 2026-01-11 02:57:42 +08:00