feat: wire context-window-recovery callers to async SDK/HTTP variants on SQLite
- empty-content-recovery: isSqliteBackend() branch delegating to extracted empty-content-recovery-sdk.ts with SDK message scanning - message-builder: sanitizeEmptyMessagesBeforeSummarize now async with SDK path using replaceEmptyTextPartsAsync/injectTextPartAsync - target-token-truncation: truncateUntilTargetTokens now async with SDK path using findToolResultsBySizeFromSDK/truncateToolResultAsync - aggressive-truncation-strategy: passes client to truncateUntilTargetTokens - summarize-retry-strategy: await sanitizeEmptyMessagesBeforeSummarize - client.ts: derive Client from PluginInput['client'] instead of manual defs - executor.test.ts: .mockReturnValue() → .mockResolvedValue() for async fns - storage.test.ts: add await for async truncateUntilTargetTokens
This commit is contained in:
@@ -1,5 +1,24 @@
|
||||
import type { PluginInput } from "@opencode-ai/plugin"
|
||||
import type { AggressiveTruncateResult } from "./tool-part-types"
|
||||
import { findToolResultsBySize, truncateToolResult } from "./tool-result-storage"
|
||||
import { findToolResultsBySizeFromSDK, truncateToolResultAsync } from "./tool-result-storage-sdk"
|
||||
import { isSqliteBackend } from "../../shared/opencode-storage-detection"
|
||||
|
||||
type OpencodeClient = PluginInput["client"]
|
||||
|
||||
interface SDKToolPart {
|
||||
id: string
|
||||
type: string
|
||||
tool?: string
|
||||
state?: { output?: string }
|
||||
truncated?: boolean
|
||||
originalSize?: number
|
||||
}
|
||||
|
||||
interface SDKMessage {
|
||||
info?: { id?: string }
|
||||
parts?: SDKToolPart[]
|
||||
}
|
||||
|
||||
function calculateTargetBytesToRemove(
|
||||
currentTokens: number,
|
||||
@@ -13,13 +32,14 @@ function calculateTargetBytesToRemove(
|
||||
return { tokensToReduce, targetBytesToRemove }
|
||||
}
|
||||
|
||||
export function truncateUntilTargetTokens(
|
||||
export async function truncateUntilTargetTokens(
|
||||
sessionID: string,
|
||||
currentTokens: number,
|
||||
maxTokens: number,
|
||||
targetRatio: number = 0.8,
|
||||
charsPerToken: number = 4
|
||||
): AggressiveTruncateResult {
|
||||
charsPerToken: number = 4,
|
||||
client?: OpencodeClient
|
||||
): Promise<AggressiveTruncateResult> {
|
||||
const { tokensToReduce, targetBytesToRemove } = calculateTargetBytesToRemove(
|
||||
currentTokens,
|
||||
maxTokens,
|
||||
@@ -38,6 +58,82 @@ export function truncateUntilTargetTokens(
|
||||
}
|
||||
}
|
||||
|
||||
if (client && isSqliteBackend()) {
|
||||
let toolPartsByKey = new Map<string, SDKToolPart>()
|
||||
try {
|
||||
const response = (await client.session.messages({
|
||||
path: { id: sessionID },
|
||||
})) as { data?: SDKMessage[] }
|
||||
const messages = response.data ?? []
|
||||
toolPartsByKey = new Map<string, SDKToolPart>()
|
||||
|
||||
for (const message of messages) {
|
||||
const messageID = message.info?.id
|
||||
if (!messageID || !message.parts) continue
|
||||
for (const part of message.parts) {
|
||||
if (part.type !== "tool") continue
|
||||
toolPartsByKey.set(`${messageID}:${part.id}`, part)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
toolPartsByKey = new Map<string, SDKToolPart>()
|
||||
}
|
||||
|
||||
const results = await findToolResultsBySizeFromSDK(client, sessionID)
|
||||
|
||||
if (results.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
sufficient: false,
|
||||
truncatedCount: 0,
|
||||
totalBytesRemoved: 0,
|
||||
targetBytesToRemove,
|
||||
truncatedTools: [],
|
||||
}
|
||||
}
|
||||
|
||||
let totalRemoved = 0
|
||||
let truncatedCount = 0
|
||||
const truncatedTools: Array<{ toolName: string; originalSize: number }> = []
|
||||
|
||||
for (const result of results) {
|
||||
const part = toolPartsByKey.get(`${result.messageID}:${result.partId}`)
|
||||
if (!part) continue
|
||||
|
||||
const truncateResult = await truncateToolResultAsync(
|
||||
client,
|
||||
sessionID,
|
||||
result.messageID,
|
||||
result.partId,
|
||||
part
|
||||
)
|
||||
if (truncateResult.success) {
|
||||
truncatedCount++
|
||||
const removedSize = truncateResult.originalSize ?? result.outputSize
|
||||
totalRemoved += removedSize
|
||||
truncatedTools.push({
|
||||
toolName: truncateResult.toolName ?? result.toolName,
|
||||
originalSize: removedSize,
|
||||
})
|
||||
|
||||
if (totalRemoved >= targetBytesToRemove) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const sufficient = totalRemoved >= targetBytesToRemove
|
||||
|
||||
return {
|
||||
success: truncatedCount > 0,
|
||||
sufficient,
|
||||
truncatedCount,
|
||||
totalBytesRemoved: totalRemoved,
|
||||
targetBytesToRemove,
|
||||
truncatedTools,
|
||||
}
|
||||
}
|
||||
|
||||
const results = findToolResultsBySize(sessionID)
|
||||
|
||||
if (results.length === 0) {
|
||||
|
||||
Reference in New Issue
Block a user