mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
refactor(prompt-cache): 移除 client_family 命名空间拆分,统一缓存 key 提升复用率
不再按 User-Agent 客户端类型拆分 prompt cache namespace, 所有客户端共享同一缓存 key,版本升级至 v3。
This commit is contained in:
@@ -11,6 +11,7 @@ from src.core.provider_types import ProviderType, normalize_provider_type
|
|||||||
from src.utils.url_utils import is_official_openai_api_url
|
from src.utils.url_utils import is_official_openai_api_url
|
||||||
|
|
||||||
_OFFICIAL_OPENAI_PROMPT_CACHE_FORMATS: frozenset[str] = frozenset({"openai:chat", "openai:cli"})
|
_OFFICIAL_OPENAI_PROMPT_CACHE_FORMATS: frozenset[str] = frozenset({"openai:chat", "openai:cli"})
|
||||||
|
_PROMPT_CACHE_NAMESPACE_VERSION = "v3"
|
||||||
_USER_AGENT_CLIENT_FAMILY_PATTERNS: tuple[tuple[tuple[str, ...], str], ...] = (
|
_USER_AGENT_CLIENT_FAMILY_PATTERNS: tuple[tuple[tuple[str, ...], str], ...] = (
|
||||||
(("codex desktop",), "codex_desktop"),
|
(("codex desktop",), "codex_desktop"),
|
||||||
(("asyncopenai/python", "openai/python"), "openai_python"),
|
(("asyncopenai/python", "openai/python"), "openai_python"),
|
||||||
@@ -69,8 +70,10 @@ def _build_stable_prompt_cache_key(
|
|||||||
if not normalized:
|
if not normalized:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
family = str(client_family or "").strip().lower() or "generic"
|
# Keep the optional argument for call-site compatibility, but ignore it.
|
||||||
namespace = f"aether:{scope}:prompt-cache:v2:user:{normalized}:client:{family}"
|
# Prompt cache reuse is more valuable than splitting namespaces by User-Agent.
|
||||||
|
_ = client_family
|
||||||
|
namespace = f"aether:{scope}:prompt-cache:{_PROMPT_CACHE_NAMESPACE_VERSION}:user:{normalized}"
|
||||||
return str(uuid.uuid5(uuid.NAMESPACE_OID, namespace))
|
return str(uuid.uuid5(uuid.NAMESPACE_OID, namespace))
|
||||||
|
|
||||||
|
|
||||||
@@ -154,16 +157,13 @@ def maybe_patch_request_with_prompt_cache_key(
|
|||||||
if prompt_cache_key:
|
if prompt_cache_key:
|
||||||
return request_body
|
return request_body
|
||||||
|
|
||||||
client_family = resolve_prompt_cache_client_family(request_headers)
|
|
||||||
if scope == "codex":
|
if scope == "codex":
|
||||||
stable_key = build_stable_codex_prompt_cache_key(
|
stable_key = build_stable_codex_prompt_cache_key(
|
||||||
user_api_key_id,
|
user_api_key_id,
|
||||||
client_family=client_family,
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
stable_key = build_stable_openai_prompt_cache_key(
|
stable_key = build_stable_openai_prompt_cache_key(
|
||||||
user_api_key_id,
|
user_api_key_id,
|
||||||
client_family=client_family,
|
|
||||||
)
|
)
|
||||||
if not stable_key:
|
if not stable_key:
|
||||||
return request_body
|
return request_body
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ def test_resolve_prompt_cache_client_family_defaults_to_generic() -> None:
|
|||||||
assert resolve_prompt_cache_client_family({"x-test": "1"}) == "generic"
|
assert resolve_prompt_cache_client_family({"x-test": "1"}) == "generic"
|
||||||
|
|
||||||
|
|
||||||
def test_build_stable_openai_prompt_cache_key_changes_by_client_family() -> None:
|
def test_build_stable_openai_prompt_cache_key_ignores_client_family() -> None:
|
||||||
python_key = build_stable_openai_prompt_cache_key(
|
python_key = build_stable_openai_prompt_cache_key(
|
||||||
"user-key-123",
|
"user-key-123",
|
||||||
client_family="openai_python",
|
client_family="openai_python",
|
||||||
@@ -42,7 +42,16 @@ def test_build_stable_openai_prompt_cache_key_changes_by_client_family() -> None
|
|||||||
|
|
||||||
assert python_key
|
assert python_key
|
||||||
assert node_key
|
assert node_key
|
||||||
assert python_key != node_key
|
assert python_key == node_key
|
||||||
|
|
||||||
|
|
||||||
|
def test_build_stable_prompt_cache_key_stays_scope_specific() -> None:
|
||||||
|
openai_key = build_stable_openai_prompt_cache_key("user-key-123")
|
||||||
|
codex_key = build_stable_codex_prompt_cache_key("user-key-123")
|
||||||
|
|
||||||
|
assert openai_key
|
||||||
|
assert codex_key
|
||||||
|
assert openai_key != codex_key
|
||||||
|
|
||||||
|
|
||||||
def test_maybe_patch_request_with_prompt_cache_key_for_official_chat() -> None:
|
def test_maybe_patch_request_with_prompt_cache_key_for_official_chat() -> None:
|
||||||
@@ -58,10 +67,7 @@ def test_maybe_patch_request_with_prompt_cache_key_for_official_chat() -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert out is not req
|
assert out is not req
|
||||||
assert out["prompt_cache_key"] == build_stable_openai_prompt_cache_key(
|
assert out["prompt_cache_key"] == build_stable_openai_prompt_cache_key("user-key-123")
|
||||||
"user-key-123",
|
|
||||||
client_family="openai_python",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_maybe_patch_request_with_prompt_cache_key_for_official_responses() -> None:
|
def test_maybe_patch_request_with_prompt_cache_key_for_official_responses() -> None:
|
||||||
@@ -77,10 +83,7 @@ def test_maybe_patch_request_with_prompt_cache_key_for_official_responses() -> N
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert out is not req
|
assert out is not req
|
||||||
assert out["prompt_cache_key"] == build_stable_openai_prompt_cache_key(
|
assert out["prompt_cache_key"] == build_stable_openai_prompt_cache_key("user-key-123")
|
||||||
"user-key-123",
|
|
||||||
client_family="openai_node",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_maybe_patch_request_with_prompt_cache_key_for_codex_openai_cli() -> None:
|
def test_maybe_patch_request_with_prompt_cache_key_for_codex_openai_cli() -> None:
|
||||||
@@ -96,10 +99,7 @@ def test_maybe_patch_request_with_prompt_cache_key_for_codex_openai_cli() -> Non
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert out is not req
|
assert out is not req
|
||||||
assert out["prompt_cache_key"] == build_stable_codex_prompt_cache_key(
|
assert out["prompt_cache_key"] == build_stable_codex_prompt_cache_key("user-key-123")
|
||||||
"user-key-123",
|
|
||||||
client_family="codex_desktop",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_maybe_patch_request_with_prompt_cache_key_skips_official_compact() -> None:
|
def test_maybe_patch_request_with_prompt_cache_key_skips_official_compact() -> None:
|
||||||
@@ -180,7 +180,7 @@ def test_maybe_patch_request_with_prompt_cache_key_skips_unmatched_provider() ->
|
|||||||
assert "prompt_cache_key" not in out
|
assert "prompt_cache_key" not in out
|
||||||
|
|
||||||
|
|
||||||
def test_maybe_patch_request_with_prompt_cache_key_uses_generic_family_without_user_agent() -> None:
|
def test_maybe_patch_request_with_prompt_cache_key_is_stable_without_user_agent() -> None:
|
||||||
req = {"model": "gpt-5", "messages": [{"role": "user", "content": "hi"}]}
|
req = {"model": "gpt-5", "messages": [{"role": "user", "content": "hi"}]}
|
||||||
|
|
||||||
out = maybe_patch_request_with_prompt_cache_key(
|
out = maybe_patch_request_with_prompt_cache_key(
|
||||||
@@ -192,7 +192,28 @@ def test_maybe_patch_request_with_prompt_cache_key_uses_generic_family_without_u
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert out is not req
|
assert out is not req
|
||||||
assert out["prompt_cache_key"] == build_stable_openai_prompt_cache_key(
|
assert out["prompt_cache_key"] == build_stable_openai_prompt_cache_key("user-key-123")
|
||||||
"user-key-123",
|
|
||||||
client_family="generic",
|
|
||||||
|
def test_maybe_patch_request_with_prompt_cache_key_ignores_user_agent_variants() -> None:
|
||||||
|
req_python = {"model": "gpt-5", "input": []}
|
||||||
|
req_codex = {"model": "gpt-5", "input": []}
|
||||||
|
|
||||||
|
out_python = maybe_patch_request_with_prompt_cache_key(
|
||||||
|
req_python,
|
||||||
|
provider_api_format="openai:cli",
|
||||||
|
provider_type="custom",
|
||||||
|
base_url="https://api.openai.com/v1",
|
||||||
|
user_api_key_id="user-key-123",
|
||||||
|
request_headers={"user-agent": "AsyncOpenAI/Python 2.14.0"},
|
||||||
)
|
)
|
||||||
|
out_codex = maybe_patch_request_with_prompt_cache_key(
|
||||||
|
req_codex,
|
||||||
|
provider_api_format="openai:cli",
|
||||||
|
provider_type="custom",
|
||||||
|
base_url="https://api.openai.com/v1",
|
||||||
|
user_api_key_id="user-key-123",
|
||||||
|
request_headers={"user-agent": "Codex Desktop/0.108.0-alpha.12"},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert out_python["prompt_cache_key"] == out_codex["prompt_cache_key"]
|
||||||
|
|||||||
Reference in New Issue
Block a user