the memory context halves: 96 lines, ~8k tokens, 2 parts
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
e36da55815
commit
428d2ecb89
4 changed files with 10 additions and 7 deletions
|
|
@ -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
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
4
memo
|
|
@ -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
|
||||||
|
|
|
||||||
9
test.py
9
test.py
|
|
@ -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):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue