const agentDefinition = {
id: "context-pruner",
displayName: "Context Pruner",
publisher: "codebuff",
version: "0.0.49",
model: "openai/gpt-5-mini",
toolNames: [],
spawnableAgents: [],
inputSchema: {
params: {
type: "object",
required: [],
properties: {
maxContextLength: {
type: "number"
}
}
}
},
includeMessageHistory: true,
outputMode: "last_message",
spawnerPrompt: `Spawn this agent between steps to prune context, starting with old tool results and then old messages.`,
systemPrompt: ``,
instructionsPrompt: ``,
stepPrompt: ``,
handleSteps: function* ({ agentState, params, logger }) {
const messages = agentState.messageHistory, countTokensJson = (obj) => {
return Math.ceil(JSON.stringify(obj).length / 3);
}, countMessageTokens = (message) => {
if (message.role === "tool" && Array.isArray(message.content)) {
let tokens = 0;
for (const part of message.content)
if (part.type === "media")
tokens += 1000;
else
tokens += countTokensJson(part);
tokens += countTokensJson({
role: message.role,
toolCallId: message.toolCallId,
toolName: message.toolName
});
return tokens;
}
if ((message.role === "user" || message.role === "assistant") && Array.isArray(message.content)) {
let tokens = 0;
for (const part of message.content)
if (part.type === "image")
tokens += 1000;
else
tokens += countTokensJson(part);
tokens += countTokensJson({ role: message.role });
return tokens;
}
return countTokensJson(message);
}, countMessagesTokens = (msgs) => {
return msgs.reduce((sum, msg) => sum + countMessageTokens(msg), 0);
}, maxMessageTokens = params?.maxContextLength ?? 200000, extractToolCallIds = (msgs) => {
const ids = new Set;
for (const message of msgs)
if (message.role === "assistant" && Array.isArray(message.content)) {
for (const part of message.content)
if (part.type === "tool-call" && part.toolCallId)
ids.add(part.toolCallId);
}
return ids;
}, extractToolResultIds = (msgs) => {
const ids = new Set;
for (const message of msgs)
if (message.role === "tool" && message.toolCallId)
ids.add(message.toolCallId);
return ids;
}, removeOrphanedToolMessages = (msgs) => {
const toolCallIds = extractToolCallIds(msgs), toolResultIds = extractToolResultIds(msgs);
return msgs.filter((message) => {
if (message.role === "tool" && message.toolCallId)
return toolCallIds.has(message.toolCallId);
return !0;
}).map((message) => {
if (message.role === "assistant" && Array.isArray(message.content)) {
const filteredContent = message.content.filter((part) => {
if (part.type === "tool-call" && part.toolCallId)
return toolResultIds.has(part.toolCallId);
return !0;
});
if (filteredContent.length === 0)
return null;
if (filteredContent.length !== message.content.length)
return { ...message, content: filteredContent };
}
return message;
}).filter((m) => m !== null);
};
let currentMessages = removeOrphanedToolMessages([...messages]);
if (countMessagesTokens(currentMessages) < maxMessageTokens) {
yield {
toolName: "set_messages",
input: { messages: currentMessages },
includeToolCall: !1
};
return;
}
let numKeptTerminalCommands = 0;
const afterTerminalPass = [];
for (let i = currentMessages.length - 1;i >= 0; i--) {
const message = currentMessages[i];
if (message.role === "tool" && message.toolName === "run_terminal_command") {
const toolMessage = message;
if (numKeptTerminalCommands < 5) {
numKeptTerminalCommands++;
afterTerminalPass.unshift(message);
} else {
const simplifiedMessage = {
...toolMessage,
content: [
{
type: "json",
value: {
command: toolMessage.content[0]?.value?.command || "",
stdoutOmittedForLength: !0
}
}
]
};
afterTerminalPass.unshift(simplifiedMessage);
}
} else
afterTerminalPass.unshift(message);
}
if (countMessagesTokens(afterTerminalPass) < maxMessageTokens) {
yield {
toolName: "set_messages",
input: {
messages: afterTerminalPass
},
includeToolCall: !1
};
return;
}
const afterToolResultsPass = afterTerminalPass.map((message) => {
if (message.role === "tool") {
const outputSize = JSON.stringify(message.content).length;
if (outputSize > 1000)
return {
...message,
content: [
{
type: "json",
value: {
message: "[LARGE_TOOL_RESULT_OMITTED]",
originalSize: outputSize
}
}
]
};
}
return message;
});
if (countMessagesTokens(afterToolResultsPass) < maxMessageTokens) {
yield {
toolName: "set_messages",
input: {
messages: afterToolResultsPass
},
includeToolCall: !1
};
return;
}
const shortenedMessageTokenFactor = 0.5, replacementMessage = {
role: "user",
content: [
{
type: "text",
text: "<system>Previous message(s) omitted due to length</system>"
}
]
}, keepLastTags = {};
for (const [i, message] of afterToolResultsPass.entries()) {
if (!message.keepLastTags)
continue;
for (const tag of message.keepLastTags)
keepLastTags[tag] = i;
}
const keepLastIndices = Object.values(keepLastTags), toolCallPairs = new Map;
for (const [i, message] of afterToolResultsPass.entries())
if (message.role === "assistant" && Array.isArray(message.content)) {
for (const part of message.content)
if (part.type === "tool-call" && part.toolCallId) {
const existing = toolCallPairs.get(part.toolCallId) || [];
existing.push(i);
toolCallPairs.set(part.toolCallId, existing);
}
} else if (message.role === "tool" && message.toolCallId) {
const existing = toolCallPairs.get(message.toolCallId) || [];
existing.push(i);
toolCallPairs.set(message.toolCallId, existing);
}
const pairedIndices = new Set;
for (const indices of toolCallPairs.values())
for (const idx of indices)
pairedIndices.add(idx);
const requiredTokens = countMessagesTokens(afterToolResultsPass.filter((m) => m.keepDuringTruncation));
let removedTokens = 0;
const tokensToRemove = (maxMessageTokens - requiredTokens) * (1 - shortenedMessageTokenFactor), placeholder = "deleted", filteredMessages = [], indicesToRemove = new Set;
let lastWasRemoval = !1;
for (const [i, message] of afterToolResultsPass.entries()) {
if (removedTokens >= tokensToRemove || message.keepDuringTruncation || keepLastIndices.includes(i) || pairedIndices.has(i)) {
lastWasRemoval = !1;
continue;
}
indicesToRemove.add(i);
removedTokens += countMessageTokens(message);
if (!lastWasRemoval)
removedTokens -= countMessageTokens(replacementMessage);
lastWasRemoval = !0;
}
for (const [i, message] of afterToolResultsPass.entries())
if (indicesToRemove.has(i)) {
if (filteredMessages.length === 0 || filteredMessages[filteredMessages.length - 1] !== placeholder)
filteredMessages.push(placeholder);
} else
filteredMessages.push(message);
const finalMessages = filteredMessages.map((m) => m === placeholder ? replacementMessage : m);
yield {
toolName: "set_messages",
input: {
messages: removeOrphanedToolMessages(finalMessages)
},
includeToolCall: !1
};
},
mcpServers: {},
inheritParentSystemPrompt: false
}