mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-06-13 22:34:06 +00:00
fix(session): reject non-integer consolidated offsets
maintainer edit: corrupt session metadata can contain JSON strings, nulls, floats, or booleans. Reset non-integer offsets before range checks so recovery keeps valid messages visible instead of falling back to an empty session.
This commit is contained in:
parent
0307ee6b73
commit
13178f3eaa
@ -101,7 +101,11 @@ class Session:
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
# An out-of-range offset (corrupt metadata) would hide all history; reset it.
|
||||
if not 0 <= self.last_consolidated <= len(self.messages):
|
||||
if (
|
||||
isinstance(self.last_consolidated, bool)
|
||||
or not isinstance(self.last_consolidated, int)
|
||||
or not 0 <= self.last_consolidated <= len(self.messages)
|
||||
):
|
||||
self.last_consolidated = 0
|
||||
|
||||
@staticmethod
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
"""Reset a corrupt last_consolidated offset instead of hiding history (#4066)."""
|
||||
|
||||
from nanobot.session.manager import Session
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from nanobot.session.manager import Session, SessionManager
|
||||
|
||||
|
||||
def _session(count: int, last_consolidated: int) -> Session:
|
||||
def _session(count: int, last_consolidated: object) -> Session:
|
||||
msgs = [{"role": "user", "content": f"msg{i}"} for i in range(count)]
|
||||
return Session(key="chan:chat", messages=msgs, last_consolidated=last_consolidated)
|
||||
|
||||
@ -13,6 +16,44 @@ def test_out_of_range_offset_is_reset():
|
||||
assert _session(3, -5).last_consolidated == 0
|
||||
|
||||
|
||||
def test_non_integer_offset_is_reset():
|
||||
for offset in ("999", None, 0.5, True):
|
||||
assert _session(3, offset).last_consolidated == 0
|
||||
|
||||
|
||||
def test_loaded_corrupt_offset_keeps_messages(tmp_path: Path):
|
||||
offsets = {
|
||||
"string": "999",
|
||||
"null": None,
|
||||
"float": 0.5,
|
||||
"bool": True,
|
||||
}
|
||||
|
||||
for name, offset in offsets.items():
|
||||
manager = SessionManager(tmp_path / name)
|
||||
path = manager._get_session_path("chan:chat")
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
message = {"role": "user", "content": f"survived {name}"}
|
||||
path.write_text(
|
||||
"\n".join([
|
||||
json.dumps({
|
||||
"_type": "metadata",
|
||||
"key": "chan:chat",
|
||||
"metadata": {},
|
||||
"last_consolidated": offset,
|
||||
}),
|
||||
json.dumps(message),
|
||||
]) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
session = manager.get_or_create("chan:chat")
|
||||
|
||||
assert session.messages == [message]
|
||||
assert session.last_consolidated == 0
|
||||
assert session.get_history(max_messages=10) == [message]
|
||||
|
||||
|
||||
def test_valid_offset_is_preserved():
|
||||
session = _session(10, 4)
|
||||
assert session.last_consolidated == 4
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user