refactor(session-controller): remove unused inspection facade

This commit is contained in:
imccyu committed 2026-10-23 16:01:27 +08:00
1 parent d6d51be4cb
commit 0c23ad233d
5 files changed
+8 -147

No files matched your search

@@ -9,7 +9,6 @@ import { installModelSelection } from '@deepseek-ai/dsh-agent'
import type {} from '@deepseek-ai/dsh-agent-preset-registry'
import { brandString } from '@deepseek-ai/dsh-brand'
import type { Session, SessionId } from '@deepseek-ai/dsh-session'
import type { SessionInspection } from '@deepseek-ai/dsh-session-persistence'
import { SessionQueryError, type SessionObservation } from '@deepseek-ai/dsh-session-query'
import { RemoteError, remoteErrorOf } from '@deepseek-ai/dsh-typert-protocol'
import type {} from '@deepseek-ai/dsh-typert-registry'
@@ -123,40 +122,6 @@ export function apiSessionSubagentOwnershipError(sessionId: SessionId): ApiSessi
)
}
/**
* Inspect one cold Session without repairing, resuming, or publishing it.
* @param ctx - Host context carrying Session persistence.
* @param sessionId - durable Session identity.
* @param signal - optional cancellation for persistence reads.
* @returns the persisted header and complete event prefix.
*/
export async function inspectApiSession(
ctx: Context,
sessionId: SessionId,
signal?: AbortSignal,
): Promise<SessionInspection> {
try {
using observation = await ctx.sessionQuery.observeSession(sessionId, {
...(signal === undefined ? {} : { signal }),
projectionMode: 'none',
})
if (observation.header.cwd === undefined) {
throw new ApiSessionNotFound(`session "${sessionId}" not found`)
}
return {
meta: observation.header,
inheritedEventCount: observation.inheritedEventCount,
events: [...observation.events],
}
} catch (error: unknown) {
if (error instanceof SessionQueryError
&& error.code === 'SESSION_QUERY_SESSION_NOT_FOUND') {
throw new ApiSessionNotFound(`session "${sessionId}" not found`)
}
throw error
}
}
/** Owns every operation that may create, resume, or configure a Web Agent. */
export class ApiSessionAgentController {
private readonly resumes = new Map<SessionId, Promise<Agent>>()
@@ -31,7 +31,6 @@ import {
ApiSessionSubagentOwnership,
apiSessionSubagentOwnershipError,
hasApiSessionSubagentOwner,
inspectApiSession,
type ApiSessionCreated,
} from './agent.ts'
import type {
@@ -54,12 +53,6 @@ import type {
SessionRequestId,
} from './types.ts'
interface SessionReadState {
readonly id: SessionId
readonly header: SessionHeader
readonly events: readonly SessionEvent[]
}
type PromptContentCandidate =
| SessionPromptRequest['content'][number]
| Extract<SessionUpdateQueueRequest['action'], { readonly kind: 'edit' }>['content'][number]
@@ -371,11 +364,16 @@ export class SessionCommandController {
* @returns the durable attachment reference and base64-encoded bytes.
*/
async attachment(request: SessionAttachmentRequest): Promise<SessionAttachmentValue> {
let source: SessionReadState
let ref: ImageAttachmentRef | undefined
try {
source = await this.readSessionState(request.sessionId)
using observation = await this.ctx.sessionQuery.observeSession(request.sessionId, { projectionMode: 'none' })
if (observation.source === 'prepared' && observation.header.cwd === undefined) {
throw new ApiSessionNotFound(`session "${request.sessionId}" not found`)
}
ref = referencedImage(observation.events, String(request.attachmentId))
} catch (error) {
if (error instanceof ApiSessionNotFound) {
if (error instanceof ApiSessionNotFound
|| (error instanceof SessionQueryError && error.code === 'SESSION_QUERY_SESSION_NOT_FOUND')) {
throw new RemoteError('session/not-found', error.message, { sessionId: request.sessionId })
}
throw new RemoteError(
@@ -384,7 +382,6 @@ export class SessionCommandController {
{},
)
}
const ref = referencedImage(source.events, String(request.attachmentId))
if (ref === undefined) {
throw new RemoteError(
'session/attachment-invalid',
@@ -533,16 +530,6 @@ export class SessionCommandController {
throw new RemoteError('gateway/internal', `failed to create session: ${String(error)}`, {})
}
private async readSessionState(sessionId: SessionId): Promise<SessionReadState> {
const attached = this.ctx.sessions.get(sessionId)
if (attached !== undefined) {
// oxlint-disable-next-line typescript/no-deprecated -- Existing Session history read; migration deferred.
return { id: attached.id, header: attached.header, events: attached.snapshotEvents() }
}
const inspected = await inspectApiSession(this.ctx, sessionId)
return { id: inspected.meta.id, header: inspected.meta, events: inspected.events }
}
private async forkWorkspace(source: SessionHeader): Promise<Workspace | undefined> {
const workspaces = this.ctx.workspaceRegistry.list()
const direct = workspaces.find(workspace => workspace.sessionIds.includes(source.id))
@@ -10,7 +10,6 @@ import { errorChain, ReasoningEffortId, type MessageSource } from '@deepseek-ai/
import type {} from '@deepseek-ai/dsh-client-file-upload'
import { canOpenNativePath, nativeFileManager, nativeFileApplications, openNativeFileApplication, openNativeAssociatedPath, revealNativePath } from '@deepseek-ai/dsh-native-command'
import type { SessionId } from '@deepseek-ai/dsh-session'
import type { SessionInspection } from '@deepseek-ai/dsh-session-persistence'
import type {} from '@deepseek-ai/dsh-session-projection-cache'
import { SessionQueryError, type SessionObservation } from '@deepseek-ai/dsh-session-query'
import { Remote, RemoteError, TypertRemoteService, principalOf } from '@deepseek-ai/dsh-typert-protocol'
@@ -19,7 +18,6 @@ import { assertNever } from '@deepseek-ai/dsh-util-values'
import type {} from '@deepseek-ai/dsh-api-remote-access'
import {
ApiSessionAgentController,
inspectApiSession,
type ApiSessionAgentResult,
} from './agent.ts'
import { SessionCommandController, hasPromptContent } from './commands.ts'
@@ -240,28 +238,6 @@ export class SessionController extends TypertRemoteService {
return this.agents.resolveAgent(sessionId)
}
/**
* Inspect one attached or persisted Session without activating its Agent.
* @param sessionId - durable Session identity.
* @param signal - optional caller cancellation for persistence reads.
* @returns the current attached state or persisted header and event prefix.
*/
inspect(
sessionId: SessionId,
signal?: AbortSignal,
): Promise<SessionInspection> {
const attached = this.ctx.sessions.get(sessionId)
if (attached !== undefined) {
return Promise.resolve({
meta: attached.header,
inheritedEventCount: attached.inheritedEventCount,
// oxlint-disable-next-line typescript/no-deprecated -- Existing Session history read; migration deferred.
events: attached.snapshotEvents(),
})
}
return inspectApiSession(this.ctx, sessionId, signal)
}
/**
* Read all visible Session rows without resuming an Agent.
* @param _request - reserved empty list request.
@@ -614,5 +590,4 @@ export class SessionController extends TypertRemoteService {
}
export { buildModelCatalog }
export default SessionController
@@ -16,7 +16,6 @@ import {
ApiSessionAgentController,
ApiSessionCwdConflict,
ApiSessionNotFound,
inspectApiSession,
} from '../src/agent.ts'
import { installSessionReadTestServices, testSessionPersistence } from './test-remote.ts'
@@ -84,60 +83,7 @@ describe('ApiSession identity failures', () => {
.toContain('belongs to "/existing"')
})
it('maps absent and cwd-less point observations to not found', async () => {
const ctx = new Context()
roots.push(ctx)
await ctx.plugin(SessionStore)
installSessionReadTestServices(ctx)
await expect(inspectApiSession(ctx, SessionId('missing')))
.rejects.toBeInstanceOf(ApiSessionNotFound)
const inspect = vi.fn(() => Promise.resolve(undefined))
const stat = vi.fn(() => Promise.resolve(undefined))
const disposeMissing = providePersistence(ctx, {
list: () => Promise.resolve([]),
stat,
inspect,
})
await expect(inspectApiSession(ctx, SessionId('missing'))).rejects.toBeInstanceOf(ApiSessionNotFound)
// Absence is decided by the stat preflight; the log itself is never opened.
expect(stat).toHaveBeenCalledOnce()
expect(inspect).not.toHaveBeenCalled()
disposeMissing()
const listed = header('cwd-less-catalog', null)
const disposeListed = providePersistence(ctx, {
list: () => Promise.resolve([listed]),
inspect: () => Promise.resolve({ meta: listed, events: [] }),
})
await expect(inspectApiSession(ctx, listed.id)).rejects.toBeInstanceOf(ApiSessionNotFound)
disposeListed()
const catalog = header('cwd-less-inspect')
const inspected = header('cwd-less-inspect', null)
providePersistence(ctx, {
list: () => Promise.resolve([catalog]),
inspect: () => Promise.resolve({ meta: inspected, events: [] }),
})
await expect(inspectApiSession(ctx, catalog.id)).rejects.toBeInstanceOf(ApiSessionNotFound)
})
it('forwards an explicit inspection signal', async () => {
const ctx = new Context()
roots.push(ctx)
await ctx.plugin(SessionStore)
installSessionReadTestServices(ctx)
const meta = header('signalled-inspection')
const inspect = vi.fn(() => Promise.resolve({ meta, inheritedEventCount: SessionLogOffset(0), events: [] }))
providePersistence(ctx, {
list: () => Promise.resolve([meta]),
inspect,
})
const signal = new AbortController().signal
await expect(inspectApiSession(ctx, meta.id, signal)).resolves.toEqual({ meta, inheritedEventCount: SessionLogOffset(0), events: [] })
expect(inspect).toHaveBeenCalledWith(meta.id, signal)
})
})
describe('ApiSession Agent lookup and recovery', () => {
@@ -63,12 +63,6 @@ describe('SessionController facade', () => {
ctx.on('api-session/error', failure)
ctx.on('api-session/activity', activity)
await expect(controller.inspect(sessionId)).resolves.toEqual({
meta: header,
inheritedEventCount: SessionLogOffset(0),
events,
})
expect(inspect).toHaveBeenCalledOnce()
const session = ctx.sessions.create(sessionId, { meta: header })
const agent = {
@@ -91,12 +85,6 @@ describe('SessionController facade', () => {
await expect(resolveUploadAgent(sessionId)).rejects.toBe(activationError)
await expect(controller.resolveAgent(sessionId)).resolves.toEqual({ agent })
await expect(controller.inspect(sessionId)).resolves.toEqual({
meta: header,
inheritedEventCount: SessionLogOffset(0),
events,
})
expect(inspect).toHaveBeenCalledOnce()
ctx.emit('agent/status', { agent, status: 'running' })
ctx.emit('agent/error', { agent, turn: 1, step: 0, error: new Error('fixture failure') })
session.append('user/message', createUserMessage({