mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
The local PTY readiness poll held its inferred_idle fallback for exactly one pollIntervalMs after a prompt marker, so a bash foreground handoff that lands on the silence boundary only wins the exact stdin_read attribution when the kernel publishes it inside that single poll. On a slow or loaded host it does not, and the attribution flips. handoffGraceMs replaces the hardcoded one-poll window as a validated, deployment-owned config field defaulting to 500ms, rejected at load when it cannot contain one readiness poll. Real-shell tests that interrupt a send now assert the session is usable again rather than which readiness tier observed the handoff, because no fixed grace removes the race.
33 lines
1.5 KiB
TypeScript
33 lines
1.5 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import type { Config } from '@deepseek-ai/dsh-pty-local/src/config.ts'
|
|
import { validateConfig } from '@deepseek-ai/dsh-pty-local/src/config.ts'
|
|
|
|
function config(overrides: Partial<Config> = {}): Config {
|
|
return {
|
|
backendType: 'shell', shellPath: '/bin/bash', shellArgs: [], rows: 40, cols: 160,
|
|
scrollbackLines: 100, scrollbackMaxBytes: 1024, maxReadBytes: 512,
|
|
pollIntervalMs: 10, exactProbeAfterMs: 20, idleSilenceMs: 100, handoffGraceMs: 50, timeoutMs: 1000,
|
|
disposeGraceMs: 100,
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
describe('pty-local config', () => {
|
|
it('accepts resolved positive bounds', () => {
|
|
expect(() => { validateConfig(config()) }).not.toThrow()
|
|
})
|
|
|
|
it('rejects empty names, invalid numbers, and a read cap above retention', () => {
|
|
expect(() => { validateConfig(config({ backendType: '' })) }).toThrow('backendType')
|
|
expect(() => { validateConfig(config({ shellPath: '' })) }).toThrow('shellPath')
|
|
expect(() => { validateConfig(config({ rows: 0 })) }).toThrow('rows')
|
|
expect(() => { validateConfig(config({ rows: 1.5 })) }).toThrow('rows')
|
|
expect(() => { validateConfig(config({ maxReadBytes: 2048 })) }).toThrow('must not exceed')
|
|
})
|
|
|
|
it('rejects a handoff grace shorter than one readiness poll', () => {
|
|
expect(() => { validateConfig(config({ handoffGraceMs: 9, pollIntervalMs: 10 })) }).toThrow('handoffGraceMs must be at least pollIntervalMs')
|
|
expect(() => { validateConfig(config({ handoffGraceMs: 10, pollIntervalMs: 10 })) }).not.toThrow()
|
|
})
|
|
})
|