mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-15 17:25:26 -04:00
fix(research): keep Discuss chats grounded on their report (#4006)
* fix(research): preserve Discuss spin-off primer during context trimming
trim_for_context() kept only system_msgs[:1] as essential and dropped the
rest under budget pressure. A research "Discuss" spin-off seeds the report
as a system message that sits after the preface system messages, so it
landed in extra_system and was the first thing evicted once the chat grew
— the conversation then lost its grounding and drifted off task.
Treat any system message carrying research_spinoff_from metadata as
essential, alongside the leading system prompt, so the seeded report
survives trimming. maybe_compact already retains all system messages.
Tests: tests/test_context_compactor.py::TestResearchPrimerPreserved
* fix(research): ground Discuss spin-off chats on the seeded report
build_chat_context injected global memory (pinned + hybrid-retrieved) and
personal-doc RAG every turn, keyed off the user-level memory_enabled pref
and a request-scoped use_rag flag — never the session. A research spin-off,
whose primer declares the report the sole knowledge base, thus had
unrelated keyword-matched facts pulled in ("wrong data") competing with the
report; its rag=False flag was also ignored (use_rag defaulted on).
Add _session_is_research_spinoff(sess) (detects the primer research_spinoff_from
metadata; handles ChatMessage and dict forms) and, for such sessions,
disable memory injection and force RAG off.
Tests: tests/test_chat_helpers.py spin-off detection cases
---------
Co-authored-by: Dan (cirim) <claude@cirim.org>
This commit is contained in:
@@ -218,3 +218,47 @@ def test_save_assistant_response_preserves_actual_and_requested_model():
|
||||
|
||||
assert sess.history[-1].metadata["requested_model"] == "selected-model"
|
||||
assert sess.history[-1].metadata["model"] == "actual-model"
|
||||
|
||||
|
||||
from types import SimpleNamespace
|
||||
from routes.chat_helpers import _session_is_research_spinoff
|
||||
|
||||
|
||||
class _SpinMsg:
|
||||
def __init__(self, role, metadata=None):
|
||||
self.role = role
|
||||
self.metadata = metadata
|
||||
|
||||
|
||||
def test_spinoff_detected_from_chatmessage_history():
|
||||
sess = SimpleNamespace(history=[
|
||||
_SpinMsg("system", {"research_spinoff_from": "rp-1"}),
|
||||
_SpinMsg("user", None),
|
||||
])
|
||||
assert _session_is_research_spinoff(sess) is True
|
||||
|
||||
|
||||
def test_spinoff_detected_from_dict_history():
|
||||
sess = SimpleNamespace(history=[
|
||||
{"role": "system", "metadata": {"research_spinoff_from": "rp-2"}},
|
||||
{"role": "user", "content": "hi"},
|
||||
])
|
||||
assert _session_is_research_spinoff(sess) is True
|
||||
|
||||
|
||||
def test_non_spinoff_plain_session_is_false():
|
||||
sess = SimpleNamespace(history=[
|
||||
_SpinMsg("system", {"compacted": True}),
|
||||
_SpinMsg("user", None),
|
||||
])
|
||||
assert _session_is_research_spinoff(sess) is False
|
||||
|
||||
|
||||
def test_metadata_on_non_system_message_ignored():
|
||||
sess = SimpleNamespace(history=[_SpinMsg("user", {"research_spinoff_from": "rp-3"})])
|
||||
assert _session_is_research_spinoff(sess) is False
|
||||
|
||||
|
||||
def test_empty_or_missing_history():
|
||||
assert _session_is_research_spinoff(SimpleNamespace(history=[])) is False
|
||||
assert _session_is_research_spinoff(SimpleNamespace()) is False
|
||||
|
||||
Reference in New Issue
Block a user