Add Ollama diagnostic logging and broaden tool-call retry
Log model name, tool count, raw response preview, and parsed tool_call count at INFO level. Broaden the retry nudge to trigger whenever no tools are called on the first attempt, not just when code is detected. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -227,8 +227,28 @@ public class ChatService : IChatService
|
||||
}
|
||||
else
|
||||
{
|
||||
var rawContent = response?.Message?.Content ?? "I'm sorry, I couldn't process that request.";
|
||||
|
||||
// If the model responded without calling any tools on the first attempt,
|
||||
// it likely fabricated data or generated code. Nudge it to use tools.
|
||||
if (toolResults.Count == 0 && i == 0)
|
||||
{
|
||||
_logger.LogWarning("Model responded without calling tools on first attempt, retrying with nudge");
|
||||
ollamaMessages.Add(new OllamaToolMessage
|
||||
{
|
||||
Role = "assistant",
|
||||
Content = rawContent
|
||||
});
|
||||
ollamaMessages.Add(new OllamaToolMessage
|
||||
{
|
||||
Role = "user",
|
||||
Content = "You did not use any tools. You MUST call the provided function tools to look up or modify my financial data. Do not make up data. Try again."
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// No tool calls - save final assistant message
|
||||
var content = StripCodeBlocks(response?.Message?.Content ?? "I'm sorry, I couldn't process that request.");
|
||||
var content = StripCodeBlocks(rawContent);
|
||||
assistantDbMessage = new ChatMessage
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
@@ -417,13 +437,22 @@ public class ChatService : IChatService
|
||||
var json = JsonSerializer.Serialize(request, OllamaJsonOptions);
|
||||
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
|
||||
_logger.LogDebug("Sending chat request to Ollama: {Url}", $"{ollamaUrl}/api/chat");
|
||||
_logger.LogInformation("Ollama request — model: {Model}, tools: {ToolCount}, messages: {MessageCount}",
|
||||
request.Model, request.Tools?.Count ?? 0, request.Messages.Count);
|
||||
|
||||
var response = await client.PostAsync($"{ollamaUrl}/api/chat", content);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var responseBody = await response.Content.ReadAsStringAsync();
|
||||
return JsonSerializer.Deserialize<OllamaToolChatResponse>(responseBody, OllamaJsonOptions);
|
||||
_logger.LogInformation("Ollama response — length: {Length}, preview: {Preview}",
|
||||
responseBody.Length, responseBody.Length > 500 ? responseBody[..500] : responseBody);
|
||||
|
||||
var parsed = JsonSerializer.Deserialize<OllamaToolChatResponse>(responseBody, OllamaJsonOptions);
|
||||
_logger.LogInformation("Ollama parsed — tool_calls: {ToolCallCount}, content_length: {ContentLength}",
|
||||
parsed?.Message?.ToolCalls?.Count ?? 0,
|
||||
parsed?.Message?.Content?.Length ?? 0);
|
||||
|
||||
return parsed;
|
||||
}
|
||||
|
||||
private async Task<(string toolResultType, object data, string summaryForLlm)> ExecuteToolAsync(Guid userId, OllamaToolCall toolCall)
|
||||
@@ -1108,6 +1137,16 @@ public class ChatService : IChatService
|
||||
};
|
||||
}
|
||||
|
||||
// Detect responses that contain code blocks or common code patterns
|
||||
private static bool LooksLikeCodeResponse(string content)
|
||||
{
|
||||
if (content.Contains("```")) return true;
|
||||
if (content.Contains("import ") && content.Contains("(")) return true;
|
||||
if (content.Contains("def ") && content.Contains("():")) return true;
|
||||
if (content.Contains("print(") || content.Contains("console.log(")) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Strip fenced code blocks that smaller models sometimes generate instead of using tools
|
||||
private static readonly Regex CodeBlockRegex = new(@"```[\s\S]*?```", RegexOptions.Compiled);
|
||||
private static string StripCodeBlocks(string content)
|
||||
|
||||
Reference in New Issue
Block a user