fix(hooks): pass sessionFile and sessionKey in after_compaction hook (#40781)

Merged via squash.

Prepared head SHA: 11e85f865148f6c6216aaf00fc5b0ef78238070a
Co-authored-by: jarimustonen <1272053+jarimustonen@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
This commit is contained in:
Jari Mustonen 2026-03-17 17:30:37 +02:00 committed by GitHub
parent f036ed27f4
commit 4f6955fb11
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 22 additions and 4 deletions

View File

@ -203,6 +203,7 @@ Docs: https://docs.openclaw.ai
- Auth/login lockout recovery: clear stale `auth_permanent` and `billing` disabled state for all profiles matching the target provider when `openclaw models auth login` is invoked, so users locked out by expired or revoked OAuth tokens can recover by re-authenticating instead of waiting for the cooldown timer to expire. (#43057)
- Auto-reply/context-engine compaction: persist the exact embedded-run metadata compaction count for main and followup runner session accounting, so metadata-only auto-compactions no longer undercount multi-compaction runs. (#42629) thanks @uf-hy.
- Auth/Codex CLI reuse: sync reused Codex CLI credentials into the supported `openai-codex:default` OAuth profile instead of reviving the deprecated `openai-codex:codex-cli` slot, so doctor cleanup no longer loops. (#45353) thanks @Gugu-sugar.
- Hooks/after_compaction: forward `sessionFile` for direct/manual compaction events and add `sessionFile` plus `sessionKey` to wired auto-compaction hook context so plugins receive the session metadata already declared in the hook types. (#40781) Thanks @jarimustonen.
## 2026.3.12

View File

@ -529,6 +529,7 @@ describe("compactEmbeddedPiSessionDirect hooks", () => {
messageCount: 1,
tokenCount: 10,
compactedCount: 1,
sessionFile: "/tmp/session.jsonl",
},
expect.objectContaining({ sessionKey: "agent:main:session-1", messageProvider: "telegram" }),
);

View File

@ -1039,6 +1039,7 @@ export async function compactEmbeddedPiSessionDirect(
messageCount: messageCountAfter,
tokenCount: tokensAfter,
compactedCount,
sessionFile: params.sessionFile,
},
{
sessionId: params.sessionId,

View File

@ -80,8 +80,9 @@ export function handleAutoCompactionEnd(
{
messageCount: ctx.params.session.messages?.length ?? 0,
compactedCount: ctx.getCompactionCount(),
sessionFile: ctx.params.session.sessionFile,
},
{},
{ sessionKey: ctx.params.sessionKey },
)
.catch((err) => {
ctx.log.warn(`after_compaction hook failed: ${String(err)}`);

View File

@ -39,11 +39,20 @@ describe("compaction hook wiring", () => {
function createCompactionEndCtx(params: {
runId: string;
messages?: unknown[];
sessionFile?: string;
sessionKey?: string;
compactionCount?: number;
withRetryHooks?: boolean;
}) {
return {
params: { runId: params.runId, session: { messages: params.messages ?? [] } },
params: {
runId: params.runId,
sessionKey: params.sessionKey,
session: {
messages: params.messages ?? [],
sessionFile: params.sessionFile,
},
},
state: { compactionInFlight: true },
log: { debug: vi.fn(), warn: vi.fn() },
maybeResolveCompactionWait: vi.fn(),
@ -107,6 +116,8 @@ describe("compaction hook wiring", () => {
const ctx = createCompactionEndCtx({
runId: "r2",
messages: [1, 2],
sessionFile: "/tmp/session.jsonl",
sessionKey: "agent:main:web-xyz",
compactionCount: 1,
});
@ -122,13 +133,16 @@ describe("compaction hook wiring", () => {
expect(hookMocks.runner.runAfterCompaction).toHaveBeenCalledTimes(1);
const afterCalls = hookMocks.runner.runAfterCompaction.mock.calls as unknown as Array<
[unknown]
[unknown, unknown]
>;
const event = afterCalls[0]?.[0] as
| { messageCount?: number; compactedCount?: number }
| { messageCount?: number; compactedCount?: number; sessionFile?: string }
| undefined;
expect(event?.messageCount).toBe(2);
expect(event?.compactedCount).toBe(1);
expect(event?.sessionFile).toBe("/tmp/session.jsonl");
const hookCtx = afterCalls[0]?.[1] as { sessionKey?: string } | undefined;
expect(hookCtx?.sessionKey).toBe("agent:main:web-xyz");
expect(ctx.incrementCompactionCount).toHaveBeenCalledTimes(1);
expect(ctx.maybeResolveCompactionWait).toHaveBeenCalledTimes(1);
expect(hookMocks.emitAgentEvent).toHaveBeenCalledWith({