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>
This commit is contained in:
Badri Narayanan S
2026-01-18 01:36:24 +05:30
parent c52d32572a
commit 973234372b
17 changed files with 35 additions and 597 deletions

View File

@@ -67,17 +67,7 @@ export const LOAD_CODE_ASSIST_ENDPOINTS = [
// Endpoint order for onboardUser (same as generateContent fallbacks)
export const ONBOARD_USER_ENDPOINTS = ANTIGRAVITY_ENDPOINT_FALLBACKS;
// Hybrid headers specifically for loadCodeAssist
// Uses google-api-nodejs-client User-Agent (required for project discovery on some accounts)
// export const LOAD_CODE_ASSIST_HEADERS = {
// 'User-Agent': 'google-api-nodejs-client/9.15.1',
// 'X-Goog-Api-Client': 'google-cloud-sdk vscode_cloudshelleditor/0.1',
// 'Client-Metadata': JSON.stringify({
// ideType: 'IDE_UNSPECIFIED',
// platform: 'PLATFORM_UNSPECIFIED',
// pluginType: 'GEMINI'
// })
// };
// Headers for loadCodeAssist API
export const LOAD_CODE_ASSIST_HEADERS = ANTIGRAVITY_HEADERS;
// Default project ID if none can be discovered

View File

@@ -47,32 +47,6 @@ export function getCachedSignature(toolUseId) {
return entry.signature;
}
/**
* Clear expired entries from the cache
* Can be called periodically to prevent memory buildup
*/
export function cleanupCache() {
const now = Date.now();
for (const [key, entry] of signatureCache) {
if (now - entry.timestamp > GEMINI_SIGNATURE_CACHE_TTL_MS) {
signatureCache.delete(key);
}
}
for (const [key, entry] of thinkingSignatureCache) {
if (now - entry.timestamp > GEMINI_SIGNATURE_CACHE_TTL_MS) {
thinkingSignatureCache.delete(key);
}
}
}
/**
* Get the current cache size (for debugging)
* @returns {number} Number of entries in the cache
*/
export function getCacheSize() {
return signatureCache.size;
}
/**
* Cache a thinking block signature with its model family
* @param {string} signature - The thinking signature to cache
@@ -105,14 +79,6 @@ export function getCachedSignatureFamily(signature) {
return entry.modelFamily;
}
/**
* Get the current thinking signature cache size (for debugging)
* @returns {number} Number of entries in the thinking signature cache
*/
export function getThinkingCacheSize() {
return thinkingSignatureCache.size;
}
/**
* Clear all entries from the thinking signature cache.
* Used for testing cold cache scenarios.

View File

@@ -12,7 +12,7 @@ import { logger } from '../utils/logger.js';
* @param {Object} part - Content part to check
* @returns {boolean} True if the part is a thinking block
*/
export function isThinkingPart(part) {
function isThinkingPart(part) {
return part.type === 'thinking' ||
part.type === 'redacted_thinking' ||
part.thinking !== undefined ||
@@ -22,7 +22,7 @@ export function isThinkingPart(part) {
/**
* Check if a thinking part has a valid signature (>= MIN_SIGNATURE_LENGTH chars)
*/
export function hasValidSignature(part) {
function hasValidSignature(part) {
const signature = part.thought === true ? part.thoughtSignature : part.signature;
return typeof signature === 'string' && signature.length >= MIN_SIGNATURE_LENGTH;
}
@@ -61,7 +61,7 @@ export function hasUnsignedThinkingBlocks(messages) {
/**
* Sanitize a thinking part by keeping only allowed fields
*/
export function sanitizeThinkingPart(part) {
function sanitizeThinkingPart(part) {
// Gemini-style thought blocks: { thought: true, text, thoughtSignature }
if (part.thought === true) {
const sanitized = { thought: true };
@@ -85,7 +85,7 @@ export function sanitizeThinkingPart(part) {
* Sanitize a thinking block by removing extra fields like cache_control.
* Only keeps: type, thinking, signature (for thinking) or type, data (for redacted_thinking)
*/
export function sanitizeAnthropicThinkingBlock(block) {
function sanitizeAnthropicThinkingBlock(block) {
if (!block) return block;
if (block.type === 'thinking') {
@@ -366,7 +366,7 @@ function isPlainUserMessage(message) {
* @param {Array<Object>} messages - Array of messages
* @returns {Object} State object with inToolLoop, interruptedTool, turnHasThinking, etc.
*/
export function analyzeConversationState(messages) {
function analyzeConversationState(messages) {
if (!Array.isArray(messages) || messages.length === 0) {
return { inToolLoop: false, interruptedTool: false, turnHasThinking: false, toolResultCount: 0 };
}

View File

@@ -103,6 +103,23 @@ app.use('/v1', (req, res, next) => {
// Setup usage statistics middleware
usageStats.setupMiddleware(app);
/**
* Silent handler for Claude Code CLI root POST requests
* Claude Code sends heartbeat/event requests to POST / which we don't need
* Using app.use instead of app.post for earlier middleware interception
*/
app.use((req, res, next) => {
// Handle Claude Code event logging requests silently
if (req.method === 'POST' && req.path === '/api/event_logging/batch') {
return res.status(200).json({ status: 'ok' });
}
// Handle Claude Code root POST requests silently
if (req.method === 'POST' && req.path === '/') {
return res.status(200).json({ status: 'ok' });
}
next();
});
// Mount WebUI (optional web interface for account management)
mountWebUI(app, __dirname, accountManager);
@@ -162,7 +179,7 @@ app.use((req, res, next) => {
const logMsg = `[${req.method}] ${req.path} ${status} (${duration}ms)`;
// Skip standard logging for event logging batch unless in debug mode
if (req.path === '/api/event_logging/batch') {
if (req.path === '/api/event_logging/batch' || req.path === '/v1/messages/count_tokens') {
if (logger.isDebugEnabled) {
logger.debug(logMsg);
}
@@ -181,6 +198,14 @@ app.use((req, res, next) => {
next();
});
/**
* Silent handler for Claude Code CLI root POST requests
* Claude Code sends heartbeat/event requests to POST / which we don't need
*/
app.post('/', (req, res) => {
res.status(200).json({ status: 'ok' });
});
/**
* Test endpoint - Clear thinking signature cache
* Used for testing cold cache scenarios in cross-model tests
@@ -810,6 +835,7 @@ app.post('/v1/messages', async (req, res) => {
usageStats.setupRoutes(app);
app.use('*', (req, res) => {
// Log 404s (use originalUrl since wildcard strips req.path)
if (logger.isDebugEnabled) {
logger.debug(`[API] 404 Not Found: ${req.method} ${req.originalUrl}`);
}

View File

@@ -49,32 +49,3 @@ export function isNetworkError(error) {
msg.includes('timeout')
);
}
/**
* Check if an error is an authentication error (permanent until fixed)
* @param {Error} error - The error to check
* @returns {boolean} True if it is an auth error
*/
export function isAuthError(error) {
const msg = error.message.toLowerCase();
return (
msg.includes('401') ||
msg.includes('unauthenticated') ||
msg.includes('invalid_grant') ||
msg.includes('invalid_client')
);
}
/**
* Check if an error is a rate limit error
* @param {Error} error - The error to check
* @returns {boolean} True if it is a rate limit error
*/
export function isRateLimitError(error) {
const msg = error.message.toLowerCase();
return (
msg.includes('429') ||
msg.includes('resource_exhausted') ||
msg.includes('quota_exhausted')
);
}

View File

@@ -140,6 +140,3 @@ class Logger extends EventEmitter {
// Export a singleton instance
export const logger = new Logger();
// Export class if needed for multiple instances
export { Logger };

View File

@@ -1,161 +0,0 @@
/**
* Retry Utilities with Exponential Backoff
*
* Provides retry logic with exponential backoff and jitter
* to prevent thundering herd and optimize API quota usage.
*/
import { sleep } from './helpers.js';
import { logger } from './logger.js';
/**
* Calculate exponential backoff delay with jitter
*
* @param {number} attempt - Current attempt number (0-based)
* @param {number} baseMs - Base delay in milliseconds
* @param {number} maxMs - Maximum delay in milliseconds
* @returns {number} Delay in milliseconds
*/
export function calculateBackoff(attempt, baseMs = 1000, maxMs = 30000) {
// Exponential: baseMs * 2^attempt
const exponential = baseMs * Math.pow(2, attempt);
// Cap at max
const capped = Math.min(exponential, maxMs);
// Add random jitter (±25%) to prevent thundering herd
const jitter = capped * 0.25 * (Math.random() * 2 - 1);
return Math.floor(capped + jitter);
}
/**
* Retry a function with exponential backoff
*
* @param {Function} fn - Async function to retry (receives attempt number)
* @param {Object} options - Retry options
* @param {number} options.maxAttempts - Maximum number of attempts (default: 5)
* @param {number} options.baseMs - Base delay in milliseconds (default: 1000)
* @param {number} options.maxMs - Maximum delay in milliseconds (default: 30000)
* @param {Function} options.shouldRetry - Function to determine if error is retryable
* @param {Function} options.onRetry - Callback before each retry (error, attempt, backoffMs)
* @returns {Promise<any>} Result from fn
* @throws {Error} Last error if all attempts fail
*/
export async function retryWithBackoff(fn, options = {}) {
const {
maxAttempts = 5,
baseMs = 1000,
maxMs = 30000,
shouldRetry = () => true,
onRetry = null
} = options;
let lastError;
for (let attempt = 0; attempt < maxAttempts; attempt++) {
try {
return await fn(attempt);
} catch (error) {
lastError = error;
// Check if this is the last attempt
if (attempt === maxAttempts - 1) {
logger.debug(`[Retry] All ${maxAttempts} attempts exhausted`);
throw error;
}
// Check if error is retryable
if (!shouldRetry(error, attempt)) {
logger.debug(`[Retry] Error not retryable, aborting: ${error.message}`);
throw error;
}
// Calculate backoff
const backoffMs = calculateBackoff(attempt, baseMs, maxMs);
logger.debug(`[Retry] Attempt ${attempt + 1}/${maxAttempts} failed, retrying in ${backoffMs}ms`);
// Call onRetry callback
if (onRetry) {
await onRetry(error, attempt, backoffMs);
}
// Wait before retrying
await sleep(backoffMs);
}
}
// Should never reach here, but just in case
throw lastError;
}
/**
* Check if an error is retryable (5xx errors or network issues)
*
* @param {Error} error - Error to check
* @returns {boolean} True if error is retryable
*/
export function isRetryableError(error) {
const message = error.message?.toLowerCase() || '';
// Network errors
if (message.includes('econnrefused') ||
message.includes('econnreset') ||
message.includes('etimedout') ||
message.includes('network') ||
message.includes('fetch failed')) {
return true;
}
// 5xx server errors
if (message.includes('500') ||
message.includes('502') ||
message.includes('503') ||
message.includes('504')) {
return true;
}
// Rate limits (429) are retryable
if (message.includes('429') || message.includes('rate limit')) {
return true;
}
return false;
}
/**
* Check if an error is NOT retryable (4xx client errors except 429)
*
* @param {Error} error - Error to check
* @returns {boolean} True if error should not be retried
*/
export function isNonRetryableError(error) {
const message = error.message?.toLowerCase() || '';
// Authentication errors (401, 403)
if (message.includes('401') ||
message.includes('403') ||
message.includes('unauthorized') ||
message.includes('forbidden')) {
return true;
}
// Bad request (400)
if (message.includes('400') || message.includes('bad request')) {
return true;
}
// Not found (404)
if (message.includes('404') || message.includes('not found')) {
return true;
}
return false;
}
export default {
calculateBackoff,
retryWithBackoff,
isRetryableError,
isNonRetryableError
};