feat: add cache routing alignment and usage visibility for 2.5.0
This commit is contained in:
1 parent
7c0c2b59ca
commit
3dd96078db
15 files changed
+316
-15
No files matched your search
@@ -3,6 +3,8 @@ from types import SimpleNamespace
|
||||
from uuid import uuid4
|
||||
import re
|
||||
|
||||
import pytest
|
||||
|
||||
from artemis.llm.cache_affinity import cache_affinity_options
|
||||
|
||||
|
||||
@@ -53,3 +55,35 @@ def test_concurrent_calls_do_not_share_or_mutate_task_headers():
|
||||
)
|
||||
assert results[0]["extra_headers"]["Thread-Id"] != results[1]["extra_headers"]["Thread-Id"]
|
||||
assert shared == {"extra_headers": {"X-Test": "shared"}}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("name", ["Thread-Id", "THREAD_ID", "session-id", "Session_id"])
|
||||
def test_header_only_override_aligns_body_and_missing_headers(name):
|
||||
headers = {name: "caller-conversation", "X-Test": "untouched"}
|
||||
actual = cache_affinity_options(context("task"), "flash", "test", {"extra_headers": headers})
|
||||
assert actual["prompt_cache_key"] == "caller-conversation"
|
||||
routing = {
|
||||
key.lower().replace("_", "-"): value for key, value in actual["extra_headers"].items()
|
||||
}
|
||||
assert routing["thread-id"] == routing["session-id"] == actual["prompt_cache_key"]
|
||||
assert headers == {name: "caller-conversation", "X-Test": "untouched"}
|
||||
assert cache_affinity_options(None, None, None, {"extra_headers": headers}) == actual
|
||||
|
||||
|
||||
def test_explicit_body_and_header_options_are_not_overwritten():
|
||||
options = {
|
||||
"prompt_cache_key": "body-override",
|
||||
"extra_headers": {"thread_id": "header-override"},
|
||||
}
|
||||
actual = cache_affinity_options(context("task"), "flash", "test", options)
|
||||
assert actual["prompt_cache_key"] == "body-override"
|
||||
assert actual["extra_headers"]["thread_id"] == "header-override"
|
||||
assert "Thread-Id" not in actual["extra_headers"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", [None, "", "unsafe\r\nheader", "a" * 129])
|
||||
def test_invalid_header_is_not_promoted_to_body(value):
|
||||
actual = cache_affinity_options(
|
||||
context("task"), "flash", "test", {"extra_headers": {"Thread-Id": value}}
|
||||
)
|
||||
assert actual["prompt_cache_key"].startswith("artemis:")
|
||||
@@ -363,6 +363,24 @@ async def test_cache_key_is_stable_for_exploration_but_separates_roles(
|
||||
assert requests[0].headers["x-client-request-id"] != requests[1].headers["x-client-request-id"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize("header", ["Thread-Id", "thread_id", "SESSION-ID", "Session_id"])
|
||||
async def test_caller_affinity_header_reaches_wire_as_body_key(transport_model, header):
|
||||
model, requests, _ = transport_model
|
||||
wrapper = RobustChatModelWrapper(model, endpoint=ModelEndpoint(model_name="test-model"))
|
||||
headers = {header: "caller-affinity"}
|
||||
for _ in range(2):
|
||||
await wrapper.ainvoke([HumanMessage(content="shared prefix")], extra_headers=headers)
|
||||
for request in requests:
|
||||
payload = json.loads(request.content)
|
||||
assert payload["prompt_cache_key"] == "caller-affinity"
|
||||
routing = {name.lower().replace("_", "-"): value for name, value in request.headers.items()}
|
||||
assert routing["thread-id"] == routing["session-id"] == "caller-affinity"
|
||||
assert "extra_headers" not in payload
|
||||
assert requests[0].headers["x-client-request-id"] != requests[1].headers["x-client-request-id"]
|
||||
assert headers == {header: "caller-affinity"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_auxiliary_summary_calls_send_role_scoped_affinity_on_responses(transport_model):
|
||||
from types import SimpleNamespace
|
||||
|
||||
Reference in new issue
Block a user