Class NaruCacheKeyChain
Why a chain and not per-segment hashes
Every provider cache in play is a prefix cache: what matters is not whether a given block of text is unchanged, but whether everything before it is also unchanged and in the same order. NARU makes this awkward because conversation history is not append-only —/history delete
removes messages at arbitrary positions.
With independent hashes, deleting the middle message of
[a, b, c] yields [a, c]. Segment c still hashes to
the same value, so a naive implementation would happily treat it as a cache
hit and claim the cached prefix "a c" was seen before. It was not: the
cached prefix was "a b c", and the bytes now differ from position 1
onward. The cache would be reported as valid while serving context that was
never cached — a correctness bug, not a missed optimisation.
Chaining removes the ambiguity. Each key commits to everything before it:
key[0] = H(seg[0]) key[i] = H(key[i-1] + seg[i])so a change anywhere shifts every key after it. Comparing two chains finds the true edit point, and the edit point is the same thing regardless of whether the edit was an append, a deletion, or a mid-history insertion.
-
Method Summary
Modifier and TypeMethodDescriptionchain(List<NaruContextSegment> segments) The hash chain over the given segments, in order.static StringSHA-256, hex encoded.static intvalidPrefixLength(List<String> previousKeys, List<String> currentKeys) How many leading segments are still a valid continuation of the previously cached prefix.
-
Method Details
-
chain
The hash chain over the given segments, in order.Returned keys are what gets persisted between turns. The chain is content-addressed, so the same context always produces the same keys on any machine and in any JVM run — which is what allows the state to be written to disk and trusted after a restart.
-
validPrefixLength
How many leading segments are still a valid continuation of the previously cached prefix.Everything in
[0, validPrefix)can keep whatever cache state it had. Everything fromvalidPrefixonward is a cache miss and must be sent as fresh content.With no baseline the answer is always
0: absence of evidence is treated as evidence of change, because the alternative is trusting a cache reference that may describe context this session never sent. -
sha256
SHA-256, hex encoded.Deliberately a cryptographic hash rather than a fast 64-bit one: a collision here is a false cache hit, which means serving context that was never sent. That failure is silent and user-visible, and it is not worth trading for microseconds next to a network-bound model call.
-