test: add unit tests for 8 modules (batch 2)
Cover model_tools, toolset_distributions, context_compressor, prompt_caching, cronjob_tools, session_search, process_registry, and cron/scheduler with 127 new test cases.
This commit is contained in:
parent
240f33a06f
commit
ffbdd7fcce
10 changed files with 1112 additions and 0 deletions
128
tests/agent/test_prompt_caching.py
Normal file
128
tests/agent/test_prompt_caching.py
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
"""Tests for agent/prompt_caching.py — Anthropic cache control injection."""
|
||||
|
||||
import copy
|
||||
import pytest
|
||||
|
||||
from agent.prompt_caching import (
|
||||
_apply_cache_marker,
|
||||
apply_anthropic_cache_control,
|
||||
)
|
||||
|
||||
|
||||
MARKER = {"type": "ephemeral"}
|
||||
|
||||
|
||||
class TestApplyCacheMarker:
|
||||
def test_tool_message_gets_top_level_marker(self):
|
||||
msg = {"role": "tool", "content": "result"}
|
||||
_apply_cache_marker(msg, MARKER)
|
||||
assert msg["cache_control"] == MARKER
|
||||
|
||||
def test_none_content_gets_top_level_marker(self):
|
||||
msg = {"role": "assistant", "content": None}
|
||||
_apply_cache_marker(msg, MARKER)
|
||||
assert msg["cache_control"] == MARKER
|
||||
|
||||
def test_string_content_wrapped_in_list(self):
|
||||
msg = {"role": "user", "content": "Hello"}
|
||||
_apply_cache_marker(msg, MARKER)
|
||||
assert isinstance(msg["content"], list)
|
||||
assert len(msg["content"]) == 1
|
||||
assert msg["content"][0]["type"] == "text"
|
||||
assert msg["content"][0]["text"] == "Hello"
|
||||
assert msg["content"][0]["cache_control"] == MARKER
|
||||
|
||||
def test_list_content_last_item_gets_marker(self):
|
||||
msg = {
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "text", "text": "First"},
|
||||
{"type": "text", "text": "Second"},
|
||||
],
|
||||
}
|
||||
_apply_cache_marker(msg, MARKER)
|
||||
assert "cache_control" not in msg["content"][0]
|
||||
assert msg["content"][1]["cache_control"] == MARKER
|
||||
|
||||
def test_empty_list_content_no_crash(self):
|
||||
msg = {"role": "user", "content": []}
|
||||
# Should not crash on empty list
|
||||
_apply_cache_marker(msg, MARKER)
|
||||
|
||||
|
||||
class TestApplyAnthropicCacheControl:
|
||||
def test_empty_messages(self):
|
||||
result = apply_anthropic_cache_control([])
|
||||
assert result == []
|
||||
|
||||
def test_returns_deep_copy(self):
|
||||
msgs = [{"role": "user", "content": "Hello"}]
|
||||
result = apply_anthropic_cache_control(msgs)
|
||||
assert result is not msgs
|
||||
assert result[0] is not msgs[0]
|
||||
# Original should be unmodified
|
||||
assert "cache_control" not in msgs[0].get("content", "")
|
||||
|
||||
def test_system_message_gets_marker(self):
|
||||
msgs = [
|
||||
{"role": "system", "content": "You are helpful"},
|
||||
{"role": "user", "content": "Hi"},
|
||||
]
|
||||
result = apply_anthropic_cache_control(msgs)
|
||||
# System message should have cache_control
|
||||
sys_content = result[0]["content"]
|
||||
assert isinstance(sys_content, list)
|
||||
assert sys_content[0]["cache_control"]["type"] == "ephemeral"
|
||||
|
||||
def test_last_3_non_system_get_markers(self):
|
||||
msgs = [
|
||||
{"role": "system", "content": "System"},
|
||||
{"role": "user", "content": "msg1"},
|
||||
{"role": "assistant", "content": "msg2"},
|
||||
{"role": "user", "content": "msg3"},
|
||||
{"role": "assistant", "content": "msg4"},
|
||||
]
|
||||
result = apply_anthropic_cache_control(msgs)
|
||||
# System (index 0) + last 3 non-system (indices 2, 3, 4) = 4 breakpoints
|
||||
# Index 1 (msg1) should NOT have marker
|
||||
content_1 = result[1]["content"]
|
||||
if isinstance(content_1, str):
|
||||
assert True # No marker applied (still a string)
|
||||
else:
|
||||
assert "cache_control" not in content_1[0]
|
||||
|
||||
def test_no_system_message(self):
|
||||
msgs = [
|
||||
{"role": "user", "content": "Hello"},
|
||||
{"role": "assistant", "content": "Hi"},
|
||||
]
|
||||
result = apply_anthropic_cache_control(msgs)
|
||||
# Both should get markers (4 slots available, only 2 messages)
|
||||
assert len(result) == 2
|
||||
|
||||
def test_1h_ttl(self):
|
||||
msgs = [{"role": "system", "content": "System prompt"}]
|
||||
result = apply_anthropic_cache_control(msgs, cache_ttl="1h")
|
||||
sys_content = result[0]["content"]
|
||||
assert isinstance(sys_content, list)
|
||||
assert sys_content[0]["cache_control"]["ttl"] == "1h"
|
||||
|
||||
def test_max_4_breakpoints(self):
|
||||
msgs = [
|
||||
{"role": "system", "content": "System"},
|
||||
] + [
|
||||
{"role": "user" if i % 2 == 0 else "assistant", "content": f"msg{i}"}
|
||||
for i in range(10)
|
||||
]
|
||||
result = apply_anthropic_cache_control(msgs)
|
||||
# Count how many messages have cache_control
|
||||
count = 0
|
||||
for msg in result:
|
||||
content = msg.get("content")
|
||||
if isinstance(content, list):
|
||||
for item in content:
|
||||
if isinstance(item, dict) and "cache_control" in item:
|
||||
count += 1
|
||||
elif "cache_control" in msg:
|
||||
count += 1
|
||||
assert count <= 4
|
||||
Loading…
Add table
Add a link
Reference in a new issue