2026-07-30 17:40:25 +08:00
import { describe , expect , it } from 'vitest'
import { Context } from 'cordis'
import Loader from '@cordisjs/plugin-loader'
import type { Agent } from '@deepseek-ai/dsh-agent'
import CommandService from '@deepseek-ai/dsh-commands'
import {
CompactService ,
ManualCompactionError ,
type CompactAgentContext ,
type CompactionResult ,
type CompactionTrigger ,
type ManualCompactAgentContext ,
} from '@deepseek-ai/dsh-compact'
import { Session , SessionId } from '@deepseek-ai/dsh-session'
import * as commandCompact from '@deepseek-ai/dsh-command-compact'
const RESULT : CompactionResult = {
startSeq : 10 ,
summarySeq : 11 ,
endSeq : 13 ,
summary : [ { type : 'text' , text : 'summary' } ] ,
shadowedRange : { start : 1 , end : 7 } ,
shadowedSeqs : [ 1 , 3 , 7 ] ,
shadowedTokenCount : 42 ,
}
class StubCompactService extends CompactService {
result : CompactionResult | null = RESULT
failure : unknown
operation : ( ( ) = > Promise < CompactionResult | null > ) | undefined
calls : { agent : ManualCompactAgentContext ; signal : AbortSignal } [ ] = [ ]
override compactIfNeeded (
_agent : CompactAgentContext ,
_trigger : CompactionTrigger ,
_signal : AbortSignal ,
) : Promise < CompactionResult | null > {
return Promise . resolve ( null )
}
override compactRegion ( ) : Promise < CompactionResult > {
return Promise . resolve ( RESULT )
}
override compactNow (
agent : ManualCompactAgentContext ,
signal : AbortSignal ,
) : Promise < CompactionResult | null > {
this . calls . push ( { agent , signal } )
if ( this . operation !== undefined ) return this . operation ( )
return this . failure === undefined
? Promise . resolve ( this . result )
// oxlint-disable-next-line typescript/prefer-promise-reject-errors -- exercise arbitrary backend rejection values.
: Promise . reject ( this . failure )
}
}
interface Harness {
readonly ctx : Context
readonly compact : StubCompactService
readonly agent : Agent
readonly plugin : Awaited < ReturnType < Context [ 'plugin' ] > >
}
async function harness ( ) : Promise < Harness > {
const ctx = new Context ( )
await ctx . plugin ( CommandService )
const compact = new StubCompactService ( ctx )
const plugin = await ctx . plugin ( commandCompact )
const session = new Session ( SessionId ( 'command-compact' ) )
const agent = {
session ,
status : 'idle' ,
options : { } ,
reserveTurnAdmission : ( ) = > ( ) = > undefined ,
} as unknown as Agent
return { ctx , compact , agent , plugin }
}
async function run (
test : Harness ,
suffix = '' ,
controller = new AbortController ( ) ,
) : Promise < NonNullable < Awaited < ReturnType < CommandService [ 'execute' ] > > > > {
const execution = await test . ctx . commands . execute ( test . agent , ` /compact ${ suffix } ` , controller . signal )
if ( execution === undefined ) throw new Error ( 'compact command was not registered' )
return execution
}
/** Assert the executor-owned lifecycle pair and absence from model history. */
function expectLastLifecycle (
test : Harness ,
args : string ,
outcome : { readonly kind : 'success' | 'error' ; readonly text? : string } ,
) : string {
const lifecycle = test . agent . session . events . slice ( - 2 )
const runEvent = lifecycle [ 0 ]
const doneEvent = lifecycle [ 1 ]
if ( runEvent ? . type !== 'command/run' || doneEvent ? . type !== 'command/done' ) {
throw new Error ( ` expected command lifecycle pair, got ${ lifecycle . map ( event = > event . type ) . join ( ',' ) } ` )
}
expect ( lifecycle . map ( event = > ( { type : event . type , data : event.data } ) ) ) . toEqual ( [
{
type : 'command/run' ,
data : {
commandId : runEvent.data.commandId ,
name : 'compact' ,
args ,
source : { kind : 'user' } ,
} ,
} ,
{
type : 'command/done' ,
data : {
commandId : runEvent.data.commandId ,
. . . outcome ,
} ,
} ,
] )
expect ( doneEvent . data . commandId ) . toBe ( runEvent . data . commandId )
expect ( test . agent . session . surface . nodes ) . toEqual ( [ ] )
expect ( test . agent . session . deriveMessages ( ) ) . toEqual ( [ ] )
return runEvent . data . commandId
}
describe ( '@deepseek-ai/dsh-command-compact registration' , ( ) = > {
it ( 'registers one argument-free command with Loader-safe exports and disposes it' , async ( ) = > {
const test = await harness ( )
expect ( commandCompact . name ) . toBe ( 'command-compact' )
expect ( commandCompact . inject ) . toEqual ( [ 'commands' , 'compact' ] )
expect ( 'default' in commandCompact ) . toBe ( false )
const loader = Object . create ( Loader . prototype ) as Loader
expect ( loader . unwrapExports ( commandCompact ) ) . toBe ( commandCompact )
expect ( test . ctx . commands . list ( test . agent ) ) . toContainEqual ( {
name : 'compact' ,
description : 'Compact older conversation history' ,
} )
await test . plugin . dispose ( )
expect ( test . ctx . commands . find ( test . agent , 'compact' ) ) . toBeUndefined ( )
} )
} )
describe ( '/compact human command' , ( ) = > {
it ( 'reports success with useful accounting and forwards the exact target and signal' , async ( ) = > {
const test = await harness ( )
const controller = new AbortController ( )
const execution = await run ( test , '' , controller )
expect ( execution . result ) . toEqual ( {
kind : 'success' ,
text : 'Compacted 3 history items (~42 tokens).' ,
} )
expect ( execution . commandId ) . toBe ( expectLastLifecycle ( test , '' , execution . result ) )
expect ( test . compact . calls ) . toEqual ( [ { agent : test.agent , signal : controller.signal } ] )
} )
it ( 'returns direct no-history and argument-rejection results' , async ( ) = > {
const test = await harness ( )
test . compact . result = null
const empty = await run ( test )
expect ( empty . result ) . toEqual ( {
kind : 'success' ,
text : 'No compactable history yet.' ,
} )
expect ( empty . commandId ) . toBe ( expectLastLifecycle ( test , '' , empty . result ) )
const rejected = await run ( test , ' now' )
expect ( rejected . result ) . toEqual ( {
kind : 'error' ,
text : 'Usage: /compact (no arguments)' ,
} )
expect ( rejected . commandId ) . toBe ( expectLastLifecycle ( test , ' now' , rejected . result ) )
expect ( test . compact . calls ) . toHaveLength ( 1 )
} )
it . each ( [
[ 'busy' , 'Compaction is unavailable because this process has an active compaction, or the agent is not idle.' ] ,
[ 'changed' , 'The history selected for compaction changed before it could be replaced. The conversation is unchanged; the attempt is recorded in the session log.' ] ,
[ 'summary' , 'Compaction could not produce a useful summary. The conversation is unchanged; the attempt is recorded in the session log.' ] ,
[ 'commit' , 'Compaction did not finish cleanly; some session history may have changed. Inspect the current session state before retrying.' ] ,
[ 'persistence' , 'Compaction finished, but the session could not be saved.' ] ,
] as const ) ( 'maps expected %s failures to direct errors' , async ( code , text ) = > {
const test = await harness ( )
test . compact . failure = new ManualCompactionError ( code , 'backend detail' )
const execution = await run ( test )
expect ( execution . result ) . toEqual ( { kind : 'error' , text } )
expect ( execution . commandId ) . toBe ( expectLastLifecycle ( test , '' , execution . result ) )
} )
it ( 'preserves cancellation and unexpected implementation failures' , async ( ) = > {
const cancelled = await harness ( )
const controller = new AbortController ( )
const abort = new Error ( 'operator cancelled' )
cancelled . compact . operation = ( ) = > {
controller . abort ( abort )
return Promise . reject ( new ManualCompactionError ( 'summary' , 'late failure' ) )
}
await expect ( run ( cancelled , '' , controller ) ) . rejects . toBe ( abort )
expectLastLifecycle ( cancelled , '' , { kind : 'error' , text : abort.message } )
const unexpected = await harness ( )
const bug = new Error ( 'unexpected backend bug' )
unexpected . compact . failure = bug
await expect ( run ( unexpected ) ) . rejects . toBe ( bug )
expectLastLifecycle ( unexpected , '' , { kind : 'error' , text : bug.message } )
} )
2026-07-30 22:00:34 +08:00
it ( 'drains an aborted handler through close and flush before plugin disposal settles' , async ( ) = > {
const test = await harness ( )
const controller = new AbortController ( )
const abort = new Error ( 'operator cancelled' )
const started = Promise . withResolvers < undefined > ( )
const allowClose = Promise . withResolvers < undefined > ( )
const closed = Promise . withResolvers < undefined > ( )
const allowFlush = Promise . withResolvers < undefined > ( )
const flushed = Promise . withResolvers < undefined > ( )
test . compact . operation = async ( ) = > {
started . resolve ( undefined )
await allowClose . promise
closed . resolve ( undefined )
await allowFlush . promise
flushed . resolve ( undefined )
throw abort
}
const execution = run ( test , '' , controller )
await started . promise
controller . abort ( abort )
await expect ( execution ) . rejects . toBe ( abort )
let disposed = false
const disposal = test . plugin . dispose ( )
void disposal . then ( ( ) = > { disposed = true } )
await new Promise ( resolve = > setTimeout ( resolve , 0 ) )
expect ( test . ctx . commands . find ( test . agent , 'compact' ) ) . toBeUndefined ( )
expect ( disposed ) . toBe ( false )
allowClose . resolve ( undefined )
await closed . promise
await new Promise ( resolve = > setTimeout ( resolve , 0 ) )
expect ( disposed ) . toBe ( false )
allowFlush . resolve ( undefined )
await flushed . promise
await disposal
expect ( disposed ) . toBe ( true )
} )
2026-07-30 17:40:25 +08:00
} )