refactor(codex): move the compaction body out of the adapter

The merge put codex-structured-session-adapter.ts over max-lines by
composition: main's rewind trio and this branch's background-terminal surface
are each compliant alone — 299 of 300 on both sides — and together they are
315. Neither side is in breach; the file simply has no room left.

Extracting `compact` completes a pattern the file already uses rather than
introducing one. The adapter is a delegation hub: the background-terminal
surface is a channel object, the rewind methods are one-line delegations to
codex-structured-rewind, and `compact` was the one member still carrying a
body of any size. It moves to its own module and the adapter keeps a
delegation like everything around it.

Chosen over extracting main's freshly-landed rewind code, which was the first
plan: that saved only 3 of the 15 lines needed, and pushed
codex-structured-rewind.ts over its own cap in turn. Extracting compact alone
lands the adapter at 298 and leaves main's rewind code untouched.

Its own commit, kept out of the merge so it can be reviewed and reverted on
its own terms.
This commit is contained in:
Merge Sim
2026-09-07 13:57:26 -07:00
parent eb31e33abe
commit a5ab7c78a4
2 changed files with 57 additions and 28 deletions
@@ -0,0 +1,46 @@
import { isCodexAppServerRequestError } from './codex-app-server-connection'
import type { StructuredSessionCompaction } from '../native-chat/agent-session-wire/structured-session-compaction'
import type { CodexStructuredTurnCancellation } from './codex-structured-turn-cancellation'
import type { CodexSession } from './codex-structured-session-state'
import type { StructuredAgentSessionAdapter } from '../native-chat/agent-session-wire/structured-agent-session-adapter'
/**
* Runs a compaction against the app-server, through the shared compaction
* bookkeeping that dedupes and settles late results.
*
* Lives outside the adapter for the same reason the background-terminal and
* rewind surfaces do: the adapter is a delegation hub, and a method with a body
* this size is the odd one out rather than the norm.
*/
export function compactCodexSession(args: {
compactions: StructuredSessionCompaction
turnCancellation: CodexStructuredTurnCancellation
session: CodexSession
requestTimeoutMs: number | undefined
input: Parameters<NonNullable<StructuredAgentSessionAdapter['compact']>>[0]
}): ReturnType<StructuredSessionCompaction['run']> {
const { compactions, input, requestTimeoutMs, session, turnCancellation } = args
return compactions.run(
input.sessionId,
session.threadId,
async () => {
await turnCancellation.captureBaseline(session)
return session.connection
.request(
'thread/compact/start',
{ threadId: session.threadId },
{ timeoutMs: requestTimeoutMs }
)
.catch((error) => {
// A refusal is a compaction outcome, not a transport failure: report
// it back rather than tearing down the session.
if (isCodexAppServerRequestError(error)) {
return { error: error.message }
}
throw error
})
},
input.onLateResult,
input.turnId
)
}
@@ -1,10 +1,10 @@
import { compactCodexSession } from './codex-structured-compact'
import * as codexRewind from './codex-structured-rewind'
import type {
AgentJournalMessageItem,
AgentSessionJournalIdentity
} from '../../shared/agent-session-journal-types'
import { StructuredSessionCompaction } from '../native-chat/agent-session-wire/structured-session-compaction'
import { isCodexAppServerRequestError } from './codex-app-server-connection'
import {
createCodexBackgroundTerminalChannel,
type CodexBackgroundTerminalChannel
@@ -212,9 +212,8 @@ export class CodexStructuredSessionAdapter implements StructuredAgentSessionAdap
backgroundTaskState = (sessionId: string) => this.backgroundTerminals.state(sessionId)
stopBackgroundTasks: NonNullable<StructuredAgentSessionAdapter['stopBackgroundTasks']> = (
input
) => this.backgroundTerminals.stop(input)
stopBackgroundTasks: CodexBackgroundTerminalChannel['stop'] = (input) =>
this.backgroundTerminals.stop(input)
rewindSupport: NonNullable<StructuredAgentSessionAdapter['rewindSupport']> = (sessionId) =>
this.sessions.get(sessionId)?.historyMode === 'legacy'
@@ -227,30 +226,14 @@ export class CodexStructuredSessionAdapter implements StructuredAgentSessionAdap
recoverRewind: NonNullable<StructuredAgentSessionAdapter['recoverRewind']> = (input) =>
codexRewind.recoverCodexRewind(this.session(input.sessionId), input, this.deps.requestTimeoutMs)
compact: NonNullable<StructuredAgentSessionAdapter['compact']> = (input) => {
const session = this.session(input.sessionId)
return this.compactions.run(
input.sessionId,
session.threadId,
async () => {
await this.turnCancellation.captureBaseline(session)
return session.connection
.request(
'thread/compact/start',
{ threadId: session.threadId },
{ timeoutMs: this.deps.requestTimeoutMs }
)
.catch((error) => {
if (isCodexAppServerRequestError(error)) {
return { error: error.message }
}
throw error
})
},
input.onLateResult,
input.turnId
)
}
compact: NonNullable<StructuredAgentSessionAdapter['compact']> = (input) =>
compactCodexSession({
compactions: this.compactions,
turnCancellation: this.turnCancellation,
session: this.session(input.sessionId),
requestTimeoutMs: this.deps.requestTimeoutMs,
input
})
async answerPrompt(input: {
sessionId: string