fix(context-engine): honor assembled prompt authority

This commit is contained in:
Eva
2026-04-29 16:09:11 +07:00
committed by Josh Lehman
parent 0ce0509856
commit 9765a071e8
4 changed files with 78 additions and 2 deletions

View File

@@ -322,6 +322,73 @@ describe("runEmbeddedAttempt context engine sessionKey forwarding", () => {
);
});
it("uses assembled context as the default precheck authority", async () => {
let sawPrompt = false;
const hugeHistory = "large raw history ".repeat(25_000);
const result = await createContextEngineAttemptRunner({
contextEngine: createTestContextEngine({
assemble: async () => ({
messages: [
{ role: "user", content: "small assembled context", timestamp: 1 },
] as AgentMessage[],
estimatedTokens: 8,
}),
}),
sessionKey,
tempPaths,
sessionMessages: [{ role: "user", content: hugeHistory, timestamp: 1 }] as AgentMessage[],
attemptOverrides: {
contextTokenBudget: 500,
},
sessionPrompt: async (session) => {
sawPrompt = true;
session.messages = [
...session.messages,
{ role: "assistant", content: "done", timestamp: 2 },
];
},
});
expect(sawPrompt).toBe(true);
expect(result.promptError).toBeNull();
expect(result.promptErrorSource).toBeNull();
});
it("honors context engines that opt into preassembly overflow authority", async () => {
let sawPrompt = false;
const hugeHistory = "large raw history ".repeat(25_000);
const result = await createContextEngineAttemptRunner({
contextEngine: createTestContextEngine({
assemble: async () => ({
messages: [
{ role: "user", content: "small assembled context", timestamp: 1 },
] as AgentMessage[],
estimatedTokens: 8,
promptAuthority: "preassembly_may_overflow",
}),
}),
sessionKey,
tempPaths,
sessionMessages: [{ role: "user", content: hugeHistory, timestamp: 1 }] as AgentMessage[],
attemptOverrides: {
contextTokenBudget: 500,
},
sessionPrompt: async (session) => {
sawPrompt = true;
session.messages = [
...session.messages,
{ role: "assistant", content: "done", timestamp: 2 },
];
},
});
expect(sawPrompt).toBe(false);
expect(result.promptErrorSource).toBe("precheck");
expect(result.preflightRecovery?.route).toBe("compact_only");
});
it("keeps gateway model runs independent from agent context and session history", async () => {
const bootstrap = vi.fn(async () => ({ bootstrapped: true }));
const assemble = vi.fn(async ({ messages }: { messages: AgentMessage[] }) => ({

View File

@@ -1527,6 +1527,7 @@ export async function runEmbeddedAttempt(
}
let prePromptMessageCount = activeSession.messages.length;
let unwindowedContextEngineMessagesForPrecheck: AgentMessage[] | undefined;
let contextEnginePromptAuthority: "assembled" | "preassembly_may_overflow" = "assembled";
abortSessionForYield = () => {
yieldAbortSettled = Promise.resolve(activeSession.abort());
};
@@ -2089,6 +2090,7 @@ export async function runEmbeddedAttempt(
if (assembled.messages !== activeSession.messages) {
activeSession.agent.state.messages = assembled.messages;
}
contextEnginePromptAuthority = assembled.promptAuthority ?? "assembled";
if (assembled.systemPromptAddition) {
systemPromptText = prependSystemPromptAddition({
systemPrompt: systemPromptText,
@@ -2760,7 +2762,9 @@ export async function runEmbeddedAttempt(
const preemptiveCompaction = shouldPreemptivelyCompactBeforePrompt({
messages: activeSession.messages,
unwindowedMessages: unwindowedContextEngineMessagesForPrecheck,
...(contextEnginePromptAuthority === "preassembly_may_overflow"
? { unwindowedMessages: unwindowedContextEngineMessagesForPrecheck }
: {}),
systemPrompt: systemPromptText,
prompt: effectivePrompt,
contextTokenBudget,

View File

@@ -93,7 +93,7 @@ describe("preemptive-compaction", () => {
expect(result.estimatedPromptTokens).toBeLessThan(result.promptBudgetBeforeReserve);
});
it("uses the larger unwindowed message estimate when context engine assembly windows history", () => {
it("uses the larger unwindowed message estimate when explicitly provided", () => {
const result = shouldPreemptivelyCompactBeforePrompt({
messages: [makeAssistantHistory("small assembled window")],
unwindowedMessages: [makeAssistantHistory(verboseHistory.repeat(4))],

View File

@@ -8,6 +8,11 @@ export type AssembleResult = {
messages: AgentMessage[];
/** Estimated total tokens in assembled context */
estimatedTokens: number;
/**
* Declares whether the assembled messages are the authoritative prompt for
* overflow prechecks. Defaults to "assembled".
*/
promptAuthority?: "assembled" | "preassembly_may_overflow";
/** Optional context-engine-provided instructions prepended to the runtime system prompt */
systemPromptAddition?: string;
};