Files
openclaw/src/agents/pi-embedded-subscribe.handlers.lifecycle.ts
Kyle Tse 2655041f69 fix: wire 9 unwired plugin hooks to core code (openclaw#14882) thanks @shtse8
Verified:
- GitHub CI checks green (non-skipped)

Co-authored-by: shtse8 <8020099+shtse8@users.noreply.github.com>
2026-02-12 18:14:14 -06:00

131 lines
3.7 KiB
TypeScript

import type { AgentEvent } from "@mariozechner/pi-agent-core";
import type { EmbeddedPiSubscribeContext } from "./pi-embedded-subscribe.handlers.types.js";
import { emitAgentEvent } from "../infra/agent-events.js";
import { createInlineCodeState } from "../markdown/code-spans.js";
import { getGlobalHookRunner } from "../plugins/hook-runner-global.js";
export function handleAgentStart(ctx: EmbeddedPiSubscribeContext) {
ctx.log.debug(`embedded run agent start: runId=${ctx.params.runId}`);
emitAgentEvent({
runId: ctx.params.runId,
stream: "lifecycle",
data: {
phase: "start",
startedAt: Date.now(),
},
});
void ctx.params.onAgentEvent?.({
stream: "lifecycle",
data: { phase: "start" },
});
}
export function handleAutoCompactionStart(ctx: EmbeddedPiSubscribeContext) {
ctx.state.compactionInFlight = true;
ctx.incrementCompactionCount();
ctx.ensureCompactionPromise();
ctx.log.debug(`embedded run compaction start: runId=${ctx.params.runId}`);
emitAgentEvent({
runId: ctx.params.runId,
stream: "compaction",
data: { phase: "start" },
});
void ctx.params.onAgentEvent?.({
stream: "compaction",
data: { phase: "start" },
});
// Run before_compaction plugin hook (fire-and-forget)
const hookRunner = getGlobalHookRunner();
if (hookRunner?.hasHooks("before_compaction")) {
void hookRunner
.runBeforeCompaction(
{
messageCount: ctx.params.session.messages?.length ?? 0,
},
{},
)
.catch((err) => {
ctx.log.warn(`before_compaction hook failed: ${String(err)}`);
});
}
}
export function handleAutoCompactionEnd(
ctx: EmbeddedPiSubscribeContext,
evt: AgentEvent & { willRetry?: unknown },
) {
ctx.state.compactionInFlight = false;
const willRetry = Boolean(evt.willRetry);
if (willRetry) {
ctx.noteCompactionRetry();
ctx.resetForCompactionRetry();
ctx.log.debug(`embedded run compaction retry: runId=${ctx.params.runId}`);
} else {
ctx.maybeResolveCompactionWait();
}
emitAgentEvent({
runId: ctx.params.runId,
stream: "compaction",
data: { phase: "end", willRetry },
});
void ctx.params.onAgentEvent?.({
stream: "compaction",
data: { phase: "end", willRetry },
});
// Run after_compaction plugin hook (fire-and-forget)
if (!willRetry) {
const hookRunnerEnd = getGlobalHookRunner();
if (hookRunnerEnd?.hasHooks("after_compaction")) {
void hookRunnerEnd
.runAfterCompaction(
{
messageCount: ctx.params.session.messages?.length ?? 0,
compactedCount: ctx.getCompactionCount(),
},
{},
)
.catch((err) => {
ctx.log.warn(`after_compaction hook failed: ${String(err)}`);
});
}
}
}
export function handleAgentEnd(ctx: EmbeddedPiSubscribeContext) {
ctx.log.debug(`embedded run agent end: runId=${ctx.params.runId}`);
emitAgentEvent({
runId: ctx.params.runId,
stream: "lifecycle",
data: {
phase: "end",
endedAt: Date.now(),
},
});
void ctx.params.onAgentEvent?.({
stream: "lifecycle",
data: { phase: "end" },
});
if (ctx.params.onBlockReply) {
if (ctx.blockChunker?.hasBuffered()) {
ctx.blockChunker.drain({ force: true, emit: ctx.emitBlockChunk });
ctx.blockChunker.reset();
} else if (ctx.state.blockBuffer.length > 0) {
ctx.emitBlockChunk(ctx.state.blockBuffer);
ctx.state.blockBuffer = "";
}
}
ctx.state.blockState.thinking = false;
ctx.state.blockState.final = false;
ctx.state.blockState.inlineCode = createInlineCodeState();
if (ctx.state.pendingCompactionRetry > 0) {
ctx.resolveCompactionRetry();
} else {
ctx.maybeResolveCompactionWait();
}
}