Skip to content

Commit d55bb08

Browse files
Merge historian references: 3 seeds, 3 scored diverse, 4 unscored recent
Co-authored-by: Alfonso <alfonso-magic-context@users.noreply.github.com>
2 parents 0e03e1b + 81f6cf3 commit d55bb08

19 files changed

Lines changed: 2100 additions & 172 deletions

‎crates/mc-module/gen/gen-historian-prompt-golden.ts‎

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const { buildCompartmentAgentPrompt } = promptMod as {
2525
extractionFree?: boolean;
2626
}) => string;
2727
};
28-
const { buildReferenceBlocks, selectSeeds, renderSeedExamplesBlock } = referenceMod as {
28+
const { buildReferenceBlocks, selectSeeds, renderSeedExamplesBlock, selectSessionReferences, renderSessionReferencesBlock } = referenceMod as {
2929
buildReferenceBlocks: (args: {
3030
sessionId: string;
3131
chunkStart: number;
@@ -37,6 +37,8 @@ const { buildReferenceBlocks, selectSeeds, renderSeedExamplesBlock } = reference
3737
count?: number,
3838
) => Array<{ importance: number; block: string }>;
3939
renderSeedExamplesBlock: (seeds: Array<{ importance: number; block: string }>) => string;
40+
selectSessionReferences: (compartments: TsReferenceCompartment[], seeds: Array<{ importance: number; block: string }>, sessionId: string, chunkStart: number) => TsReferenceCompartment[];
41+
renderSessionReferencesBlock: (selected: TsReferenceCompartment[], window?: number) => string;
4042
};
4143
const { renderHistorianMemoryBlock } = injectMod as {
4244
renderHistorianMemoryBlock: (memories: TsMemory[]) => string | null;
@@ -190,14 +192,14 @@ const matureCompartments: ReferenceCompartmentJson[] = [
190192
{
191193
start_message: 1,
192194
end_message: 5,
193-
title: "old omitted one",
195+
title: "older low-mid one",
194196
content: "old content one",
195197
importance: 10,
196198
},
197199
{
198200
start_message: 6,
199201
end_message: 12,
200-
title: "old omitted two",
202+
title: "older low-mid two",
201203
content: "old content two",
202204
importance: 20,
203205
},
@@ -334,9 +336,9 @@ const promptCaseSpecs: PromptCaseSpec[] = [
334336
];
335337

336338
const seedCaseSpecs: SeedCaseSpec[] = [
337-
{ label: "default rotation a", session_id: "rot-a", chunk_start: 0, count: 4 },
338-
{ label: "default rotation b", session_id: "rot-b", chunk_start: 1, count: 4 },
339-
{ label: "unicode utf16 rotation", session_id: "emoji-🚀-session", chunk_start: 7, count: 4 },
339+
{ label: "default rotation a", session_id: "rot-a", chunk_start: 0, count: 3 },
340+
{ label: "default rotation b", session_id: "rot-b", chunk_start: 1, count: 3 },
341+
{ label: "unicode utf16 rotation", session_id: "emoji-🚀-session", chunk_start: 7, count: 3 },
340342
{ label: "flat fallback count above band guard", session_id: "fallback", chunk_start: 12345, count: 25 },
341343
];
342344

@@ -367,7 +369,7 @@ const promptCases: PromptCase[] = promptCaseSpecs.map((spec) => {
367369
});
368370
return {
369371
...spec,
370-
selected_seed_indices: selectedSeedIndices(spec.session_id, spec.chunk_start, 4),
372+
selected_seed_indices: selectedSeedIndices(spec.session_id, spec.chunk_start, 3),
371373
seed_examples: refs.seedExamples,
372374
session_references: refs.sessionReferences,
373375
project_memory: projectMemory,
@@ -376,7 +378,7 @@ const promptCases: PromptCase[] = promptCaseSpecs.map((spec) => {
376378
});
377379

378380
const distinctDefaultSelections = new Set(
379-
seedCases.filter((c) => c.count === 4).map((c) => JSON.stringify(c.selected_indices)),
381+
seedCases.filter((c) => c.count === 3).map((c) => JSON.stringify(c.selected_indices)),
380382
);
381383
if (distinctDefaultSelections.size <= 1) {
382384
throw new Error("seed rotation cases are vacuous; distinct inputs produced the same selection");
@@ -394,7 +396,38 @@ if (!promptCases.some((c) => c.project_memory.length > 0)) {
394396
throw new Error("prompt cases never emitted project memory");
395397
}
396398

397-
const golden = { seed_cases: seedCases, prompt_cases: promptCases };
399+
// Boundary scores, clustered histories and Unicode ids pin band choice, tie
400+
// rotation, no-content exclusion and every fitting suffix in both languages.
401+
const referenceSpecs = [
402+
{ label: "mixed recent bands", scores: [1, 9, 10, 29, 30, 59, 60, 84, 85, 100, 70, 90, 70, 90] },
403+
{ label: "all bands covered", scores: [5, 20, 40, 70, 90, 5, 20, 40, 70, 90, 5, 20, 40, 70] },
404+
{ label: "history lacks low bands", scores: [40, 70, 90, 40, 70, 90, 70, 70, 70, 70] },
405+
{ label: "one older band", scores: [...Array(20).fill(40), 70, 70, 70, 70] },
406+
{ label: "no-content gaps", scores: [5, 20, 40, 70, 90, 50, 70, 90], markers: true },
407+
...Array.from({ length: 6 }, (_, count) => ({ label: `young ${count}`, scores: Array(count).fill(50) })),
408+
];
409+
const referenceCases = referenceSpecs.map((spec, caseIndex) => {
410+
const session_id = "calibration-🚀";
411+
const chunk_start = 42 + caseIndex;
412+
const session_compartments: ReferenceCompartmentJson[] = spec.scores.map((importance, i) => ({
413+
start_message: i * 10 + 1, end_message: i * 10 + 10,
414+
title: `Compartment ${i}`, content: `Body & <${i}>`, importance, episode_type: "feature",
415+
}));
416+
if ("markers" in spec && spec.markers) {
417+
for (const at of [session_compartments.length, 4, 0]) session_compartments.splice(at, 0, {
418+
start_message: 999, end_message: 999, title: "", content: "", importance: 1,
419+
});
420+
}
421+
const seeds = selectSeeds(session_id, chunk_start);
422+
const selected = selectSessionReferences(session_compartments.map(toTsCompartment), seeds, session_id, chunk_start);
423+
return {
424+
label: spec.label, session_id, chunk_start, session_compartments,
425+
seed_examples: renderSeedExamplesBlock(seeds),
426+
selected_starts: selected.map((c) => c.startMessage),
427+
windows: Array.from({ length: 8 }, (_, window) => ({ window, block: renderSessionReferencesBlock(selected, window) })),
428+
};
429+
});
430+
const golden = { seed_cases: seedCases, prompt_cases: promptCases, reference_cases: referenceCases };
398431
const rendered = `${JSON.stringify(golden, null, 2)}\n`;
399432
const outPath = join(import.meta.dir, "..", "testdata", "historian-prompt-golden.json");
400433

@@ -408,8 +441,8 @@ if (process.argv.includes("--check")) {
408441
console.error(`historian prompt golden drifted; regenerate ${outPath}`);
409442
process.exit(1);
410443
}
411-
console.log(`historian prompt golden up to date: ${outPath}`);
444+
console.log(`historian prompt golden up to date: ${promptCases.length} prompts, ${seedCases.length} seeds, ${referenceCases.length} reference selections: ${outPath}`);
412445
} else {
413446
writeFileSync(outPath, rendered);
414-
console.log(`wrote ${promptCases.length} historian prompt cases + ${seedCases.length} seed cases → ${outPath}`);
447+
console.log(`wrote ${promptCases.length} prompts + ${seedCases.length} seed cases + ${referenceCases.length} reference selections → ${outPath}`);
415448
}

‎crates/mc-module/src/historian_chunk.rs‎

Lines changed: 89 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::historian::{
2020
use crate::historian_prompt::{
2121
build_compartment_agent_prompt, order_historian_memories, render_historian_memory_block,
2222
render_seed_examples_block, render_session_references_block_window, select_seeds,
23-
CompartmentPromptInputs, ReferenceCompartment, SEED_FLOOR, SESSION_REF_WINDOW,
23+
select_session_references, CompartmentPromptInputs, ReferenceCompartment, SEED_FLOOR,
2424
};
2525
use crate::historian_validate::{
2626
ChunkLine, HistorianChunk, MessageRange, StoredCompartmentRange, ValidateOptions,
@@ -846,19 +846,26 @@ struct HistorianPromptFitInput<'a> {
846846

847847
/// Size the historian prompt to the producer window: reserve the system prompt,
848848
/// the fixed user-prompt blocks and the output first, and give the chunk what
849-
/// remains. When the full requested chunk does not fit, trim recent compartments
850-
/// (oldest first), then project-memory lines (lowest priority first), then seed
849+
/// remains. When the full requested chunk does not fit, trim diverse older
850+
/// compartments before recent compartments (oldest first), then project-memory
851+
/// lines (lowest priority first), then seed
851852
/// examples, and only then shrink the chunk. When not even a minimal chunk fits,
852853
/// the untrimmed blocks are returned so the firing's admission check refuses the
853854
/// prompt and records the failure with a backoff. Untrimmed blocks are
854855
/// byte-identical to the ones the prompt golden pins.
855856
fn fit_historian_prompt(input: &HistorianPromptFitInput<'_>) -> HistorianPromptFit {
856857
let seeds = select_seeds(input.session_id, input.chunk_start as i64, SEED_FLOOR);
858+
let references = select_session_references(
859+
input.compartments,
860+
&seeds,
861+
input.session_id,
862+
input.chunk_start as i64,
863+
);
857864
let memories = order_historian_memories(input.memories);
858865
let render = |refs: usize, memory_count: usize, seed_count: usize| {
859866
(
860867
render_seed_examples_block(&seeds[..seed_count]),
861-
render_session_references_block_window(input.compartments, refs),
868+
render_session_references_block_window(&references, refs),
862869
render_historian_memory_block(&memories[..memory_count]),
863870
)
864871
};
@@ -871,14 +878,14 @@ fn fit_historian_prompt(input: &HistorianPromptFitInput<'_>) -> HistorianPromptF
871878
session_references,
872879
memory_block,
873880
kept: (refs, memory_count, seed_count),
874-
trimmed: refs < SESSION_REF_WINDOW
881+
trimmed: refs < references.len()
875882
|| memory_count < memories.len()
876883
|| seed_count < seeds.len(),
877884
}
878885
};
879886
let untrimmed = || {
880887
accept(
881-
SESSION_REF_WINDOW,
888+
references.len(),
882889
memories.len(),
883890
seeds.len(),
884891
input.requested,
@@ -938,8 +945,8 @@ fn fit_historian_prompt(input: &HistorianPromptFitInput<'_>) -> HistorianPromptF
938945
room(refs, memory_count, seed_count).is_some_and(|room| room >= input.requested)
939946
};
940947

941-
// 1. Recent compartments, oldest dropped first.
942-
for refs in (0..=SESSION_REF_WINDOW).rev() {
948+
// 1. Diverse compartments first, then recent compartments oldest first.
949+
for refs in (0..=references.len()).rev() {
943950
if has_room(refs, memories.len(), seeds.len()) {
944951
return accept(refs, memories.len(), seeds.len(), input.requested);
945952
}
@@ -2392,9 +2399,10 @@ mod tests {
23922399
"producer must receive the whole formatted component"
23932400
);
23942401
let prompt_hash = format!("{:x}", sha2::Sha256::digest(firing.prompt.as_bytes()));
2402+
// Calibration uses three seeds; the transcript component itself is unchanged.
23952403
assert_eq!(
23962404
prompt_hash,
2397-
"90e949d5ecab64b27a84497213d8aa03b450b025d2bf301e0d61593d98f2de27"
2405+
"1b08d1670ba7beb7434d8d8140a74d7037b9a271c31088b731b3326786f76e5c"
23982406
);
23992407
let validated = crate::historian_validate::validate_historian_output(
24002408
&historian_output(1, 3, 4),
@@ -3439,10 +3447,74 @@ mod prompt_fit_tests {
34393447
let (fit, limit, sent) = fit_with(1_000_000, 8_000, &memories, &compartments);
34403448
assert!(!fit.trimmed);
34413449
assert_eq!(fit.chunk_tokens, 10_000);
3442-
assert_eq!(fit.kept, (SESSION_REF_WINDOW, 300, SEED_FLOOR));
3450+
assert_eq!(fit.kept, (compartments.len(), 300, SEED_FLOOR));
34433451
assert!(sent <= limit as f64);
34443452
}
34453453

3454+
#[test]
3455+
fn fit_drops_diverse_before_recent_and_oldest_recent_first() {
3456+
let mut compartments = compartments();
3457+
// Twelve distinct rows give three diverse older examples and four recent.
3458+
while compartments.len() < 12 {
3459+
let i = compartments.len();
3460+
let mut row = compartments[0].clone();
3461+
row.start_message = i as i64 * 10 + 1;
3462+
row.end_message = i as i64 * 10 + 10;
3463+
row.title = format!("Compartment {i}");
3464+
compartments.push(row);
3465+
}
3466+
let seeds = select_seeds("ses-fit", 61, SEED_FLOOR);
3467+
let refs = select_session_references(&compartments, &seeds, "ses-fit", 61);
3468+
assert_eq!(refs.len(), 7);
3469+
let seed = DecisionCalibration::for_model(Some(MODEL));
3470+
let system_tokens =
3471+
estimate_tokens(crate::historian_prompt::HISTORIAN_SYSTEM_PROMPT) as f64;
3472+
for remaining in [6, 4, 3] {
3473+
let expected = render_session_references_block_window(&refs, remaining);
3474+
let prompt = build_compartment_agent_prompt(&CompartmentPromptInputs {
3475+
seed_examples: &render_seed_examples_block(&seeds),
3476+
session_references: &expected,
3477+
project_memory: "",
3478+
input_source: "Messages 61-400:\n\n",
3479+
memory_enabled: true,
3480+
extraction_free: false,
3481+
});
3482+
let limit = seed
3483+
.provider_mass(
3484+
LocalMass {
3485+
system: system_tokens,
3486+
prose: (estimate_tokens(&prompt) + 10_000 + PROMPT_FIT_SLACK_TOKENS) as f64,
3487+
tools: 0.0,
3488+
},
3489+
true,
3490+
)
3491+
.ceil() as usize;
3492+
let fit = fit_historian_prompt(&HistorianPromptFitInput {
3493+
session_id: "ses-fit",
3494+
chunk_start: 61,
3495+
last_ordinal: 400,
3496+
compartments: &compartments,
3497+
memories: &[],
3498+
memory_enabled: true,
3499+
extraction_free: false,
3500+
limit: Some(limit),
3501+
seed: &seed,
3502+
system_tokens,
3503+
requested: 10_000,
3504+
});
3505+
assert_eq!(fit.kept, (remaining, 0, 3));
3506+
assert_eq!(fit.session_references, expected);
3507+
for i in (12 - remaining.min(4))..12 {
3508+
assert!(fit
3509+
.session_references
3510+
.contains(&format!("title=\"Compartment {i}\"")));
3511+
}
3512+
if remaining == 3 {
3513+
assert!(!fit.session_references.contains("title=\"Compartment 8\""));
3514+
}
3515+
}
3516+
}
3517+
34463518
#[test]
34473519
fn trims_references_then_memory_so_the_requested_chunk_fits() {
34483520
let memories = memories(300);
@@ -3453,8 +3525,13 @@ mod prompt_fit_tests {
34533525
let full = build_compartment_agent_prompt(&CompartmentPromptInputs {
34543526
seed_examples: &render_seed_examples_block(&select_seeds("ses-fit", 61, SEED_FLOOR)),
34553527
session_references: &render_session_references_block_window(
3456-
&compartments,
3457-
SESSION_REF_WINDOW,
3528+
&select_session_references(
3529+
&compartments,
3530+
&select_seeds("ses-fit", 61, SEED_FLOOR),
3531+
"ses-fit",
3532+
61,
3533+
),
3534+
crate::historian_prompt::SESSION_REF_LIMIT,
34583535
),
34593536
project_memory: &render_historian_memory_block(&memories),
34603537
input_source: "Messages 61-400:\n\n",

0 commit comments

Comments
 (0)