Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/sour-gorillas-smoke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"deepagents": patch
---

fix(deepagents): handle non-string content blocks in tool result sizechecking
91 changes: 91 additions & 0 deletions libs/deepagents/src/middleware/fs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,97 @@ describe("createFilesystemMiddleware", () => {
expect(result.content).toBe(largeContent);
}
});

it("should evict large array-based content blocks", async () => {
const mockBackend = createMockBackend();
const mockWrite = vi.fn().mockResolvedValue({
error: null,
filesUpdate: {
"/large_tool_results/test-id": {
content: ["large content"],
created_at: "2024-01-01T00:00:00Z",
modified_at: "2024-01-01T00:00:00Z",
},
},
});
mockBackend.write = mockWrite;

const middleware = createFilesystemMiddleware({
backend: mockBackend,
toolTokenLimitBeforeEvict: 100,
});

const largeText = "x".repeat(100 * NUM_CHARS_PER_TOKEN + 1000);
const mockMessage = new ToolMessage({
content: [
{ type: "text", text: largeText },
{ type: "text", text: " extra" },
],
tool_call_id: "test-id",
name: "some_tool",
});
const mockHandler = vi.fn().mockResolvedValue(mockMessage);
const request = {
toolCall: { id: "test-id", name: "some_tool" },
state: {},
config: {},
};

const result = await middleware.wrapToolCall!(
request as any,
mockHandler,
);

expect(mockWrite).toHaveBeenCalledWith(
"/large_tool_results/test-id",
largeText + " extra",
);

expect(isCommand(result)).toBe(true);
if (isCommand(result)) {
const update = result.update as any;
expect(update.messages).toHaveLength(1);
const truncatedMsg = update.messages[0];
expect(truncatedMsg.content).toContain("Tool result too large");
expect(truncatedMsg.content).toContain("/large_tool_results/test-id");
expect(truncatedMsg.tool_call_id).toBe("test-id");
}
});

it("should not evict small array-based content blocks", async () => {
const middleware = createFilesystemMiddleware({
backend: createMockBackend(),
toolTokenLimitBeforeEvict: 1000,
});

const mockMessage = new ToolMessage({
content: [
{ type: "text", text: "small result" },
{ type: "text", text: " part two" },
],
tool_call_id: "test-id",
name: "some_tool",
});
const mockHandler = vi.fn().mockResolvedValue(mockMessage);
const request = {
toolCall: { id: "test-id", name: "some_tool" },
state: {},
config: {},
};

const result = await middleware.wrapToolCall!(
request as any,
mockHandler,
);

expect(ToolMessage.isInstance(result)).toBe(true);
if (ToolMessage.isInstance(result)) {
expect(result.content).toEqual([
{ type: "text", text: "small result" },
{ type: "text", text: " part two" },
]);
}
});
});

describe("tools", () => {
Expand Down
9 changes: 5 additions & 4 deletions libs/deepagents/src/middleware/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -871,9 +871,10 @@ export function createFilesystemMiddleware(
msg: ToolMessage,
toolTokenLimitBeforeEvict: number,
) {
const textContent = msg.text;
if (
typeof msg.content === "string" &&
msg.content.length > toolTokenLimitBeforeEvict * NUM_CHARS_PER_TOKEN
textContent.length >
toolTokenLimitBeforeEvict * NUM_CHARS_PER_TOKEN
) {
// Build StateAndStore from request
const stateAndStore: StateAndStore = {
Expand All @@ -889,15 +890,15 @@ export function createFilesystemMiddleware(

const writeResult = await resolvedBackend.write(
evictPath,
msg.content,
textContent,
);

if (writeResult.error) {
return { message: msg, filesUpdate: null };
}

// Create preview showing head and tail of the result
const contentSample = createContentPreview(msg.content);
const contentSample = createContentPreview(textContent);
const replacementText = TOO_LARGE_TOOL_MSG.replace(
"{tool_call_id}",
msg.tool_call_id,
Expand Down
Loading