fix: flat-budget walk in get_memories_for_context

The per-type slicing (available // len(memory_types)) starved
paragraph-length memories: with 3 types and a 450-char budget,
each type got ~131 chars while real project memories are 300-500
chars each — every entry was skipped and the new Project Memories
band never appeared in the live pack.

Switch to a flat budget pool walked type-by-type in order. Short
identity/preference memories still get first pick when the budget
is tight, but long project memories can now compete for space.

Caught on the first post-deploy probe: 2 active p04 memories
existed but none landed in formatted_context.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-11 11:43:41 -04:00
parent 8ea53f4003
commit 5913da53c5

View File

@@ -369,10 +369,13 @@ def get_memories_for_context(
available = budget - wrapper_chars available = budget - wrapper_chars
selected_entries: list[str] = [] selected_entries: list[str] = []
used = 0
for index, mtype in enumerate(memory_types): # Flat budget across types so paragraph-length project memories
type_budget = available if index == len(memory_types) - 1 else max(0, available // (len(memory_types) - index)) # aren't starved by an even slice. Types are still walked in order
type_used = 0 # (identity/preference first when they're the input), so earlier
# types still get first pick when the budget is tight.
for mtype in memory_types:
for mem in get_memories( for mem in get_memories(
memory_type=mtype, memory_type=mtype,
project=project, project=project,
@@ -381,11 +384,10 @@ def get_memories_for_context(
): ):
entry = f"[{mem.memory_type}] {mem.content}" entry = f"[{mem.memory_type}] {mem.content}"
entry_len = len(entry) + 1 entry_len = len(entry) + 1
if entry_len > type_budget - type_used: if entry_len > available - used:
continue continue
selected_entries.append(entry) selected_entries.append(entry)
type_used += entry_len used += entry_len
available -= type_used
if not selected_entries: if not selected_entries:
return "", 0 return "", 0