mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
feat(fireworks_ai): full chat_template_kwargs parity with the gateway
Map the remaining gateway-documented effort keys: thinking as an alias for enable_thinking (enable_thinking wins when both are present), reasoning_budget to an integer reasoning_effort (skipped when thinking is explicitly off), and low_effort=true to reasoning_effort=low (budget wins when both are set). guided_json and guided_choice response_format wrappers now include the name field (response and choice) to match the gateway wire shape.
This commit is contained in:
parent
431f61b4f7
commit
4a601c49a6
2 changed files with 104 additions and 15 deletions
|
|
@ -61,8 +61,32 @@ def _extract_fireworks_hidden_params(payload: dict) -> dict:
|
|||
return {**top_level, **per_choice}
|
||||
|
||||
|
||||
def _json_schema_response_format(schema: object) -> Mapping[str, object]:
|
||||
return {"type": "json_schema", "json_schema": {"schema": schema}} # mutable-ok: JSON request body
|
||||
def _json_schema_response_format(schema: object, name: str) -> Mapping[str, object]:
|
||||
return {"type": "json_schema", "json_schema": {"name": name, "schema": schema}} # mutable-ok: JSON request body
|
||||
|
||||
|
||||
_EFFORT_KWARG_KEYS: Final = frozenset({"enable_thinking", "thinking", "reasoning_budget", "low_effort"})
|
||||
|
||||
|
||||
def _bool_from_kwargs(kwargs: Mapping[str, object], keys: tuple[str, ...]) -> bool | None:
|
||||
for key in keys:
|
||||
value = kwargs.get(key)
|
||||
if isinstance(value, bool):
|
||||
return value
|
||||
return None
|
||||
|
||||
|
||||
def _effort_from_chat_template_kwargs(kwargs: Mapping[str, object]) -> object:
|
||||
enable_thinking: Final = _bool_from_kwargs(kwargs, ("enable_thinking", "thinking"))
|
||||
if enable_thinking is False:
|
||||
return "none"
|
||||
budget: Final = kwargs.get("reasoning_budget")
|
||||
if isinstance(budget, (int, float)) and not isinstance(budget, bool) and budget > 0:
|
||||
return int(budget)
|
||||
low_effort: Final = _bool_from_kwargs(kwargs, ("low_effort",))
|
||||
if low_effort is True:
|
||||
return "low"
|
||||
return None
|
||||
|
||||
|
||||
_NIM_VLLM_STRIP_PARAMS: Final = frozenset(
|
||||
|
|
@ -357,29 +381,28 @@ class FireworksAIConfig(FireworksAIMixin, OpenAIGPTConfig):
|
|||
type(chat_template_kwargs).__name__,
|
||||
)
|
||||
return ()
|
||||
other_keys: Final = tuple(sorted(k for k in chat_template_kwargs if k != "enable_thinking"))
|
||||
other_keys: Final = tuple(sorted(k for k in chat_template_kwargs if k not in _EFFORT_KWARG_KEYS))
|
||||
if other_keys:
|
||||
verbose_logger.debug(
|
||||
"fireworks_ai does not support chat_template_kwargs keys %s for model=%s; dropping them.",
|
||||
other_keys,
|
||||
model,
|
||||
)
|
||||
if "enable_thinking" not in chat_template_kwargs:
|
||||
return ()
|
||||
if "reasoning_effort" in optional_params or "thinking" in optional_params:
|
||||
verbose_logger.debug(
|
||||
"fireworks_ai ignoring chat_template_kwargs.enable_thinking; explicit reasoning_effort/thinking takes precedence."
|
||||
"fireworks_ai ignoring chat_template_kwargs; explicit reasoning_effort/thinking takes precedence."
|
||||
)
|
||||
return ()
|
||||
effort: Final = _effort_from_chat_template_kwargs(chat_template_kwargs)
|
||||
if effort is None:
|
||||
return ()
|
||||
if not supports_reasoning(model=model, custom_llm_provider="fireworks_ai"):
|
||||
verbose_logger.debug(
|
||||
"fireworks_ai model %r does not support reasoning; dropping chat_template_kwargs.enable_thinking.",
|
||||
"fireworks_ai model %r does not support reasoning; dropping chat_template_kwargs effort keys.",
|
||||
model,
|
||||
)
|
||||
return ()
|
||||
if chat_template_kwargs["enable_thinking"]:
|
||||
return ()
|
||||
return (("reasoning_effort", "none"),)
|
||||
return (("reasoning_effort", effort),)
|
||||
|
||||
@staticmethod
|
||||
def _translate_guided_params(
|
||||
|
|
@ -396,7 +419,7 @@ class FireworksAIConfig(FireworksAIMixin, OpenAIGPTConfig):
|
|||
)
|
||||
return ()
|
||||
if extra_body.get("guided_json") is not None:
|
||||
return (("response_format", _json_schema_response_format(extra_body["guided_json"])),)
|
||||
return (("response_format", _json_schema_response_format(extra_body["guided_json"], "response")),)
|
||||
if extra_body.get("guided_grammar") is not None:
|
||||
grammar_response_format: Final = { # mutable-ok: JSON request body
|
||||
"type": "grammar",
|
||||
|
|
@ -407,7 +430,7 @@ class FireworksAIConfig(FireworksAIMixin, OpenAIGPTConfig):
|
|||
"type": "string",
|
||||
"enum": extra_body["guided_choice"],
|
||||
}
|
||||
return (("response_format", _json_schema_response_format(choice_schema)),)
|
||||
return (("response_format", _json_schema_response_format(choice_schema, "choice")),)
|
||||
|
||||
def _transform_tools(self, tools: list[OpenAIChatCompletionToolParam]) -> list[OpenAIChatCompletionToolParam]:
|
||||
for tool in tools:
|
||||
|
|
|
|||
|
|
@ -1338,6 +1338,66 @@ def test_map_extra_body_params_chat_template_kwargs_enable_thinking():
|
|||
assert enabled == {}
|
||||
|
||||
|
||||
def test_map_extra_body_params_chat_template_kwargs_thinking_alias():
|
||||
config = FireworksAIConfig()
|
||||
result = config.map_extra_body_params(
|
||||
{"extra_body": {"chat_template_kwargs": {"thinking": False}}},
|
||||
_REASONING_MODEL,
|
||||
)
|
||||
assert result == {"reasoning_effort": "none"}
|
||||
|
||||
|
||||
def test_map_extra_body_params_chat_template_kwargs_enable_thinking_wins_over_thinking():
|
||||
config = FireworksAIConfig()
|
||||
result = config.map_extra_body_params(
|
||||
{"extra_body": {"chat_template_kwargs": {"enable_thinking": True, "thinking": False}}},
|
||||
_REASONING_MODEL,
|
||||
)
|
||||
assert result == {}
|
||||
|
||||
|
||||
def test_map_extra_body_params_chat_template_kwargs_reasoning_budget():
|
||||
config = FireworksAIConfig()
|
||||
result = config.map_extra_body_params(
|
||||
{"extra_body": {"chat_template_kwargs": {"reasoning_budget": 512}}},
|
||||
_REASONING_MODEL,
|
||||
)
|
||||
assert result == {"reasoning_effort": 512}
|
||||
|
||||
|
||||
def test_map_extra_body_params_chat_template_kwargs_budget_ignored_when_thinking_off():
|
||||
config = FireworksAIConfig()
|
||||
result = config.map_extra_body_params(
|
||||
{"extra_body": {"chat_template_kwargs": {"enable_thinking": False, "reasoning_budget": 512}}},
|
||||
_REASONING_MODEL,
|
||||
)
|
||||
assert result == {"reasoning_effort": "none"}
|
||||
|
||||
|
||||
def test_map_extra_body_params_chat_template_kwargs_low_effort():
|
||||
config = FireworksAIConfig()
|
||||
result = config.map_extra_body_params(
|
||||
{"extra_body": {"chat_template_kwargs": {"low_effort": True}}},
|
||||
_REASONING_MODEL,
|
||||
)
|
||||
assert result == {"reasoning_effort": "low"}
|
||||
|
||||
budget_wins = config.map_extra_body_params(
|
||||
{"extra_body": {"chat_template_kwargs": {"low_effort": True, "reasoning_budget": 256}}},
|
||||
_REASONING_MODEL,
|
||||
)
|
||||
assert budget_wins == {"reasoning_effort": 256}
|
||||
|
||||
|
||||
def test_map_extra_body_params_chat_template_kwargs_effort_keys_dropped_for_non_reasoning_model():
|
||||
config = FireworksAIConfig()
|
||||
result = config.map_extra_body_params(
|
||||
{"extra_body": {"chat_template_kwargs": {"reasoning_budget": 512, "low_effort": True}}},
|
||||
_NON_REASONING_MODEL,
|
||||
)
|
||||
assert result == {}
|
||||
|
||||
|
||||
def test_map_extra_body_params_chat_template_kwargs_native_reasoning_effort_wins():
|
||||
config = FireworksAIConfig()
|
||||
result = config.map_extra_body_params(
|
||||
|
|
@ -1388,7 +1448,10 @@ def test_map_extra_body_params_guided_json():
|
|||
{"extra_body": {"guided_json": schema}}, _REASONING_MODEL
|
||||
)
|
||||
assert result == {
|
||||
"response_format": {"type": "json_schema", "json_schema": {"schema": schema}}
|
||||
"response_format": {
|
||||
"type": "json_schema",
|
||||
"json_schema": {"name": "response", "schema": schema},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1407,7 +1470,10 @@ def test_map_extra_body_params_guided_grammar_and_choice():
|
|||
assert choice == {
|
||||
"response_format": {
|
||||
"type": "json_schema",
|
||||
"json_schema": {"schema": {"type": "string", "enum": ["yes", "no"]}},
|
||||
"json_schema": {
|
||||
"name": "choice",
|
||||
"schema": {"type": "string", "enum": ["yes", "no"]},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1440,7 +1506,7 @@ def test_map_extra_body_params_multiple_guided_params_priority_order():
|
|||
assert result == {
|
||||
"response_format": {
|
||||
"type": "json_schema",
|
||||
"json_schema": {"schema": {"type": "object"}},
|
||||
"json_schema": {"name": "response", "schema": {"type": "object"}},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue