aca4dc86a3
_truncate_for_sync documents "the last sentence boundary within max_len", but it looped over separator KINDS and returned on the first kind that qualified. An early "。" therefore outranked a "." 240 characters later, and in pure ASCII "." outranked a later "!" or "?" purely because it comes first in the tuple. With the 450-char default, "a"*200 + "。" + "b"*240 + "." + "c"*100 kept 201 of the 442 characters available: 241 characters the embedder would have accepted were discarded, so any fact in the second half of the turn never reached extraction. The add() call succeeds, so unlike #106235 nothing is logged — the turn is simply remembered from its first sentence. Raising sync_max_chars widens the gap rather than closing it. Take the max over every separator instead, from a named tuple so the set is not buried in the loop. ".\n" is dropped: its index can never exceed the bare "." it starts with, so under a max it is unreachable. The first-third guard and the hard-cut fallback for unsegmented input are unchanged. Fixes #108868