docs: rebalance prose cleanup and add trimming skill

This commit is contained in:
Tianyi Cui
2026-07-13 23:27:00 +08:00
parent fcdc318dda
commit 148046b9c8
392 changed files with 2801 additions and 1754 deletions

View File

@@ -34,8 +34,10 @@ declare module 'cordis' {
interface Events {
/**
* Emitted after session publication. A synchronous throw vetoes and rolls
* Creation announcement during session publication. A synchronous throw vetoes and rolls
* back with a paired disposal; detach requested during dispatch is deferred.
* A returned-promise rejection is logged but cannot retroactively veto this
* synchronous boundary.
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners
* receive only sessions entered through that agent's context.
* @param session - the session just entered and announced.
@@ -44,14 +46,17 @@ declare module 'cordis' {
'session/created'(this: Scoped<Session>, session: Session): void
/**
* Emitted once when an announced session leaves the store, including
* publication rollback. Listener failures are contained.
* publication rollback, but never for an entry whose creation announcement
* did not begin. Listener failures are logged and contained.
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`) reuses the owner scope.
* @param session - the session that is no longer live in the store.
* @mode emit
*/
'session/disposed'(this: Scoped<Session>, session: Session): void
/**
* Post-commit append feed. Observer failures are logged and contained.
* Post-commit, fire-and-forget append feed. The listener snapshot resolves
* before the log push, but callbacks run after it; observer failures are
* logged and contained without making the committed append fail.
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners
* receive only events from sessions entered through that agent's context.
* @param session - the session whose log grew.
@@ -60,7 +65,8 @@ declare module 'cordis' {
*/
'session/event'(this: Scoped<Session>, session: Session, event: SessionEvent): void
/**
* Awaited parallel durability checkpoint; dispatch through
* Awaited parallel durability checkpoint: every listener runs and the
* caller awaits all of them, with no waterfall veto. Dispatch through
* {@link SessionStore.flush}. Scope-filtered dispatch
* (`@deepseek-ai/dsh-scope`) reuses the session's owner scope.
* @param session - the session whose buffered events must reach durable storage.
@@ -70,7 +76,11 @@ declare module 'cordis' {
}
}
/** Render injected context as a tagged synthetic user-role message. */
/**
* Render injected context as tagged synthetic user-role content, keeping the
* canonical session vocabulary provider-neutral. Adapter-specific exceptions
* belong in the adapter.
*/
function renderTagged(tag: string, content: ContentBlock[], source: MessageSource): ContentBlock[] {
const open = `<${tag} source=${JSON.stringify(source.kind)}>`
const close = `</${tag}>`

View File

@@ -12,9 +12,10 @@
export type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }
/**
* Validate and detach lossless JSON in one read per property. Accepts ordinary
* arrays, plain or null-prototype objects, and JSON scalars; rejects sparse,
* cyclic, exotic, negative-zero, and non-finite values. Getter throws propagate.
* Validate and detach lossless JSON in one read per property, so a stateful
* getter cannot change between validation and copying. Accepts ordinary arrays,
* plain or null-prototype objects, and JSON scalars; rejects sparse, cyclic,
* exotic, negative-zero, and non-finite values. Getter throws propagate.
*
* @param value - the candidate value to validate and detach.
* @returns the detached snapshot, or `undefined` when the value is not

View File

@@ -1,5 +1,7 @@
/**
* Crash-recovery repair for an interrupted session log.
* Crash-recovery repair for an interrupted session log. It preserves a fully
* written final turn and supplies the missing tool, step, and turn boundaries
* needed to resume with a provider-valid transcript.
* @module @deepseek-ai/dsh-session/repair
*/
@@ -7,8 +9,10 @@ import type { CallId } from '@deepseek-ai/dsh-llm'
import type { SessionEvent } from './types.ts'
/**
* Return deterministic synthetic events that close an open tail turn or step.
* Sequences continue the log and timestamps reuse the last real event.
* Return deterministic synthetic events that close an open tail turn. Unmatched
* calls receive error results first, followed by an open `step/end` and an
* interrupted `turn/end`; sequences continue the log and timestamps reuse the
* last real event. A balanced or empty log returns no events.
*
* @param events - the loaded durable log to scan (a valid committed prefix, possibly with a crash tail).
* @returns the synthetic closer events to append after `events`, in order; empty when the log is already balanced.
@@ -16,8 +20,8 @@ import type { SessionEvent } from './types.ts'
export function interruptedTurnClosers(events: readonly SessionEvent[]): SessionEvent[] {
let openTurn: number | null = null
let openStep: number | null = null
// Track tool calls vs. their results WITHIN the currently-open turn only: a call is "pending"
// until its matching tool/result arrives.
// Reset at each turn boundary so earlier calls cannot leak into tail repair.
// Assistant blocks register calls; later tool/call events add provenance seqs.
const pendingCalls = new Map<CallId, { step: number; callSeq?: number }>()
for (const event of events) {
switch (event.type) {
@@ -46,8 +50,7 @@ export function interruptedTurnClosers(events: readonly SessionEvent[]): Session
}
break
case 'tool/call':
// Capture the tool/call event seq for surface provenance on the synthesized
// tool/result.
// Add the tool/call seq used as provenance on a synthetic result.
{
const entry = pendingCalls.get(event.data.callId)
if (entry) {
@@ -76,9 +79,8 @@ export function interruptedTurnClosers(events: readonly SessionEvent[]): Session
const time = last.time
const closers: SessionEvent[] = []
// Synthesize an error tool/result for each tool-call left unanswered by the crash, so
// deriveMessages() yields a valid provider transcript on resume (a dangling assistant
// tool-call is rejected by every provider).
// Close calls before their step: providers reject dangling assistant calls,
// and Map insertion order preserves their transcript order.
for (const [callId, { step, callSeq }] of pendingCalls) {
closers.push({
type: 'tool/result',

View File

@@ -1,6 +1,7 @@
/**
* Request-header reconstruction utilities: the pure fold/diff/apply trio over the
* `request/header` / `request/header-delta` session events.
* Request-header reconstruction utilities over `request/header` snapshots and
* `request/header-delta` events. Writers round-trip each proposed delta and use
* a full snapshot when the encoding cannot represent the change.
* @module dsh-session/request-header
*/
@@ -128,8 +129,11 @@ function sameMessages(a: readonly Message[] | undefined, b: readonly Message[] |
}
/**
* Compute the `request/header-delta` payload between two canonical headers, or undefined when
* they are equal.
* Compute the `request/header-delta` payload between two canonical headers, or
* `undefined` when they are equal. The encoding cannot represent every change,
* including pure tool reordering, so callers must apply and compare the result
* before logging it and fall back to a full snapshot on mismatch. The session
* prefix is replaced whole; an empty array removes it.
*
* @param prev - the folded header the log currently implies.
* @param next - the header the next request will actually use.

View File

@@ -23,8 +23,9 @@ const SURFACE_EVENT_TYPES = new Set<string>([
])
/**
* Check only whether a type may enter the message surface. Use
* {@link isSurfaceEvent} when the mandatory `surfaceOp` must also be present.
* Check only whether a type may enter the message surface; it does not require `surfaceOp`. This
* detects eligible seed/load events missing their mandatory marker. Use {@link isSurfaceEvent} to
* narrow a fully formed event whose marker is present.
* @param type - the event type string to test.
* @returns true when the type is one of the five message-producing types.
*/

View File

@@ -1,6 +1,7 @@
/**
* Tool-pairing balance over a session's surface: is a given cut point in the surface a safe
* edge for a collapsed region (e.g. compaction)?
* Tool-pairing balance over a session surface. Compaction changes surface
* positions, so safe cuts are derived from tool-call/result content on the
* surface rather than step markers in the append-only log.
* @module @deepseek-ai/dsh-session/tool-pairing
*/
@@ -27,10 +28,12 @@ function nodeDelta(event: SessionEvent): number {
}
/**
* Check that a surface cut does not split a tool call from its result.
* Check that a surface cut does not split a tool call from its result. A region
* is safe to collapse only when the cuts before its first node and after its
* last node both return `true`.
* @param nodes - the surface linked list in head→tail order.
* @param events - the session log each node's `seq` indexes into.
* @param beforeSeq - node immediately after the cut; absent from the surface means after-tail.
* @param beforeSeq - node immediately after the cut; `null` or a seq absent from the surface means after-tail.
* @returns whether every call before the cut has its result before the cut.
* @throws if a result appears without a preceding open call.
*/

View File

@@ -39,8 +39,8 @@ export interface SessionHeader {
/** The session this one was forked from (seed lineage), if any. */
readonly parentSession?: SessionId
/**
* How many leading events were INHERITED via a seed rather than produced by this session —
* the seed boundary.
* How many leading events were inherited through a seed. Persisting this
* boundary lets resume and replay distinguish parent history from child work.
*/
readonly seedLength?: number
}
@@ -99,6 +99,7 @@ export interface TurnEndReasonMap {
*/
error: { kind: 'error'; step: number; message: string; code?: string }
disposed: { kind: 'disposed' }
/** At least one step reached its output-token ceiling, even if a plugin continued the turn. */
'max-tokens': { kind: 'max-tokens' }
/**
* Policy blocked every prompt before the first step. The zero-step turn still
@@ -106,8 +107,8 @@ export interface TurnEndReasonMap {
*/
rejected: { kind: 'rejected'; reason: string }
/**
* The turn never ended on its own: the process crashed mid-turn and a persistence backend
* later closed the orphaned (open) turn on reload so the log stays balanced.
* A persistence backend closed a crash-orphaned turn on reload. The loop never
* emits this marker, and the events recorded before the crash remain intact.
*/
interrupted: { kind: 'interrupted' }
}
@@ -198,10 +199,10 @@ export interface ToolsDelta {
}
/**
* The session event vocabulary — the append-only source of truth for an agent's whole
* interaction history. The LLM message history is *derived* from this log; nothing else is
* authoritative. Replay = re-derive from the same events; trace/telemetry = subscribe to the
* log.
* The merge-extensible, append-only source of truth for an agent interaction.
* Message history is derived from this log. Every event is lossless JSON and
* sequence numbers stay contiguous, including raw chunks, so persistence can
* store the canonical log verbatim.
*/
export interface SessionEventMap {
/**
@@ -224,8 +225,8 @@ export interface SessionEventMap {
/** A user-visible prompt (queued message drained at turn start). */
'user/message': { content: ContentBlock[]; source: MessageSource }
/**
* A queued prompt an `agent/prompt-submit` listener VETOED — the durable record of a blocked
* prompt and why.
* Durable record of a prompt veto and its reason. It is log-only: the blocked
* prompt never enters the model-visible surface, including in a mixed batch.
*/
'prompt/blocked': { content: ContentBlock[]; source: MessageSource; reason: string }
/**
@@ -262,24 +263,19 @@ export interface SessionEventMap {
/** Steering content injected between steps of a running turn. */
'steering/message': { turn: number; content: ContentBlock[]; source: MessageSource }
/**
* The agent's whole todo list, carried as a full snapshot and replaced wholesale on each
* write — the current list is the most recent `todo/write` (last-write-wins on replay, no
* fold). Appended by an owning agent via `session.append('todo/write', { todos })`.
* Whole-list snapshot; the latest write wins on replay. It is log-only UI
* state and never enters derived model history.
*/
'todo/write': { todos: TodoItem[] }
/**
* Full snapshot of the {@link EpochHeader} the NEXT request is built under, with the {@link
* RequestHeaderReason} it was recorded whole.
* Full {@link EpochHeader} for the next request, appended inside its step
* before dispatch. It is log-only and anchors subsequent deltas.
*/
'request/header': { header: EpochHeader; reason: RequestHeaderReason }
/**
* Amendment to the folded {@link EpochHeader}: at least one of a {@link SystemDelta}, a
* {@link ToolsDelta}, a whole replacement {@link LlmCallConfig} (four scalars — not worth
* diffing), or a whole replacement session prefix (`messagePrefix` — small advisory content,
* replaced whole; an EMPTY array encodes the transition to "none", mirroring the canonical
* form's absent field — the loop never produces one in practice: the prefix is composed once
* per instance and anchored by that instance's snapshot, so this arm exists for codec
* totality).
* Log-only amendment to the folded {@link EpochHeader}. System and tools use
* their delta codecs; config and prefix replace whole, with an empty prefix
* encoding removal. Writers verify round-trip equality or log a fallback snapshot.
*/
'request/header-delta': { system?: SystemDelta; tools?: ToolsDelta; config?: LlmCallConfig; messagePrefix?: Message[] }
}