mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-01 17:00:21 +08:00
feat(codex): 引入 upstream_headers hook 机制,为 Codex 注入 session/conversation/account headers
- 新增 upstream_headers.py:可注册 provider+endpoint 维度的 extra headers 构建 hook - Codex openai:cli 注入 session_id + conversation_id(由 prompt_cache_key sha256 派生) - Codex openai:compact 注入 chatgpt-account-id(来自 auth_config)+ session_id,不注入 conversation_id - 修复 prompt_cache:compact 格式现统一为 codex 策略,不再跳过注入 - chat_handler_base / cli_request_mixin 均在 extra_headers 阶段调用 build_upstream_extra_headers
This commit is contained in:
@@ -106,6 +106,21 @@ def test_maybe_patch_request_with_prompt_cache_key_for_codex_openai_cli() -> Non
|
||||
assert out["prompt_cache_key"] == build_stable_codex_prompt_cache_key("user-key-123")
|
||||
|
||||
|
||||
def test_maybe_patch_request_with_prompt_cache_key_for_codex_openai_compact() -> None:
|
||||
req = {"model": "gpt-5", "input": []}
|
||||
|
||||
out = maybe_patch_request_with_prompt_cache_key(
|
||||
req,
|
||||
provider_api_format="openai:compact",
|
||||
provider_type="codex",
|
||||
base_url="https://chatgpt.com/backend-api/codex",
|
||||
user_api_key_id="user-key-123",
|
||||
)
|
||||
|
||||
assert out is not req
|
||||
assert out["prompt_cache_key"] == build_stable_codex_prompt_cache_key("user-key-123")
|
||||
|
||||
|
||||
def test_maybe_patch_request_with_prompt_cache_key_skips_official_compact() -> None:
|
||||
req = {"model": "gpt-5", "input": []}
|
||||
|
||||
@@ -121,7 +136,7 @@ def test_maybe_patch_request_with_prompt_cache_key_skips_official_compact() -> N
|
||||
assert "prompt_cache_key" not in out
|
||||
|
||||
|
||||
def test_maybe_patch_request_with_prompt_cache_key_skips_legacy_codex_compact_context() -> None:
|
||||
def test_maybe_patch_request_with_prompt_cache_key_for_legacy_codex_compact_context() -> None:
|
||||
req = {"model": "gpt-5", "input": []}
|
||||
|
||||
try:
|
||||
@@ -136,8 +151,8 @@ def test_maybe_patch_request_with_prompt_cache_key_skips_legacy_codex_compact_co
|
||||
finally:
|
||||
set_codex_request_context(None)
|
||||
|
||||
assert out is req
|
||||
assert "prompt_cache_key" not in out
|
||||
assert out is not req
|
||||
assert out["prompt_cache_key"] == build_stable_codex_prompt_cache_key("user-key-123")
|
||||
|
||||
|
||||
def test_maybe_patch_request_with_prompt_cache_key_preserves_existing_key() -> None:
|
||||
|
||||
95
tests/services/test_upstream_headers.py
Normal file
95
tests/services/test_upstream_headers.py
Normal file
@@ -0,0 +1,95 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
|
||||
from src.services.provider.adapters.codex.context import (
|
||||
CodexRequestContext,
|
||||
set_codex_request_context,
|
||||
)
|
||||
from src.services.provider.upstream_headers import build_upstream_extra_headers
|
||||
|
||||
|
||||
def test_build_upstream_extra_headers_for_codex_openai_cli() -> None:
|
||||
request_body = {"model": "gpt-5", "input": [], "prompt_cache_key": "pcache-123"}
|
||||
|
||||
headers = build_upstream_extra_headers(
|
||||
provider_type="codex",
|
||||
endpoint_sig="openai:cli",
|
||||
request_body=request_body,
|
||||
original_headers={},
|
||||
decrypted_auth_config={"account_id": "acc-1"},
|
||||
)
|
||||
|
||||
short_id = hashlib.sha256(b"pcache-123").hexdigest()[:16]
|
||||
assert headers == {
|
||||
"chatgpt-account-id": "acc-1",
|
||||
"session_id": short_id,
|
||||
"conversation_id": short_id,
|
||||
}
|
||||
|
||||
|
||||
def test_build_upstream_extra_headers_respects_existing_session_headers() -> None:
|
||||
headers = build_upstream_extra_headers(
|
||||
provider_type="codex",
|
||||
endpoint_sig="openai:cli",
|
||||
request_body={"model": "gpt-5", "input": [], "prompt_cache_key": "pcache-123"},
|
||||
original_headers={
|
||||
"Session_ID": "client-session",
|
||||
"Conversation_ID": "client-conversation",
|
||||
},
|
||||
decrypted_auth_config={"account_id": "acc-1"},
|
||||
)
|
||||
|
||||
assert headers == {"chatgpt-account-id": "acc-1"}
|
||||
|
||||
|
||||
def test_build_upstream_extra_headers_for_codex_openai_compact() -> None:
|
||||
request_body = {"model": "gpt-5", "input": [], "prompt_cache_key": "pcache-123"}
|
||||
|
||||
headers = build_upstream_extra_headers(
|
||||
provider_type="codex",
|
||||
endpoint_sig="openai:compact",
|
||||
request_body=request_body,
|
||||
original_headers={},
|
||||
decrypted_auth_config={"account_id": "acc-1"},
|
||||
)
|
||||
|
||||
short_id = hashlib.sha256(b"pcache-123").hexdigest()[:16]
|
||||
assert headers == {
|
||||
"chatgpt-account-id": "acc-1",
|
||||
"session_id": short_id,
|
||||
}
|
||||
|
||||
|
||||
def test_build_upstream_extra_headers_for_legacy_codex_compact_context() -> None:
|
||||
request_body = {"model": "gpt-5", "input": [], "prompt_cache_key": "pcache-123"}
|
||||
|
||||
try:
|
||||
set_codex_request_context(CodexRequestContext(is_compact=True))
|
||||
headers = build_upstream_extra_headers(
|
||||
provider_type="codex",
|
||||
endpoint_sig="openai:cli",
|
||||
request_body=request_body,
|
||||
original_headers={},
|
||||
decrypted_auth_config={"account_id": "acc-1"},
|
||||
)
|
||||
finally:
|
||||
set_codex_request_context(None)
|
||||
|
||||
short_id = hashlib.sha256(b"pcache-123").hexdigest()[:16]
|
||||
assert headers == {
|
||||
"chatgpt-account-id": "acc-1",
|
||||
"session_id": short_id,
|
||||
}
|
||||
|
||||
|
||||
def test_build_upstream_extra_headers_returns_empty_without_match() -> None:
|
||||
headers = build_upstream_extra_headers(
|
||||
provider_type="codex",
|
||||
endpoint_sig="openai:chat",
|
||||
request_body={"model": "gpt-5", "messages": []},
|
||||
original_headers={},
|
||||
decrypted_auth_config={"account_id": "acc-1"},
|
||||
)
|
||||
|
||||
assert headers == {}
|
||||
Reference in New Issue
Block a user