Eva Kadlecová (ceac2c88) at 19 Mar 15:03
fix: improve create_commit tool approval message
... and 2 more commits
Eva Kadlecová (a8c15ffc) at 19 Mar 13:07
fix: improve create_commit tool approval message
... and 9 more commits
Eva Kadlecová (9132d3ef) at 18 Mar 15:07
fix: retry invalid tool call
Eva Kadlecová (a3034a90) at 18 Mar 11:35
fix: retry invalid tool call
Fixes an issue where LLMs occasionally produce malformed tool call arguments (e.g. passing a string instead of a list), which causes tool execution to fail silently and results in blank or broken responses for the user.
This MR adds pre-approval validation of tool call arguments against their Pydantic schemas in ChatAgent. When a malformed tool call is detected, the agent automatically retries the LLM request (up to 3 times), appending the validation error to the conversation history so the model can self-correct. If all retries are exhausted, a user-friendly error message is returned.
Closes gitlab-org/gitlab#592447
use_generic_gitlab_api_tools feature flag enabled.diff --git a/duo_workflow_service/agents/chat_agent.py b/duo_workflow_service/agents/chat_agent.py
index 702dccd5b..5aeb78444 100644
--- a/duo_workflow_service/agents/chat_agent.py
+++ b/duo_workflow_service/agents/chat_agent.py
@@ -173,10 +173,37 @@ class ChatAgent:
return messages
async def _get_agent_response(self, state: ChatWorkflowState) -> BaseMessage:
- return await self.prompt_adapter.get_response(
+ # --- DEV ONLY: mock corrupt tool calls to test retry exhaustion ---
+ import json as _json # noqa: F811,E402 # DEV ONLY
+
+ _MOCK_REMAINING = 4
+ if not hasattr(self, "_mock_corrupt_ctr"):
+ self._mock_corrupt_ctr = _MOCK_REMAINING
+
+ response = await self.prompt_adapter.get_response(
state, system_template_override=self.system_template_override
)
+ if (
+ self._mock_corrupt_ctr > 0
+ and isinstance(response, AIMessage)
+ and response.tool_calls
+ ):
+ for call in response.tool_calls:
+ if call["name"] == "create_commit" and isinstance(
+ call["args"].get("actions"), list
+ ):
+ log.warning(
+ "DEV MOCK: Corrupting create_commit tool call args",
+ remaining=self._mock_corrupt_ctr,
+ )
+ call["args"]["actions"] = _json.dumps(call["args"]["actions"])
+ self._mock_corrupt_ctr -= 1
+ break
+
+ return response
+ # --- END DEV ONLY ---
+
def _build_response(
self, agent_response: BaseMessage, state: ChatWorkflowState
) -> Dict[str, Any]:
@@ -317,3 +344,4 @@ class ChatAgent:
except Exception as error:
log_exception(error, extra={"context": "Error processing chat agent"})
return self._create_error_response(error)
| Before | After - with one failure | After - with continuous failure |
|---|---|---|
![]() |
![]() |
![]() |
Eva Kadlecová (3ade930a) at 18 Mar 10:38
fix: retry invalid tool call
Eva Kadlecová (be9cfc67) at 18 Mar 10:27
fix: retry invalid tool call
Thanks for the fix, the code looks good, I just left one minor comment
@s_murray Can you please do the maintainer review?