align platform build config with working submission
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# Adapted from
|
||||
# https://github.com/lm-sys/FastChat/blob/168ccc29d3f7edc50823016105c024fe2282732a/fastchat/protocol/openai_api_protocol.py
|
||||
import json
|
||||
import time
|
||||
from argparse import Namespace
|
||||
from typing import Any, Dict, List, Literal, Optional, Union
|
||||
@@ -254,6 +255,15 @@ class ChatCompletionRequest(OpenAIBaseModel):
|
||||
description=("Additional kwargs to pass to the template renderer. "
|
||||
"Will be accessible by the chat template."),
|
||||
)
|
||||
thinking: Optional[Any] = Field(
|
||||
default=None,
|
||||
description=(
|
||||
"Per-request thinking switch (OpenAI-style top-level). Accepts: "
|
||||
"{'type':'disabled'} / {'type':'enabled'} / bool true/false. "
|
||||
"Translated to chat_template_kwargs.enable_thinking (bool) so the "
|
||||
"Qwen3.6 template's enable_thinking branch controls reasoning. "
|
||||
"Null/absent = server default (thinking on via --reasoning-parser)."),
|
||||
)
|
||||
guided_json: Optional[Union[str, dict, BaseModel]] = Field(
|
||||
default=None,
|
||||
description=("If specified, the output will follow the JSON schema."),
|
||||
@@ -411,6 +421,26 @@ class ChatCompletionRequest(OpenAIBaseModel):
|
||||
"Each message must have at least one of 'content' or "
|
||||
"'reasoning_content'.")
|
||||
msg = {**msg, "content": ""}
|
||||
# tool_calls arguments: dict -> JSON string.
|
||||
# Many clients/datasets send function.arguments as a dict (e.g.
|
||||
# {"cmd":"ls"}), but upstream ChatCompletionMessageParam strictly
|
||||
# requires a JSON string. Convert here so validation passes (matches
|
||||
# OpenAI's lenient acceptance of both forms). Without this, dataset
|
||||
# requests with tool messages 4xx with
|
||||
# "function.arguments: Input should be a valid string".
|
||||
tool_calls = msg.get("tool_calls")
|
||||
if isinstance(tool_calls, list):
|
||||
new_tc = []
|
||||
for tc in tool_calls:
|
||||
if isinstance(tc, dict) and isinstance(tc.get("function"), dict):
|
||||
fn = tc["function"]
|
||||
args = fn.get("arguments")
|
||||
if isinstance(args, dict):
|
||||
fn = {**fn, "arguments": json.dumps(
|
||||
args, ensure_ascii=False)}
|
||||
tc = {**tc, "function": fn}
|
||||
new_tc.append(tc)
|
||||
msg = {**msg, "tool_calls": new_tc}
|
||||
normalized.append(msg)
|
||||
data = {**data, "messages": normalized}
|
||||
return data
|
||||
@@ -424,6 +454,48 @@ class ChatCompletionRequest(OpenAIBaseModel):
|
||||
|
||||
return data
|
||||
|
||||
@model_validator(mode="before")
|
||||
@classmethod
|
||||
def validate_thinking(cls, data):
|
||||
"""Translate top-level `thinking` → chat_template_kwargs.enable_thinking.
|
||||
|
||||
Accepts {'type':'disabled'|'enabled'} or bool. The Qwen3.6 template's
|
||||
`enable_thinking is false` branch (chat_template.jinja:149) gates the
|
||||
reasoning prefix, so a bool is what actually controls it. Merged into
|
||||
chat_template_kwargs (request-level value wins over any pre-existing
|
||||
enable_thinking). Without this, top-level `thinking` 4xx with
|
||||
extra_forbidden (OpenAIBaseModel has extra="forbid").
|
||||
"""
|
||||
thinking = data.get("thinking")
|
||||
if thinking is None:
|
||||
return data
|
||||
# Normalize to a bool.
|
||||
enable: Optional[bool]
|
||||
if isinstance(thinking, bool):
|
||||
enable = thinking
|
||||
elif isinstance(thinking, dict):
|
||||
t = str(thinking.get("type", "")).lower()
|
||||
if t == "disabled":
|
||||
enable = False
|
||||
elif t == "enabled" or t == "auto":
|
||||
enable = True
|
||||
elif t == "":
|
||||
enable = None
|
||||
else:
|
||||
raise ValueError(
|
||||
f"thinking.type must be 'enabled'/'disabled'/'auto', "
|
||||
f"got {thinking.get('type')!r}")
|
||||
else:
|
||||
raise ValueError(
|
||||
f"thinking must be bool or {{'type':'disabled'|'enabled'}}, "
|
||||
f"got {type(thinking).__name__}")
|
||||
if enable is not None:
|
||||
ctk = dict(data.get("chat_template_kwargs") or {})
|
||||
ctk["enable_thinking"] = enable
|
||||
data["chat_template_kwargs"] = ctk
|
||||
data.pop("thinking", None)
|
||||
return data
|
||||
|
||||
@model_validator(mode="before")
|
||||
@classmethod
|
||||
def check_logprobs(cls, data):
|
||||
|
||||
Reference in New Issue
Block a user