Skip to content

Commit fe3496c

Browse files
committed
confirmed response api works
1 parent 2f3f841 commit fe3496c

File tree

2 files changed

+97
-50
lines changed

2 files changed

+97
-50
lines changed

src/BE/Services/Models/ChatServices/GoogleAI/GoogleAI2ChatService.cs

Lines changed: 76 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,13 @@ public override async IAsyncEnumerable<ChatSegment> ChatStreamed(IReadOnlyList<C
6767
};
6868
}
6969

70-
Tool tool = ToGoogleAITool(options) ?? new Tool();
71-
if (SupportsCodeExecution)
70+
Tool? tool = ToGoogleAIToolCallTool(options);
71+
if (tool == null && SupportsCodeExecution)
7272
{
73-
tool.CodeExecution = new();
73+
tool = new Tool()
74+
{
75+
CodeExecution = new()
76+
};
7477
}
7578

7679
int fcIndex = 0;
@@ -80,51 +83,50 @@ public override async IAsyncEnumerable<ChatSegment> ChatStreamed(IReadOnlyList<C
8083
SystemInstruction = OpenAIChatMessageToGoogleContent(messages.Where(x => x is SystemChatMessage)) switch { [] => null, var x => x[0] },
8184
GenerationConfig = gc,
8285
SafetySettings = _safetySettings,
83-
Tools = [tool],
86+
Tools = tool == null ? null : [tool],
8487
};
8588
await foreach (GenerateContentResponse response in _generativeModel.GenerateContentStream(gcr, new RequestOptions(null, NetworkTimeout), cancellationToken))
8689
{
8790
if (response.Candidates != null && response.Candidates.Count > 0)
8891
{
89-
string? text = response.Candidates[0].Content?.Text;
90-
InlineData? image = response.Candidates[0].Content?.Parts[0].InlineData;
91-
FinishReason? finishReason = response.Candidates[0].FinishReason;
92-
FunctionCall? functionCall = response.Candidates[0].Content?.Parts[0].FunctionCall;
93-
Dtos.ChatTokenUsage? usage = GetUsage(response.UsageMetadata);
94-
ExecutableCode? code = response.Candidates[0].Content?.Parts[0].ExecutableCode;
95-
CodeExecutionResult? result = response.Candidates[0].Content?.Parts[0].CodeExecutionResult;
96-
9792
List<ChatSegmentItem> items = [];
98-
if (code != null)
93+
foreach (Part part in response.Candidates[0].Content?.Parts ?? [])
9994
{
100-
items.Add(ChatSegmentItem.FromText($"""
101-
```{code.Language}
102-
{code.Code}
95+
if (part.ExecutableCode != null)
96+
{
97+
items.Add(ChatSegmentItem.FromText($"""
98+
```{part.ExecutableCode.Language}
99+
{part.ExecutableCode.Code}
103100
```
104101
105102
"""));
106-
}
107-
else if (result != null)
108-
{
109-
items.Add(ChatSegmentItem.FromText($"""
103+
}
104+
else if (part.CodeExecutionResult != null)
105+
{
106+
items.Add(ChatSegmentItem.FromText($"""
110107
```
111-
{result.Output}
108+
{part.CodeExecutionResult.Output}
112109
```
113110
114111
"""));
112+
}
113+
else if (part.Text != null)
114+
{
115+
items.Add(ChatSegmentItem.FromText(part.Text));
116+
}
117+
if (part.InlineData != null)
118+
{
119+
items.Add(ChatSegmentItem.FromBase64Image(part.InlineData.Data, part.InlineData.MimeType));
120+
}
121+
if (part.FunctionCall != null)
122+
{
123+
items.Add(ChatSegmentItem.FromToolCall(fcIndex++, part.FunctionCall));
124+
}
115125
}
116-
else if (text != null)
117-
{
118-
items.Add(ChatSegmentItem.FromText(text));
119-
}
120-
if (image != null)
121-
{
122-
items.Add(ChatSegmentItem.FromBase64Image(image.Data, image.MimeType));
123-
}
124-
if (functionCall != null)
125-
{
126-
items.Add(ChatSegmentItem.FromToolCall(fcIndex++, functionCall));
127-
}
126+
127+
FinishReason? finishReason = response.Candidates[0].FinishReason;
128+
Dtos.ChatTokenUsage? usage = GetUsage(response.UsageMetadata);
129+
128130
yield return new ChatSegment()
129131
{
130132
FinishReason = ToChatFinishReason(finishReason),
@@ -182,24 +184,53 @@ static List<Content> OpenAIChatMessageToGoogleContent(IEnumerable<ChatMessage> c
182184
return [.. chatMessages
183185
.Select(msg => msg switch
184186
{
185-
SystemChatMessage s => new Content("") { Role = "system", Parts = [.. msg.Content.Select(OpenAIPartToGooglePart)] },
186-
UserChatMessage u => new Content("") { Role = "user", Parts = [.. msg.Content.Select(OpenAIPartToGooglePart)] },
187-
AssistantChatMessage a => new Content("") { Role = "model", Parts = [.. msg.Content.Select(OpenAIPartToGooglePart)] },
187+
SystemChatMessage s => new Content("") { Role = Role.System, Parts = [.. msg.Content.Select(x => OpenAIPartToGooglePart(x))] },
188+
UserChatMessage u => new Content("") { Role = Role.User, Parts = [.. msg.Content.Select(x => OpenAIPartToGooglePart(x))] },
189+
AssistantChatMessage a => new Content("") { Role = Role.Model, Parts = AssistantMessageToParts(a) },
190+
ToolChatMessage t => new Content("") { Role = Role.Function, Parts = [ToolCallMessageToPart(t)] },
188191
_ => throw new NotSupportedException($"Unsupported message type: {msg.GetType()} in {nameof(GoogleAI2ChatService)}"),
189192
})];
190-
}
191193

192-
static IPart OpenAIPartToGooglePart(ChatMessageContentPart part)
193-
{
194-
return part.Kind switch
194+
static IPart ToolCallMessageToPart(ToolChatMessage message)
195195
{
196-
ChatMessageContentPartKind.Text => new TextData() { Text = part.Text },
197-
ChatMessageContentPartKind.Image => new InlineData() { Data = Convert.ToBase64String(part.ImageBytes.ToArray()), MimeType = part.ImageBytesMediaType },
198-
_ => throw new NotSupportedException($"Unsupported part kind: {part.Kind}"),
199-
};
196+
return Part.FromFunctionResponse(message.ToolCallId, new
197+
{
198+
result = string.Join("\r\n", message.Content.Select(x => x.Text))
199+
});
200+
}
201+
202+
static List<IPart> AssistantMessageToParts(AssistantChatMessage assistantChatMessage)
203+
{
204+
List<IPart> results = [];
205+
if (assistantChatMessage.ToolCalls != null && assistantChatMessage.ToolCalls.Count > 0)
206+
{
207+
foreach (ChatToolCall toolCall in assistantChatMessage.ToolCalls)
208+
{
209+
results.Add(new FunctionCall()
210+
{
211+
Id = toolCall.Id,
212+
Name = toolCall.FunctionName,
213+
Args = toolCall.FunctionArguments.ToObjectFromJson<JsonObject>(),
214+
});
215+
}
216+
}
217+
218+
results.AddRange(assistantChatMessage.Content.Select(OpenAIPartToGooglePart));
219+
return results;
220+
}
221+
222+
static IPart OpenAIPartToGooglePart(ChatMessageContentPart part)
223+
{
224+
return part.Kind switch
225+
{
226+
ChatMessageContentPartKind.Text => new TextData() { Text = part.Text },
227+
ChatMessageContentPartKind.Image => new InlineData() { Data = Convert.ToBase64String(part.ImageBytes.ToArray()), MimeType = part.ImageBytesMediaType },
228+
_ => throw new NotSupportedException($"Unsupported part kind: {part.Kind}"),
229+
};
230+
}
200231
}
201232

202-
static Tool? ToGoogleAITool(ChatCompletionOptions cco)
233+
static Tool? ToGoogleAIToolCallTool(ChatCompletionOptions cco)
203234
{
204235
if (cco.Tools == null || cco.Tools.Count == 0)
205236
{

src/BE/Services/Models/ChatServices/OpenAI/Special/AzureResponseApiService.cs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,17 +130,33 @@ static List<ResponseItem> ToResponse(IReadOnlyList<ChatMessage> messages)
130130
List<ResponseItem> responseItems = [];
131131
foreach (ChatMessage message in messages)
132132
{
133-
responseItems.Add(message switch
133+
responseItems.AddRange(message switch
134134
{
135-
SystemChatMessage sys => ResponseItem.CreateSystemMessageItem(MessageContentPartToResponse(sys.Content, input: true)),
136-
UserChatMessage user => ResponseItem.CreateUserMessageItem(MessageContentPartToResponse(user.Content, input: true)),
137-
AssistantChatMessage assistant => ResponseItem.CreateAssistantMessageItem(MessageContentPartToResponse(assistant.Content, input: false)),
138-
DeveloperChatMessage developer => ResponseItem.CreateDeveloperMessageItem(MessageContentPartToResponse(developer.Content, input: true)),
135+
SystemChatMessage sys => [ResponseItem.CreateSystemMessageItem(MessageContentPartToResponse(sys.Content, input: true))],
136+
UserChatMessage user => [ResponseItem.CreateUserMessageItem(MessageContentPartToResponse(user.Content, input: true))],
137+
AssistantChatMessage assistant => AssistantChatMessageToResponse(assistant),
138+
DeveloperChatMessage developer => [ResponseItem.CreateDeveloperMessageItem(MessageContentPartToResponse(developer.Content, input: true))],
139+
ToolChatMessage tool => [ResponseItem.CreateFunctionCallOutputItem(tool.ToolCallId, string.Join("\r\n", tool.Content.Select(x => x.Text)))],
139140
_ => throw new NotSupportedException($"Unsupported message type: {message.GetType()}"),
140141
});
141142
}
142143
return responseItems;
143144

145+
static IEnumerable<ResponseItem> AssistantChatMessageToResponse(AssistantChatMessage assistantChatMessage)
146+
{
147+
if (assistantChatMessage.ToolCalls != null && assistantChatMessage.ToolCalls.Count > 0)
148+
{
149+
foreach (var toolCall in assistantChatMessage.ToolCalls)
150+
{
151+
yield return ResponseItem.CreateFunctionCallItem(toolCall.Id, toolCall.FunctionName, toolCall.FunctionArguments);
152+
}
153+
}
154+
if (assistantChatMessage.Content != null && assistantChatMessage.Content.Count > 0)
155+
{
156+
yield return ResponseItem.CreateAssistantMessageItem(MessageContentPartToResponse(assistantChatMessage.Content, input: false));
157+
}
158+
}
159+
144160
static IReadOnlyList<ResponseContentPart> MessageContentPartToResponse(IReadOnlyList<ChatMessageContentPart> parts, bool input)
145161
{
146162
List<ResponseContentPart> responseParts = [];

0 commit comments

Comments
 (0)