mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-05 06:59:42 +02:00
refactor: consolidate shared regex patterns and token validation
- Create src/utils/regex-patterns.ts with ANSI_ESCAPE_PATTERN_FULL, ANSI_ESCAPE_PATTERN_SIMPLE, TOKEN_PATTERN, and helper functions - Create src/utils/token-validation.ts with MAX_SESSION_TOKENS and validation utilities - Update session.ts, respawn-controller.ts, ai-checker-base.ts, ralph-tracker.ts, state-store.ts to use shared utilities - Export all new utilities from src/utils/index.ts Reduces code duplication while maintaining pre-compiled patterns for performance. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,3 +10,17 @@ export { BufferAccumulator } from './buffer-accumulator.js';
|
||||
export { LRUMap, type LRUMapOptions } from './lru-map.js';
|
||||
export { CleanupManager, type TimerOptions } from './cleanup-manager.js';
|
||||
export { StaleExpirationMap, type StaleExpirationMapOptions } from './stale-expiration-map.js';
|
||||
export {
|
||||
ANSI_ESCAPE_PATTERN_FULL,
|
||||
ANSI_ESCAPE_PATTERN_SIMPLE,
|
||||
TOKEN_PATTERN,
|
||||
createAnsiPatternFull,
|
||||
createAnsiPatternSimple,
|
||||
stripAnsi,
|
||||
stripAnsiSimple,
|
||||
} from './regex-patterns.js';
|
||||
export {
|
||||
MAX_SESSION_TOKENS,
|
||||
validateTokenCounts,
|
||||
validateTokensAndCost,
|
||||
} from './token-validation.js';
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @fileoverview Shared regex patterns for terminal and token parsing.
|
||||
*
|
||||
* Pre-compiled patterns avoid re-compilation overhead on each use.
|
||||
* Import these patterns instead of defining them locally.
|
||||
*
|
||||
* @module utils/regex-patterns
|
||||
*/
|
||||
|
||||
/**
|
||||
* Comprehensive ANSI escape pattern that handles:
|
||||
* - SGR (colors/styles): ESC [ params m
|
||||
* - CSI sequences (cursor, scroll, etc.): ESC [ params letter
|
||||
* - OSC sequences (title, etc.): ESC ] ... BEL or ESC ] ... ST
|
||||
* - Single-char escapes: ESC = or ESC >
|
||||
*
|
||||
* Use this when you need complete ANSI stripping including OSC sequences.
|
||||
* Note: Has global flag - reset lastIndex before exec() if reusing.
|
||||
*/
|
||||
export const ANSI_ESCAPE_PATTERN_FULL = /\x1b(?:\[[0-9;?]*[A-Za-z]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[=>])/g;
|
||||
|
||||
/**
|
||||
* Simple ANSI CSI-only pattern for basic escape code stripping.
|
||||
* Matches: ESC [ params letter (e.g., colors, cursor movement)
|
||||
*
|
||||
* Use this for faster stripping when OSC sequences aren't a concern.
|
||||
* Note: Has global flag - reset lastIndex before exec() if reusing.
|
||||
*/
|
||||
export const ANSI_ESCAPE_PATTERN_SIMPLE = /\x1b\[[0-9;]*[A-Za-z]/g;
|
||||
|
||||
/**
|
||||
* Pattern to extract token count from Claude's status line.
|
||||
* Matches: "123.4k tokens", "5234 tokens", "1.2M tokens"
|
||||
*
|
||||
* Capture groups:
|
||||
* - Group 1: The numeric value (e.g., "123.4", "5234", "1.2")
|
||||
* - Group 2: Optional suffix (k, K, m, M) or undefined
|
||||
*/
|
||||
export const TOKEN_PATTERN = /(\d+(?:\.\d+)?)\s*([kKmM])?\s*tokens/;
|
||||
|
||||
/**
|
||||
* Creates a fresh copy of ANSI_ESCAPE_PATTERN_FULL.
|
||||
* Use when you need a pattern without shared lastIndex state.
|
||||
*/
|
||||
export function createAnsiPatternFull(): RegExp {
|
||||
return /\x1b(?:\[[0-9;?]*[A-Za-z]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[=>])/g;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fresh copy of ANSI_ESCAPE_PATTERN_SIMPLE.
|
||||
* Use when you need a pattern without shared lastIndex state.
|
||||
*/
|
||||
export function createAnsiPatternSimple(): RegExp {
|
||||
return /\x1b\[[0-9;]*[A-Za-z]/g;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips ANSI escape codes from text using the comprehensive pattern.
|
||||
* @param text - Text containing ANSI escape codes
|
||||
* @returns Text with ANSI codes removed
|
||||
*/
|
||||
export function stripAnsi(text: string): string {
|
||||
return text.replace(ANSI_ESCAPE_PATTERN_FULL, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips simple ANSI CSI codes from text (faster, less comprehensive).
|
||||
* @param text - Text containing ANSI escape codes
|
||||
* @returns Text with ANSI CSI codes removed
|
||||
*/
|
||||
export function stripAnsiSimple(text: string): string {
|
||||
return text.replace(ANSI_ESCAPE_PATTERN_SIMPLE, '');
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @fileoverview Token validation utilities.
|
||||
*
|
||||
* Centralizes token count validation logic used across the codebase.
|
||||
* Claude's context window is ~200k tokens, so 500k is a generous upper bound.
|
||||
*
|
||||
* @module utils/token-validation
|
||||
*/
|
||||
|
||||
/**
|
||||
* Maximum tokens allowed per session.
|
||||
* Claude's context is ~200k, so 500k is a safe upper bound for validation.
|
||||
*/
|
||||
export const MAX_SESSION_TOKENS = 500_000;
|
||||
|
||||
/**
|
||||
* Validates token counts are within acceptable bounds.
|
||||
* Rejects negative values and values exceeding MAX_SESSION_TOKENS.
|
||||
*
|
||||
* @param inputTokens - Input token count to validate
|
||||
* @param outputTokens - Output token count to validate
|
||||
* @returns Object with isValid flag and optional error reason
|
||||
*/
|
||||
export function validateTokenCounts(
|
||||
inputTokens: number,
|
||||
outputTokens: number
|
||||
): { isValid: boolean; reason?: string } {
|
||||
if (inputTokens < 0 || outputTokens < 0) {
|
||||
return {
|
||||
isValid: false,
|
||||
reason: `Negative token values: input=${inputTokens}, output=${outputTokens}`,
|
||||
};
|
||||
}
|
||||
|
||||
if (inputTokens > MAX_SESSION_TOKENS || outputTokens > MAX_SESSION_TOKENS) {
|
||||
return {
|
||||
isValid: false,
|
||||
reason: `Token values exceed maximum (${MAX_SESSION_TOKENS}): input=${inputTokens}, output=${outputTokens}`,
|
||||
};
|
||||
}
|
||||
|
||||
return { isValid: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates token counts and cost for restoration/persistence.
|
||||
* Returns true if all values are valid.
|
||||
*
|
||||
* @param inputTokens - Input token count
|
||||
* @param outputTokens - Output token count
|
||||
* @param cost - Cost value (must be non-negative)
|
||||
* @returns Object with isValid flag and optional error reason
|
||||
*/
|
||||
export function validateTokensAndCost(
|
||||
inputTokens: number,
|
||||
outputTokens: number,
|
||||
cost: number
|
||||
): { isValid: boolean; reason?: string } {
|
||||
const tokenValidation = validateTokenCounts(inputTokens, outputTokens);
|
||||
if (!tokenValidation.isValid) {
|
||||
return tokenValidation;
|
||||
}
|
||||
|
||||
if (cost < 0) {
|
||||
return {
|
||||
isValid: false,
|
||||
reason: `Negative cost value: ${cost}`,
|
||||
};
|
||||
}
|
||||
|
||||
return { isValid: true };
|
||||
}
|
||||
Reference in New Issue
Block a user