fix(actor): top-level config keys take precedence over options block duplicates
CI / push-validation (pull_request) Successful in 31s
CI / lint (pull_request) Successful in 34s
CI / quality (pull_request) Successful in 47s
CI / helm (pull_request) Successful in 47s
CI / build (pull_request) Successful in 53s
CI / typecheck (pull_request) Successful in 1m2s
CI / security (pull_request) Successful in 1m2s
CI / integration_tests (pull_request) Successful in 2m49s
CI / unit_tests (pull_request) Successful in 6m36s
CI / docker (pull_request) Failing after 15m28s
CI / coverage (pull_request) Failing after 15m28s
CI / status-check (pull_request) Has been cancelled

In both ToolCallingLLMCaller._resolve_llm and SimpleLLMAgent._resolve_llm,
the options block was merged after top-level keys were applied, causing
llm_kwargs.update(...) to overwrite top-level temperature/max_tokens/
max_retries with any duplicate values from the options block.

Fix: apply build_llm_kwargs_from_options first, then re-apply the
top-level extracted values so they always win.

ISSUES CLOSED: #11243 #11223
This commit is contained in:
2026-05-28 16:53:51 -04:00
committed by Forgejo
parent 2dd920078a
commit fae4384370
2 changed files with 19 additions and 13 deletions
+7 -4
View File
@@ -220,16 +220,19 @@ class SimpleLLMAgent:
max_tokens = self.config.get("max_tokens")
max_retries = self.config.get("max_retries")
llm_kwargs: dict[str, Any] = {}
# Options are applied first so top-level keys take precedence over
# any duplicates in the options block.
options = dict(self.config.get("options") or {})
from cleveragents.actor.config import build_llm_kwargs_from_options
llm_kwargs.update(build_llm_kwargs_from_options(options, logger=logger_sr))
if temperature is not None:
llm_kwargs["temperature"] = temperature
if max_tokens is not None:
llm_kwargs["max_tokens"] = max_tokens
if max_retries is not None:
llm_kwargs["max_retries"] = max_retries
options = dict(self.config.get("options") or {})
from cleveragents.actor.config import build_llm_kwargs_from_options
llm_kwargs.update(build_llm_kwargs_from_options(options, logger=logger_sr))
registry = get_provider_registry()
self._llm = registry.create_llm(
provider_type=provider, model_id=model, **llm_kwargs
+12 -9
View File
@@ -131,6 +131,18 @@ class ToolCallingLLMCaller:
max_retries = self._actor_config.get("max_retries")
llm_kwargs: dict[str, Any] = {}
# M7 (#11243): merge options block so custom LLM backend kwargs
# (e.g. openai_api_base, openai_api_key) are forwarded to the
# LLM constructor — mirrors the fix applied to SimpleLLMAgent in
# stream_router.py (PR #11225 / commit b3851693).
# Options are applied first so top-level keys take precedence over
# any duplicates in the options block.
options = dict(self._actor_config.get("options") or {})
from cleveragents.actor.config import build_llm_kwargs_from_options
llm_kwargs.update(build_llm_kwargs_from_options(options, logger=logger))
if temperature is not None:
llm_kwargs["temperature"] = temperature
if max_tokens is not None:
@@ -138,15 +150,6 @@ class ToolCallingLLMCaller:
if max_retries is not None:
llm_kwargs["max_retries"] = max_retries
# M7 (#11243): merge options block so custom LLM backend kwargs
# (e.g. openai_api_base, openai_api_key) are forwarded to the
# LLM constructor — mirrors the fix applied to SimpleLLMAgent in
# stream_router.py (PR #11225 / commit b3851693).
options = dict(self._actor_config.get("options") or {})
from cleveragents.actor.config import build_llm_kwargs_from_options
llm_kwargs.update(build_llm_kwargs_from_options(options, logger=logger))
registry = get_provider_registry()
# Annotated as Any because create_llm() returns BaseLanguageModel but the
# real runtime object is BaseChatModel which has bind_tools().