Files
gemini-nexus/thoughts/ledgers/CONTINUITY_ses_2338.md
T

81 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
session: ses_2338
updated: 2026-04-27T01:04:57.050Z
---
# Session Summary
## Goal
Produce a detailed architectural review report of the Gemini Nexus Electron + NestJS backend, including subsystem ratings (SOLID/NEEDS_WORK/RISKY), specific bugs with file:line references, and concrete refactoring steps.
## Constraints & Preferences
- Focus on coupling between Electron main and NestJS (registry bridge pattern), service decomposition, data flow integrity, error handling, DB transaction safety, and circuit breaker/rate limiter effectiveness
- Use exact file paths and line numbers where possible
- Return findings as a detailed markdown report with the requested structure
- Preserve all previous analysis context when continuing
## Progress
### Done
- [x] Read `src/main.ts` — Electron main process bootstraps NestJS as child process via `bootstrapNestServer()`, stops via `stopNestServer()`; creates MessagePort for ORPC IPC; installs native modules via Sentry; manages window lifecycle
- [x] Read `src/server/main.ts` — NestFactory creates Fastify app, enables CORS, registers API logging plugin; exports `stopNestServer` and `getCurrentProxyPort`; no graceful shutdown beyond `app.close()`
- [x] Read `src/ipc/proxy-advanced/service-registry.ts` — global mutable `proxyAdvancedRegistry` object with `tokenManager`, `proxyMetrics`, `proxyReplay`, `proxyIdeConfig` all initialized to `null`; services register themselves via `registerProxyAdvancedService()` in constructors
- [x] Read `src/ipc/proxy-advanced/handler.ts` — IPC handlers for traffic logs, metrics, replay, IDE configs, model capabilities; uses `proxyAdvancedRegistry` for IDE config, metrics, replay; directly calls `TrafficLogsRepo` and `CloudAccountRepo` for logs
- [x] Read `src/ipc/proxy-advanced/router.ts` — ORPC Zod schemas for IPC routes; defines `getModelCapabilities` calling handler; `CapabilitiesResponseSchema` uses hardcoded zod shapes, no dynamic model discovery
- [x] Read `src/server/modules/proxy/proxy.service.ts` (2222+ lines) — Core proxy logic: request transformation (Claude/OpenAI ↔ Gemini), streaming/non-streaming paths, tool call handling, fallback to non-streaming on stream error, retry logic with `calculateRetryDelay`, circuit breaker check via `tokenManager.getNextToken()`, token refresh, traffic logging via `trafficLogger`
- [x] Read `src/server/modules/proxy/proxy.controller.ts` (~1700 lines) — HTTP routes for OpenAI (`/chat/completions`, `/models`), Anthropic (`/v1/messages`), Gemini (`/models/:model:generateContent`, etc.); SSE streaming via RxJS; `listModelCapabilities` uses hardcoded `capabilitiesMap` (lines 1316–1352); multipart/form-data proxy; error response normalization; heavy controller with private utility methods mixed in
- [x] Read `src/server/modules/proxy/token-manager.service.ts` (1303 lines) — Round-robin token scheduling with `schedulingMode` (`cache-first`, `balance`, `performance-first`), circuit breaker per token (`CircuitBreakerEntry` with `failureCount`, `state`, `requestLog`), rate limit tracking via `RateLimitTracker`, model quota/limit management, account refresh via `GoogleAPIService`, auto-registers into `proxyAdvancedRegistry` in constructor
- [x] Read `src/server/modules/proxy/rate-limit-tracker.ts` — In-memory `failureCounts` map with `FAILURE_COUNT_EXPIRY_MS` (1 hour); parses Google error details; `cleanupExpired()` exists but no scheduled caller found in any read file
- [x] Read `src/server/modules/proxy/proxy-replay.service.ts` — In-memory circular buffer (`buffer: ReplayEntry[]`, `maxSize = 20`); records requests for replay; auto-registers into `proxyAdvancedRegistry`; no persistence
- [x] Read `src/services/CloudMonitorService.ts` — 5-minute interval polling (`monitorIntervalMs = 300000`) via `setInterval`; checks account quotas via `GoogleAPIService.getAllQuotaData()`; sends Electron `Notification` on low quota; triggers `AutoSwitchService.findBestAccount()` and `switchCloudAccount()`; updates DB via `CloudAccountRepo.updateAccount()`
- [x] Read `src/services/AutoSwitchService.ts` — Static methods only; `findBestAccount()` filters by status `active`, checks `quota.models` for `< 5%`, sorts by average quota; calls `switchCloudAccount()` directly from main process context
- [x] Read `src/ipc/database/cloudHandler.ts` (first ~600 lines) — `CloudAccountRepo` with AES-256-GCM encryption via `encrypt`/`decryptWithMigration`; retry logic for SQLite busy errors (`SQLITE_MAX_RETRIES = 3`); Drizzle ORM operations; no explicit `BEGIN TRANSACTION` wrappers observed in read sections; updates happen via individual `db.update()` calls
### In Progress
- [ ] Synthesizing findings into the final markdown report with subsystem ratings and concrete refactoring proposals
### Blocked
- (none)
## Key Decisions
- **Prioritize reading source over generating report immediately**: Needed exact line numbers and behavior confirmation before making claims about race conditions, transaction safety, and registry nullability.
## Next Steps
1. Synthesize all read file contents into the requested markdown report structure:
- Deep architectural review (coupling, decomposition, data flow, error handling, DB transactions, circuit breaker/rate limiter)
- Specific bugs/anti-patterns with file:line references
- Subsystem ratings (IPC, Proxy, DB, Auth)
- Concrete refactoring steps
2. Cross-reference `proxyAdvancedRegistry` null-handling paths in `handler.ts` with specific fallback behavior
3. Verify `RateLimitTracker.cleanupExpired()` caller absence and document as finding
4. Document proxy monolith splitting strategy based on observed responsibilities in `proxy.service.ts` and `proxy.controller.ts`
## Critical Context
- **Registry null hazard**: `proxyAdvancedRegistry` starts all-null; IPC handlers return empty fallbacks when NestJS is not running. In `handler.ts`, `generateIdeConfig` and `getProxyMetrics` guard against null registry entries; `getModelCapabilities` does not use registry but ProxyController hardcodes capabilities.
- **No scheduled `cleanupExpired()`**: `rate-limit-tracker.ts:107` defines `cleanupExpired()`, but no `setInterval` or cron job was found in `token-manager.service.ts`, `proxy.service.ts`, `main.ts`, or `CloudMonitorService.ts`. Failure counts may leak memory over long uptimes.
- **In-memory only state**: `ProxyReplayService` uses a 20-entry in-memory buffer; `switchMetrics.ts` mentioned in exploration but file not read yet; `RateLimitTracker` is in-memory only (no SQLite persistence).
- **Proxy monolith responsibilities observed**:
- `proxy.service.ts`: Request transformation (Claude/Gemini/OpenAI), streaming state machine (`PartProcessor`), retry logic, token acquisition, tool call normalization, schema normalization, user-agent resolution, traffic logging
- `proxy.controller.ts`: Route handling, SSE emission, multipart proxy, model listing, capability hardcoding, error response formatting (OpenAI/Anthropic/Gemini shapes), request parsing
- **AutoSwitch race potential**: `AutoSwitchService.findBestAccount()` is static and reads from DB; `CloudMonitorService` runs on a 5-minute timer in main process and calls `switchCloudAccount()` directly. If multiple monitors or manual switches run concurrently, there is no distributed lock or transaction around the switch operation.
- **Circuit breaker implementation**: `token-manager.service.ts` maintains per-token `CircuitBreakerEntry` with `failureCount`, `lastFailureTime`, `state` (`healthy`/`degraded`/`unhealthy`), and a `requestLog` array. No external library used; custom logic.
- **CloudAccountRepo retry pattern**: Uses `SQLITE_MAX_RETRIES = 3` with `SQLITE_BUSY_TIMEOUT_MS = 3000` for busy/locked errors, but reads showed Drizzle individual operations without explicit transaction boundaries around multi-step updates.
## File Operations
### Read
- `D:\Documents\Github\Gemini Proxys\Draculabo-AntigravityManager\src\ipc\database\cloudHandler.ts`
- `D:\Documents\Github\Gemini Proxys\Draculabo-AntigravityManager\src\ipc\proxy-advanced\handler.ts`
- `D:\Documents\Github\Gemini Proxys\Draculabo-AntigravityManager\src\ipc\proxy-advanced\router.ts`
- `D:\Documents\Github\Gemini Proxys\Draculabo-AntigravityManager\src\ipc\proxy-advanced\service-registry.ts`
- `D:\Documents\Github\Gemini Proxys\Draculabo-AntigravityManager\src\main.ts`
- `D:\Documents\Github\Gemini Proxys\Draculabo-AntigravityManager\src\server\main.ts`
- `D:\Documents\Github\Gemini Proxys\Draculabo-AntigravityManager\src\server\modules\proxy\proxy-replay.service.ts`
- `D:\Documents\Github\Gemini Proxys\Draculabo-AntigravityManager\src\server\modules\proxy\proxy.controller.ts`
- `D:\Documents\Github\Gemini Proxys\Draculabo-AntigravityManager\src\server\modules\proxy\proxy.service.ts`
- `D:\Documents\Github\Gemini Proxys\Draculabo-AntigravityManager\src\server\modules\proxy\rate-limit-tracker.ts`
- `D:\Documents\Github\Gemini Proxys\Draculabo-AntigravityManager\src\server\modules\proxy\token-manager.service.ts`
- `D:\Documents\Github\Gemini Proxys\Draculabo-AntigravityManager\src\services\AutoSwitchService.ts`
- `D:\Documents\Github\Gemini Proxys\Draculabo-AntigravityManager\src\services\CloudMonitorService.ts`
### Modified
- (none)