John Scianna 5607da90d5
feat: pass modelId to context engine assemble() (#47437)
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
2026-03-20 08:05:02 -07:00

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,
});
}