round 1: implement bracket-first manual compaction

This commit is contained in:
Hypatia May
2026-07-30 17:40:25 +08:00
parent 86b95a3856
commit faac9b4fd5
101 changed files with 3452 additions and 295 deletions

View File

@@ -0,0 +1,87 @@
/**
* Human-facing `/compact` command over the backend-independent compaction seam.
* @module @deepseek-ai/dsh-command-compact
*/
import type { Context } from 'cordis'
import { ManualCompactionError } from '@deepseek-ai/dsh-compact'
import type { CommandInvocation, CommandResult } from '@deepseek-ai/dsh-commands'
export const name = 'command-compact'
export const inject = ['commands', 'compact']
const USAGE = 'Usage: /compact (no arguments)'
/** Fail loudly if a locally closed union gains an unhandled member. */
/* v8 ignore start -- closed-union backstop is unreachable without violating the TypeScript contract */
function assertNever(value: never): never {
throw new TypeError(`unknown manual compaction error code: ${String(value)}`)
}
/* v8 ignore stop */
/** Convert expected capability failures into concise human-only outcomes. */
function expectedFailure(error: ManualCompactionError): CommandResult {
switch (error.code) {
case 'busy':
return {
kind: 'error',
text: 'Compaction is unavailable because this process has an active compaction, or the agent is not idle.',
}
case 'changed':
return {
kind: 'error',
text: 'The history selected for compaction changed before it could be replaced. The conversation is unchanged; the attempt is recorded in the session log.',
}
case 'summary':
return {
kind: 'error',
text: 'Compaction could not produce a useful summary. The conversation is unchanged; the attempt is recorded in the session log.',
}
case 'commit':
return {
kind: 'error',
text: 'Compaction did not finish cleanly; some session history may have changed. Inspect the current session state before retrying.',
}
case 'persistence':
return {
kind: 'error',
text: 'Compaction finished, but the session could not be saved.',
}
/* v8 ignore next 2 -- ManualCompactionErrorCode is closed and every member is handled above */
default: return assertNever(error.code)
}
}
/** Execute one argument-free manual compaction request. */
async function executeCompact(
ctx: Context,
invocation: CommandInvocation,
): Promise<CommandResult> {
if (invocation.rawInput.trim().length > 0) {
return { kind: 'error', text: USAGE }
}
try {
const result = await ctx.compact.compactNow(invocation.agent, invocation.signal)
if (result === null) return { kind: 'success', text: 'No compactable history yet.' }
return {
kind: 'success',
text: `Compacted ${result.shadowedSeqs.length} history items (~${result.shadowedTokenCount} tokens).`,
}
} catch (error: unknown) {
if (invocation.signal.aborted) return { kind: 'error', text: 'Compaction cancelled.' }
if (error instanceof ManualCompactionError) return expectedFailure(error)
throw error
}
}
/**
* Register `/compact` for every composed human-command adapter.
* @param ctx - context carrying the command registry and the compaction seam.
*/
export function apply(ctx: Context): void {
ctx.commands.register({
name: 'compact',
description: 'Compact older conversation history',
handler: invocation => executeCompact(ctx, invocation),
})
}

View File

@@ -0,0 +1,30 @@
/**
* Package-owned invariant companion for `@deepseek-ai/dsh-command-compact`.
* @module @deepseek-ai/dsh-command-compact/invariant
*/
/* jscpd:ignore-start */
import type { Context } from 'cordis'
import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants'
const PACKAGE_NAME = '@deepseek-ai/dsh-command-compact'
/** Cordis companion plugin name. */
export const name = 'command-compact-invariant'
/** Service required before the companion can reserve package ownership. */
export const inject = ['invariants']
/**
* No runtime invariant: this command adapter owns no state or event stream; the compaction seam owns
* the balanced durable transaction and the command registry owns registration and dispatch lifecycle.
*/
const install: InvariantInstaller = () => {}
/**
* Register this package's invariant companion.
* @param ctx - Cordis context carrying the invariant service.
* @returns the installed registration's disposer after setup succeeds.
*/
export const apply = (ctx: Context): Promise<() => void> =>
Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install))
/* jscpd:ignore-end */