From da790db75baa5341046fa8e8da35d6f8786a1dd2 Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Tue, 21 Apr 2026 14:15:27 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A1=A5=E5=85=85=20OpenAI=20=E6=9E=9A?= =?UTF-8?q?=E4=B8=BE=E5=8F=82=E6=95=B0=E5=92=8C=E8=BE=B9=E7=95=8C=E8=B6=8A?= =?UTF-8?q?=E7=95=8C=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - service_tier: 补充 flex, priority 测试 - reasoning_effort: 补充 none, minimal 测试 - verbosity: 补充 medium, high 测试 - 边界越界测试: frequency_penalty, presence_penalty, top_p, n - core.py: http_stream_request 支持 method 参数 - Anthropic: 补充 content_block_start 事件验证 --- scripts/core.py | 6 +- scripts/detect_anthropic.py | 12 +++ scripts/detect_openai.py | 178 +++++++++++++++++++++++++++++++++++- 3 files changed, 192 insertions(+), 4 deletions(-) diff --git a/scripts/core.py b/scripts/core.py index c26d2ab..a0e549d 100644 --- a/scripts/core.py +++ b/scripts/core.py @@ -140,7 +140,8 @@ def http_stream_request( headers: Optional[Dict[str, str]] = None, body: Optional[Any] = None, ssl_ctx: Optional[ssl.SSLContext] = None, - retries: int = MAX_RETRIES + retries: int = MAX_RETRIES, + method: str = "POST" ) -> TestResult: """执行流式 HTTP 请求 (SSE,支持重试) @@ -150,11 +151,12 @@ def http_stream_request( body: 请求体 (dict) ssl_ctx: SSL 上下文 retries: 重试次数 + method: HTTP 方法 (默认 POST) Returns: TestResult 对象 """ - req = urllib.request.Request(url, method="POST") + req = urllib.request.Request(url, method=method) if headers: for k, v in headers.items(): req.add_header(k, v) diff --git a/scripts/detect_anthropic.py b/scripts/detect_anthropic.py index 0797218..8b7fcb7 100644 --- a/scripts/detect_anthropic.py +++ b/scripts/detect_anthropic.py @@ -262,6 +262,18 @@ def validate_anthropic_streaming_response(response_text: str) -> Tuple[bool, Lis elif event_type == "message_stop": has_message_stop = True + elif event_type == "content_block_start": + if "index" not in event: + errors.append(f"content_block_start 事件缺少 index 字段") + if "content_block" not in event: + errors.append(f"content_block_start 事件缺少 content_block 字段") + elif not isinstance(event["content_block"], dict): + errors.append(f"content_block_start 事件的 content_block 不是对象") + else: + cb = event["content_block"] + if "type" not in cb: + errors.append(f"content_block_start.content_block 缺少 type 字段") + elif event_type == "content_block_delta": if "delta" not in event: errors.append(f"content_block_delta 事件缺少 delta 字段") diff --git a/scripts/detect_openai.py b/scripts/detect_openai.py index 147e0a8..4dea9f6 100755 --- a/scripts/detect_openai.py +++ b/scripts/detect_openai.py @@ -564,6 +564,102 @@ def main(): "temperature": 2.5 } )) + cases.append(TestCase( + desc="frequency_penalty 超出范围 (3.0)", + method="POST", + url=chat_url, + headers=headers, + body={ + "model": model, + "messages": [{"role": "user", "content": "Hi"}], + "max_tokens": 5, + "frequency_penalty": 3.0 + } + )) + cases.append(TestCase( + desc="frequency_penalty 超出范围 (-3.0)", + method="POST", + url=chat_url, + headers=headers, + body={ + "model": model, + "messages": [{"role": "user", "content": "Hi"}], + "max_tokens": 5, + "frequency_penalty": -3.0 + } + )) + cases.append(TestCase( + desc="presence_penalty 超出范围 (3.0)", + method="POST", + url=chat_url, + headers=headers, + body={ + "model": model, + "messages": [{"role": "user", "content": "Hi"}], + "max_tokens": 5, + "presence_penalty": 3.0 + } + )) + cases.append(TestCase( + desc="presence_penalty 超出范围 (-3.0)", + method="POST", + url=chat_url, + headers=headers, + body={ + "model": model, + "messages": [{"role": "user", "content": "Hi"}], + "max_tokens": 5, + "presence_penalty": -3.0 + } + )) + cases.append(TestCase( + desc="top_p 超出范围 (1.5)", + method="POST", + url=chat_url, + headers=headers, + body={ + "model": model, + "messages": [{"role": "user", "content": "Hi"}], + "max_tokens": 5, + "top_p": 1.5 + } + )) + cases.append(TestCase( + desc="top_p 超出范围 (-0.1)", + method="POST", + url=chat_url, + headers=headers, + body={ + "model": model, + "messages": [{"role": "user", "content": "Hi"}], + "max_tokens": 5, + "top_p": -0.1 + } + )) + cases.append(TestCase( + desc="n 为负数", + method="POST", + url=chat_url, + headers=headers, + body={ + "model": model, + "messages": [{"role": "user", "content": "Hi"}], + "max_tokens": 5, + "n": -1 + } + )) + cases.append(TestCase( + desc="n 为 0", + method="POST", + url=chat_url, + headers=headers, + body={ + "model": model, + "messages": [{"role": "user", "content": "Hi"}], + "max_tokens": 5, + "n": 0 + } + )) # ---- --vision ---- if args.vision: @@ -807,7 +903,7 @@ def main(): # reasoning_effort: 推理努力级别(需要模型支持) cases.append(TestCase( - desc="reasoning_effort: medium", + desc="reasoning_effort: none", method="POST", url=chat_url, headers=headers, @@ -815,7 +911,20 @@ def main(): "model": model, "messages": [{"role": "user", "content": "1+1=?"}], "max_tokens": 10, - "reasoning_effort": "medium" + "reasoning_effort": "none" + }, + validator=validate_openai_chat_completion_response + )) + cases.append(TestCase( + desc="reasoning_effort: minimal", + method="POST", + url=chat_url, + headers=headers, + body={ + "model": model, + "messages": [{"role": "user", "content": "1+1=?"}], + "max_tokens": 10, + "reasoning_effort": "minimal" }, validator=validate_openai_chat_completion_response )) @@ -832,6 +941,19 @@ def main(): }, validator=validate_openai_chat_completion_response )) + cases.append(TestCase( + desc="reasoning_effort: medium", + method="POST", + url=chat_url, + headers=headers, + body={ + "model": model, + "messages": [{"role": "user", "content": "1+1=?"}], + "max_tokens": 10, + "reasoning_effort": "medium" + }, + validator=validate_openai_chat_completion_response + )) cases.append(TestCase( desc="reasoning_effort: high", method="POST", @@ -873,6 +995,32 @@ def main(): }, validator=validate_openai_chat_completion_response )) + cases.append(TestCase( + desc="service_tier: flex", + method="POST", + url=chat_url, + headers=headers, + body={ + "model": model, + "messages": [{"role": "user", "content": "Hi"}], + "max_tokens": 5, + "service_tier": "flex" + }, + validator=validate_openai_chat_completion_response + )) + cases.append(TestCase( + desc="service_tier: priority", + method="POST", + url=chat_url, + headers=headers, + body={ + "model": model, + "messages": [{"role": "user", "content": "Hi"}], + "max_tokens": 5, + "service_tier": "priority" + }, + validator=validate_openai_chat_completion_response + )) # verbosity: 冗长程度 cases.append(TestCase( @@ -888,6 +1036,32 @@ def main(): }, validator=validate_openai_chat_completion_response )) + cases.append(TestCase( + desc="verbosity: medium", + method="POST", + url=chat_url, + headers=headers, + body={ + "model": model, + "messages": [{"role": "user", "content": "介绍一下Python"}], + "max_tokens": 50, + "verbosity": "medium" + }, + validator=validate_openai_chat_completion_response + )) + cases.append(TestCase( + desc="verbosity: high", + method="POST", + url=chat_url, + headers=headers, + body={ + "model": model, + "messages": [{"role": "user", "content": "介绍一下Python"}], + "max_tokens": 50, + "verbosity": "high" + }, + validator=validate_openai_chat_completion_response + )) # ---- 执行测试 ---- flags = []