Skip to content
Closed
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
7 changes: 6 additions & 1 deletion agent/title_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
def generate_title(
user_message: str,
assistant_response: str,
timeout: float = 30.0,
timeout: Optional[float] = None,
failure_callback: Optional[FailureCallback] = None,
main_runtime: dict = None,
) -> Optional[str]:
Expand All @@ -39,6 +39,11 @@ def generate_title(
auxiliary LLM client (cheapest/fastest available model).
Returns the title string or None on failure.

``timeout`` defaults to ``None``, which delegates to
``call_llm``'s config-driven resolution (reads
``auxiliary.title_generation.timeout`` from config.yaml).
An explicit value overrides the config.

``failure_callback`` is invoked with ``(task, exception)`` when the
auxiliary call raises β€” the caller typically wires this to
``AIAgent._emit_auxiliary_failure`` so the user sees a warning instead
Expand Down
38 changes: 38 additions & 0 deletions tests/agent/test_title_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,44 @@ def test_no_callback_matches_legacy_behavior(self):
with patch("agent.title_generator.call_llm", side_effect=RuntimeError("nope")):
assert generate_title("q", "a") is None

def test_default_timeout_delegates_to_config(self):
"""Regression: timeout=None delegates to call_llm config resolution (#41812).

Previously generate_title defaulted to timeout=30.0, which caused
call_llm to use that hardcoded value instead of reading
auxiliary.title_generation.timeout from config.yaml.
"""
captured_kwargs = {}

def mock_call_llm(**kwargs):
captured_kwargs.update(kwargs)
resp = MagicMock()
resp.choices = [MagicMock()]
resp.choices[0].message.content = "Config-Aware Title"
return resp

with patch("agent.title_generator.call_llm", side_effect=mock_call_llm):
generate_title("question", "answer")

# Default must be None so call_llm reads from config
assert captured_kwargs.get("timeout") is None

def test_explicit_timeout_is_forwarded(self):
"""When an explicit timeout is passed, it must reach call_llm."""
captured_kwargs = {}

def mock_call_llm(**kwargs):
captured_kwargs.update(kwargs)
resp = MagicMock()
resp.choices = [MagicMock()]
resp.choices[0].message.content = "Explicit Timeout"
return resp

with patch("agent.title_generator.call_llm", side_effect=mock_call_llm):
generate_title("question", "answer", timeout=120.0)

assert captured_kwargs.get("timeout") == 120.0

def test_truncates_long_messages(self):
"""Long user/assistant messages should be truncated in the LLM request."""
captured_kwargs = {}
Expand Down
Loading