feat(server): add DCP clean-room context pruning
- Deduplication: removes consecutive identical tool_call+tool_result pairs - Purge-errors: removes failed/empty tool results - Transform orchestrator runs strategies in sequence pre-payload - Wired into turn.ts before buildMessagesPayload - Clean-room reimplementation (AGPL reference: behavior only)
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
// Purge-errors strategy — removes failed/empty tool_result entries.
|
||||
// Clean-room implementation.
|
||||
|
||||
import type { DcpMessage } from '../messages.js';
|
||||
|
||||
const ERROR_PREFIXES = ['Error:', 'error:', 'Error: '];
|
||||
const DEFAULT_WINDOW = 5;
|
||||
|
||||
export function purgeErrors(
|
||||
messages: DcpMessage[],
|
||||
windowSize: number = DEFAULT_WINDOW,
|
||||
): { messages: DcpMessage[]; stats: { removedCount: number; freedTokens: number } } {
|
||||
const result: DcpMessage[] = [];
|
||||
let removedCount = 0;
|
||||
let freedTokens = 0;
|
||||
|
||||
for (const msg of messages) {
|
||||
if (msg.role === 'tool') {
|
||||
const shouldRemove =
|
||||
msg.isError ||
|
||||
ERROR_PREFIXES.some((p) => msg.content.startsWith(p)) ||
|
||||
msg.content.trim() === '';
|
||||
|
||||
if (shouldRemove) {
|
||||
removedCount++;
|
||||
freedTokens += Math.ceil(msg.content.length / 4);
|
||||
continue; // Skip this message
|
||||
}
|
||||
}
|
||||
result.push(msg);
|
||||
}
|
||||
|
||||
return { messages: result, stats: { removedCount, freedTokens } };
|
||||
}
|
||||
Reference in New Issue
Block a user