summaryrefslogtreecommitdiff
path: root/Omni/Agent
diff options
context:
space:
mode:
authorBen Sima <ben@bensima.com>2025-12-12 21:45:53 -0500
committerBen Sima <ben@bensima.com>2025-12-12 21:45:53 -0500
commit862b10aa05ef66af5a88f307e6209ce10185bbcf (patch)
treed1e0fe0217a0a9e46378d397c745c9cb54775f77 /Omni/Agent
parent49f6fe47e19c42b87615dd2d75e53f43331e00ab (diff)
fix: prompt for text response when agent returns empty after tool calls
When the LLM returned empty content after executing tools, the agent would complete with an empty message. Now both agent loops (LLM-based and Provider-based) detect this case and inject a prompt asking the LLM to provide a response to the user.
Diffstat (limited to 'Omni/Agent')
-rw-r--r--Omni/Agent/Engine.hs60
1 files changed, 36 insertions, 24 deletions
diff --git a/Omni/Agent/Engine.hs b/Omni/Agent/Engine.hs
index fe3b3d5..dab1329 100644
--- a/Omni/Agent/Engine.hs
+++ b/Omni/Agent/Engine.hs
@@ -667,18 +667,24 @@ runAgent engineCfg agentCfg userPrompt = do
unless (Text.null assistantText)
<| engineOnAssistant engineCfg assistantText
case msgToolCalls msg of
- Nothing -> do
- engineOnActivity engineCfg "Agent completed"
- engineOnComplete engineCfg
- pure
- <| Right
- <| AgentResult
- { resultFinalMessage = msgContent msg,
- resultToolCallCount = totalCalls,
- resultIterations = iteration + 1,
- resultTotalCost = newCost,
- resultTotalTokens = newTokens
- }
+ Nothing
+ | Text.null (msgContent msg) && totalCalls > 0 -> do
+ engineOnActivity engineCfg "Empty response after tools, prompting for text"
+ let promptMsg = Message ToolRole "Please provide a response to the user." Nothing Nothing
+ newMsgs = msgs <> [msg, promptMsg]
+ loop llm tools' toolMap newMsgs (iteration + 1) totalCalls newTokens newCost toolCallCounts testFailures editFailures
+ | otherwise -> do
+ engineOnActivity engineCfg "Agent completed"
+ engineOnComplete engineCfg
+ pure
+ <| Right
+ <| AgentResult
+ { resultFinalMessage = msgContent msg,
+ resultToolCallCount = totalCalls,
+ resultIterations = iteration + 1,
+ resultTotalCost = newCost,
+ resultTotalTokens = newTokens
+ }
Just [] -> do
engineOnActivity engineCfg "Agent completed (empty tool calls)"
engineOnComplete engineCfg
@@ -886,18 +892,24 @@ runAgentWithProvider engineCfg provider agentCfg userPrompt = do
unless (Text.null assistantText)
<| engineOnAssistant engineCfg assistantText
case Provider.msgToolCalls msg of
- Nothing -> do
- engineOnActivity engineCfg "Agent completed"
- engineOnComplete engineCfg
- pure
- <| Right
- <| AgentResult
- { resultFinalMessage = Provider.msgContent msg,
- resultToolCallCount = totalCalls,
- resultIterations = iteration + 1,
- resultTotalCost = newCost,
- resultTotalTokens = newTokens
- }
+ Nothing
+ | Text.null (Provider.msgContent msg) && totalCalls > 0 -> do
+ engineOnActivity engineCfg "Empty response after tools, prompting for text"
+ let promptMsg = Provider.Message Provider.ToolRole "Please provide a response to the user." Nothing Nothing
+ newMsgs = msgs <> [msg, promptMsg]
+ loopProvider prov toolApis' toolMap newMsgs (iteration + 1) totalCalls newTokens newCost toolCallCounts testFailures editFailures
+ | otherwise -> do
+ engineOnActivity engineCfg "Agent completed"
+ engineOnComplete engineCfg
+ pure
+ <| Right
+ <| AgentResult
+ { resultFinalMessage = Provider.msgContent msg,
+ resultToolCallCount = totalCalls,
+ resultIterations = iteration + 1,
+ resultTotalCost = newCost,
+ resultTotalTokens = newTokens
+ }
Just [] -> do
engineOnActivity engineCfg "Agent completed (empty tool calls)"
engineOnComplete engineCfg