Preserve native Codex history and add configurable cross-model compression
Separate encrypted reasoning from actual compaction, stop migration after native return, and retain full history and recent exchanges. Add typed settings, Gemini fallback, verified provider windows, bounded summaries and durable concurrent checkpoints. Validation: 245 bridge tests plus focused concurrency tests; 71 settings/connection tests; 66 supplementary tests; TypeScript checks; renderer and Electron bundles; real primary/native/fallback summary probes and 700K input acceptance.
This commit is contained in:
1 parent
1c6e3656b8
commit
91ecad8e5c
27 files changed
+1119
-117
No files matched your search
@@ -0,0 +1,37 @@
|
||||
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { afterEach, expect, it, vi } from 'vitest'
|
||||
|
||||
import { I18nProvider } from '@/i18n/context'
|
||||
|
||||
import defaults from '../../../assets/codex-bridge/compression-defaults.json'
|
||||
|
||||
import { CompressionSettingsView } from './compression-settings'
|
||||
|
||||
afterEach(() => { cleanup(); delete (window as unknown as { hermesDesktop?: unknown }).hermesDesktop })
|
||||
|
||||
it('loads settings, excludes small fallback models, and saves the selected values', async () => {
|
||||
const state = { settings: defaults, modelsAvailable: true, models: [
|
||||
{ id: 'ide/small', name: 'Small', window: 32768, source: 'catalog' },
|
||||
{ id: 'ide/large', name: 'Large', window: 1000000, source: 'catalog' }
|
||||
] }
|
||||
const save = vi.fn(async settings => ({ ...state, settings }))
|
||||
;(window as unknown as { hermesDesktop: unknown }).hermesDesktop = { codexLink: { getCompression: async () => state, setCompression: save } }
|
||||
render(<I18nProvider configClient={null} initialLocale="tr"><CompressionSettingsView /></I18nProvider>)
|
||||
const keep = await screen.findByRole('spinbutton', { name: 'Korunan son mesajlaşma sayısı' })
|
||||
expect((keep as HTMLInputElement).value).toBe('10')
|
||||
const fallback = screen.getByRole('combobox', { name: 'Yedek sıkıştırıcı (1M)' })
|
||||
expect(fallback.textContent).not.toContain('Small')
|
||||
fireEvent.change(keep, { target: { value: '12' } })
|
||||
fireEvent.change(fallback, { target: { value: 'ide/large' } })
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Kaydet' }))
|
||||
await waitFor(() => expect(save).toHaveBeenCalledWith(expect.objectContaining({ keepTurns: 12, fallbackModel: 'ide/large' })))
|
||||
expect(await screen.findByText('Kaydedildi. Sonraki hazırlıkta uygulanacak.')).toBeTruthy()
|
||||
})
|
||||
|
||||
it('shows a failed save without claiming success', async () => {
|
||||
const save = vi.fn().mockRejectedValue(new Error('disk unavailable'))
|
||||
;(window as unknown as { hermesDesktop: unknown }).hermesDesktop = { codexLink: { getCompression: async () => ({ settings: defaults, models: [], modelsAvailable: false }), setCompression: save } }
|
||||
render(<I18nProvider configClient={null} initialLocale="tr"><CompressionSettingsView /></I18nProvider>)
|
||||
fireEvent.click(await screen.findByRole('button', { name: 'Kaydet' }))
|
||||
expect((await screen.findByRole('alert')).textContent).toContain('Kaydedilemedi')
|
||||
})
|
||||
Reference in new issue
Block a user