Merge pull request #990 from iceljc/master

fix gemini function call
This commit is contained in:
iceljc 2025-04-02 21:01:45 -05:00 committed by GitHub
commit 1100ef40f8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 42 additions and 27 deletions

View file

@ -49,7 +49,7 @@ public class GeminiChatCompletionProvider : IChatCompletion
var text = part?.Text ?? string.Empty;
RoleDialogModel responseMessage;
if (response.GetFunction()!=null)
if (response.GetFunction() != null)
{
responseMessage = new RoleDialogModel(AgentRole.Function, text)
{
@ -78,7 +78,10 @@ public class GeminiChatCompletionProvider : IChatCompletion
{
Prompt = prompt,
Provider = Provider,
Model = _model
Model = _model,
PromptCount = response.UsageMetadata?.PromptTokenCount ?? 0,
CachedPromptCount = response.UsageMetadata?.CachedContentTokenCount ?? 0,
CompletionCount = response.UsageMetadata?.CandidatesTokenCount ?? 0
});
}
@ -96,8 +99,8 @@ public class GeminiChatCompletionProvider : IChatCompletion
}
var client = ProviderHelper.GetGeminiClient(Provider, _model, _services);
var chatClient = client.CreateGeminiModel(_model);
var (prompt, messages) = PrepareOptions(chatClient,agent, conversations);
var chatClient = client.CreateGenerativeModel(_model);
var (prompt, messages) = PrepareOptions(chatClient, agent, conversations);
var response = await chatClient.GenerateContentAsync(messages);
@ -120,11 +123,12 @@ public class GeminiChatCompletionProvider : IChatCompletion
Provider = Provider,
Model = _model,
PromptCount = response?.UsageMetadata?.PromptTokenCount ?? 0,
CompletionCount = response?.UsageMetadata?.CandidatesTokenCount ?? 0
CachedPromptCount = response.UsageMetadata?.CachedContentTokenCount ?? 0,
CompletionCount = response.UsageMetadata?.CandidatesTokenCount ?? 0
});
}
if (response.GetFunction()!=null)
if (response.GetFunction() != null)
{
var toolCall = response.GetFunction();
_logger.LogInformation($"[{agent.Name}]: {toolCall?.Name}({toolCall?.Args?.ToJsonString()})");
@ -167,10 +171,10 @@ public class GeminiChatCompletionProvider : IChatCompletion
await foreach (var response in asyncEnumerable)
{
if (response.GetFunction()!=null)
if (response.GetFunction() != null)
{
var func = response.GetFunction();
var update =func?.Args?.ToJsonString().ToString() ?? string.Empty;
var update = func?.Args?.ToJsonString().ToString() ?? string.Empty;
_logger.LogInformation(update);
await onMessageReceived(new RoleDialogModel(AgentRole.Assistant, update)
@ -212,6 +216,7 @@ public class GeminiChatCompletionProvider : IChatCompletion
{
AutoCallFunction = false
};
// Assembly messages
var contents = new List<Content>();
var tools = new List<Tool>();
@ -221,7 +226,6 @@ public class GeminiChatCompletionProvider : IChatCompletion
if (!string.IsNullOrEmpty(agent.Instruction) || !agent.SecondaryInstructions.IsNullOrEmpty())
{
var instruction = agentService.RenderedInstruction(agent);
contents.Add(new Content(instruction, AgentRole.User));
renderedInstructions.Add(instruction);
systemPrompts.Add(instruction);
}
@ -237,7 +241,7 @@ public class GeminiChatCompletionProvider : IChatCompletion
var parameters = !string.IsNullOrWhiteSpace(props) && props != "{}" ? new Schema()
{
Type = "object",
Properties = JsonSerializer.Deserialize<dynamic>(props),
Properties = JsonSerializer.Deserialize<Dictionary<string, Schema>>(props),
Required = def?.Required ?? []
} : null;
@ -261,23 +265,32 @@ public class GeminiChatCompletionProvider : IChatCompletion
{
if (message.Role == AgentRole.Function)
{
contents.Add( new Content(message.Content,AgentRole.Function)
{
Role = AgentRole.Function,
Parts =
[
new Part()
contents.Add(new Content([
new Part()
{
FunctionCall = new FunctionCall
{
FunctionCall = new FunctionCall
Name = message.FunctionName,
Args = JsonNode.Parse(message.FunctionArgs ?? "{}")
}
}
], AgentRole.Model));
contents.Add(new Content([
new Part()
{
FunctionResponse = new FunctionResponse
{
Name = message.FunctionName,
Response = new JsonObject()
{
Name = message.FunctionName,
Args = JsonNode.Parse(message.FunctionArgs ?? "{}")
["result"] = message.Content ?? string.Empty
}
}
]
});
}
], AgentRole.Function));
convPrompts.Add($"{AgentRole.Assistant}: Call function {message.FunctionName}({message.FunctionArgs})");
convPrompts.Add($"{AgentRole.Assistant}: Call function {message.FunctionName}({message.FunctionArgs}) => {message.Content}");
}
else if (message.Role == AgentRole.User)
{
@ -299,6 +312,7 @@ public class GeminiChatCompletionProvider : IChatCompletion
: agent.LlmConfig?.MaxOutputTokens ?? LlmConstant.DEFAULT_MAX_OUTPUT_TOKEN;
var request = new GenerateContentRequest
{
SystemInstruction = !systemPrompts.IsNullOrEmpty() ? new Content(systemPrompts[0], AgentRole.System) : null,
Contents = contents,
Tools = tools,
GenerationConfig = new()

View file

@ -51,11 +51,8 @@ public class GeminiTextCompletionProvider : ITextCompletion
var aiModel = client.CreateGenerativeModel(_model);
PrepareOptions(aiModel);
_tokenStatistics.StartTimer();
var response = await aiModel.GenerateContentAsync(text);
_tokenStatistics.StopTimer();
var completion = response.Text ?? string.Empty;
var completion = response?.Text ?? string.Empty;
// After completion hook
foreach (var hook in contentHooks)
@ -64,7 +61,10 @@ public class GeminiTextCompletionProvider : ITextCompletion
{
Prompt = text,
Provider = Provider,
Model = _model
Model = _model,
PromptCount = response.UsageMetadata?.PromptTokenCount ?? 0,
CachedPromptCount = response.UsageMetadata?.CachedContentTokenCount ?? 0,
CompletionCount = response.UsageMetadata?.CandidatesTokenCount ?? 0
});
}
@ -79,6 +79,7 @@ public class GeminiTextCompletionProvider : ITextCompletion
private void PrepareOptions(GenerativeModel aiModel)
{
var settings = _services.GetRequiredService<GoogleAiSettings>();
aiModel.UseGoogleSearch = settings.Gemini.UseGoogleSearch;
aiModel.UseGrounding = settings.Gemini.UseGrounding;
aiModel.FunctionCallingBehaviour = new FunctionCallingBehaviour()