























@@ -26,6 +26,87 @@ const useTwoAuthProfiles = () => {
2626}));
2727};
282829+type CompactRuntimeContext = {
30+promptCache?: {
31+retention?: string;
32+lastCallUsage?: {
33+input?: number;
34+cacheRead?: number;
35+};
36+observation?: {
37+broke?: boolean;
38+cacheRead?: number;
39+};
40+lastCacheTouchAt?: number;
41+};
42+trigger?: string;
43+attempt?: number;
44+maxAttempts?: number;
45+messageChannel?: string;
46+messageProvider?: string;
47+agentAccountId?: string;
48+currentChannelId?: string;
49+currentThreadTs?: string;
50+currentMessageId?: string;
51+senderId?: string;
52+senderIsOwner?: boolean;
53+authProfileId?: string;
54+};
55+56+type CompactParams = {
57+sessionId?: string;
58+sessionFile?: string;
59+tokenBudget?: number;
60+force?: boolean;
61+compactionTarget?: string;
62+runtimeContext?: CompactRuntimeContext;
63+};
64+65+type AttemptParams = {
66+sessionId?: string;
67+sessionFile?: string;
68+authProfileId?: string;
69+};
70+71+type HookEvent = {
72+messageCount?: number;
73+compactedCount?: number;
74+tokenCount?: number;
75+sessionFile?: string;
76+};
77+78+type HookContext = {
79+sessionKey?: string;
80+};
81+82+function compactCallAt(index: number): CompactParams {
83+const call = mockedCompactDirect.mock.calls[index];
84+if (!call) {
85+throw new Error(`expected compact call ${index + 1}`);
86+}
87+return call[0] as CompactParams;
88+}
89+90+function attemptCallAt(index: number): AttemptParams {
91+const call = mockedRunEmbeddedAttempt.mock.calls[index];
92+if (!call) {
93+throw new Error(`expected embedded attempt call ${index + 1}`);
94+}
95+return call[0] as AttemptParams;
96+}
97+98+function hookCallAt(index: number, kind: "before" | "after"): [HookEvent, HookContext] {
99+const mock =
100+kind === "before"
101+ ? mockedGlobalHookRunner.runBeforeCompaction
102+ : mockedGlobalHookRunner.runAfterCompaction;
103+const call = mock.mock.calls[index];
104+if (!call) {
105+throw new Error(`expected ${kind} compaction hook call ${index + 1}`);
106+}
107+return call as unknown as [HookEvent, HookContext];
108+}
109+29110describe("timeout-triggered compaction", () => {
30111beforeAll(async () => {
31112({ runEmbeddedPiAgent } = await loadRunOverflowCompactionHarness());
@@ -72,32 +153,21 @@ describe("timeout-triggered compaction", () => {
72153const result = await runEmbeddedPiAgent(overflowBaseRunParams);
7315474155expect(mockedCompactDirect).toHaveBeenCalledTimes(1);
75-expect(mockedCompactDirect).toHaveBeenCalledWith(
76-expect.objectContaining({
77-sessionId: "test-session",
78-sessionFile: "/tmp/session.json",
79-tokenBudget: 200000,
80-force: true,
81-compactionTarget: "budget",
82-runtimeContext: expect.objectContaining({
83-promptCache: expect.objectContaining({
84-retention: "short",
85-lastCallUsage: expect.objectContaining({
86-input: 150000,
87-cacheRead: 32000,
88-}),
89-observation: expect.objectContaining({
90-broke: false,
91-cacheRead: 32000,
92-}),
93-lastCacheTouchAt: 1_700_000_000_000,
94-}),
95-trigger: "timeout_recovery",
96-attempt: 1,
97-maxAttempts: 2,
98-}),
99-}),
100-);
156+const compactParams = compactCallAt(0);
157+expect(compactParams.sessionId).toBe("test-session");
158+expect(compactParams.sessionFile).toBe("/tmp/session.json");
159+expect(compactParams.tokenBudget).toBe(200000);
160+expect(compactParams.force).toBe(true);
161+expect(compactParams.compactionTarget).toBe("budget");
162+expect(compactParams.runtimeContext?.promptCache?.retention).toBe("short");
163+expect(compactParams.runtimeContext?.promptCache?.lastCallUsage?.input).toBe(150000);
164+expect(compactParams.runtimeContext?.promptCache?.lastCallUsage?.cacheRead).toBe(32000);
165+expect(compactParams.runtimeContext?.promptCache?.observation?.broke).toBe(false);
166+expect(compactParams.runtimeContext?.promptCache?.observation?.cacheRead).toBe(32000);
167+expect(compactParams.runtimeContext?.promptCache?.lastCacheTouchAt).toBe(1_700_000_000_000);
168+expect(compactParams.runtimeContext?.trigger).toBe("timeout_recovery");
169+expect(compactParams.runtimeContext?.attempt).toBe(1);
170+expect(compactParams.runtimeContext?.maxAttempts).toBe(2);
101171expect(mockedRunEmbeddedAttempt).toHaveBeenCalledTimes(2);
102172expect(result.meta.error).toBeUndefined();
103173expect(result.meta.agentMeta?.compactionTokensAfter).toBe(80_000);
@@ -136,13 +206,9 @@ describe("timeout-triggered compaction", () => {
136206137207// Verify the loop continued (retry happened)
138208expect(mockedRunEmbeddedAttempt).toHaveBeenCalledTimes(2);
139-expect(mockedRunEmbeddedAttempt).toHaveBeenNthCalledWith(
140-2,
141-expect.objectContaining({
142-sessionId: "timeout-rotated-session",
143-sessionFile: "/tmp/timeout-rotated-session.json",
144-}),
145-);
209+const retryParams = attemptCallAt(1);
210+expect(retryParams.sessionId).toBe("timeout-rotated-session");
211+expect(retryParams.sessionFile).toBe("/tmp/timeout-rotated-session.json");
146212expect(mockedRunPostCompactionSideEffects).not.toHaveBeenCalled();
147213expect(result.meta.error).toBeUndefined();
148214});
@@ -177,20 +243,16 @@ describe("timeout-triggered compaction", () => {
177243senderIsOwner: true,
178244});
179245180-expect(mockedCompactDirect).toHaveBeenCalledWith(
181-expect.objectContaining({
182-runtimeContext: expect.objectContaining({
183-messageChannel: "slack",
184-messageProvider: "slack",
185-agentAccountId: "acct-1",
186-currentChannelId: "channel-1",
187-currentThreadTs: "thread-1",
188-currentMessageId: "message-1",
189-senderId: "sender-1",
190-senderIsOwner: true,
191-}),
192-}),
193-);
246+expect(mockedCompactDirect).toHaveBeenCalledTimes(1);
247+const compactParams = compactCallAt(0);
248+expect(compactParams.runtimeContext?.messageChannel).toBe("slack");
249+expect(compactParams.runtimeContext?.messageProvider).toBe("slack");
250+expect(compactParams.runtimeContext?.agentAccountId).toBe("acct-1");
251+expect(compactParams.runtimeContext?.currentChannelId).toBe("channel-1");
252+expect(compactParams.runtimeContext?.currentThreadTs).toBe("thread-1");
253+expect(compactParams.runtimeContext?.currentMessageId).toBe("message-1");
254+expect(compactParams.runtimeContext?.senderId).toBe("sender-1");
255+expect(compactParams.runtimeContext?.senderIsOwner).toBe(true);
194256});
195257196258it("falls through to normal handling when timeout compaction fails", async () => {
@@ -448,23 +510,17 @@ describe("timeout-triggered compaction", () => {
448510449511await runEmbeddedPiAgent(overflowBaseRunParams);
450512451-expect(mockedGlobalHookRunner.runBeforeCompaction).toHaveBeenCalledWith(
452-{ messageCount: -1, sessionFile: "/tmp/session.json" },
453-expect.objectContaining({
454-sessionKey: "test-key",
455-}),
456-);
457-expect(mockedGlobalHookRunner.runAfterCompaction).toHaveBeenCalledWith(
458-{
459-messageCount: -1,
460-compactedCount: -1,
461-tokenCount: 70,
462-sessionFile: "/tmp/session.json",
463-},
464-expect.objectContaining({
465-sessionKey: "test-key",
466-}),
467-);
513+const [beforeEvent, beforeContext] = hookCallAt(0, "before");
514+expect(beforeEvent).toEqual({ messageCount: -1, sessionFile: "/tmp/session.json" });
515+expect(beforeContext.sessionKey).toBe("test-key");
516+const [afterEvent, afterContext] = hookCallAt(0, "after");
517+expect(afterEvent).toEqual({
518+messageCount: -1,
519+compactedCount: -1,
520+tokenCount: 70,
521+sessionFile: "/tmp/session.json",
522+});
523+expect(afterContext.sessionKey).toBe("test-key");
468524expect(mockedRunPostCompactionSideEffects).toHaveBeenCalledTimes(1);
469525});
470526@@ -506,26 +562,14 @@ describe("timeout-triggered compaction", () => {
506562const result = await runEmbeddedPiAgent(overflowBaseRunParams);
507563508564expect(mockedCompactDirect).toHaveBeenCalledTimes(2);
509-expect(mockedCompactDirect).toHaveBeenNthCalledWith(
510-1,
511-expect.objectContaining({
512-runtimeContext: expect.objectContaining({
513-authProfileId: "profile-a",
514-attempt: 1,
515-maxAttempts: 2,
516-}),
517-}),
518-);
519-expect(mockedCompactDirect).toHaveBeenNthCalledWith(
520-2,
521-expect.objectContaining({
522-runtimeContext: expect.objectContaining({
523-authProfileId: "profile-b",
524-attempt: 2,
525-maxAttempts: 2,
526-}),
527-}),
528-);
565+const firstCompact = compactCallAt(0);
566+expect(firstCompact.runtimeContext?.authProfileId).toBe("profile-a");
567+expect(firstCompact.runtimeContext?.attempt).toBe(1);
568+expect(firstCompact.runtimeContext?.maxAttempts).toBe(2);
569+const secondCompact = compactCallAt(1);
570+expect(secondCompact.runtimeContext?.authProfileId).toBe("profile-b");
571+expect(secondCompact.runtimeContext?.attempt).toBe(2);
572+expect(secondCompact.runtimeContext?.maxAttempts).toBe(2);
529573expect(mockedRunEmbeddedAttempt).toHaveBeenCalledTimes(2);
530574expect(result.payloads?.[0]?.isError).toBe(true);
531575expect(result.payloads?.[0]?.text).toContain("timed out");
@@ -562,14 +606,8 @@ describe("timeout-triggered compaction", () => {
562606563607expect(mockedCompactDirect).toHaveBeenCalledTimes(2);
564608expect(mockedRunEmbeddedAttempt).toHaveBeenCalledTimes(2);
565-expect(mockedRunEmbeddedAttempt).toHaveBeenNthCalledWith(
566-1,
567-expect.objectContaining({ authProfileId: "profile-a" }),
568-);
569-expect(mockedRunEmbeddedAttempt).toHaveBeenNthCalledWith(
570-2,
571-expect.objectContaining({ authProfileId: "profile-b" }),
572-);
609+expect(attemptCallAt(0).authProfileId).toBe("profile-a");
610+expect(attemptCallAt(1).authProfileId).toBe("profile-b");
573611expect(result.payloads?.[0]?.isError).toBe(true);
574612expect(result.payloads?.[0]?.text).toContain("timed out");
575613});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。