84 lines
2.1 KiB
TypeScript
84 lines
2.1 KiB
TypeScript
import { existsSync, readdirSync, readFileSync } from "node:fs"
|
|
import { join } from "node:path"
|
|
import { getOpenCodeStorageDir } from "../../shared/data-path"
|
|
import { truncateToolResult } from "./storage"
|
|
import { log } from "../../shared/logger"
|
|
import { getMessageDir } from "../../shared/opencode-message-dir"
|
|
|
|
interface StoredToolPart {
|
|
type?: string
|
|
callID?: string
|
|
truncated?: boolean
|
|
state?: {
|
|
output?: string
|
|
}
|
|
}
|
|
|
|
function getMessageStorage(): string {
|
|
return join(getOpenCodeStorageDir(), "message")
|
|
}
|
|
|
|
function getPartStorage(): string {
|
|
return join(getOpenCodeStorageDir(), "part")
|
|
}
|
|
|
|
function getMessageIds(sessionID: string): string[] {
|
|
const messageDir = getMessageDir(sessionID)
|
|
if (!messageDir) return []
|
|
|
|
const messageIds: string[] = []
|
|
for (const file of readdirSync(messageDir)) {
|
|
if (!file.endsWith(".json")) continue
|
|
messageIds.push(file.replace(".json", ""))
|
|
}
|
|
|
|
return messageIds
|
|
}
|
|
|
|
export function truncateToolOutputsByCallId(
|
|
sessionID: string,
|
|
callIds: Set<string>,
|
|
): { truncatedCount: number } {
|
|
if (callIds.size === 0) return { truncatedCount: 0 }
|
|
|
|
const messageIds = getMessageIds(sessionID)
|
|
if (messageIds.length === 0) return { truncatedCount: 0 }
|
|
|
|
let truncatedCount = 0
|
|
|
|
for (const messageID of messageIds) {
|
|
const partDir = join(getPartStorage(), messageID)
|
|
if (!existsSync(partDir)) continue
|
|
|
|
for (const file of readdirSync(partDir)) {
|
|
if (!file.endsWith(".json")) continue
|
|
const partPath = join(partDir, file)
|
|
|
|
try {
|
|
const content = readFileSync(partPath, "utf-8")
|
|
const part = JSON.parse(content) as StoredToolPart
|
|
|
|
if (part.type !== "tool" || !part.callID) continue
|
|
if (!callIds.has(part.callID)) continue
|
|
if (!part.state?.output || part.truncated) continue
|
|
|
|
const result = truncateToolResult(partPath)
|
|
if (result.success) {
|
|
truncatedCount++
|
|
}
|
|
} catch {
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
|
|
if (truncatedCount > 0) {
|
|
log("[auto-compact] pruned duplicate tool outputs", {
|
|
sessionID,
|
|
truncatedCount,
|
|
})
|
|
}
|
|
|
|
return { truncatedCount }
|
|
}
|