gateway: fix compaction regression coverage

This commit is contained in:
scoootscooob
2026-04-06 15:35:36 -07:00
parent 7c1ca59b32
commit 66a281c4f9
6 changed files with 90 additions and 12 deletions

View File

@@ -9,6 +9,7 @@ import {
waitForEmbeddedPiRunEnd,
} from "../../agents/pi-embedded-runner/runs.js";
import { compactEmbeddedPiSession } from "../../agents/pi-embedded.js";
import { normalizeReasoningLevel, normalizeThinkLevel } from "../../auto-reply/thinking.js";
import { clearSessionQueues } from "../../auto-reply/reply/queue/cleanup.js";
import { loadConfig } from "../../config/config.js";
import {
@@ -1464,7 +1465,7 @@ export const sessionsHandlers: GatewayRequestHandlers = {
const messages = limit < allMessages.length ? allMessages.slice(-limit) : allMessages;
respond(true, { messages }, undefined);
},
"sessions.compact": async ({ params, respond, context }) => {
"sessions.compact": async ({ req, params, respond, context, client, isWebchatConnect }) => {
if (!assertValidParams(params, validateSessionsCompactParams, "sessions.compact", respond)) {
return;
}
@@ -1523,10 +1524,10 @@ export const sessionsHandlers: GatewayRequestHandlers = {
if (maxLines === undefined) {
const interruptResult = await interruptSessionRunIfActive({
req: undefined,
req,
context,
client: null,
isWebchatConnect: () => false,
client,
isWebchatConnect,
requestedKey: key,
canonicalKey: target.canonicalKey,
sessionId,
@@ -1548,8 +1549,8 @@ export const sessionsHandlers: GatewayRequestHandlers = {
config: cfg,
provider: resolvedModel.provider,
model: resolvedModel.model,
thinkLevel: entry?.thinkingLevel,
reasoningLevel: entry?.reasoningLevel,
thinkLevel: normalizeThinkLevel(entry?.thinkingLevel),
reasoningLevel: normalizeReasoningLevel(entry?.reasoningLevel),
bashElevated: {
enabled: false,
allowed: false,

View File

@@ -2,6 +2,7 @@ import fsSync from "node:fs";
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import type { AssistantMessage, UserMessage } from "@mariozechner/pi-ai";
import { SessionManager } from "@mariozechner/pi-coding-agent";
import { afterAll, beforeAll, beforeEach, describe, expect, test, vi } from "vitest";
import { WebSocket } from "ws";
@@ -225,11 +226,36 @@ async function writeSingleLineSession(dir: string, sessionId: string, content: s
function createCheckpointFixture(dir: string) {
const session = SessionManager.create(dir, dir);
session.appendMessage({ role: "user", content: "before compaction" });
session.appendMessage({
const userMessage: UserMessage = {
role: "user",
content: "before compaction",
timestamp: Date.now(),
};
const assistantMessage: AssistantMessage = {
role: "assistant",
content: [{ type: "text", text: "working on it" }],
});
api: "responses",
provider: "openai",
model: "gpt-test",
usage: {
input: 1,
output: 1,
cacheRead: 0,
cacheWrite: 0,
totalTokens: 2,
cost: {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
total: 0,
},
},
stopReason: "stop",
timestamp: Date.now(),
};
session.appendMessage(userMessage);
session.appendMessage(assistantMessage);
const preCompactionLeafId = session.getLeafId();
if (!preCompactionLeafId) {
throw new Error("expected persisted session leaf before compaction");

View File

@@ -2,6 +2,7 @@ import fsSync from "node:fs";
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import type { AssistantMessage, UserMessage } from "@mariozechner/pi-ai";
import { SessionManager } from "@mariozechner/pi-coding-agent";
import { afterEach, describe, expect, test } from "vitest";
import {
@@ -21,11 +22,36 @@ describe("session-compaction-checkpoints", () => {
tempDirs.push(dir);
const session = SessionManager.create(dir, dir);
session.appendMessage({ role: "user", content: "before compaction" });
session.appendMessage({
const userMessage: UserMessage = {
role: "user",
content: "before compaction",
timestamp: Date.now(),
};
const assistantMessage: AssistantMessage = {
role: "assistant",
content: [{ type: "text", text: "working on it" }],
});
api: "responses",
provider: "openai",
model: "gpt-test",
usage: {
input: 1,
output: 1,
cacheRead: 0,
cacheWrite: 0,
totalTokens: 2,
cost: {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
total: 0,
},
},
stopReason: "stop",
timestamp: Date.now(),
};
session.appendMessage(userMessage);
session.appendMessage(assistantMessage);
const sessionFile = session.getSessionFile();
const leafId = session.getLeafId();

View File

@@ -22,6 +22,7 @@ export type AgentCommandFn = (...args: unknown[]) => Promise<void>;
export type SendWhatsAppFn = (...args: unknown[]) => Promise<{ messageId: string; toJid: string }>;
export type RunBtwSideQuestionFn = (...args: unknown[]) => Promise<unknown>;
export type DispatchInboundMessageFn = (...args: unknown[]) => Promise<unknown>;
export type CompactEmbeddedPiSessionFn = (...args: unknown[]) => Promise<unknown>;
const GATEWAY_TEST_CONFIG_ROOT_KEY = Symbol.for("openclaw.gatewayTestHelpers.configRoot");
@@ -49,6 +50,7 @@ export type GatewayTestHoistedState = {
abortCalls: string[];
waitCalls: string[];
waitResults: Map<string, boolean>;
compactEmbeddedPiSession: Mock<CompactEmbeddedPiSessionFn>;
};
testTailscaleWhois: { value: TailscaleWhoisIdentity | null };
getReplyFromConfig: Mock<GetReplyFromConfigFn>;
@@ -99,6 +101,16 @@ const gatewayTestHoisted = vi.hoisted(() => {
abortCalls: [],
waitCalls: [],
waitResults: new Map<string, boolean>(),
compactEmbeddedPiSession: vi.fn().mockResolvedValue({
ok: true,
compacted: true,
result: {
summary: "summary",
firstKeptEntryId: "entry-1",
tokensBefore: 120,
tokensAfter: 80,
},
}),
},
testTailscaleWhois: { value: null },
getReplyFromConfig: vi.fn<GetReplyFromConfigFn>().mockResolvedValue(undefined),

View File

@@ -22,6 +22,11 @@ function createState(request: RequestFn, overrides: Partial<SessionsState> = {})
sessionsFilterLimit: "0",
sessionsIncludeGlobal: true,
sessionsIncludeUnknown: true,
sessionsExpandedCheckpointKey: null,
sessionsCheckpointItemsByKey: {},
sessionsCheckpointLoadingKey: null,
sessionsCheckpointBusyKey: null,
sessionsCheckpointErrorByKey: {},
...overrides,
};
}

View File

@@ -41,6 +41,11 @@ function buildProps(result: SessionsListResult): SessionsProps {
page: 0,
pageSize: 10,
selectedKeys: new Set<string>(),
expandedCheckpointKey: null,
checkpointItemsByKey: {},
checkpointLoadingKey: null,
checkpointBusyKey: null,
checkpointErrorByKey: {},
onFiltersChange: () => undefined,
onSearchChange: () => undefined,
onSortChange: () => undefined,
@@ -53,6 +58,9 @@ function buildProps(result: SessionsListResult): SessionsProps {
onDeselectPage: () => undefined,
onDeselectAll: () => undefined,
onDeleteSelected: () => undefined,
onToggleCheckpointDetails: () => undefined,
onBranchFromCheckpoint: () => undefined,
onRestoreCheckpoint: () => undefined,
};
}