mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
fix(tui,host): project the human transcript from append-origin events
The terminal and history pagination both treated the model-visible surface as the human transcript. A landed compaction replacement therefore erased the conversation it summarized — messages the reader had already seen — and a model-only replacement copy consumed a page's `maxMessages` quota, which could also split a compaction's provenance from the replacement citing it. `dsh-session` now exports the marker split `isAppendSurfaceEvent` / `isReplacementSurfaceEvent`. The terminal replays append-origin surface events, keeps a shadowed step's tool cards paired through its append-origin assistant message, and renders one dim marker where a compaction landed; the checkpoint is recognized through the compaction seam's `isCompactCheckpointSource` contract, not the shape of the replacement. `session.history` counts only append-origin human messages. Everything model-facing keeps reading `session.surface`.
This commit is contained in:
@@ -27,7 +27,7 @@ export { interruptedTurnClosers, TOOL_NOT_STARTED, TOOL_OUTCOME_UNKNOWN } from '
|
||||
export { decodeStorageRecord, packChunkRuns } from './chunk-rows.ts'
|
||||
export type { ChunkRow, StorageRecord } from './chunk-rows.ts'
|
||||
export type { SessionSurface, SurfaceFoldReplacement, SurfaceFoldResult } from './surface.ts'
|
||||
export { foldSurface, isSurfaceEvent, isSurfaceEligibleType } from './surface.ts'
|
||||
export { foldSurface, isAppendSurfaceEvent, isReplacementSurfaceEvent, isSurfaceEvent, isSurfaceEligibleType } from './surface.ts'
|
||||
export { canonicalHeader, foldRequestHeader, headerEquals } from './request-header.ts'
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,6 +37,36 @@ export function isSurfaceEvent(event: SessionEvent): event is SurfaceEvent {
|
||||
return (event as SessionEvent<SurfaceEventType>).surfaceOp !== undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Narrow an event to an append-origin surface event: one that entered the
|
||||
* surface at its own log position and was never itself a replacement copy.
|
||||
*
|
||||
* The model-visible surface deliberately shadows replaced ranges, so it is the
|
||||
* wrong source for a human transcript — a landed replacement would erase
|
||||
* conversation the user already saw. Append-origin events are that transcript's
|
||||
* durable source material; replacement copies stay model-only.
|
||||
* @param event - event to test.
|
||||
* @returns true when the event appended to the surface tail.
|
||||
*/
|
||||
export function isAppendSurfaceEvent(
|
||||
event: SessionEvent,
|
||||
): event is SurfaceEvent & { surfaceOp: 'append' } {
|
||||
return isSurfaceEvent(event) && event.surfaceOp === 'append'
|
||||
}
|
||||
|
||||
/**
|
||||
* Narrow an event to a surface replacement: a node that shadowed an existing
|
||||
* surface range instead of appending to the tail. The counterpart of
|
||||
* {@link isAppendSurfaceEvent} over the two {@link SurfaceOp} variants.
|
||||
* @param event - event to test.
|
||||
* @returns true when the event replaced a surface range.
|
||||
*/
|
||||
export function isReplacementSurfaceEvent(
|
||||
event: SessionEvent,
|
||||
): event is SurfaceEvent & { surfaceOp: { op: 'replace'; start: number; end: number } } {
|
||||
return isSurfaceEvent(event) && event.surfaceOp !== 'append'
|
||||
}
|
||||
|
||||
/** One replacement operation observed while folding a session surface. */
|
||||
export interface SurfaceFoldReplacement {
|
||||
/** Seq of the event that replaced the prior surface range. */
|
||||
|
||||
Reference in New Issue
Block a user