70 lines
2.1 KiB
Python
70 lines
2.1 KiB
Python
# backend/src/agent/_llm_params.py
|
|
# #region AgentChat.LlmParams [C:3] [TYPE Module] [SEMANTICS agent-chat,llm,openai,compatibility]
|
|
# @defgroup AgentChat Shared LLM parameter compatibility helpers.
|
|
# @LAYER Service
|
|
# @BRIEF Build provider-safe ChatOpenAI kwargs and raw OpenAI payloads.
|
|
# @POST Unsupported sampling parameters are omitted for reasoning/codex models.
|
|
# @RATIONALE Some OpenAI-compatible gateways reject temperature for reasoning/codex
|
|
# models. Centralising the guard prevents resume, health-check, and title
|
|
# generation paths from diverging.
|
|
|
|
from typing import Any
|
|
|
|
_TEMPERATURE_UNSUPPORTED_PREFIXES = (
|
|
"codex/",
|
|
"omni/codex/",
|
|
"gpt-5",
|
|
"o1",
|
|
"o3",
|
|
"o4",
|
|
)
|
|
|
|
|
|
def _canonical_model_name(model: str | None) -> str:
|
|
"""Return provider-stripped, lowercase model name for compatibility checks."""
|
|
name = (model or "").strip().lower()
|
|
if name.startswith(("codex/", "omni/codex/")):
|
|
return name
|
|
if "/" in name:
|
|
return name.rsplit("/", 1)[-1]
|
|
return name
|
|
|
|
|
|
def supports_temperature(model: str | None) -> bool:
|
|
"""Return False for model families whose APIs reject temperature."""
|
|
name = _canonical_model_name(model)
|
|
return not any(name.startswith(prefix) for prefix in _TEMPERATURE_UNSUPPORTED_PREFIXES)
|
|
|
|
|
|
def chat_openai_kwargs(
|
|
*,
|
|
model: str,
|
|
base_url: str | None,
|
|
api_key: str,
|
|
max_tokens: int,
|
|
temperature: float = 0,
|
|
) -> dict[str, Any]:
|
|
"""Build ChatOpenAI kwargs without unsupported temperature for reasoning models."""
|
|
kwargs: dict[str, Any] = {
|
|
"model": model,
|
|
"base_url": base_url,
|
|
"api_key": api_key,
|
|
"max_tokens": max_tokens,
|
|
}
|
|
if supports_temperature(model):
|
|
kwargs["temperature"] = temperature
|
|
return kwargs
|
|
|
|
|
|
def add_temperature_if_supported(
|
|
payload: dict[str, Any],
|
|
*,
|
|
model: str | None,
|
|
temperature: float = 0,
|
|
) -> dict[str, Any]:
|
|
"""Mutate and return payload with temperature only when the model supports it."""
|
|
if supports_temperature(model):
|
|
payload["temperature"] = temperature
|
|
return payload
|
|
# #endregion AgentChat.LlmParams
|