the memory context halves: 96 lines, ~8k tokens, 2 parts

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
victortaelin 2026-07-29 11:25:22 -03:00
parent e36da55815
commit 428d2ecb89
4 changed files with 10 additions and 7 deletions

View file

@ -43,7 +43,7 @@ background.
```sh ```sh
memo config # show the sizes memo config # show the sizes
memo config WAKE_LINES=300 # how many lines wake prints (208 ≈ 16k tokens) memo config WAKE_LINES=300 # how many lines wake prints (96 ≈ 8k tokens)
memo config WAKE_LINES= # back to the default memo config WAKE_LINES= # back to the default
``` ```

View file

@ -325,7 +325,7 @@ function docFrame(n, a) {
cx.globalAlpha = a === undefined ? 1 : a; cx.globalAlpha = a === undefined ? 1 : a;
rich("the *memory context* remains *constant-sized*", W/2, DOC.y - 26, 27); rich("the *memory context* remains *constant-sized*", W/2, DOC.y - 26, 27);
T(num(n) + " memories", W/2 - 195, rowY(9) + 42, 23, INK, "center"); T(num(n) + " memories", W/2 - 195, rowY(9) + 42, 23, INK, "center");
T("16k tokens, always", W/2 + 195, rowY(9) + 42, 23, GREEN, "center"); T("8k tokens, always", W/2 + 195, rowY(9) + 42, 23, GREEN, "center");
cx.globalAlpha = 1; cx.globalAlpha = 1;
} }
// the tree of blocks: 512 memories at the bottom, one block per size above // the tree of blocks: 512 memories at the bottom, one block per size above

4
memo
View file

@ -48,12 +48,12 @@ ME = pretty(__file__)
# what it means. `memo config` shows and edits them. The globals below start # what it means. `memo config` shows and edits them. The globals below start
# at these defaults, so a memory that overrides nothing follows the tool. # at these defaults, so a memory that overrides nothing follows the tool.
KNOBS = { KNOBS = {
"WAKE_LINES": (208, "the memory context: how many lines wake prints"), "WAKE_LINES": (96, "the memory context: how many lines wake prints"),
"ENTRY_CHARS": (280, "the longest one memory may be, in bytes"), "ENTRY_CHARS": (280, "the longest one memory may be, in bytes"),
"PART_CHARS": (20000, "output paging: largest part, in bytes"), "PART_CHARS": (20000, "output paging: largest part, in bytes"),
"PART_LINES": (500, "output paging: largest part, in lines"), "PART_LINES": (500, "output paging: largest part, in lines"),
} }
WAKE_LINES = KNOBS["WAKE_LINES"][0] # ~16k tokens of dense text, in 3 parts WAKE_LINES = KNOBS["WAKE_LINES"][0] # ~8k tokens of dense text, in 2 parts
ENTRY_CHARS = KNOBS["ENTRY_CHARS"][0] ENTRY_CHARS = KNOBS["ENTRY_CHARS"][0]
# Every harness truncates a command that prints too much, and each drops a # Every harness truncates a command that prints too much, and each drops a
# different piece: Claude Code cuts the middle at 30,000 chars, pi cuts the # different piece: Claude Code cuts the middle at 30,000 chars, pi cuts the

View file

@ -214,7 +214,10 @@ check(r.stdout.rstrip().endswith("You are awake."),
with open(os.path.join(d, "seed.txt"), "w") as f: with open(os.path.join(d, "seed.txt"), "w") as f:
day = datetime.date(2020, 1, 1) day = datetime.date(2020, 1, 1)
for i in range(N): for i in range(N):
f.write("%s memory number %d, a thing that happened\n" f.write("%s memory number %d, a thing that happened, was weighed "
"against the rest of the week, turned out to matter more than "
"anyone guessed at the time, and left a mark on every plan "
"that followed it\n"
% ((day + datetime.timedelta(days=i // 5)).isoformat(), i)) % ((day + datetime.timedelta(days=i // 5)).isoformat(), i))
r = run("import", os.path.join(d, "seed.txt")) r = run("import", os.path.join(d, "seed.txt"))
check("Imported %d" % N in r.stdout, "import failed: " + r.stdout + r.stderr) check("Imported %d" % N in r.stdout, "import failed: " + r.stdout + r.stderr)
@ -586,7 +589,7 @@ def fingerprint(path):
# back, an empty value restores the default, and a wake obeys immediately -- # back, an empty value restores the default, and a wake obeys immediately --
# nothing is recomputed, because a size only selects what gets printed. # nothing is recomputed, because a size only selects what gets printed.
r = run("config", "WAKE_LINES=12") r = run("config", "WAKE_LINES=12")
check("12" in r.stdout and "default 208" in r.stdout, "config did not set:\n" + r.stdout) check("12" in r.stdout and "default 96" in r.stdout, "config did not set:\n" + r.stdout)
check(len(run("wake").stdout.splitlines()) <= 13, "wake ignored the new size") check(len(run("wake").stdout.splitlines()) <= 13, "wake ignored the new size")
r = run("config", "WAKE_LINES=") r = run("config", "WAKE_LINES=")
check("default" not in r.stdout, "an empty value did not restore the default") check("default" not in r.stdout, "an empty value did not restore the default")
@ -595,7 +598,7 @@ for bad in ("WAKE_LINES=0", "WAKE_LINES=x", "ENTRY_CHARS=999", "NOPE=1", "WAKE_L
check(run("config", bad).returncode == 1, "config accepted %s" % bad) check(run("config", bad).returncode == 1, "config accepted %s" % bad)
with open(os.path.join(d, "config"), "a") as f: with open(os.path.join(d, "config"), "a") as f:
f.write("WAKE_LINES=120\n") # a size the user tuned by hand f.write("WAKE_LINES=12\n") # a size the user tuned by hand
before = fingerprint(d) before = fingerprint(d)
check(len(before) > 3 and before["LOG.txt"], "the store under test is empty") check(len(before) > 3 and before["LOG.txt"], "the store under test is empty")
for _ in range(3): for _ in range(3):