mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-05 08:57:46 +08:00
feat(codex): 拆分openai:compact为独立端点,简化Codex请求为透传模式
- 新增openai:compact端点类型(EndpointKind.COMPACT),独立于openai:cli - OpenAICompactAdapter继承OpenAICliAdapter,自动标记compact模式 - Codex请求补丁改为纯透传:仅清理内部标记,不再修改客户端payload - stream_policy支持openai:compact独立策略,compact端点移除stream字段 - candidate_builder支持compact回退到cli端点 - auth_type: vertex_ai重命名为service_account,保持向后兼容 - Vertex Provider新增api_formats与auth_type组合校验 - KeyAllowedModels对话框改为从Provider获取模型,展示provider_model_name - Dialog内Select组件自动禁用Portal,修复层级遮挡问题 - 新增Codex compact端点回填迁移脚本
This commit is contained in:
@@ -6,94 +6,39 @@ from src.services.provider.adapters.codex.request_patching import (
|
||||
)
|
||||
|
||||
|
||||
def test_patch_openai_cli_request_for_codex_sets_store_and_instructions() -> None:
|
||||
req = {"model": "gpt-test", "input": []}
|
||||
out = patch_openai_cli_request_for_codex(req)
|
||||
|
||||
assert out is not req
|
||||
assert out["store"] is False
|
||||
assert out["stream"] is True
|
||||
assert out["instructions"] == ""
|
||||
|
||||
|
||||
def test_patch_openai_cli_request_for_codex_strips_rejected_params() -> None:
|
||||
def test_patch_openai_cli_request_for_codex_is_passthrough_except_internal_sentinel() -> None:
|
||||
req = {
|
||||
"model": "gpt-test",
|
||||
"input": [],
|
||||
"max_output_tokens": 123,
|
||||
"max_completion_tokens": 456,
|
||||
"temperature": 0.5,
|
||||
"top_p": 0.9,
|
||||
"service_tier": "default",
|
||||
"truncation": "auto",
|
||||
"context_management": {"compaction": {"type": "summary"}},
|
||||
"user": "u_123",
|
||||
}
|
||||
out = patch_openai_cli_request_for_codex(req)
|
||||
|
||||
for key in (
|
||||
"max_output_tokens",
|
||||
"max_completion_tokens",
|
||||
"temperature",
|
||||
"top_p",
|
||||
"service_tier",
|
||||
"truncation",
|
||||
"context_management",
|
||||
"user",
|
||||
):
|
||||
assert key not in out
|
||||
|
||||
|
||||
def test_patch_openai_cli_request_for_codex_converts_system_role_to_developer() -> None:
|
||||
req = {
|
||||
"model": "gpt-test",
|
||||
"instructions": "ignored",
|
||||
"input": [
|
||||
{
|
||||
"type": "message",
|
||||
"role": "system",
|
||||
"content": [{"type": "input_text", "text": "You are a pirate."}],
|
||||
},
|
||||
{
|
||||
"type": "message",
|
||||
"role": "user",
|
||||
"content": [{"type": "input_text", "text": "Hello"}],
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
out = patch_openai_cli_request_for_codex(req)
|
||||
|
||||
assert isinstance(out.get("input"), list)
|
||||
assert out["input"][0]["role"] == "developer"
|
||||
assert out["input"][1]["role"] == "user"
|
||||
|
||||
|
||||
def test_patch_openai_cli_request_for_codex_adds_required_include_item() -> None:
|
||||
req = {"model": "gpt-test", "input": []}
|
||||
out = patch_openai_cli_request_for_codex(req)
|
||||
|
||||
assert out["include"] == ["reasoning.encrypted_content"]
|
||||
|
||||
|
||||
def test_patch_openai_cli_request_for_codex_overrides_include() -> None:
|
||||
req = {
|
||||
"model": "gpt-test",
|
||||
"input": [],
|
||||
"include": ["foo", "bar"],
|
||||
}
|
||||
out = patch_openai_cli_request_for_codex(req)
|
||||
assert out["include"] == ["reasoning.encrypted_content"]
|
||||
|
||||
|
||||
def test_patch_openai_cli_request_for_codex_compact_drops_stream() -> None:
|
||||
req = {
|
||||
"model": "gpt-test",
|
||||
"input": [],
|
||||
"store": True,
|
||||
"stream": False,
|
||||
"instructions": "keep",
|
||||
"include": ["foo"],
|
||||
"parallel_tool_calls": False,
|
||||
"temperature": 0.7,
|
||||
"context_management": {"compaction": {"type": "summary"}},
|
||||
"user": "u_123",
|
||||
"_aether_compact": True,
|
||||
"stream": True,
|
||||
}
|
||||
out = patch_openai_cli_request_for_codex(req)
|
||||
assert "stream" not in out
|
||||
|
||||
assert out is not req
|
||||
assert "_aether_compact" not in out
|
||||
assert out["store"] is True
|
||||
assert out["stream"] is False
|
||||
assert out["instructions"] == "keep"
|
||||
assert out["include"] == ["foo"]
|
||||
assert out["parallel_tool_calls"] is False
|
||||
assert out["temperature"] == 0.7
|
||||
assert out["context_management"] == {"compaction": {"type": "summary"}}
|
||||
assert out["user"] == "u_123"
|
||||
assert out["input"][0]["role"] == "system"
|
||||
|
||||
|
||||
def test_maybe_patch_request_for_codex_is_noop_for_non_codex() -> None:
|
||||
@@ -117,7 +62,7 @@ def test_maybe_patch_request_for_codex_is_noop_for_non_openai_cli() -> None:
|
||||
|
||||
|
||||
def test_maybe_patch_request_for_codex_patches_for_codex_openai_cli() -> None:
|
||||
req = {"model": "gpt-test", "input": []}
|
||||
req = {"model": "gpt-test", "input": [], "_aether_compact": True, "store": True}
|
||||
out = maybe_patch_request_for_codex(
|
||||
provider_type="codex",
|
||||
provider_api_format="openai:cli",
|
||||
@@ -125,8 +70,41 @@ def test_maybe_patch_request_for_codex_patches_for_codex_openai_cli() -> None:
|
||||
)
|
||||
|
||||
assert out is not req
|
||||
assert out["store"] is True
|
||||
assert "_aether_compact" not in out
|
||||
|
||||
|
||||
def test_maybe_patch_request_for_codex_patches_for_codex_openai_compact() -> None:
|
||||
req = {"model": "gpt-test", "input": [], "_aether_compact": True, "store": True}
|
||||
out = maybe_patch_request_for_codex(
|
||||
provider_type="codex",
|
||||
provider_api_format="openai:compact",
|
||||
request_body=req,
|
||||
)
|
||||
|
||||
assert out is not req
|
||||
assert out["store"] is True
|
||||
assert "_aether_compact" not in out
|
||||
|
||||
|
||||
def test_openai_cli_normalizer_request_from_internal_codex_variant_preserves_store() -> None:
|
||||
from src.core.api_format.conversion.normalizers.openai_cli import OpenAICliNormalizer
|
||||
|
||||
normalizer = OpenAICliNormalizer()
|
||||
internal = normalizer.request_to_internal({"model": "gpt-test", "input": [], "store": True})
|
||||
out = normalizer.request_from_internal(internal, target_variant="codex")
|
||||
|
||||
assert out["store"] is True
|
||||
|
||||
|
||||
def test_openai_cli_normalizer_request_from_internal_codex_variant_defaults_store_false() -> None:
|
||||
from src.core.api_format.conversion.normalizers.openai_cli import OpenAICliNormalizer
|
||||
|
||||
normalizer = OpenAICliNormalizer()
|
||||
internal = normalizer.request_to_internal({"model": "gpt-test", "input": []})
|
||||
out = normalizer.request_from_internal(internal, target_variant="codex")
|
||||
|
||||
assert out["store"] is False
|
||||
assert "instructions" in out
|
||||
|
||||
|
||||
def test_codex_envelope_extra_headers_includes_sse_accept_and_session() -> None:
|
||||
|
||||
Reference in New Issue
Block a user