Merged via squash. Prepared head SHA: d708ddb222abda2c8d5396bbf4ce9ee5c4549fe3 Co-authored-by: jscianna <9017016+jscianna@users.noreply.github.com> Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com> Reviewed-by: @jalehman
92 lines
2.7 KiB
TypeScript
92 lines
2.7 KiB
TypeScript
import type { AgentMessage } from "@mariozechner/pi-agent-core";
|
|
import { delegateCompactionToRuntime } from "./delegate.js";
|
|
import { registerContextEngineForOwner } from "./registry.js";
|
|
import type {
|
|
ContextEngine,
|
|
ContextEngineInfo,
|
|
AssembleResult,
|
|
CompactResult,
|
|
ContextEngineRuntimeContext,
|
|
IngestResult,
|
|
} from "./types.js";
|
|
|
|
/**
|
|
* LegacyContextEngine wraps the existing compaction behavior behind the
|
|
* ContextEngine interface, preserving 100% backward compatibility.
|
|
*
|
|
* - ingest: no-op (SessionManager handles message persistence)
|
|
* - assemble: pass-through (existing sanitize/validate/limit pipeline in attempt.ts handles this)
|
|
* - compact: delegates to compactEmbeddedPiSessionDirect
|
|
*/
|
|
export class LegacyContextEngine implements ContextEngine {
|
|
readonly info: ContextEngineInfo = {
|
|
id: "legacy",
|
|
name: "Legacy Context Engine",
|
|
version: "1.0.0",
|
|
};
|
|
|
|
async ingest(_params: {
|
|
sessionId: string;
|
|
sessionKey?: string;
|
|
message: AgentMessage;
|
|
isHeartbeat?: boolean;
|
|
}): Promise<IngestResult> {
|
|
// No-op: SessionManager handles message persistence in the legacy flow
|
|
return { ingested: false };
|
|
}
|
|
|
|
async assemble(params: {
|
|
sessionId: string;
|
|
sessionKey?: string;
|
|
messages: AgentMessage[];
|
|
tokenBudget?: number;
|
|
model?: string;
|
|
}): Promise<AssembleResult> {
|
|
// Pass-through: the existing sanitize -> validate -> limit -> repair pipeline
|
|
// in attempt.ts handles context assembly for the legacy engine.
|
|
// We just return the messages as-is with a rough token estimate.
|
|
return {
|
|
messages: params.messages,
|
|
estimatedTokens: 0, // Caller handles estimation
|
|
};
|
|
}
|
|
|
|
async afterTurn(_params: {
|
|
sessionId: string;
|
|
sessionKey?: string;
|
|
sessionFile: string;
|
|
messages: AgentMessage[];
|
|
prePromptMessageCount: number;
|
|
autoCompactionSummary?: string;
|
|
isHeartbeat?: boolean;
|
|
tokenBudget?: number;
|
|
runtimeContext?: ContextEngineRuntimeContext;
|
|
}): Promise<void> {
|
|
// No-op: legacy flow persists context directly in SessionManager.
|
|
}
|
|
|
|
async compact(params: {
|
|
sessionId: string;
|
|
sessionKey?: string;
|
|
sessionFile: string;
|
|
tokenBudget?: number;
|
|
force?: boolean;
|
|
currentTokenCount?: number;
|
|
compactionTarget?: "budget" | "threshold";
|
|
customInstructions?: string;
|
|
runtimeContext?: ContextEngineRuntimeContext;
|
|
}): Promise<CompactResult> {
|
|
return await delegateCompactionToRuntime(params);
|
|
}
|
|
|
|
async dispose(): Promise<void> {
|
|
// Nothing to clean up for legacy engine
|
|
}
|
|
}
|
|
|
|
export function registerLegacyContextEngine(): void {
|
|
registerContextEngineForOwner("legacy", () => new LegacyContextEngine(), "core", {
|
|
allowSameOwnerRefresh: true,
|
|
});
|
|
}
|