mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
round 1: implement bracket-first manual compaction
This commit is contained in:
87
packages/compact/command-compact/src/index.ts
Normal file
87
packages/compact/command-compact/src/index.ts
Normal 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),
|
||||
})
|
||||
}
|
||||
30
packages/compact/command-compact/src/invariant.ts
Normal file
30
packages/compact/command-compact/src/invariant.ts
Normal 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 */
|
||||
Reference in New Issue
Block a user