feat(session): project the inherited-history boundary into the log
A plugin owning a standalone open/close bracket cannot tell a dead marker from a live one: an unmatched `compact/start` reads identically whether the previous writer died mid-compaction or a compaction is running now. `Session.firstLiveSeq` already holds that answer exactly, but only in memory. Append the log-only `session/inherited` event at that seq from the seeded constructor — the single waist all six seeded-start paths pass through (resume, configured startup on a persisted id, `sessions.fork()`, a subagent fork child, `adopt()`'s live prefix, and a bare seeded `create`). Read it through the new `isInheritedSeq(events, seq)`. The constructor placement means persistence needs no changes: the marker is already in `events` when a backend captures the creation seed, so it rides the ordinary seed path with no load-time write. It also covers fork, where the inherited bracket's owner may still be running — the case a persistence-layer boundary could not reach. Activity ordering excludes the boundary through `lastActivityTime()`, since lazy resume makes browsing a pickup and the three call sites would otherwise float every opened session to the top of a picker or list.
This commit is contained in:
@@ -23,6 +23,7 @@ import {
|
||||
type AgentLlmTarget,
|
||||
} from '@deepseek-ai/dsh-agent'
|
||||
import type { LlmModelInfo, LlmModelReasoningInfo, ReasoningEffortId } from '@deepseek-ai/dsh-llm'
|
||||
import { lastActivityTime } from '@deepseek-ai/dsh-session'
|
||||
import type { SessionId } from '@deepseek-ai/dsh-session'
|
||||
import { foldGoal, type GoalPhase } from '@deepseek-ai/dsh-goal'
|
||||
import { foldSessionTitle } from '@deepseek-ai/dsh-session-title'
|
||||
@@ -512,7 +513,8 @@ export function summarizeResumeCandidate(
|
||||
return {
|
||||
record,
|
||||
title,
|
||||
lastActivityAt: snapshot.events.at(-1)?.time ?? snapshot.session.createdAt,
|
||||
// Excludes a prior pickup's boundary, or every browsed session floats up.
|
||||
lastActivityAt: lastActivityTime(snapshot.events) ?? snapshot.session.createdAt,
|
||||
lastTurn: resumeTurnLabel(snapshot),
|
||||
currentWorkspace: record.header.cwd === cwd,
|
||||
workspaceLabel: formatWorkspace(record.header.cwd),
|
||||
|
||||
@@ -35,6 +35,7 @@ import type { ContentBlock, MessageId } from '@deepseek-ai/dsh-llm'
|
||||
import type {} from '@deepseek-ai/dsh-llm-retry'
|
||||
import { renderPrompt } from '@deepseek-ai/dsh-system-prompt'
|
||||
import {
|
||||
lastActivityTime,
|
||||
SessionId,
|
||||
type SessionEvent,
|
||||
type UserMessage,
|
||||
@@ -985,7 +986,7 @@ export function createTuiChat(
|
||||
const systemPrompt = displayText(renderPrompt(assembly)) || '(empty)'
|
||||
const registeredTools = assembly.tools.map(tool => displayText(tool.name)).join(', ') || '(none)'
|
||||
const events = agent.session.events
|
||||
const latestActivity = events.at(-1)?.time ?? agent.session.header.createdAt
|
||||
const latestActivity = lastActivityTime(events) ?? agent.session.header.createdAt
|
||||
const usedContext = Math.max(0, Math.round(ctx.tokenMeter.measure(agent.session).totalTokens))
|
||||
let context = `${formatDiagnosticNumber(usedContext)} used · capacity unknown`
|
||||
const contextWindow = modelController.contextWindow()
|
||||
|
||||
Reference in New Issue
Block a user