feat(endpoint): 端点默认 body_rules 机制与 Codex 规则回填

- EndpointDefinition 新增 default_body_rules 字段,openai:cli/compact 配置 Codex 默认规则
- 创建端点时若未指定 body_rules 则自动填充对应格式的默认值
- 新增 GET /defaults/{api_format}/body-rules 接口查询默认规则
- 前端 EndpointFormDialog 增加"重置请求体"按钮,支持一键恢复默认
- Alembic 迁移回填已有 Codex 端点的默认 body_rules
- 新增 metadata 和 endpoint 创建默认值的单元测试
This commit is contained in:
fawney19
2026-03-02 22:08:39 +08:00
parent 3384c6d666
commit 0bff15f964
8 changed files with 392 additions and 1 deletions

View File

@@ -51,6 +51,7 @@ from src.core.api_format.metadata import (
can_passthrough_endpoint,
get_auth_config_for_endpoint,
get_data_format_id_for_endpoint,
get_default_body_rules_for_endpoint,
get_default_path_for_endpoint,
get_endpoint_definition,
get_extra_headers_for_endpoint,
@@ -98,6 +99,7 @@ __all__ = [
"get_extra_headers_for_endpoint",
"get_protected_keys_for_endpoint",
"get_data_format_id_for_endpoint",
"get_default_body_rules_for_endpoint",
"can_passthrough_endpoint",
# Utils
"is_cli_format",

View File

@@ -9,8 +9,10 @@ API endpoint metadata (new mode).
from __future__ import annotations
from collections.abc import Iterable, Mapping, Sequence
from copy import deepcopy
from dataclasses import dataclass, field
from types import MappingProxyType
from typing import Any
from src.core.api_format.enums import ApiFamily, AuthMethod, EndpointKind
from src.core.api_format.signature import EndpointSignature, make_signature_key, parse_signature_key
@@ -47,6 +49,7 @@ class EndpointDefinition:
stream_in_body: bool = True
data_format_id: str = ""
default_body_rules: Sequence[dict[str, Any]] = field(default_factory=tuple)
@property
def signature(self) -> EndpointSignature:
@@ -65,6 +68,19 @@ class EndpointDefinition:
yield value
_CODEX_DEFAULT_BODY_RULES: tuple[dict[str, Any], ...] = (
{"action": "drop", "path": "max_output_tokens"},
{"action": "drop", "path": "temperature"},
{"action": "drop", "path": "top_p"},
{"action": "set", "path": "store", "value": False},
{
"action": "set",
"path": "instructions",
"value": "You are GPT-5.",
"condition": {"path": "instructions", "op": "not_exists"},
},
)
_ENDPOINT_DEFINITIONS: dict[tuple[ApiFamily, EndpointKind], EndpointDefinition] = {
# Claude
(ApiFamily.CLAUDE, EndpointKind.CHAT): EndpointDefinition(
@@ -122,6 +138,7 @@ _ENDPOINT_DEFINITIONS: dict[tuple[ApiFamily, EndpointKind], EndpointDefinition]
auth_type="bearer",
protected_keys=frozenset({"authorization", "content-type"}),
data_format_id="openai_responses",
default_body_rules=_CODEX_DEFAULT_BODY_RULES,
),
(ApiFamily.OPENAI, EndpointKind.COMPACT): EndpointDefinition(
api_family=ApiFamily.OPENAI,
@@ -135,6 +152,7 @@ _ENDPOINT_DEFINITIONS: dict[tuple[ApiFamily, EndpointKind], EndpointDefinition]
# compact endpoint is non-streaming by design.
stream_in_body=False,
data_format_id="openai_responses",
default_body_rules=_CODEX_DEFAULT_BODY_RULES,
),
(ApiFamily.OPENAI, EndpointKind.VIDEO): EndpointDefinition(
api_family=ApiFamily.OPENAI,
@@ -292,6 +310,15 @@ def get_data_format_id_for_endpoint(
return ""
def get_default_body_rules_for_endpoint(
value: str | EndpointSignature | tuple[ApiFamily, EndpointKind],
) -> list[dict[str, Any]]:
definition = resolve_endpoint_definition(value)
if not definition or not definition.default_body_rules:
return []
return deepcopy(list(definition.default_body_rules))
def can_passthrough_endpoint(
client: str | EndpointSignature | tuple[ApiFamily, EndpointKind],
provider: str | EndpointSignature | tuple[ApiFamily, EndpointKind],
@@ -336,6 +363,7 @@ __all__ = [
"get_extra_headers_for_endpoint",
"get_protected_keys_for_endpoint",
"get_data_format_id_for_endpoint",
"get_default_body_rules_for_endpoint",
"can_passthrough_endpoint",
"make_endpoint_signature",
]