test(cliproxy): cover auto compact windows

This commit is contained in:
Tam Nhu Tran committed 2026-07-29 13:46:53 -04:00
1 parent b0732613a3
commit c107a6752c
3 files changed
+203 -16

No files matched your search

@@ -75,6 +75,18 @@ describe('model-catalog compatibility lookups', () => {
expect(catalog?.models[0]?.extendedContext).toBeUndefined();
});
it('maps positive integer live context length into contextWindow metadata', () => {
const catalog = mergeCatalog('xai', [
{
id: 'grok-4.3',
display_name: 'Grok 4.3 Live',
context_length: 1_000_000,
},
]);
expect(catalog?.models[0]?.contextWindow).toBe(1_000_000);
});
it('does not re-add stale static-only models when live catalog data is present', () => {
const catalog = mergeCatalog('gemini', [
{
@@ -0,0 +1,180 @@
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
import { invalidateConfigCache } from '../../../config/config-loader-facade';
import { clearConfigCache } from '../base-config-loader';
import { applyClaudeAutoCompactWindow } from '../env-builder';
import { buildClaudeEnvironment } from '../../executor/env-resolver';
describe('applyClaudeAutoCompactWindow', () => {
it('injects the catalog window for the effective model after suffix normalization', () => {
const env = applyClaudeAutoCompactWindow(
{
ANTHROPIC_MODEL: 'gpt-5.6-sol-xhigh[1m]',
},
'codex'
);
expect(env.CLAUDE_CODE_AUTO_COMPACT_WINDOW).toBe('372000');
});
it('uses the selected provider when the same model family exists in multiple catalogs', () => {
const env = applyClaudeAutoCompactWindow(
{
ANTHROPIC_MODEL: 'claude-opus-4-6-thinking',
},
'agy'
);
expect(env.CLAUDE_CODE_AUTO_COMPACT_WINDOW).toBe('200000');
});
it('does not inject a value for unknown or custom models', () => {
const env = applyClaudeAutoCompactWindow(
{
ANTHROPIC_MODEL: 'custom-model-with-unknown-window',
},
'codex'
);
expect('CLAUDE_CODE_AUTO_COMPACT_WINDOW' in env).toBe(false);
});
it('preserves an explicit user value', () => {
const env = applyClaudeAutoCompactWindow(
{
ANTHROPIC_MODEL: 'gpt-5.6-sol',
CLAUDE_CODE_AUTO_COMPACT_WINDOW: '123456',
},
'codex'
);
expect(env.CLAUDE_CODE_AUTO_COMPACT_WINDOW).toBe('123456');
});
it('treats an explicit empty value as authoritative', () => {
const env = applyClaudeAutoCompactWindow(
{
ANTHROPIC_MODEL: 'gpt-5.6-sol',
CLAUDE_CODE_AUTO_COMPACT_WINDOW: '',
},
'codex'
);
expect(env.CLAUDE_CODE_AUTO_COMPACT_WINDOW).toBe('');
});
it('does not mistake a differently cased variable for the Claude Code key', () => {
const env = applyClaudeAutoCompactWindow(
{
ANTHROPIC_MODEL: 'gpt-5.6-sol',
claude_code_auto_compact_window: '123456',
},
'codex'
);
expect(env.claude_code_auto_compact_window).toBe('123456');
expect(env.CLAUDE_CODE_AUTO_COMPACT_WINDOW).toBe('372000');
});
});
describe('Claude launch auto-compact integration', () => {
let tempHome: string;
let originalCcsHome: string | undefined;
let originalAutoCompactWindow: string | undefined;
beforeEach(() => {
originalCcsHome = process.env.CCS_HOME;
originalAutoCompactWindow = process.env.CLAUDE_CODE_AUTO_COMPACT_WINDOW;
tempHome = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-auto-compact-'));
process.env.CCS_HOME = tempHome;
delete process.env.CLAUDE_CODE_AUTO_COMPACT_WINDOW;
invalidateConfigCache();
clearConfigCache();
});
afterEach(() => {
if (originalCcsHome === undefined) delete process.env.CCS_HOME;
else process.env.CCS_HOME = originalCcsHome;
if (originalAutoCompactWindow === undefined) {
delete process.env.CLAUDE_CODE_AUTO_COMPACT_WINDOW;
} else {
process.env.CLAUDE_CODE_AUTO_COMPACT_WINDOW = originalAutoCompactWindow;
}
invalidateConfigCache();
clearConfigCache();
fs.rmSync(tempHome, { recursive: true, force: true });
});
it('injects the catalog window for the provider default model on Claude launches', () => {
const env = buildClaudeEnvironment({
provider: 'codex',
useRemoteProxy: false,
localPort: 8317,
verbose: false,
});
expect(env.ANTHROPIC_MODEL).toBe('gpt-5.4(high)');
expect(env.CLAUDE_CODE_AUTO_COMPACT_WINDOW).toBe('1050000');
});
it('preserves an inherited user value on Claude launches', () => {
process.env.CLAUDE_CODE_AUTO_COMPACT_WINDOW = '';
const env = buildClaudeEnvironment({
provider: 'codex',
useRemoteProxy: false,
localPort: 8317,
verbose: false,
});
expect(env.CLAUDE_CODE_AUTO_COMPACT_WINDOW).toBe('');
});
it('uses the composite default tier provider for model lookup', () => {
const env = buildClaudeEnvironment({
provider: 'codex',
useRemoteProxy: false,
localPort: 8317,
verbose: false,
isComposite: true,
compositeTiers: {
opus: { provider: 'agy', model: 'claude-opus-4-6-thinking' },
sonnet: { provider: 'codex', model: 'gpt-5.6-sol' },
haiku: { provider: 'kimi', model: 'kimi-k2' },
},
compositeDefaultTier: 'opus',
});
expect(env.CLAUDE_CODE_AUTO_COMPACT_WINDOW).toBe('200000');
});
it('preserves an explicit empty value from a custom settings file', () => {
const settingsPath = path.join(tempHome, 'codex-custom.settings.json');
fs.writeFileSync(
settingsPath,
JSON.stringify({
env: {
ANTHROPIC_BASE_URL: 'http://127.0.0.1:8317',
ANTHROPIC_AUTH_TOKEN: 'test-token',
ANTHROPIC_MODEL: 'gpt-5.6-sol',
CLAUDE_CODE_AUTO_COMPACT_WINDOW: '',
},
})
);
const env = buildClaudeEnvironment({
provider: 'codex',
useRemoteProxy: false,
localPort: 8317,
customSettingsPath: settingsPath,
verbose: false,
});
expect(env.CLAUDE_CODE_AUTO_COMPACT_WINDOW).toBe('');
});
});
@@ -42,10 +42,7 @@ describe('cliproxy catalog --json output', () => {
it('includes metadata fields when present on model entries', () => {
handleCatalogJson();
const parsed = JSON.parse(capturedOutput[0]) as Record<
string,
Array<Record<string, unknown>>
>;
const parsed = JSON.parse(capturedOutput[0]) as Record<string, Array<Record<string, unknown>>>;
const allModels = Object.values(parsed).flat();
// At least some models in the static catalog have tier set
@@ -56,15 +53,19 @@ describe('cliproxy catalog --json output', () => {
for (const model of withTier) {
expect(['free', 'pro', 'ultra']).toContain(model.tier);
}
const withContextWindow = allModels.filter((m) => m.contextWindow !== undefined);
expect(withContextWindow.length).toBeGreaterThan(0);
for (const model of withContextWindow) {
expect(Number.isInteger(model.contextWindow)).toBe(true);
expect(model.contextWindow as number).toBeGreaterThan(0);
}
});
it('omits undefined optional fields instead of including nulls', () => {
handleCatalogJson();
const parsed = JSON.parse(capturedOutput[0]) as Record<
string,
Array<Record<string, unknown>>
>;
const parsed = JSON.parse(capturedOutput[0]) as Record<string, Array<Record<string, unknown>>>;
const allModels = Object.values(parsed).flat();
for (const model of allModels) {
@@ -78,10 +79,7 @@ describe('cliproxy catalog --json output', () => {
it('includes explicit false boolean values in output', () => {
handleCatalogJson();
const parsed = JSON.parse(capturedOutput[0]) as Record<
string,
Array<Record<string, unknown>>
>;
const parsed = JSON.parse(capturedOutput[0]) as Record<string, Array<Record<string, unknown>>>;
const allModels = Object.values(parsed).flat();
// Static catalog has models with extendedContext: false
@@ -92,10 +90,7 @@ describe('cliproxy catalog --json output', () => {
it('includes thinking configuration when present on models', () => {
handleCatalogJson();
const parsed = JSON.parse(capturedOutput[0]) as Record<
string,
Array<Record<string, unknown>>
>;
const parsed = JSON.parse(capturedOutput[0]) as Record<string, Array<Record<string, unknown>>>;
const allModels = Object.values(parsed).flat();
// Static catalog has thinking models (e.g. Claude Opus 4.6 Thinking)