feat(engine): finalize after tool iteration limit
This commit is contained in:
@ -708,8 +708,19 @@ class AgentLoop:
|
|||||||
break
|
break
|
||||||
|
|
||||||
if iterations >= resolved_max_tool_iterations:
|
if iterations >= resolved_max_tool_iterations:
|
||||||
final_text = response.content or "Tool loop stopped after reaching the configured iteration limit."
|
finalized = await self._finalize_after_tool_limit(
|
||||||
final_finish_reason = "max_tool_iterations"
|
provider=provider,
|
||||||
|
messages=messages,
|
||||||
|
model=final_model,
|
||||||
|
max_tokens=resolved_max_tokens,
|
||||||
|
temperature=resolved_temperature,
|
||||||
|
thinking_enabled=thinking_enabled,
|
||||||
|
)
|
||||||
|
final_text = finalized or (
|
||||||
|
"Tool loop stopped after reaching the configured iteration limit, "
|
||||||
|
"and no final answer was produced."
|
||||||
|
)
|
||||||
|
final_finish_reason = "max_tool_iterations_finalized" if finalized else "max_tool_iterations"
|
||||||
session_manager.append_message(
|
session_manager.append_message(
|
||||||
resolved_session_id,
|
resolved_session_id,
|
||||||
run_id=resolved_run_id,
|
run_id=resolved_run_id,
|
||||||
@ -853,6 +864,39 @@ class AgentLoop:
|
|||||||
raise RuntimeError(f"Engine loader did not provide required dependency {field_name!r}")
|
raise RuntimeError(f"Engine loader did not provide required dependency {field_name!r}")
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
async def _finalize_after_tool_limit(
|
||||||
|
*,
|
||||||
|
provider: Any,
|
||||||
|
messages: list[dict[str, Any]],
|
||||||
|
model: str,
|
||||||
|
max_tokens: int,
|
||||||
|
temperature: float,
|
||||||
|
thinking_enabled: bool | None,
|
||||||
|
) -> str:
|
||||||
|
final_messages = [
|
||||||
|
*messages,
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": (
|
||||||
|
"The configured tool iteration budget is exhausted. Do not call tools. "
|
||||||
|
"Produce the best final answer from the existing conversation and tool results. "
|
||||||
|
"State uncertainty explicitly."
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
kwargs: dict[str, Any] = {
|
||||||
|
"messages": final_messages,
|
||||||
|
"tools": None,
|
||||||
|
"model": model,
|
||||||
|
"max_tokens": max_tokens,
|
||||||
|
"temperature": temperature,
|
||||||
|
}
|
||||||
|
if thinking_enabled is not None:
|
||||||
|
kwargs["thinking_enabled"] = thinking_enabled
|
||||||
|
response = await provider.chat(**kwargs)
|
||||||
|
return (response.content or "").strip()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _load_pinned_skill_contexts(skills_loader: Any, skill_names: list[str]) -> list[SkillContext]:
|
def _load_pinned_skill_contexts(skills_loader: Any, skill_names: list[str]) -> list[SkillContext]:
|
||||||
contexts: list[SkillContext] = []
|
contexts: list[SkillContext] = []
|
||||||
|
|||||||
@ -608,6 +608,12 @@ def test_agent_loop_records_max_tool_iterations_as_failed_skill_effect(tmp_path:
|
|||||||
provider_name="stub",
|
provider_name="stub",
|
||||||
model="stub-model",
|
model="stub-model",
|
||||||
),
|
),
|
||||||
|
LLMResponse(
|
||||||
|
content="Based on the available tool result, the container likely failed during startup.",
|
||||||
|
finish_reason="stop",
|
||||||
|
provider_name="stub",
|
||||||
|
model="stub-model",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -621,7 +627,9 @@ def test_agent_loop_records_max_tool_iterations_as_failed_skill_effect(tmp_path:
|
|||||||
)
|
)
|
||||||
loaded = loop.boot()
|
loaded = loop.boot()
|
||||||
|
|
||||||
assert result.finish_reason == "max_tool_iterations"
|
assert result.finish_reason == "max_tool_iterations_finalized"
|
||||||
|
assert "Based on the available tool result" in result.output_text
|
||||||
|
assert "Tool loop stopped" not in result.output_text
|
||||||
effect_records = loaded.run_memory_store.list_skill_effects("docker-debug", version="v0007")
|
effect_records = loaded.run_memory_store.list_skill_effects("docker-debug", version="v0007")
|
||||||
assert effect_records[-1].run_id == result.run_id
|
assert effect_records[-1].run_id == result.run_id
|
||||||
assert effect_records[-1].success is False
|
assert effect_records[-1].success is False
|
||||||
|
|||||||
Reference in New Issue
Block a user