import { normalizeResponsesToolHistory } from "../responses/tool-history.ts"; export const DEFAULT_RETAINED_USER_MESSAGE_TOKEN_BUDGET = 64_000; const APPROX_BYTES_PER_TOKEN = 4; const CONTEXTUAL_USER_MARKERS: ReadonlyArray = [ ["# AGENTS.md instructions", ""], ["", ""], ["", ""], ["", ""], ["", ""], ["", ""], ["", ""], ]; function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } function validMetadata(value: unknown): boolean { return ( value === undefined || value === null || (isRecord(value) && (value.turn_id === undefined || value.turn_id === null || typeof value.turn_id === "string")) ); } /** Accept only the provider-issued opaque compaction item. */ export function canonicalCompactionOutput(item: unknown): Record | undefined { if (!isRecord(item) || (item.type !== "compaction" && item.type !== "compaction_summary")) return undefined; if (typeof item.encrypted_content !== "string" || item.encrypted_content.trim() === "") return undefined; if (item.id !== undefined && item.id !== null && typeof item.id !== "string") return undefined; if (!validMetadata(item.internal_chat_message_metadata_passthrough)) return undefined; const metadata = item.internal_chat_message_metadata_passthrough; return { type: "compaction", ...(typeof item.id === "string" ? { id: item.id } : {}), encrypted_content: item.encrypted_content, ...(isRecord(metadata) ? { internal_chat_message_metadata_passthrough: typeof metadata.turn_id === "string" ? { turn_id: metadata.turn_id } : {}, } : {}), }; } export function normalizeRemoteCompactionV2PromptInput(input: readonly unknown[]): Record[] { return normalizeResponsesToolHistory(input) .filter((item): item is Record => isRecord(item)) .map((item) => structuredClone(item)); } function matchesMarkedText(text: string, start: string, end: string): boolean { const trimmed = text.trim(); return ( trimmed.slice(0, start.length).toLowerCase() === start.toLowerCase() && trimmed.slice(-end.length).toLowerCase() === end.toLowerCase() ); } function isHookPrompt(text: string): boolean { const match = /^\s*[\s\S]*<\/hook_prompt>\s*$/.exec(text); return (match?.[1] ?? match?.[2] ?? "").trim() !== ""; } function isAdditionalContext(text: string): boolean { const trimmed = text.trim(); if (!trimmed.startsWith(""); if (close < 0) return false; const key = trimmed.slice("`); } function isInternalModelContext(text: string): boolean { const trimmed = text.trim(); if (trimmed.startsWith("") && trimmed.endsWith("")) return true; return /^[\s\S]*<\/codex_internal_context>$/.test(trimmed); } function isLegacyContextWarning(text: string): boolean { const trimmed = text.trim(); return ( trimmed.startsWith("Warning: The maximum number of unified exec processes you can keep open is") || trimmed.startsWith("Warning: Your account was flagged for potentially high-risk cyber activity") || (trimmed.startsWith("Warning: apply_patch was requested via ") && trimmed.endsWith("Use the apply_patch tool instead of exec_command.")) ); } export function isContextualUserText(text: string): boolean { return ( CONTEXTUAL_USER_MARKERS.some(([start, end]) => matchesMarkedText(text, start, end)) || isAdditionalContext(text) || isInternalModelContext(text) || isLegacyContextWarning(text) ); } function retainedRealUserMessage(item: unknown): Record | undefined { if ( !isRecord(item) || (item.type !== undefined && item.type !== "message") || item.role !== "user" || !Array.isArray(item.content) ) return undefined; const content = item.content.filter((part) => { if (!isRecord(part)) return false; if (part.type !== "input_text" || typeof part.text !== "string") return true; return !isHookPrompt(part.text) && !isContextualUserText(part.text); }); return content.length > 0 ? { ...structuredClone(item), type: "message", content: structuredClone(content) } : undefined; } function approxTokenCount(value: string): number { return Math.ceil(Buffer.byteLength(value, "utf8") / APPROX_BYTES_PER_TOKEN); } function messageTextTokenCount(item: Record): number { if (!Array.isArray(item.content)) return 0; return item.content.reduce((tokens, part) => { if (!isRecord(part) || (part.type !== "input_text" && part.type !== "output_text") || typeof part.text !== "string") return tokens; return tokens + approxTokenCount(part.text); }, 0); } /** Build the replay window required by remote-v2: recent real user messages plus opaque output. */ export function buildRemoteCompactionV2Window( promptInput: readonly unknown[], compactionOutput: Record, maxTokens = DEFAULT_RETAINED_USER_MESSAGE_TOKEN_BUDGET, ): Record[] { const retained = promptInput .filter( (item) => isRecord(item) && (item.type === undefined || item.type === "message") && (item.role === "user" || item.role === "developer" || item.role === "system"), ) .map(retainedRealUserMessage) .filter((item): item is Record => item !== undefined); let remaining = Math.max(0, Math.floor(maxTokens)); const reversed: Record[] = []; for (let index = retained.length - 1; index >= 0; index--) { const item = retained[index]!; const tokens = Math.max(1, messageTextTokenCount(item)); if (tokens <= remaining) { reversed.push(item); remaining = Math.max(0, remaining - tokens); } else break; } reversed.reverse(); return [...reversed, structuredClone(compactionOutput)]; }