feat: implement SDK/HTTP pruning for deduplication and tool-output truncation on SQLite
- executeDeduplication: now async, reads messages from SDK on SQLite via client.session.messages() instead of JSON file reads - truncateToolOutputsByCallId: now async, uses truncateToolResultAsync() HTTP PATCH on SQLite instead of file-based truncateToolResult() - deduplication-recovery: passes client through to both functions - recovery-hook: passes ctx.client to attemptDeduplicationRecovery Removes the last intentional feature gap on SQLite backend — dynamic context pruning (dedup + tool-output truncation) now works on both JSON and SQLite storage backends.
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
import { readdirSync, readFileSync } from "node:fs"
|
||||
import { join } from "node:path"
|
||||
import type { PluginInput } from "@opencode-ai/plugin"
|
||||
import type { PruningState, ToolCallSignature } from "./pruning-types"
|
||||
import { estimateTokens } from "./pruning-types"
|
||||
import { log } from "../../shared/logger"
|
||||
import { getMessageDir } from "../../shared/opencode-message-dir"
|
||||
import { isSqliteBackend } from "../../shared/opencode-storage-detection"
|
||||
|
||||
type OpencodeClient = PluginInput["client"]
|
||||
|
||||
export interface DeduplicationConfig {
|
||||
enabled: boolean
|
||||
protectedTools?: string[]
|
||||
@@ -45,7 +48,6 @@ function sortObject(obj: unknown): unknown {
|
||||
}
|
||||
|
||||
function readMessages(sessionID: string): MessagePart[] {
|
||||
if (isSqliteBackend()) return []
|
||||
const messageDir = getMessageDir(sessionID)
|
||||
if (!messageDir) return []
|
||||
|
||||
@@ -67,20 +69,29 @@ function readMessages(sessionID: string): MessagePart[] {
|
||||
return messages
|
||||
}
|
||||
|
||||
export function executeDeduplication(
|
||||
async function readMessagesFromSDK(client: OpencodeClient, sessionID: string): Promise<MessagePart[]> {
|
||||
try {
|
||||
const response = await client.session.messages({ path: { id: sessionID } })
|
||||
const rawMessages = (response.data ?? []) as Array<{ parts?: ToolPart[] }>
|
||||
return rawMessages.filter((m) => m.parts) as MessagePart[]
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
export async function executeDeduplication(
|
||||
sessionID: string,
|
||||
state: PruningState,
|
||||
config: DeduplicationConfig,
|
||||
protectedTools: Set<string>
|
||||
): number {
|
||||
if (isSqliteBackend()) {
|
||||
log("[pruning-deduplication] Skipping deduplication on SQLite backend")
|
||||
return 0
|
||||
}
|
||||
|
||||
protectedTools: Set<string>,
|
||||
client?: OpencodeClient,
|
||||
): Promise<number> {
|
||||
if (!config.enabled) return 0
|
||||
|
||||
const messages = readMessages(sessionID)
|
||||
const messages = (client && isSqliteBackend())
|
||||
? await readMessagesFromSDK(client, sessionID)
|
||||
: readMessages(sessionID)
|
||||
|
||||
const signatures = new Map<string, ToolCallSignature[]>()
|
||||
|
||||
let currentTurn = 0
|
||||
|
||||
Reference in New Issue
Block a user