Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions python/sglang/srt/entrypoints/openai/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,10 @@ class ChatCompletionRequest(BaseModel):
parallel_tool_calls: bool = True
return_hidden_states: bool = False
return_routed_experts: bool = False
# Skip this many leading token positions in the returned routed_experts
# tensor; multi-turn clients that already hold the prefix rows receive
# only the rows for newly processed tokens.
routed_experts_start_len: int = 0
return_cached_tokens_details: bool = False
return_prompt_token_ids: bool = False
return_completion_token_ids: bool = False
Expand Down
1 change: 1 addition & 0 deletions python/sglang/srt/entrypoints/openai/serving_chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ def _convert_to_internal_request(
disagg_prefill_dp_rank=request.disagg_prefill_dp_rank,
return_hidden_states=request.return_hidden_states,
return_routed_experts=request.return_routed_experts,
routed_experts_start_len=request.routed_experts_start_len,
rid=request.rid,
extra_key=self._compute_extra_key(request),
require_reasoning=self._get_reasoning_from_request(request),
Expand Down
4 changes: 3 additions & 1 deletion python/sglang/srt/function_call/multi_format_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -1030,7 +1030,9 @@ def _deserialize_glm_value(value: str) -> Any:
except Exception:
pass
try:
return ast.literal_eval(value)
result = ast.literal_eval(value)
json.dumps(result)
return result
except Exception:
pass
return value
Expand Down
3 changes: 3 additions & 0 deletions python/sglang/srt/managers/tokenizer_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -1604,6 +1604,9 @@ def _handle_batch_output(
if getattr(recv_obj, "routed_experts", None):
routed_experts_tensor = recv_obj.routed_experts[i]
if routed_experts_tensor is not None:
start_len = getattr(state.obj, "routed_experts_start_len", 0) or 0
if start_len > 0:
routed_experts_tensor = routed_experts_tensor[start_len:]
meta_info["routed_experts"] = pybase64.b64encode(
routed_experts_tensor.numpy().tobytes()
).decode("utf-8")
Expand Down
12 changes: 12 additions & 0 deletions test/registered/function_call/test_multi_format_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,18 @@ def test_python_tuple_literal_value(self):
# ast.literal handles tuple syntax; serialized as a JSON array.
self.assertEqual(args["days"], [1, 2])

def test_python_set_literal_value_stays_string(self):
text = (
"<tool_call>get_weather"
"<arg_key>days</arg_key><arg_value>{1, 2}</arg_value>"
"</tool_call>"
)
result = self.det.detect_and_parse(text, self.tools)
args = json.loads(result.calls[0].parameters)
# ast.literal_eval yields a set, which JSON cannot represent; the raw
# string is kept so the arguments dict stays serializable.
self.assertEqual(args["days"], "{1, 2}")


class TestGptOssDialect(unittest.TestCase):
def setUp(self):
Expand Down
Loading