fix(claude_sdk,conversations,rotation): context size from the last api call, new-day text by rotation reason

This commit is contained in:
hh
2026-08-29 16:54:29 +02:00
parent 72639c4b90
commit 4a59c59bda
8 changed files with 120 additions and 16 deletions
+18 -2
View File
@@ -98,7 +98,12 @@ class FakeClient:
self.interrupted = True
async def receive_response(self):
start = {"type": "message_start", "message": {}}
start = {
"type": "message_start",
"message": {
"usage": {"input_tokens": 5, "cache_read_input_tokens": 20_000}
},
}
yield StreamEvent(uuid="u", session_id="s", event=start)
for e in _stream(0, "calling "):
yield e
@@ -119,7 +124,17 @@ class FakeClient:
yield UserMessage(
content=[ToolResultBlock(tool_use_id="toolu_1", content="42")]
)
yield StreamEvent(uuid="u", session_id="s", event=start)
second = {
"type": "message_start",
"message": {
"usage": {
"input_tokens": 7,
"cache_read_input_tokens": 20_000,
"cache_creation_input_tokens": 3_000,
}
},
}
yield StreamEvent(uuid="u", session_id="s", event=second)
for e in _stream(0, "done"):
yield e
yield AssistantMessage(content=[TextBlock(text="done")], model="m")
@@ -194,6 +209,7 @@ async def test_stream_envelope_and_index_rebase(cwd: Path) -> None:
assert capture.session_id == "fresh-session"
assert capture.usage is not None and capture.usage.cost_usd == 0.01
assert capture.usage.context_tokens == 23_007
assert capture.synthesized_messages == [
{
"role": "assistant",
+28 -2
View File
@@ -100,7 +100,7 @@ async def test_rotation_order_handout_close_marks_moves_and_new_day(
return f"напиши хендаут за {ctx.day}"
world.conversations._texts = ConversationTexts( # noqa: SLF001
handout=handout, new_day="Новый день {day}."
handout=handout, new_day=lambda ctx: f"Новый день {ctx.day} ({ctx.reason})."
)
old = await world.conversations.spawn(kind="master", agent="a", seed="clean")
old = await age(world, old, datetime(2026, 8, 27, 9, 0, tzinfo=UTC))
@@ -140,7 +140,7 @@ async def test_rotation_order_handout_close_marks_moves_and_new_day(
prompt = new_client.prompts[0]
assert prompt.startswith("[сид: morning] master")
assert "[инжект: ротация" in prompt
assert "Новый день" in prompt
assert "Новый день 20" in prompt and "(ночь)" in prompt
assert "переехало из старого мастера: 1" in prompt
moved = await world.conversations.queue.pending(new.id)
assert [(i.priority, i.text) for i in moved] == [("normal", "later")]
@@ -172,3 +172,29 @@ async def test_due_uses_last_usage_row_for_context_size(world: World) -> None:
rotation = Rotation(world.conversations, RotationPolicy(max_context_tokens=5))
(pair,) = await rotation.due()
assert pair[0].id == conv.id and pair[1] == "транскрипт"
def test_context_of_prefers_last_call_and_averages_old_rows() -> None:
from beaver_gateway.core.conversations import context_of
from beaver_gateway.storage.models import Usage
fresh = Usage(
agent_name="a",
model="m",
input_tokens=12,
cache_read_tokens=142_984,
cache_creation_tokens=29_584,
num_turns=6,
context_tokens=29_000,
)
assert context_of(fresh) == 29_000
old = Usage(
agent_name="a",
model="m",
input_tokens=12,
cache_read_tokens=142_984,
cache_creation_tokens=29_584,
num_turns=6,
)
assert context_of(old) == 28_763
assert context_of(None) == 0