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

@@ -18,6 +18,7 @@ from src.api.base.admin_adapter import AdminApiAdapter
from src.api.base.context import ApiRequestContext
from src.api.base.models_service import invalidate_models_list_cache
from src.api.base.pipeline import ApiRequestPipeline
from src.core.api_format.metadata import get_default_body_rules_for_endpoint
from src.core.api_format.signature import parse_signature_key
from src.core.exceptions import InvalidRequestException, NotFoundException
from src.core.logger import logger
@@ -136,6 +137,17 @@ async def create_provider_endpoint(
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
@router.get("/defaults/{api_format}/body-rules")
async def get_default_endpoint_body_rules(
api_format: str,
request: Request,
db: Session = Depends(get_db),
) -> dict[str, Any]:
"""获取指定 endpoint signature 的默认 body_rules。"""
adapter = AdminGetDefaultBodyRulesAdapter(api_format=api_format)
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
@router.get("/{endpoint_id}", response_model=ProviderEndpointResponse)
async def get_endpoint(
endpoint_id: str,
@@ -324,6 +336,9 @@ class AdminCreateProviderEndpointAdapter(AdminApiAdapter):
endpoint_kind = sig.endpoint_kind.value
# 使用归一化后的 signature key确保格式一致性
normalized_api_format = sig.key
body_rules = self.endpoint_data.body_rules
if body_rules is None:
body_rules = get_default_body_rules_for_endpoint(normalized_api_format) or None
new_endpoint = ProviderEndpoint(
id=str(uuid.uuid4()),
@@ -334,7 +349,7 @@ class AdminCreateProviderEndpointAdapter(AdminApiAdapter):
base_url=self.endpoint_data.base_url,
custom_path=self.endpoint_data.custom_path,
header_rules=self.endpoint_data.header_rules,
body_rules=self.endpoint_data.body_rules,
body_rules=body_rules,
max_retries=self.endpoint_data.max_retries,
is_active=True,
config=self.endpoint_data.config,
@@ -593,3 +608,19 @@ class AdminDeleteProviderEndpointAdapter(AdminApiAdapter):
"message": f"Endpoint {self.endpoint_id} 已删除",
"affected_keys_count": affected_keys_count,
}
@dataclass
class AdminGetDefaultBodyRulesAdapter(AdminApiAdapter):
api_format: str
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
try:
normalized_api_format = parse_signature_key(self.api_format).key
except Exception as exc:
raise InvalidRequestException(f"无效的 api_format: {self.api_format}") from exc
return {
"api_format": normalized_api_format,
"body_rules": get_default_body_rules_for_endpoint(normalized_api_format),
}