refactor(agent): extract agent+shared into standalone packages with full GRACE semantic markup

- Move agent code from backend/src/agent/ to agent/src/ss_tools/agent/
- Extract shared stdlib-only utilities to shared/src/ss_tools/shared/
- Add #region/#endregion contracts to all ~140 functions (INV_1 compliance)
- Update docker files, entrypoint, build scripts for new package layout
- Backend now imports ss_tools.shared._llm_health (no gradio/langchain deps)
- Add specs for 036-039 feature plans
This commit is contained in:
2026-07-07 15:18:24 +03:00
parent ce368429f7
commit b95df37cd5
75 changed files with 2711 additions and 1861 deletions

View File

@@ -0,0 +1,75 @@
# agent/src/ss_tools/agent/_llm_params.py
# #region AgentChat.LlmParams [C:3] [TYPE Module] [SEMANTICS agent-chat,llm,openai,compatibility]
# @BRIEF Build provider-safe ChatOpenAI kwargs and raw OpenAI payloads.
# @POST Unsupported sampling parameters are omitted for reasoning/codex models.
from typing import Any
_TEMPERATURE_UNSUPPORTED_PREFIXES = (
"codex/",
"omni/codex/",
"gpt-5",
"o1",
"o3",
"o4",
)
# #region AgentChat.LlmParams.CanonicalModelName [C:1] [TYPE Function] [SEMANTICS agent-chat,llm,model,canonical]
# @ingroup AgentChat
# @BRIEF Strip provider prefix from model name for compatibility checks.
def _canonical_model_name(model: str | None) -> str:
name = (model or "").strip().lower()
if name.startswith(("codex/", "omni/codex/")):
return name
if "/" in name:
return name.rsplit("/", 1)[-1]
return name
# #endregion AgentChat.LlmParams.CanonicalModelName
# #region AgentChat.LlmParams.SupportsTemperature [C:1] [TYPE Function] [SEMANTICS agent-chat,llm,temperature,check]
# @ingroup AgentChat
# @BRIEF Check if a model supports temperature parameter (reasoning/codex models don't).
def supports_temperature(model: str | None) -> bool:
name = _canonical_model_name(model)
return not any(name.startswith(prefix) for prefix in _TEMPERATURE_UNSUPPORTED_PREFIXES)
# #endregion AgentChat.LlmParams.SupportsTemperature
# #region AgentChat.LlmParams.ChatOpenAIKwargs [C:2] [TYPE Function] [SEMANTICS agent-chat,llm,openai,kwargs]
# @ingroup AgentChat
# @BRIEF Build ChatOpenAI constructor kwargs with provider-safe parameters.
def chat_openai_kwargs(
*,
model: str,
base_url: str | None,
api_key: str,
max_tokens: int,
temperature: float = 0,
) -> dict[str, Any]:
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
# #endregion AgentChat.LlmParams.ChatOpenAIKwargs
# #region AgentChat.LlmParams.AddTemperature [C:2] [TYPE Function] [SEMANTICS agent-chat,llm,payload,temperature]
# @ingroup AgentChat
# @BRIEF Conditionally add temperature to raw OpenAI payload dict.
def add_temperature_if_supported(
payload: dict[str, Any],
*,
model: str | None,
temperature: float = 0,
) -> dict[str, Any]:
if supports_temperature(model):
payload["temperature"] = temperature
return payload
# #endregion AgentChat.LlmParams.AddTemperature
# #endregion AgentChat.LlmParams