Files
goodbuddy/src/main/agent/tool-operation-summary.ts
T
mesalogo 0d7ba55a50 fix: preserve tool details and prevent repeated history growth
Show bounded operation summaries for Continue, DeepSeek Harness and direct-model tools, retaining input details across incremental updates. Use one canonical workspace path for DeepSeek Host startup and ACP sessions so equivalent Windows paths reuse a working Runtime.

Compare persisted subagent tool fields by value, release terminal task caches, and avoid rebuilding caches for duplicate remote events. Upgrade to schema 35 to recompact repeated schema-34 tool blocks while preserving events and provenance. Include regression coverage, validation records and temporary-resource test exclusions.

Validation: 4155 tests passed, 66 skipped; typecheck and lint passed. Full desktop real-model validation covered all three tool-summary paths and both Windows path spellings. Storage validation evidence includes local and remote tool workloads and real database upgrade checks.

Release note: Tool records now show paths, commands and search details across runtimes. Fix DeepSeek Windows workspace failures and repeated subagent history growth; schema 35 reclaims redundant history data while preserving execution records, and older clients cannot reopen the upgraded database.
2026-09-14 00:34:51 +08:00

35 lines
1.3 KiB
TypeScript

// Kept self-contained so the Continue host can use it before truncating input.
export function toolOperationSummary(
input: unknown,
title?: unknown
): string | undefined {
const singleLine = (value: unknown): string =>
typeof value === 'string'
? [...value].map((character) => {
const code = character.charCodeAt(0)
return code <= 31 || code === 127 ? ' ' : character
}).join('').replace(/\s+/gu, ' ').trim()
: ''
const nativeTitle = singleLine(title)
if (nativeTitle) return nativeTitle.slice(0, 240)
if (typeof input === 'string') {
try {
input = JSON.parse(input)
} catch {
return undefined
}
}
if (!input || typeof input !== 'object' || Array.isArray(input)) return undefined
const args = input as Record<string, unknown>
const first = (keys: string[]): string =>
keys.map((key) => singleLine(args[key])).find(Boolean) ?? ''
const command = first(['command'])
const path = first(['path', 'filePath', 'file_path', 'filepath', 'dirpath'])
const search = first(['query', 'pattern', 'glob'])
const filter = first(['filePattern', 'include'])
const summary = command || (search
? [search, path, filter].filter(Boolean).join(' | ')
: path || first(['url']))
return summary ? summary.slice(0, 240) : undefined
}