891f44c1a9
llama-server only reuses a byte-identical prompt prefix. Several things changed the prefix every turn, forcing most of the prompt to be re-prefilled: - Memories: rank still chooses which memories fit the budget, but the chosen ones are emitted in stored order, so the block is identical across queries. - History trimming: the conversation-evidence summary is only included when turns were actually dropped (it duplicated retained turns otherwise). On overflow, old turns are dropped at stable cut points down to ~65% of the budget, so the retained prefix holds for several turns instead of shifting by one turn every request. - Tools: TOOL_ROUTING_MODE=static (default) binds the full role-appropriate tool set in registration order with no discovery tool; admin gating is unchanged. TOOL_ROUTING_MODE=dynamic keeps the keyword router. - Observability: per-call model_calls in the stream_request log now include cached_prompt_tokens when the provider reports cache reads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
80 lines
2.9 KiB
Python
80 lines
2.9 KiB
Python
from unittest.mock import AsyncMock
|
|
|
|
import pytest
|
|
|
|
from blueprints.conversation import memory
|
|
|
|
|
|
def test_old_relevant_memory_beats_recent_unrelated():
|
|
memories = ["Favorite restaurant is Nori", "Cat Simba takes insulin"]
|
|
assert (
|
|
memory.rank_memories(memories, "What insulin does Simba take?")[0]
|
|
== memories[1]
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("query", ["", "please", "quantum oscillators"])
|
|
def test_empty_or_unknown_query_retains_recency(query):
|
|
memories = ["Favorite restaurant is Nori", "Cat Simba takes insulin"]
|
|
assert memory.rank_memories(memories, query) == memories
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_prompt_relevance_and_total_memory_budget(monkeypatch):
|
|
old = "Simba insulin dose is two units."
|
|
recent = "Favorite restaurant is Nori. " * 20
|
|
monkeypatch.setattr(
|
|
memory, "get_memories_for_user", AsyncMock(return_value=[recent, old])
|
|
)
|
|
monkeypatch.setattr(memory, "MEMORY_BUDGET_TOKENS", 110)
|
|
prompt = await memory.build_system_prompt_with_memories(
|
|
"user", query="Simba insulin"
|
|
)
|
|
assert old in prompt
|
|
assert recent not in prompt
|
|
assert memory.estimate_tokens(prompt[len(memory.SIMBA_SYSTEM_PROMPT) :]) <= 110
|
|
memory.get_memories_for_user.assert_awaited_once_with("user")
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_backwards_compatible_no_query_and_empty_memories(monkeypatch):
|
|
fetch = AsyncMock(return_value=[])
|
|
monkeypatch.setattr(memory, "get_memories_for_user", fetch)
|
|
assert (
|
|
await memory.build_system_prompt_with_memories("user")
|
|
== memory.SIMBA_SYSTEM_PROMPT
|
|
)
|
|
fetch.return_value = ["Likes tea"]
|
|
assert "Likes tea" in await memory.build_system_prompt_with_memories("user")
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_memory_block_is_identical_across_queries_when_all_fit(monkeypatch):
|
|
memories = ["Favorite restaurant is Nori", "Cat Simba takes insulin", "Gym is Y"]
|
|
monkeypatch.setattr(
|
|
memory, "get_memories_for_user", AsyncMock(return_value=memories)
|
|
)
|
|
prompts = {
|
|
await memory.build_system_prompt_with_memories("user", query=q)
|
|
for q in ["", "Simba insulin", "gym", "Nori restaurant"]
|
|
}
|
|
assert len(prompts) == 1
|
|
prompt = prompts.pop()
|
|
assert prompt.index("Nori") < prompt.index("insulin") < prompt.index("Gym")
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_rank_chooses_memories_but_stored_order_is_kept(monkeypatch):
|
|
filler = "Favorite restaurant is Nori. " * 20
|
|
memories = ["Likes tea", filler, "Simba insulin dose is two units."]
|
|
monkeypatch.setattr(
|
|
memory, "get_memories_for_user", AsyncMock(return_value=memories)
|
|
)
|
|
monkeypatch.setattr(memory, "MEMORY_BUDGET_TOKENS", 110)
|
|
prompt = await memory.build_system_prompt_with_memories(
|
|
"user", query="Simba insulin"
|
|
)
|
|
assert filler not in prompt
|
|
# Insulin ranks first but is emitted after the newer memory.
|
|
assert prompt.index("Likes tea") < prompt.index("insulin")
|