diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Dtos/Gemini/GeminiGenerateContentAcquirer.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Dtos/Gemini/GeminiGenerateContentAcquirer.cs index 65012772..ca70532a 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Dtos/Gemini/GeminiGenerateContentAcquirer.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Dtos/Gemini/GeminiGenerateContentAcquirer.cs @@ -109,46 +109,58 @@ public static class GeminiGenerateContentAcquirer /// /// 获取图片 base64(包含 data:image 前缀) - /// 优先从 inlineData.data 中获取,其次从 markdown text 中解析 + /// 从最后一个 part 开始查找 inlineData,找不到再从最后一个 part 开始查找 text /// public static string GetImagePrefixBase64(JsonElement response) { - // Step 1: 优先尝试从 candidates[0].content.parts[0].inlineData.data 获取 - var inlineBase64 = response - .GetPath("candidates", 0, "content", "parts", 0, "inlineData", "data") - .GetString(); - - if (!string.IsNullOrEmpty(inlineBase64)) - { - // 默认按 png 格式拼接前缀 - return $"data:image/png;base64,{inlineBase64}"; - } - - // Step 2: fallback,从 candidates[0].content.parts[0].text 中解析 markdown 图片 - var text = response - .GetPath("candidates", 0, "content", "parts", 0, "text") - .GetString(); - - if (string.IsNullOrEmpty(text)) + var parts = response.GetPath("candidates", 0, "content", "parts"); + if (!parts.HasValue || parts.Value.ValueKind != JsonValueKind.Array) { return string.Empty; } - // markdown 图片格式: ![image](data:image/png;base64,xxx) - var startMarker = "(data:image/"; - var startIndex = text.IndexOf(startMarker, StringComparison.Ordinal); - if (startIndex < 0) + var partsArray = parts.Value.EnumerateArray().ToList(); + if (partsArray.Count == 0) { return string.Empty; } - startIndex += 1; // 跳过 "(" - var endIndex = text.IndexOf(')', startIndex); - if (endIndex <= startIndex) + // Step 1: 从最后一个 part 开始查找 inlineData + for (int i = partsArray.Count - 1; i >= 0; i--) { - return string.Empty; + var inlineBase64 = partsArray[i].GetPath("inlineData", "data").GetString(); + if (!string.IsNullOrEmpty(inlineBase64)) + { + var mimeType = partsArray[i].GetPath("inlineData", "mimeType").GetString() ?? "image/png"; + return $"data:{mimeType};base64,{inlineBase64}"; + } } - return text.Substring(startIndex, endIndex - startIndex); + // Step 2: 从最后一个 part 开始查找 text 中的 markdown 图片 + for (int i = partsArray.Count - 1; i >= 0; i--) + { + var text = partsArray[i].GetPath("text").GetString(); + if (string.IsNullOrEmpty(text)) + { + continue; + } + + // markdown 图片格式: ![image](data:image/png;base64,xxx) + var startMarker = "(data:image/"; + var startIndex = text.IndexOf(startMarker, StringComparison.Ordinal); + if (startIndex < 0) + { + continue; + } + + startIndex += 1; // 跳过 "(" + var endIndex = text.IndexOf(')', startIndex); + if (endIndex > startIndex) + { + return text.Substring(startIndex, endIndex - startIndex); + } + } + + return string.Empty; } } \ No newline at end of file