Files
oh-my-opencode/src/hooks/anthropic-context-window-limit-recovery/message-builder.ts
T
YeonGyu-Kim 161d6e4159 refactor(context-window-recovery): split executor and storage into focused modules
Extract recovery strategies and storage management:
- recovery-strategy.ts, aggressive-truncation-strategy.ts
- summarize-retry-strategy.ts, target-token-truncation.ts
- empty-content-recovery.ts, message-builder.ts
- tool-result-storage.ts, storage-paths.ts, state.ts
- client.ts, tool-part-types.ts
2026-02-08 16:22:01 +09:00

74 lines
2.0 KiB
TypeScript

import { log } from "../../shared/logger"
import {
findEmptyMessages,
injectTextPart,
replaceEmptyTextParts,
} from "../session-recovery/storage"
import type { Client } from "./client"
export const PLACEHOLDER_TEXT = "[user interrupted]"
export function sanitizeEmptyMessagesBeforeSummarize(sessionID: string): number {
const emptyMessageIds = findEmptyMessages(sessionID)
if (emptyMessageIds.length === 0) {
return 0
}
let fixedCount = 0
for (const messageID of emptyMessageIds) {
const replaced = replaceEmptyTextParts(messageID, PLACEHOLDER_TEXT)
if (replaced) {
fixedCount++
} else {
const injected = injectTextPart(sessionID, messageID, PLACEHOLDER_TEXT)
if (injected) {
fixedCount++
}
}
}
if (fixedCount > 0) {
log("[auto-compact] pre-summarize sanitization fixed empty messages", {
sessionID,
fixedCount,
totalEmpty: emptyMessageIds.length,
})
}
return fixedCount
}
export function formatBytes(bytes: number): string {
if (bytes < 1024) return `${bytes}B`
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`
}
export async function getLastAssistant(
sessionID: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
client: any,
directory: string,
): Promise<Record<string, unknown> | null> {
try {
const resp = await (client as Client).session.messages({
path: { id: sessionID },
query: { directory },
})
const data = (resp as { data?: unknown[] }).data
if (!Array.isArray(data)) return null
const reversed = [...data].reverse()
const last = reversed.find((m) => {
const msg = m as Record<string, unknown>
const info = msg.info as Record<string, unknown> | undefined
return info?.role === "assistant"
})
if (!last) return null
return (last as { info?: Record<string, unknown> }).info ?? null
} catch {
return null
}
}