fix(session): preserve clean shortened close snapshots
parent
69fd846ef8
commit
50aebcbcff
10
run_agent.py
10
run_agent.py
|
|
@ -1887,7 +1887,15 @@ class AIAgent:
|
||||||
# clean replacement for an API-local noted payload. Preserve the
|
# clean replacement for an API-local noted payload. Preserve the
|
||||||
# historical text-only guard for a list payload, though: a plain
|
# historical text-only guard for a list payload, though: a plain
|
||||||
# text override must not erase its image/audio transcript summary.
|
# text override must not erase its image/audio transcript summary.
|
||||||
if _ov_idx == _msg_idx and msg.get("role") == "user":
|
# The close safety-net may flush a shortened snapshot while
|
||||||
|
# turn setup still owns its staged CLI dict. In that shape the
|
||||||
|
# normal turn index refers to the full history, not this list;
|
||||||
|
# preserve the API-local override by recognizing the same dict.
|
||||||
|
pending_cli_message = getattr(self, "_pending_cli_user_message", None)
|
||||||
|
is_current_turn_user = (
|
||||||
|
_ov_idx == _msg_idx or msg is pending_cli_message
|
||||||
|
)
|
||||||
|
if is_current_turn_user and msg.get("role") == "user":
|
||||||
if _ov_content is not None and (
|
if _ov_content is not None and (
|
||||||
not isinstance(content, list) or isinstance(_ov_content, list)
|
not isinstance(content, list) or isinstance(_ov_content, list)
|
||||||
):
|
):
|
||||||
|
|
|
||||||
|
|
@ -492,6 +492,51 @@ def test_cli_close_persists_pending_user_when_agent_snapshot_is_empty(tmp_path,
|
||||||
assert staged["_db_persisted"] is True
|
assert staged["_db_persisted"] is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_cli_close_uses_clean_override_for_shortened_pending_snapshot(tmp_path, monkeypatch):
|
||||||
|
"""Close retains the clean user text when its snapshot omits the prefix."""
|
||||||
|
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
|
||||||
|
|
||||||
|
import cli as cli_mod
|
||||||
|
from hermes_state import SessionDB
|
||||||
|
|
||||||
|
db = SessionDB(db_path=tmp_path / "state.db")
|
||||||
|
session_id = "cli-close-shortened-noted-pending"
|
||||||
|
db.create_session(session_id=session_id, source="cli")
|
||||||
|
prefix = [
|
||||||
|
{"role": "user", "content": "old prompt"},
|
||||||
|
{"role": "assistant", "content": "old answer"},
|
||||||
|
]
|
||||||
|
for message in prefix:
|
||||||
|
db.append_message(
|
||||||
|
session_id=session_id,
|
||||||
|
role=message["role"],
|
||||||
|
content=message["content"],
|
||||||
|
)
|
||||||
|
|
||||||
|
agent = _real_agent(db, session_id, [])
|
||||||
|
staged = {"role": "user", "content": "[MODEL NOTE]\n\nnew prompt"}
|
||||||
|
agent._pending_cli_user_message = staged
|
||||||
|
# The normal worker index is relative to the full resumed history, while a
|
||||||
|
# close before its first persistence flush sees only this staged dict.
|
||||||
|
agent._persist_user_message_idx = len(prefix)
|
||||||
|
agent._persist_user_message_override = "new prompt"
|
||||||
|
agent._persist_user_message_timestamp = None
|
||||||
|
|
||||||
|
cli = object.__new__(cli_mod.HermesCLI)
|
||||||
|
cli.conversation_history = list(prefix) + [staged]
|
||||||
|
cli.session_id = session_id
|
||||||
|
cli.agent = agent
|
||||||
|
|
||||||
|
cli._persist_active_session_before_close()
|
||||||
|
|
||||||
|
assert [m["content"] for m in db.get_messages_as_conversation(session_id)] == [
|
||||||
|
"old prompt",
|
||||||
|
"old answer",
|
||||||
|
"new prompt",
|
||||||
|
]
|
||||||
|
assert staged["_db_persisted"] is True
|
||||||
|
|
||||||
|
|
||||||
def test_cli_close_preserves_clean_staged_user_across_noted_worker_turn(tmp_path, monkeypatch):
|
def test_cli_close_preserves_clean_staged_user_across_noted_worker_turn(tmp_path, monkeypatch):
|
||||||
"""A noted API-only turn reuses the close-marked clean staged user row."""
|
"""A noted API-only turn reuses the close-marked clean staged user row."""
|
||||||
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
|
monkeypatch.setenv("HERMES_HOME", str(tmp_path / ".hermes"))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue