mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
refactor(events): add stable conversation correlation ids
This commit is contained in:
@@ -63,7 +63,7 @@ async function executeCompact(
|
||||
return { kind: 'error', text: USAGE }
|
||||
}
|
||||
try {
|
||||
const result = await ctx.compact.compactNow(invocation.agent, invocation.signal)
|
||||
const result = await ctx.compact.compactNow(invocation.agent, invocation.signal, invocation.commandId)
|
||||
if (result === null) return { kind: 'success', text: 'No compactable history yet.' }
|
||||
return {
|
||||
kind: 'success',
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
"peerDependencies": {
|
||||
"@deepseek-ai/dsh-agent": "^0.0.1",
|
||||
"@deepseek-ai/dsh-compact": "^0.0.1",
|
||||
"@deepseek-ai/dsh-commands": "^0.0.1",
|
||||
"@deepseek-ai/dsh-invariants": "^0.0.1",
|
||||
"@deepseek-ai/dsh-llm": "^0.0.1",
|
||||
"@deepseek-ai/dsh-session": "^0.0.1",
|
||||
@@ -49,6 +50,7 @@
|
||||
"@deepseek-ai/dsh-agent-loop": "workspace:^",
|
||||
"@deepseek-ai/dsh-agent-loop-testkit": "workspace:^",
|
||||
"@deepseek-ai/dsh-compact": "workspace:^",
|
||||
"@deepseek-ai/dsh-commands": "workspace:^",
|
||||
"@deepseek-ai/dsh-invariants": "workspace:^",
|
||||
"@deepseek-ai/dsh-llm": "workspace:^",
|
||||
"@deepseek-ai/dsh-llm-retry": "workspace:^",
|
||||
|
||||
@@ -13,6 +13,7 @@ import type { Session } from '@deepseek-ai/dsh-session'
|
||||
import { CONTEXT_WINDOW_EXCEEDED_CODE, assertNever } from '@deepseek-ai/dsh-llm'
|
||||
import type { LlmCallConfig } from '@deepseek-ai/dsh-llm'
|
||||
import type { Agent, PreStepDecision } from '@deepseek-ai/dsh-agent'
|
||||
import type { CommandId } from '@deepseek-ai/dsh-commands/brand'
|
||||
// Type-only: makes the optional sibling service available to `ctx.get()`.
|
||||
import type {} from '@deepseek-ai/dsh-compact-tool-result-prune'
|
||||
import {
|
||||
@@ -361,9 +362,14 @@ export class BasicCompactService extends CompactService {
|
||||
* resolve only after its standalone marker pair is durably checkpointed.
|
||||
* @param agent - idle agent whose next-turn admission this call reserves.
|
||||
* @param signal - cancellation scoped to this compaction request.
|
||||
* @param sourceCommandId - initiating command identity for presentation correlation.
|
||||
* @returns the committed result, or `null` when no safe useful range exists.
|
||||
*/
|
||||
override compactNow(agent: Agent, signal: AbortSignal): Promise<CompactionResult | null> {
|
||||
override compactNow(
|
||||
agent: Agent,
|
||||
signal: AbortSignal,
|
||||
sourceCommandId?: CommandId,
|
||||
): Promise<CompactionResult | null> {
|
||||
signal.throwIfAborted()
|
||||
try {
|
||||
return agent.runMaintenance(async (agentSignal) => {
|
||||
@@ -385,6 +391,7 @@ export class BasicCompactService extends CompactService {
|
||||
{
|
||||
owner: null,
|
||||
stability: 'selected-span',
|
||||
...sourceCommandId === undefined ? {} : { sourceCommandId },
|
||||
flush: async () => {
|
||||
await this.ctx.sessions.flush(agent.session)
|
||||
},
|
||||
|
||||
@@ -5,14 +5,17 @@
|
||||
* @module @deepseek-ai/dsh-compact-basic/region
|
||||
*/
|
||||
|
||||
import { randomUUID } from 'node:crypto'
|
||||
import { isDeepStrictEqual } from 'node:util'
|
||||
import {
|
||||
COMPACT_CHECKPOINT_SOURCE,
|
||||
CompactionId,
|
||||
ManualCompactionError,
|
||||
compactCheckpointSource,
|
||||
toolPairingBalancedAfter,
|
||||
toolPairingBalancedBefore,
|
||||
} from '@deepseek-ai/dsh-compact'
|
||||
import type { CompactionResult } from '@deepseek-ai/dsh-compact'
|
||||
import type { CommandId } from '@deepseek-ai/dsh-commands/brand'
|
||||
import { createUserMessage, errorChain } from '@deepseek-ai/dsh-llm'
|
||||
import type { Message, UserMessage } from '@deepseek-ai/dsh-llm'
|
||||
import type { TokenMeasurement, TokenMeterService } from '@deepseek-ai/dsh-token-meter'
|
||||
@@ -54,6 +57,8 @@ interface CompactionTransactionOptions {
|
||||
readonly stability: 'whole-surface' | 'selected-span'
|
||||
/** Optional durability checkpoint after a successfully closed bracket. */
|
||||
readonly flush?: () => Promise<void>
|
||||
/** Manual command that initiated this transaction, when present. */
|
||||
readonly sourceCommandId?: CommandId
|
||||
}
|
||||
|
||||
interface CompactionEntryState {
|
||||
@@ -175,7 +180,13 @@ export async function compactSurfaceRegion(
|
||||
owner = entryState.openTurn
|
||||
}
|
||||
|
||||
const startEvent = session.append('compact/start', { turn: owner })
|
||||
const compactionId = CompactionId(randomUUID())
|
||||
const lifecycle = {
|
||||
compactionId,
|
||||
...options.sourceCommandId === undefined ? {} : { sourceCommandId: options.sourceCommandId },
|
||||
turn: owner,
|
||||
}
|
||||
const startEvent = session.append('compact/start', lifecycle)
|
||||
const assertStable: StabilityCheck = options.stability === 'whole-surface'
|
||||
? assertWholeSurfaceUnchanged
|
||||
: assertSelectedSpanStable
|
||||
@@ -188,13 +199,20 @@ export async function compactSurfaceRegion(
|
||||
|
||||
try {
|
||||
const prepared = prepareCompaction(dependencies, session, selection)
|
||||
const summarized = await summarizeCompaction(dependencies, prepared, agent, signal)
|
||||
const summarized = await summarizeCompaction(
|
||||
dependencies,
|
||||
prepared,
|
||||
agent,
|
||||
compactionId,
|
||||
options.sourceCommandId,
|
||||
signal,
|
||||
)
|
||||
if (options.owner === null) signal?.throwIfAborted()
|
||||
assertStable(dependencies, session, summarized)
|
||||
stage = 'commit'
|
||||
const pending = commitCompactionBody(session, startEvent, summarized)
|
||||
closing = true
|
||||
const endEvent = session.append('compact/end', { turn: owner })
|
||||
const endEvent = session.append('compact/end', lifecycle)
|
||||
closed = true
|
||||
result = completeCompaction(pending, endEvent)
|
||||
} catch (error: unknown) {
|
||||
@@ -202,7 +220,7 @@ export async function compactSurfaceRegion(
|
||||
if (!closing) {
|
||||
closing = true
|
||||
try {
|
||||
session.append('compact/end', { turn: owner, error: errorChain(error) })
|
||||
session.append('compact/end', { ...lifecycle, error: errorChain(error) })
|
||||
closed = true
|
||||
} catch (closeError: unknown) {
|
||||
failure = { error: closeError, stage: 'commit' }
|
||||
@@ -343,12 +361,14 @@ async function summarizeCompaction(
|
||||
dependencies: RegionDependencies,
|
||||
prepared: PreparedCompaction,
|
||||
agent: Agent,
|
||||
compactionId: CompactionResult['compactionId'],
|
||||
sourceCommandId: CommandId | undefined,
|
||||
signal?: AbortSignal,
|
||||
): Promise<SummarizedCompaction> {
|
||||
const summaryResult = await dependencies.summarize(prepared.input, agent, signal)
|
||||
const checkpointMessage = createUserMessage({
|
||||
content: frameSummary(summaryResult.summary),
|
||||
source: COMPACT_CHECKPOINT_SOURCE,
|
||||
source: compactCheckpointSource(compactionId, sourceCommandId),
|
||||
})
|
||||
const framedSummaryTokenCount = dependencies.meter.estimateMessage(checkpointMessage)
|
||||
if (framedSummaryTokenCount >= prepared.shadowedTokenCount) {
|
||||
@@ -425,6 +445,10 @@ function commitCompactionBody(
|
||||
? { rawOutput: summarized.rawOutput, llmStreamCall: true as const }
|
||||
: summarized.rawOutput === undefined ? {} : { rawOutput: summarized.rawOutput }
|
||||
const summaryEvent = session.append('compact/summary', {
|
||||
compactionId: startEvent.data.compactionId,
|
||||
...startEvent.data.sourceCommandId === undefined
|
||||
? {}
|
||||
: { sourceCommandId: startEvent.data.sourceCommandId },
|
||||
summary,
|
||||
...callProvenance,
|
||||
shadowedRange: { start, end },
|
||||
@@ -440,6 +464,10 @@ function commitCompactionBody(
|
||||
sourceEventSeqs: [startEvent.seq, summaryEvent.seq, ...shadowedSeqs],
|
||||
})
|
||||
return {
|
||||
compactionId: startEvent.data.compactionId,
|
||||
...startEvent.data.sourceCommandId === undefined
|
||||
? {}
|
||||
: { sourceCommandId: startEvent.data.sourceCommandId },
|
||||
startSeq: startEvent.seq,
|
||||
summarySeq: summaryEvent.seq,
|
||||
summary,
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
{
|
||||
"path": "../../core/agent"
|
||||
},
|
||||
{
|
||||
"path": "../../interaction/commands"
|
||||
},
|
||||
{
|
||||
"path": "../compact"
|
||||
},
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
"types": "./lib/types/checkpoint.d.ts",
|
||||
"default": "./lib/types/checkpoint.js"
|
||||
},
|
||||
"./brand": {
|
||||
"types": "./lib/types/brand.d.ts",
|
||||
"default": "./lib/types/brand.js"
|
||||
},
|
||||
"./src/*": "./src/*",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
@@ -30,12 +34,16 @@
|
||||
],
|
||||
"license": "BSD-3-Clause",
|
||||
"peerDependencies": {
|
||||
"@deepseek-ai/dsh-brand": "^0.0.1",
|
||||
"@deepseek-ai/dsh-commands": "^0.0.1",
|
||||
"@deepseek-ai/dsh-invariants": "^0.0.1",
|
||||
"@deepseek-ai/dsh-llm": "^0.0.1",
|
||||
"@deepseek-ai/dsh-session": "^0.0.1",
|
||||
"cordis": "^4.0.0-rc.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@deepseek-ai/dsh-brand": "workspace:^",
|
||||
"@deepseek-ai/dsh-commands": "workspace:^",
|
||||
"@deepseek-ai/dsh-invariants": "workspace:^",
|
||||
"@deepseek-ai/dsh-llm": "workspace:^",
|
||||
"@deepseek-ai/dsh-session": "workspace:^",
|
||||
|
||||
13
packages/compact/compact/src/brand.ts
Normal file
13
packages/compact/compact/src/brand.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { Branded } from '@deepseek-ai/dsh-brand'
|
||||
|
||||
/** Stable identity shared by one compact start/summary/checkpoint/end transaction. */
|
||||
export type CompactionId = Branded<'CompactionId'>
|
||||
|
||||
/**
|
||||
* Brand an implementation-minted compaction identity.
|
||||
* @param id - opaque transaction identity.
|
||||
* @returns the same string, branded; no validation is performed.
|
||||
*/
|
||||
export function CompactionId(id: string): CompactionId {
|
||||
return id as CompactionId
|
||||
}
|
||||
@@ -13,10 +13,35 @@
|
||||
*/
|
||||
|
||||
import type { MessageSource } from '@deepseek-ai/dsh-llm/message'
|
||||
import type { CommandId } from '@deepseek-ai/dsh-commands/brand'
|
||||
import type { CompactionId } from './brand.ts'
|
||||
|
||||
/** Canonical source for the replacement user message produced by every compaction backend. */
|
||||
export const COMPACT_CHECKPOINT_SOURCE = Object.freeze({ kind: 'plugin', plugin: 'compact' } as const)
|
||||
|
||||
/** Message provenance carried by a concrete compaction checkpoint. */
|
||||
export type CompactCheckpointSource = typeof COMPACT_CHECKPOINT_SOURCE & {
|
||||
readonly compactionId: CompactionId
|
||||
readonly sourceCommandId?: CommandId
|
||||
}
|
||||
|
||||
/**
|
||||
* Create checkpoint provenance correlated with one compaction transaction.
|
||||
* @param compactionId - owning compaction identity.
|
||||
* @param sourceCommandId - initiating manual command, when present.
|
||||
* @returns immutable checkpoint source.
|
||||
*/
|
||||
export function compactCheckpointSource(
|
||||
compactionId: CompactionId,
|
||||
sourceCommandId?: CommandId,
|
||||
): CompactCheckpointSource {
|
||||
return Object.freeze({
|
||||
...COMPACT_CHECKPOINT_SOURCE,
|
||||
compactionId,
|
||||
...sourceCommandId === undefined ? {} : { sourceCommandId },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether a persisted message source identifies a compaction checkpoint.
|
||||
* @param source - source restored from a surface user message.
|
||||
|
||||
@@ -9,14 +9,17 @@
|
||||
|
||||
import { Context, Service } from 'cordis'
|
||||
import type { Session } from '@deepseek-ai/dsh-session'
|
||||
import type { CommandId } from '@deepseek-ai/dsh-commands/brand'
|
||||
import type { CompactionResult } from './types.ts'
|
||||
|
||||
export type { CompactionResult } from './types.ts'
|
||||
export { CompactionId } from './brand.ts'
|
||||
export { toolPairingBalancedAfter, toolPairingBalancedBefore } from './tool-pairing.ts'
|
||||
// The checkpoint source and its predicate are declared on the cordis-free
|
||||
// `./checkpoint` leaf so client and wire programs can name them without this
|
||||
// root's Context merge; the root stays the host-side entry point for both.
|
||||
export { COMPACT_CHECKPOINT_SOURCE, isCompactCheckpointSource } from './checkpoint.ts'
|
||||
export { COMPACT_CHECKPOINT_SOURCE, compactCheckpointSource, isCompactCheckpointSource } from './checkpoint.ts'
|
||||
export type { CompactCheckpointSource } from './checkpoint.ts'
|
||||
|
||||
/** Why automatic policy is asking a backend to consider compaction. */
|
||||
export type CompactionTrigger = 'pressure' | 'context-overflow'
|
||||
@@ -126,6 +129,7 @@ export abstract class CompactService extends Service {
|
||||
*
|
||||
* @param agent - idle agent whose durable history should be compacted.
|
||||
* @param signal - cancellation scoped to this compaction request.
|
||||
* @param sourceCommandId - initiating command identity for a manual compaction.
|
||||
* @returns the compaction result, or `null` when no safe useful range exists.
|
||||
* @throws {@link ManualCompactionError} for expected busy, agent-cancellation,
|
||||
* changed-span, summarization/shrink, commit-stage, or persistence failures;
|
||||
@@ -135,6 +139,7 @@ export abstract class CompactService extends Service {
|
||||
abstract compactNow(
|
||||
agent: ManualCompactAgentContext,
|
||||
signal: AbortSignal,
|
||||
sourceCommandId?: CommandId,
|
||||
): Promise<CompactionResult | null>
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
/** Package-owned compaction log-stream invariants. @module @deepseek-ai/dsh-compact/invariant */
|
||||
|
||||
import type { Context } from 'cordis'
|
||||
import { isReplacementSurfaceEvent } from '@deepseek-ai/dsh-session'
|
||||
import type { Session, SessionEvent } from '@deepseek-ai/dsh-session'
|
||||
import type { InvariantFailure, InvariantInstaller } from '@deepseek-ai/dsh-invariants'
|
||||
import type { CompactionId } from './brand.ts'
|
||||
import { isCompactCheckpointSource } from './checkpoint.ts'
|
||||
import type { CompactCheckpointSource } from './checkpoint.ts'
|
||||
import type {} from './types.ts'
|
||||
|
||||
const PACKAGE_NAME = '@deepseek-ai/dsh-compact'
|
||||
@@ -13,6 +17,8 @@ export const name = 'compact-invariant'
|
||||
export const inject = ['invariants']
|
||||
|
||||
interface CompactionTrace {
|
||||
compactionId: CompactionId
|
||||
sourceCommandId: string | undefined
|
||||
startSeq: number
|
||||
turn: number | null
|
||||
summarized: boolean
|
||||
@@ -24,11 +30,48 @@ interface SessionTrace {
|
||||
}
|
||||
|
||||
type CompactionTransition =
|
||||
| { kind: 'start'; startSeq: number; turn: number | null }
|
||||
| { kind: 'summary'; startSeq: number; turn: number | null }
|
||||
| { kind: 'start'; compactionId: CompactionId; sourceCommandId: string | undefined; startSeq: number; turn: number | null }
|
||||
| { kind: 'summary'; compactionId: CompactionId; sourceCommandId: string | undefined; startSeq: number; turn: number | null }
|
||||
| { kind: 'end' }
|
||||
| { kind: 'end-seed' }
|
||||
|
||||
/** Require a durable opaque identity to be a non-empty string. */
|
||||
function validateId(value: unknown, label: string, fail: InvariantFailure): asserts value is string {
|
||||
if (typeof value !== 'string' || value.length === 0) fail(`${label} must be a non-empty string`)
|
||||
}
|
||||
|
||||
/** Keep the optional initiating command identity stable across one transaction. */
|
||||
function validateSourceCommandId(
|
||||
eventType: string,
|
||||
value: unknown,
|
||||
expected: string | undefined,
|
||||
fail: InvariantFailure,
|
||||
): void {
|
||||
if (value !== undefined) validateId(value, `${eventType} sourceCommandId`, fail)
|
||||
if (value !== expected) {
|
||||
fail(`${eventType} sourceCommandId ${String(value)} does not match compact/start sourceCommandId ${String(expected)}`)
|
||||
}
|
||||
}
|
||||
|
||||
/** Validate one replacement checkpoint against its open compaction transaction. */
|
||||
function validateCheckpoint(
|
||||
trace: SessionTrace,
|
||||
event: SessionEvent<'user/message'>,
|
||||
fail: InvariantFailure,
|
||||
): void {
|
||||
const source = event.data.source as typeof event.data.source & Partial<CompactCheckpointSource>
|
||||
validateId(source.compactionId, 'compaction checkpoint compactionId', fail)
|
||||
if (source.sourceCommandId !== undefined) {
|
||||
validateId(source.sourceCommandId, 'compaction checkpoint sourceCommandId', fail)
|
||||
}
|
||||
const open = trace.compaction
|
||||
if (open === undefined) fail('compaction checkpoint has no matching compact/start')
|
||||
if (source.compactionId !== open.compactionId) {
|
||||
fail(`compaction checkpoint id ${source.compactionId} does not match compact/start id ${open.compactionId}`)
|
||||
}
|
||||
validateSourceCommandId('compaction checkpoint', source.sourceCommandId, open.sourceCommandId, fail)
|
||||
}
|
||||
|
||||
/** Compaction starts still unmatched when a later seed boundary made them stale. */
|
||||
function inheritedOrphanStartSeqs(
|
||||
events: readonly SessionEvent[],
|
||||
@@ -99,20 +142,44 @@ function validateCompactionEvent(
|
||||
fail: InvariantFailure,
|
||||
): CompactionTransition | undefined {
|
||||
if (event.type === 'session/end-seed') return { kind: 'end-seed' }
|
||||
if (event.type === 'user/message'
|
||||
&& isReplacementSurfaceEvent(event)
|
||||
&& isCompactCheckpointSource(event.data.source)) {
|
||||
validateCheckpoint(trace, event, fail)
|
||||
return undefined
|
||||
}
|
||||
if (event.type !== 'compact/start' && event.type !== 'compact/summary' && event.type !== 'compact/end') {
|
||||
return undefined
|
||||
}
|
||||
const open = trace.compaction
|
||||
if (event.type === 'compact/start') {
|
||||
validateId(event.data.compactionId, 'compact/start compactionId', fail)
|
||||
if (event.data.sourceCommandId !== undefined) {
|
||||
validateId(event.data.sourceCommandId, 'compact/start sourceCommandId', fail)
|
||||
}
|
||||
if (open !== undefined) {
|
||||
const owner = open.turn === null ? 'standalone compaction' : `turn ${open.turn}`
|
||||
fail(`compact/start while ${owner} is still compacting`)
|
||||
}
|
||||
validateOwner(event.data.turn, trace.openTurn, event.type, fail)
|
||||
return { kind: 'start', startSeq: event.seq, turn: event.data.turn }
|
||||
return {
|
||||
kind: 'start',
|
||||
compactionId: event.data.compactionId,
|
||||
sourceCommandId: event.data.sourceCommandId,
|
||||
startSeq: event.seq,
|
||||
turn: event.data.turn,
|
||||
}
|
||||
}
|
||||
if (event.type === 'compact/summary') {
|
||||
validateId(event.data.compactionId, 'compact/summary compactionId', fail)
|
||||
if (event.data.sourceCommandId !== undefined) {
|
||||
validateId(event.data.sourceCommandId, 'compact/summary sourceCommandId', fail)
|
||||
}
|
||||
if (open === undefined) fail('compact/summary has no matching compact/start')
|
||||
if (event.data.compactionId !== open.compactionId) {
|
||||
fail(`compact/summary id ${event.data.compactionId} does not match compact/start id ${open.compactionId}`)
|
||||
}
|
||||
validateSourceCommandId('compact/summary', event.data.sourceCommandId, open.sourceCommandId, fail)
|
||||
validateOwner(open.turn, trace.openTurn, event.type, fail)
|
||||
if (open.summarized) fail('compact/summary repeated within one compaction')
|
||||
const seqs = event.data.shadowedSeqs
|
||||
@@ -123,9 +190,23 @@ function validateCompactionEvent(
|
||||
if (!Number.isSafeInteger(event.data.shadowedTokenCount) || event.data.shadowedTokenCount < 0) {
|
||||
fail('compact/summary shadowedTokenCount must be a non-negative safe integer')
|
||||
}
|
||||
return { kind: 'summary', startSeq: open.startSeq, turn: open.turn }
|
||||
return {
|
||||
kind: 'summary',
|
||||
compactionId: open.compactionId,
|
||||
sourceCommandId: open.sourceCommandId,
|
||||
startSeq: open.startSeq,
|
||||
turn: open.turn,
|
||||
}
|
||||
}
|
||||
validateId(event.data.compactionId, 'compact/end compactionId', fail)
|
||||
if (event.data.sourceCommandId !== undefined) {
|
||||
validateId(event.data.sourceCommandId, 'compact/end sourceCommandId', fail)
|
||||
}
|
||||
if (open === undefined) fail('compact/end has no matching compact/start')
|
||||
if (event.data.compactionId !== open.compactionId) {
|
||||
fail(`compact/end id ${event.data.compactionId} does not match compact/start id ${open.compactionId}`)
|
||||
}
|
||||
validateSourceCommandId('compact/end', event.data.sourceCommandId, open.sourceCommandId, fail)
|
||||
if (event.data.turn !== open.turn) {
|
||||
fail(`compact/end owner ${String(event.data.turn)} does not match compact/start owner ${String(open.turn)}`)
|
||||
}
|
||||
@@ -142,6 +223,8 @@ function applyCompactionTransition(
|
||||
): CompactionTrace | undefined {
|
||||
if (transition.kind === 'start') {
|
||||
return {
|
||||
compactionId: transition.compactionId,
|
||||
sourceCommandId: transition.sourceCommandId,
|
||||
startSeq: transition.startSeq,
|
||||
turn: transition.turn,
|
||||
summarized: false,
|
||||
@@ -149,6 +232,8 @@ function applyCompactionTransition(
|
||||
}
|
||||
if (transition.kind === 'summary') {
|
||||
return {
|
||||
compactionId: transition.compactionId,
|
||||
sourceCommandId: transition.sourceCommandId,
|
||||
startSeq: transition.startSeq,
|
||||
turn: transition.turn,
|
||||
summarized: true,
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
*/
|
||||
|
||||
import type { ContentBlock, TokenUsage } from '@deepseek-ai/dsh-llm'
|
||||
import type { CommandId } from '@deepseek-ai/dsh-commands/brand'
|
||||
import type { CompactionId } from './brand.ts'
|
||||
|
||||
declare module '@deepseek-ai/dsh-session' {
|
||||
interface SessionEventMap {
|
||||
@@ -16,7 +18,7 @@ declare module '@deepseek-ai/dsh-session' {
|
||||
* `compact/end`. A numbered owner is strictly enclosed by that open turn;
|
||||
* `null` identifies a standalone manual transaction between turns.
|
||||
*/
|
||||
'compact/start': { turn: number | null }
|
||||
'compact/start': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null }
|
||||
/**
|
||||
* Completed summary, its inputs, and its model call facts — log-only, no surfaceOp.
|
||||
* The summary content is in `data.summary`; the actual surface replacement
|
||||
@@ -27,6 +29,8 @@ declare module '@deepseek-ai/dsh-session' {
|
||||
* before it (`compact/prune` documents the shared protocol).
|
||||
*/
|
||||
'compact/summary': {
|
||||
compactionId: CompactionId
|
||||
sourceCommandId?: CommandId
|
||||
summary: ContentBlock[]
|
||||
shadowedRange: { start: number; end: number }
|
||||
shadowedSeqs: number[]
|
||||
@@ -62,7 +66,7 @@ declare module '@deepseek-ai/dsh-session' {
|
||||
* Marks the end of a compaction — log-only, releases the lock. Its owner
|
||||
* matches `compact/start`; `error` records an unsuccessful attempt.
|
||||
*/
|
||||
'compact/end': { turn: number | null; error?: string }
|
||||
'compact/end': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; error?: string }
|
||||
/**
|
||||
* Shadow price of one model-free prune replacement — log-only, no
|
||||
* surfaceOp. The shared shadow-price protocol: a surface `replace` event
|
||||
@@ -85,6 +89,10 @@ declare module '@deepseek-ai/dsh-session' {
|
||||
|
||||
/** Result of a successful compaction operation. */
|
||||
export interface CompactionResult {
|
||||
/** Stable identity shared by this compaction's complete durable lifecycle. */
|
||||
compactionId: CompactionId
|
||||
/** Human command that initiated this compaction, when it was manual. */
|
||||
sourceCommandId?: CommandId
|
||||
/** The seq of the appended `compact/start` event. */
|
||||
startSeq: number
|
||||
/** The seq of the appended `compact/summary` event. */
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
"src"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../util/brand"
|
||||
},
|
||||
{
|
||||
"path": "../../../vendor/cosmokit"
|
||||
},
|
||||
@@ -17,6 +20,9 @@
|
||||
{
|
||||
"path": "../../llm/llm"
|
||||
},
|
||||
{
|
||||
"path": "../../interaction/commands"
|
||||
},
|
||||
{
|
||||
"path": "../../core/session"
|
||||
},
|
||||
|
||||
13
packages/compact/compact/tsdown.config.ts
Normal file
13
packages/compact/compact/tsdown.config.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { defineConfig } from 'tsdown'
|
||||
|
||||
/** Builds each published entry as a self-contained file admitted by the package whitelist. */
|
||||
export default defineConfig([
|
||||
{
|
||||
entry: ['lib/types/index.js'], outDir: 'lib', format: ['esm'], platform: 'node', target: 'es2024',
|
||||
fixedExtension: false, outputOptions: { codeSplitting: false }, dts: false, clean: false,
|
||||
},
|
||||
{
|
||||
entry: ['lib/types/invariant.js'], outDir: 'lib', format: ['esm'], platform: 'node', target: 'es2024',
|
||||
fixedExtension: false, outputOptions: { codeSplitting: false }, dts: false, clean: false,
|
||||
},
|
||||
])
|
||||
Reference in New Issue
Block a user