refactor(session): remove synthetic log-only turns

This commit is contained in:
_Kerman
2026-07-28 14:41:51 +08:00
parent 4c6fb8b957
commit cee0666a4d
83 changed files with 355 additions and 819 deletions

View File

@@ -9,10 +9,8 @@ import type { Branded } from '@deepseek-ai/dsh-brand'
import { deepFreeze, isAgentLoopRequest } from '@deepseek-ai/dsh-llm'
import type { GenerateOptions } from '@deepseek-ai/dsh-llm'
import type {
OutOfBandSessionEventType,
Session,
SessionEvent,
SessionEventMap,
} from '@deepseek-ai/dsh-session'
import { fallbackSessionTitle, normalizeSessionTitle } from './normalize.ts'
@@ -82,11 +80,6 @@ declare module 'cordis' {
}
declare module '@deepseek-ai/dsh-session' {
interface TurnTriggerMap {
/** Zero-step turn opened only to durably append a late title update. */
'session-title': { kind: 'session-title' }
}
interface SessionEventMap {
/**
* Latest-wins session title snapshot. Log-only: it never enters the model
@@ -94,50 +87,6 @@ declare module '@deepseek-ai/dsh-session' {
*/
'session/title': SessionTitleEventData
}
interface OutOfBandSessionEventMap {
'session/title': true
}
}
/** Per-session settlement tails for title-capability out-of-band writes. */
const SESSION_TITLE_WRITE_TAILS = new WeakMap<Session, Promise<void>>()
/** Convert either write outcome into a fulfilled queue tail. */
function settleSessionTitleWrite(): void {}
/**
* Serialize one title-capability out-of-band event with its session peers.
* Cancellation is checked when the write reaches the head of the queue; once
* the core append starts, its durability contract runs to completion.
* @param ctx - context exposing the live session store.
* @param session - exact live session that owns the title-capability event.
* @param type - plugin-declared log-only title event type.
* @param data - typed JSON payload for the event.
* @param signal - service or provider lifetime checked before publication starts.
* @returns the durably accepted event.
*/
export async function appendSessionTitleOutOfBand<T extends OutOfBandSessionEventType>(
ctx: Context,
session: Session,
type: T,
data: SessionEventMap[T],
signal: AbortSignal,
): Promise<SessionEvent<T>> {
const predecessor = SESSION_TITLE_WRITE_TAILS.get(session)
const run = Promise.resolve(predecessor).then(() => {
signal.throwIfAborted()
return ctx.sessions.appendOutOfBand(session, type, data, { kind: 'session-title' })
})
const tail = run.then(settleSessionTitleWrite, settleSessionTitleWrite)
SESSION_TITLE_WRITE_TAILS.set(session, tail)
try {
return await run
} finally {
if (SESSION_TITLE_WRITE_TAILS.get(session) === tail) {
SESSION_TITLE_WRITE_TAILS.delete(session)
}
}
}
/** One eligible human text message exposed to title providers. */
@@ -163,7 +112,7 @@ export interface SessionTitleProviderRequest {
readonly signal: AbortSignal
}
/** Provider output before service-owned normalization and durable acceptance. */
/** Provider output before service-owned normalization and log acceptance. */
export interface SessionTitleProviderResult {
/** Proposed title text. */
readonly title: string
@@ -360,7 +309,7 @@ export class SessionTitleService extends Service {
* Explicitly retry the registered provider, or materialize the built-in
* fallback when no provider is registered.
* @param session - exact live session to refresh.
* @param signal - optional caller cancellation; an in-progress fallback append may finish durably before rejection.
* @param signal - optional caller cancellation.
* @returns latest accepted title, or `undefined` when no eligible text exists.
*/
async refresh(session: Session, signal?: AbortSignal): Promise<SessionTitleSnapshot | undefined> {
@@ -509,7 +458,7 @@ export class SessionTitleService extends Service {
return this.track(run, work.registration)
}
/** Execute and durably accept one current provider revision. */
/** Execute and accept one current provider revision. */
private async runProvider(
session: Session,
work: ActiveProviderWork,
@@ -528,7 +477,7 @@ export class SessionTitleService extends Service {
})
this.assertCurrent(session, work)
const accepted = this.validateResult(result, messages)
await appendSessionTitleOutOfBand(this.ctx, session, 'session/title', {
session.append('session/title', {
title: accepted.title,
messageSeqs: [...accepted.messageSeqs],
source: {
@@ -536,7 +485,7 @@ export class SessionTitleService extends Service {
provider: work.registration.provider.id,
...accepted.model === undefined ? {} : { model: accepted.model },
},
}, work.signal)
})
return this.get(session)
} finally {
const state = this.work.get(session)
@@ -711,11 +660,20 @@ export class SessionTitleService extends Service {
if (title.length === 0) return undefined
const state = this.stateFor(session)
if (state.fallback !== undefined) return state.fallback
const fallback = appendSessionTitleOutOfBand(this.ctx, session, 'session/title', {
title,
messageSeqs: [first.seq],
source: { kind: 'fallback' },
}, this.lifetime.signal).then(() => this.get(session))
const fallback = Promise.resolve().then(() => {
this.assertServiceActive()
if (this.ctx.sessions.get(session.id) !== session) {
throw new Error(`session "${session.id}" is not live in this store`)
}
const accepted = this.get(session)
if (accepted !== undefined) return accepted
session.append('session/title', {
title,
messageSeqs: [first.seq],
source: { kind: 'fallback' },
})
return this.get(session)
})
state.fallback = fallback
try {
return await fallback