mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-13 18:15:02 +00:00
fix(llm): commit the staged head hash unconditionally on a recorded response
An unchained request with no system message staged None, and the record step skipped the commit, so the previous head hash survived a transcript that never received a head; a later chained request restoring that head would have omitted it. The staged value is now committed as-is, None included. Also pins each rejection predicate of is_usable_compression_point with its own test.
This commit is contained in:
1 parent
5837c300df
commit
427d85d737
3 files changed
+51
-4
No files matched your search
@@ -1423,10 +1423,12 @@ class OpenAILLM(BaseLLM):
|
||||
if rid:
|
||||
self._last_response_id = rid
|
||||
# The provider recorded this request, so the head it carried (or
|
||||
# kept) is now the chain's head.
|
||||
if self._pending_system_hash is not None:
|
||||
self._chain_system_hash = self._pending_system_hash
|
||||
self._pending_system_hash = None
|
||||
# kept) is now the chain's head — including "no head at all", when
|
||||
# an unchained request went out without a system message: a stale
|
||||
# hash would let a later chained request omit a head this
|
||||
# transcript never received.
|
||||
self._chain_system_hash = self._pending_system_hash
|
||||
self._pending_system_hash = None
|
||||
self._last_response_call_ids = self._function_call_ids(response)
|
||||
usage = getattr(response, "usage", None)
|
||||
if usage is not None:
|
||||
|
||||
@@ -499,3 +499,34 @@ class TestUnusableSavedPoints:
|
||||
|
||||
assert result.compression_performed
|
||||
assert svc.compress_and_save.call_args.kwargs["start_index"] == 2
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestUsablePointPredicates:
|
||||
"""Each rejection predicate of ``is_usable_compression_point`` on its own."""
|
||||
|
||||
def _with_later_point(self, **point):
|
||||
conv = _compressed_conversation()
|
||||
conv["queries"].append({"prompt": "q4", "response": "r4"})
|
||||
conv["compression_metadata"]["compression_points"].append(
|
||||
{"timestamp": "2026-09-04T09:00:00+00:00", "query_index": 3, **point}
|
||||
)
|
||||
return conv
|
||||
|
||||
def test_a_positive_count_does_not_rescue_a_blank_summary(self):
|
||||
conv = self._with_later_point(compressed_summary=" ", compressed_token_count=12)
|
||||
summary, recent = CompressionService(llm=None, model_id="m").get_compressed_context(conv)
|
||||
assert summary == "S"
|
||||
assert [q["prompt"] for q in recent] == ["q2", "q3", "q4"]
|
||||
|
||||
def test_a_zero_count_does_not_rescue_a_non_blank_summary(self):
|
||||
conv = self._with_later_point(compressed_summary="newer", compressed_token_count=0)
|
||||
summary, recent = CompressionService(llm=None, model_id="m").get_compressed_context(conv)
|
||||
assert summary == "S"
|
||||
assert [q["prompt"] for q in recent] == ["q2", "q3", "q4"]
|
||||
|
||||
def test_a_missing_count_with_a_summary_is_usable(self):
|
||||
conv = self._with_later_point(compressed_summary="newer")
|
||||
summary, recent = CompressionService(llm=None, model_id="m").get_compressed_context(conv)
|
||||
assert summary == "newer"
|
||||
assert [q["prompt"] for q in recent] == ["q4"]
|
||||
@@ -402,3 +402,17 @@ def test_output_capped_response_still_records_chain_state(monkeypatch):
|
||||
assert llm._responses_gen("gpt-5.6", _messages(), tools=None) == "partial"
|
||||
assert llm._last_response_id == "resp_len"
|
||||
assert llm._chain_system_hash is not None
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_recorded_request_without_a_head_clears_the_committed_hash(monkeypatch):
|
||||
llm = _make_llm(monkeypatch)
|
||||
llm._build_responses_input(_messages("sys v1"), None)
|
||||
_accepted(llm, "resp_1")
|
||||
# An unchained fallback with no system message at all is recorded: the
|
||||
# new transcript holds no head, so the old hash must not survive it.
|
||||
llm._build_responses_input([{"role": "user", "content": "q"}], None)
|
||||
_accepted(llm, "resp_2")
|
||||
assert llm._chain_system_hash is None
|
||||
chained, _ = llm._build_responses_input(_messages("sys v1"), "resp_2")
|
||||
assert _roles(chained) == ["system", "user"]
|
||||
Reference in new issue
Block a user