Skip to content

fix(agent): persist on a copy so early persist can't strip live user message (salvage #48817) - #56300

Merged
kshitijk4poor merged 1 commit into
NousResearch:mainfrom
kshitijk4poor:salvage-persistcopy
Jul 1, 2026
Merged

kshitijk4poor merged 1 commit into
NousResearch:mainfrom
kshitijk4poor:salvage-persistcopy

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Contributor

Salvage of #48817 (@kyssta-exe), rebased onto current main. Fixes #48677.

Issue (#48677)

_persist_session applied _apply_persist_user_message_override directly to the live messages list. The crash-resilience early persist in build_turn_context runs BEFORE api_messages is built, so with observe_unmentioned_group_messages the override rewrote messages[idx]['content'] to the bare current message — silently dropping observed group-chat context before the request reached the model (and withholding it from replay history). No error, no log.

Fix

Operate on a shallow copy in _persist_session. The override only writes string content, so the copy is sufficient: DB/log get the cleaned transcript while the live list keeps full content for the API call. The override's existing multimodal guard (skips list-content) is unaffected.

Verification

Existing test_persist_session_rewrites_current_turn_user_message updated to assert the live list keeps original content AND the DB write gets the override. Mutation-checked: reverting to in-place mutation fails it.

Closes #48817.

Co-authored-by: kyssta-exe kyssta-exe@users.noreply.github.com

@kshitijk4poor
kshitijk4poor enabled auto-merge (rebase) July 1, 2026 10:41
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jul 1, 2026
… list (NousResearch#48677)

The persist user-message override was applied in place to the live messages
list. On the early crash-resilience persist (which runs BEFORE api_messages is
built), that stripped observed group-chat context off the live user message and
silently dropped it when observe_unmentioned_group_messages was enabled.

Fix at the single chokepoint: _flush_messages_to_session_db resolves the
override (idx/content/timestamp) locally and applies it ONLY to the row written
to the DB — the live dict is never mutated, so EVERY persist caller (early
persist, mid tool-loop flush, /resume, /branch) is protected uniformly. This
supersedes the earlier shallow-copy approach, which broke the intrinsic
_DB_PERSISTED_MARKER idempotency (copies never propagated the marker back to
the live dicts → duplicate rows) and closes the sibling class tracked in NousResearch#56303.

Trailing empty-response scaffolding is still dropped from the live list in
_persist_session (unchanged behavior).

Salvaged from NousResearch#48817; chokepoint reworked to coexist with the marker-based
dedup (NousResearch#50372).

Co-authored-by: kyssta-exe <kyssta-exe@users.noreply.github.com>
@kshitijk4poor
kshitijk4poor force-pushed the salvage-persistcopy branch from dc04fd0 to 1c50027 Compare July 1, 2026 11:53
@kshitijk4poor
kshitijk4poor merged commit 7eb9716 into NousResearch:main Jul 1, 2026
29 checks passed
@kshitijk4poor
kshitijk4poor deleted the salvage-persistcopy branch August 5, 2026 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

observe_unmentioned_group_messages: observed context silently dropped before the API call (early persist mutates the shared messages list)

3 participants