import fs from 'node:fs' import path from 'node:path' import defaults from '../assets/codex-bridge/compression-defaults.json' import type { CompressionSettings } from './compression-settings-types' export function validateCompression(value: unknown): CompressionSettings { if (!value || typeof value !== 'object') throw new Error('Invalid compression settings') const v = value as CompressionSettings if (Object.keys(v).sort().join() !== Object.keys(defaults).sort().join()) throw new Error('Invalid settings fields') if (v.schemaVersion !== 1 || !['mini', 'az', 'orta', 'fazla', 'cok-fazla'].includes(v.level) || !['percent', 'tokens'].includes(v.budgetMode)) throw new Error('Invalid compression mode') for (const key of ['primaryModel', 'fallbackModel'] as const) { if (typeof v[key] !== 'string' || v[key].length > 256) throw new Error('Invalid model') } for (const key of ['autoEnabled', 'currentModelFallback'] as const) { if (typeof v[key] !== 'boolean') throw new Error('Invalid option') } const limits: [keyof CompressionSettings, number, number][] = [ ['keepTurns', 1, 100], ['transferPercent', 10, 90], ['triggerPercent', 20, 90], ['targetPercent', 10, 80], ['maxTokens', 1024, 2000000], ['timeoutSeconds', 1, 3600] ] for (const [key, low, high] of limits) { const n = v[key] if (typeof n !== 'number' || !Number.isInteger(n) || n < low || n > high) throw new Error(`Invalid ${key}`) } if (v.targetPercent >= v.triggerPercent) throw new Error('Target must be below trigger') return structuredClone(v) } export function createCompressionStore(directory: string) { const file = path.join(directory, 'compression-settings.json') return { get: (): CompressionSettings => validateCompression(fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, 'utf8')) : defaults), save(value: unknown): CompressionSettings { const next = validateCompression(value) fs.mkdirSync(directory, { recursive: true }) const tmp = `${file}.${process.pid}.tmp` try { fs.writeFileSync(tmp, JSON.stringify(next, null, 2), { mode: 0o600 }) fs.renameSync(tmp, file) } finally { if (fs.existsSync(tmp)) fs.unlinkSync(tmp) } return next } } }