feat(routing): add relayMode for schema-locked context handoffs (#11839)

Boarded with #12003/#11841/#11840 in one combined worktree: typecheck:core, check:file-size, check:changelog-integrity, check:complexity, check:cognitive-complexity, check:cycles all green; 24/24 focused tests pass. relayMode is opt-in and defaults to standard, so this is backward-compatible as claimed — verified the plumbing through resolveUniversalHandoffConfig/resolveContextRelayConfig/selectMessagesForSummary. Thanks for the clean, well-tested addition.
This commit is contained in:
Syed Raheemuddin
2026-08-30 11:22:10 +05:30
committed by GitHub
parent 92574de164
commit d26fe03801
4 changed files with 89 additions and 10 deletions

View File

@@ -1640,7 +1640,8 @@ async function handleComboChatInner({
lastModel,
modelStr,
`Model routing: ${lastModel}${modelStr}`,
existingHandoff
existingHandoff,
universalHandoffConfig.relayMode
);
}
}

View File

@@ -48,6 +48,7 @@ export interface ContextRelayConfig {
handoffThreshold?: number;
handoffProviders?: string[];
maxMessagesForSummary?: number;
relayMode?: "schema-locked" | "standard";
}
export interface UniversalHandoffConfig {
@@ -65,6 +66,7 @@ export interface UniversalHandoffConfig {
ttlMinutes: number;
/** Preserve existing system prompt when injecting handoff */
preserveSystemPrompt: boolean;
relayMode?: "schema-locked" | "standard";
}
export const DEFAULT_UNIVERSAL_HANDOFF_CONFIG: UniversalHandoffConfig = {
@@ -155,6 +157,8 @@ export function resolveUniversalHandoffConfig(
"preserveSystemPrompt",
DEFAULT_UNIVERSAL_HANDOFF_CONFIG.preserveSystemPrompt
),
relayMode:
getString("relayMode", "standard") === "schema-locked" ? "schema-locked" : "standard",
};
}
export interface ParsedHandoffContent {
@@ -192,6 +196,7 @@ export function resolveContextRelayConfig(
Number.isFinite(rawMaxMessages) && rawMaxMessages >= 5 && rawMaxMessages <= 100
? Math.round(rawMaxMessages)
: DEFAULT_MAX_MESSAGES_FOR_SUMMARY,
relayMode: config?.relayMode === "schema-locked" ? "schema-locked" : "standard",
};
}
@@ -232,7 +237,8 @@ function formatMessagesForPrompt(messages: MessageLike[]): string {
export function selectMessagesForSummary(
messages: MessageLike[],
maxMessages: number
maxMessages: number,
relayMode?: "schema-locked" | "standard"
): MessageLike[] {
const validMessages = messages.filter((m) => m && typeof m === "object");
const system = validMessages.filter(
@@ -242,15 +248,23 @@ export function selectMessagesForSummary(
(m) => typeof m.role !== "string" || (m.role !== "system" && m.role !== "developer")
);
const recentMessages = [...system, ...nonSystem.slice(-maxMessages)];
const recentMessages =
relayMode === "schema-locked"
? [...nonSystem.slice(-maxMessages)]
: [...system, ...nonSystem.slice(-maxMessages)];
let working = [...recentMessages];
while (working.length > system.length + 1) {
const minWorkingLength = relayMode === "schema-locked" ? 1 : system.length + 1;
while (working.length > minWorkingLength) {
const history = formatMessagesForPrompt(working);
if (estimateTokens(history) <= MAX_HISTORY_TOKENS_FOR_SUMMARY) {
return working;
}
working = [...system, ...working.slice(system.length + 1)];
working =
relayMode === "schema-locked"
? working.slice(1)
: [...system, ...working.slice(system.length + 1)];
}
const fallbackHistory = formatMessagesForPrompt(working);
@@ -258,7 +272,7 @@ export function selectMessagesForSummary(
// If there are system messages, return them so the caller can still produce context.
// If there are no system messages (system=[]), fall back to the single most-recent
// non-system message rather than returning [] which would silently drop the handoff.
if (system.length > 0) {
if (relayMode !== "schema-locked" && system.length > 0) {
return system;
}
const lastNonSystem = nonSystem[nonSystem.length - 1];
@@ -386,7 +400,8 @@ async function generateHandoffAsync(options: {
const summaryModel = relayConfig.handoffModel || options.model;
const selectedMessages = selectMessagesForSummary(
Array.isArray(options.messages) ? options.messages : [],
relayConfig.maxMessagesForSummary
relayConfig.maxMessagesForSummary,
relayConfig.relayMode
);
const historyText = formatMessagesForPrompt(selectedMessages);
if (!historyText) return;
@@ -499,7 +514,8 @@ The context above contains a concise summary of the prior work. Continue seamles
export function injectHandoffIntoBody(
body: Record<string, unknown>,
payload: HandoffPayload
payload: HandoffPayload,
_relayMode?: "schema-locked" | "standard"
): Record<string, unknown> {
const handoffContent = buildHandoffSystemMessage(payload);
const isResponsesRequest =
@@ -680,12 +696,14 @@ async function generateUniversalHandoffAsync(options: {
handoffModel: string;
ttlMs: number;
maxMessages: number;
relayMode?: "schema-locked" | "standard";
providerAllowlist: string[];
handleSingleModel: (body: Record<string, unknown>, modelStr: string) => Promise<Response>;
}): Promise<UniversalHandoffOutcome> {
const selectedMessages = selectMessagesForSummary(
Array.isArray(options.messages) ? options.messages : [],
options.maxMessages
options.maxMessages,
options.relayMode
);
const historyText = formatMessagesForPrompt(selectedMessages);
if (!historyText) return "unavailable";
@@ -789,6 +807,7 @@ export function maybeGenerateUniversalHandoff(options: {
handoffModel: options.universalConfig.handoffModel || options.currModel,
ttlMs,
maxMessages: options.universalConfig.maxMessagesForSummary,
relayMode: options.universalConfig.relayMode,
providerAllowlist: options.universalConfig.providerAllowlist,
handleSingleModel: options.handleSingleModel,
})
@@ -812,7 +831,8 @@ export function injectUniversalHandoffBody(
prevModel: string,
currModel: string,
reason: string,
existingPayload?: HandoffPayload | null
existingPayload?: HandoffPayload | null,
_relayMode?: "schema-locked" | "standard"
): Record<string, unknown> {
const handoffContent = buildUniversalHandoffSystemMessage(
prevModel,

View File

@@ -200,6 +200,7 @@ export const comboRuntimeConfigSchema = z
fallbackCompressionMode: compressionModeSchema.optional(),
fallbackCompressionThreshold: z.coerce.number().int().min(0).max(2_000_000).optional(),
predictiveTtftMs: z.coerce.number().int().min(0).max(300000).optional(),
relayMode: z.enum(["schema-locked", "standard"]).optional(),
// Auto-Combo / LKGP Extensions
candidatePool: z.array(z.string().min(1)).optional(),
weights: scoringWeightsSchema.optional(),

View File

@@ -307,6 +307,63 @@ test("maybeGenerateHandoff allows a new attempt after a failed in-flight generat
assert.equal(calls, 2);
});
test("selectMessagesForSummary handles schema-locked vs standard relayMode", () => {
const messages = [
{ role: "system", content: "System instruction" },
{ role: "user", content: "Msg 1" },
{ role: "assistant", content: "Msg 2" },
{ role: "user", content: "Msg 3" },
];
// Standard mode includes system message
const standard = contextHandoff.selectMessagesForSummary(messages, 2, "standard");
assert.equal(standard[0].role, "system");
assert.equal(standard.length, 3); // system + last 2
// Schema-locked mode excludes system message
const locked = contextHandoff.selectMessagesForSummary(messages, 2, "schema-locked");
assert.equal(locked[0].role, "assistant");
assert.equal(locked[0].content, "Msg 2");
assert.equal(locked.length, 2); // only non-system slice
});
test("selectMessagesForSummary trims non-system messages and excludes system in schema-locked token overflow", () => {
// Input with system messages and huge non-system messages exceeding token limit
const hugeText = "x".repeat(35000);
const messages = [
{ role: "system", content: "System prompt" },
{ role: "developer", content: "Developer prompt" },
{ role: "user", content: `User msg 1: ${hugeText}` },
{ role: "assistant", content: `Assistant msg 2: ${hugeText}` },
{ role: "user", content: "User msg 3 short" },
];
const trimmedLocked = contextHandoff.selectMessagesForSummary(messages, 10, "schema-locked");
// Should exclude system and developer messages
assert.ok(trimmedLocked.every((m) => m.role !== "system" && m.role !== "developer"));
// Should have trimmed down to non-overflowing messages (or last non-system)
assert.ok(trimmedLocked.length < 3);
assert.equal(trimmedLocked[trimmedLocked.length - 1].content, "User msg 3 short");
});
test("resolveUniversalHandoffConfig correctly parses relayMode", async () => {
const comboSchema = await import("../../src/shared/validation/schemas/combo.ts");
const parsedLocked = comboSchema.comboRuntimeConfigSchema.parse({
relayMode: "schema-locked",
});
assert.equal(parsedLocked.relayMode, "schema-locked");
const parsedStandard = comboSchema.comboRuntimeConfigSchema.parse({
relayMode: "standard",
});
assert.equal(parsedStandard.relayMode, "standard");
const resolvedConfig = contextHandoff.resolveUniversalHandoffConfig({
relayMode: "schema-locked",
});
assert.equal(resolvedConfig.relayMode, "schema-locked");
});
test("maybeGenerateHandoff respects explicit empty handoffProviders and skips generation", async () => {
let called = false;