mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-14 21:32:40 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea76f7501d | ||
|
|
daaffe6109 |
@@ -0,0 +1,155 @@
|
||||
import { describe, test, expect, beforeEach, afterEach } from "vitest";
|
||||
import { appendFileSync, mkdtempSync, rmSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
|
||||
import {
|
||||
createDaemonTestContext,
|
||||
type DaemonTestContext,
|
||||
} from "../test-utils/index.js";
|
||||
|
||||
const MIB = 1024 * 1024;
|
||||
const APP_PAGE_SIZE = 40;
|
||||
|
||||
describe("daemon E2E - large agent history (#2610)", () => {
|
||||
let ctx: DaemonTestContext;
|
||||
let cwd: string;
|
||||
|
||||
beforeEach(async () => {
|
||||
ctx = await createDaemonTestContext();
|
||||
cwd = mkdtempSync(path.join(tmpdir(), "daemon-e2e-"));
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await ctx.cleanup();
|
||||
rmSync(cwd, { recursive: true, force: true });
|
||||
}, 60_000);
|
||||
|
||||
async function createAgentWithHistory(
|
||||
rows: number,
|
||||
rowBytes: number
|
||||
): Promise<string> {
|
||||
const agent = await ctx.client.createAgent({
|
||||
provider: "codex",
|
||||
cwd,
|
||||
title: "Large history",
|
||||
});
|
||||
const body = "x".repeat(rowBytes);
|
||||
for (let index = 0; index < rows; index += 1) {
|
||||
await ctx.daemon.daemon.agentManager.appendTimelineItem(agent.id, {
|
||||
type: "assistant_message",
|
||||
text: `${index} ${body}`,
|
||||
});
|
||||
await ctx.daemon.daemon.agentManager.appendTimelineItem(agent.id, {
|
||||
type: "user_message",
|
||||
text: `next ${index}`,
|
||||
});
|
||||
}
|
||||
return agent.id;
|
||||
}
|
||||
|
||||
test("opens an agent whose history totals more than 64 MiB of ordinary rows", async () => {
|
||||
const agentId = await createAgentWithHistory(20_000, 4_000);
|
||||
|
||||
const page = await ctx.client.fetchAgentTimeline(agentId, {
|
||||
direction: "tail",
|
||||
limit: APP_PAGE_SIZE,
|
||||
projection: "projected",
|
||||
timeout: 60_000,
|
||||
});
|
||||
|
||||
expect(page.error).toBeNull();
|
||||
expect(page.entries).toHaveLength(APP_PAGE_SIZE);
|
||||
expect(page.hasOlder).toBe(true);
|
||||
}, 300_000);
|
||||
|
||||
test("opens an agent whose latest file writes total more than 64 MiB", async () => {
|
||||
const agent = await ctx.client.createAgent({
|
||||
provider: "codex",
|
||||
cwd,
|
||||
title: "Large writes",
|
||||
});
|
||||
const content = "x".repeat(2 * MIB);
|
||||
for (let index = 0; index < APP_PAGE_SIZE; index += 1) {
|
||||
await ctx.daemon.daemon.agentManager.appendTimelineItem(agent.id, {
|
||||
type: "tool_call",
|
||||
callId: `write_${index}`,
|
||||
name: "Write",
|
||||
status: "completed",
|
||||
error: null,
|
||||
detail: {
|
||||
type: "write",
|
||||
filePath: `fixtures/data-${index}.json`,
|
||||
content,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const page = await ctx.client.fetchAgentTimeline(agent.id, {
|
||||
direction: "tail",
|
||||
limit: APP_PAGE_SIZE,
|
||||
projection: "projected",
|
||||
timeout: 60_000,
|
||||
});
|
||||
|
||||
expect(page.error).toBeNull();
|
||||
expect(page.entries.length).toBeGreaterThan(0);
|
||||
}, 300_000);
|
||||
|
||||
test("opens an agent cold-loaded from a provider history of more than 64 MiB", async () => {
|
||||
const agent = await ctx.client.createAgent({
|
||||
provider: "codex",
|
||||
cwd,
|
||||
title: "Cold load",
|
||||
});
|
||||
await ctx.client.sendMessage(agent.id, "Respond with exactly: READY");
|
||||
const finished = await ctx.client.waitForFinish(agent.id, 5_000);
|
||||
const handle = finished.final!.persistence as PersistenceHandle;
|
||||
const historyPath = path.join(
|
||||
tmpdir(),
|
||||
"paseo-fake-provider-history",
|
||||
"codex",
|
||||
`${handle.sessionId}.jsonl`
|
||||
);
|
||||
const body = "x".repeat(4_000);
|
||||
const lines: string[] = [];
|
||||
for (let index = 0; index < 20_000; index += 1) {
|
||||
lines.push(
|
||||
JSON.stringify({ type: "turn_started", provider: "codex" }),
|
||||
JSON.stringify({
|
||||
type: "timeline",
|
||||
provider: "codex",
|
||||
item: { type: "user_message", text: `question ${index}` },
|
||||
}),
|
||||
JSON.stringify({
|
||||
type: "timeline",
|
||||
provider: "codex",
|
||||
item: { type: "assistant_message", text: `${index} ${body}` },
|
||||
}),
|
||||
JSON.stringify({
|
||||
type: "turn_completed",
|
||||
provider: "codex",
|
||||
usage: { inputTokens: 1, outputTokens: 1 },
|
||||
})
|
||||
);
|
||||
}
|
||||
appendFileSync(historyPath, lines.join("\n") + "\n");
|
||||
|
||||
await ctx.cleanup();
|
||||
ctx = await createDaemonTestContext();
|
||||
const resumed = await ctx.client.resumeAgent(handle);
|
||||
|
||||
const page = await ctx.client.fetchAgentTimeline(resumed.id, {
|
||||
direction: "tail",
|
||||
limit: APP_PAGE_SIZE,
|
||||
projection: "projected",
|
||||
timeout: 60_000,
|
||||
});
|
||||
|
||||
expect(page.error).toBeNull();
|
||||
expect(page.entries).toHaveLength(APP_PAGE_SIZE);
|
||||
expect(page.entries.at(-1)?.item).toMatchObject({
|
||||
type: "assistant_message",
|
||||
});
|
||||
}, 300_000);
|
||||
});
|
||||
Reference in New Issue
Block a user