fix(agent): run post_llm_call hook before session persistence - #14913
aniruddhaadak80 wants to merge 3 commits into
Conversation
|
Thanks for the focused ordering investigation. Problems
Suggested changes
Automated hermes-sweeper review. |
30b4cf6 to
605f368
Compare
The hook fired after _persist_session, so a plugin's rewritten response was delivered to the user but never became durable: /resume replayed the original text and post_llm_call observers synced the untransformed transcript. Move the hook into the finalize path right after the closing-assistant-row block and before the persist override/micro-compaction/persist sequence. When a transformation applies, rewrite the turn's closing assistant row in place using the same durability steps as the pure-tool-tail fill (restamp, drop _db_persisted so the next flush re-writes content, invalidate the bounded flush-scan cursor). post_llm_call now observes the transformed response, matching what the user saw. Adds regression tests pinning: hook-before-persist ordering, transformed text in the persisted transcript, no-op results leaving everything intact, post_llm_call receiving the transformed text, and hook failures staying contained. Fixes feedback on NousResearch#14913 (rebased onto current main).
605f368 to
bb82198
Compare
|
@teknium1 Both points from your review are addressed in bb82198 (pushed to this branch):
Regression coverage in Happy to adjust if the durability rewrite should use a different mechanism than the flush-marker path. |
|
Thanks for the precise review - both readings are correct, and they leave this PR at a genuine fork that needs a maintainer call rather than a mechanical fix:
Two paths forward:
Happy to execute either immediately - @teknium1 / @austinpickett, which way do you want it? |
…ersist-order # Conflicts: # agent/turn_finalizer.py
What does this PR do?
The
transform_llm_outputplugin hook ran after the assistant turn had already been persisted. Consequences: (a) plugins that mutate the final response could not influence what got saved, so session replay/search showed pre-transform text that never matched what the user saw; (b) a hook raising mid-flight left the persisted row and the in-memory history inconsistent.This PR moves the hook to run inside the persist try-block, immediately after the closing assistant row is filled but before the row is stamped/persisted � so a transformed response is what reaches the session DB and the returned
final_response. When a transform occurs, the pending assistant message is rewritten with the transformed content and the DB flush cursor invalidated (_db_flush_scan_prefix = None) so the updated row is re-persisted; timestamps stay consistent viastamp_message_timestamp.post_llm_callstill fires after the turn-completion explainer, unchanged.Recreated fresh off current
main(the original branch was based on an old tree where the hook lived inplugins; it now lives inhermes_cli.lifecycle.invoke_hook).Related Issue
N/A � reviewer-requested rebuild of #14913 itself.
Type of Change
Changes Made
agent/turn_finalizer.py: hoisted_response_transformed/_pre_transform_responseinit next to_cleanup_errors; moved thetransform_llm_outputinvocation from the post-persist block into the persist try-block after the tail-closing fill; on transform, rewrite the last assistant message (restamp +_db_persistedpop + flush-prefix invalidation); removed the late post-persist block.tests/agent/test_transform_before_persist.py: new � 5 behavior tests using a stub agent (transform result replaces persisted + returned text; untransformed turns untouched; hook errors don't break persistence; ordering vs persist asserted).tests/test_transform_llm_output_hook.pypasses unchanged.How to Test
pytest tests/agent/test_transform_before_persist.py tests/test_transform_llm_output_hook.py -qtransform_llm_outputlifecycle hook that appends a marker string, run one CLI turn with a fresh session, then/searchthe marker � before this change the session DB only contained pre-transform text; now the transformed text is searchable.Checklist
Code
pytest tests/ -qand all tests pass (9 targeted tests green; unrelated Windows-local failures reproduce on cleanmain)Documentation & Housekeeping
cli-config.yaml.example� or N/ACONTRIBUTING.md/AGENTS.md� or N/AScreenshots / Logs
N/A.