mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-16 14:57:36 +08:00
Merge pull request #7585 from ResidualBlood/fix/antigravity-pdf-inline-data
fix(antigravity): forward chat PDF file parts as Gemini inlineData
This commit is contained in:
@@ -532,8 +532,8 @@ func buildParts(content json.RawMessage, toolIDToName map[string]string, allowDu
|
||||
}
|
||||
parts = append(parts, part)
|
||||
|
||||
case "image":
|
||||
if block.Source != nil && block.Source.Type == "base64" {
|
||||
case "image", "document":
|
||||
if block.Source != nil && block.Source.Type == "base64" && strings.TrimSpace(block.Source.Data) != "" {
|
||||
parts = append(parts, GeminiPart{
|
||||
InlineData: &GeminiInlineData{
|
||||
MimeType: block.Source.MediaType,
|
||||
|
||||
@@ -646,6 +646,20 @@ func TestGeminiToolConfig_DropsBuiltinsWhenClientFunctionsPresent(t *testing.T)
|
||||
})
|
||||
}
|
||||
|
||||
func TestBuildParts_DocumentBecomesInlineData(t *testing.T) {
|
||||
content := `[
|
||||
{"type":"text","text":"read this"},
|
||||
{"type":"document","source":{"type":"base64","media_type":"application/pdf","data":"JVBERi0="}}
|
||||
]`
|
||||
parts, stripped, err := buildParts(json.RawMessage(content), map[string]string{}, true)
|
||||
require.NoError(t, err)
|
||||
require.False(t, stripped)
|
||||
require.Len(t, parts, 2)
|
||||
require.NotNil(t, parts[1].InlineData)
|
||||
require.Equal(t, "application/pdf", parts[1].InlineData.MimeType)
|
||||
require.Equal(t, "JVBERi0=", parts[1].InlineData.Data)
|
||||
}
|
||||
|
||||
// TestToolConfigAlwaysPresent ensures toolConfig is always emitted, including for
|
||||
// reasoning models without any tools: upstream rejects requests that omit it.
|
||||
func TestToolConfigAlwaysPresent(t *testing.T) {
|
||||
|
||||
@@ -109,7 +109,23 @@ func TestResponsesToAnthropic_UnknownItemTypeKeepsRecognizableText(t *testing.T)
|
||||
require.NotContains(t, string(messages[0].Content), "drop me")
|
||||
}
|
||||
|
||||
// user 消息的分片全部不可识别时,以前会退化成 content:"",Anthropic 拒收空内容消息。
|
||||
// data URI 形式的 input_file 要变成 Anthropic document,供后续 Gemini inlineData 使用。
|
||||
func TestResponsesToAnthropic_InputFileDataURIBecomesDocument(t *testing.T) {
|
||||
messages := responsesToAnthropicMessages(t, `[
|
||||
{"type":"message","role":"user","content":[
|
||||
{"type":"input_text","text":"read this"},
|
||||
{"type":"input_file","filename":"token.pdf","file_data":"data:application/pdf;base64,JVBERi0="}
|
||||
]}
|
||||
]`)
|
||||
|
||||
requireAnthropicMessagesAreSendable(t, messages)
|
||||
require.Len(t, messages, 1)
|
||||
require.Contains(t, string(messages[0].Content), `"type":"document"`)
|
||||
require.Contains(t, string(messages[0].Content), `"media_type":"application/pdf"`)
|
||||
require.Contains(t, string(messages[0].Content), `"data":"JVBERi0="`)
|
||||
}
|
||||
|
||||
// 只有 file_id、没有 data URI 的 input_file 仍然无法转换,整条消息丢掉。
|
||||
func TestResponsesToAnthropic_UserMessageWithOnlyUnknownPartsIsDropped(t *testing.T) {
|
||||
messages := responsesToAnthropicMessages(t, `[
|
||||
{"type":"message","role":"user","content":[{"type":"input_file","file_id":"file_1"}]}
|
||||
|
||||
@@ -530,6 +530,14 @@ func convertResponsesUserToAnthropicContent(raw json.RawMessage) (json.RawMessag
|
||||
Source: src,
|
||||
})
|
||||
}
|
||||
case "input_file":
|
||||
src := dataURIToAnthropicFileSource(p.FileData)
|
||||
if src != nil {
|
||||
blocks = append(blocks, AnthropicContentBlock{
|
||||
Type: "document",
|
||||
Source: src,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,6 +625,12 @@ func dataURIToAnthropicImageSource(dataURI string) *AnthropicImageSource {
|
||||
}
|
||||
}
|
||||
|
||||
// dataURIToAnthropicFileSource parses a data URI into a document source.
|
||||
// file_id-only parts are not convertible here and stay dropped.
|
||||
func dataURIToAnthropicFileSource(fileData string) *AnthropicImageSource {
|
||||
return dataURIToAnthropicImageSource(fileData)
|
||||
}
|
||||
|
||||
// mergeConsecutiveMessages merges consecutive messages with the same role
|
||||
// because Anthropic requires alternating user/assistant turns.
|
||||
func mergeConsecutiveMessages(messages []AnthropicMessage) []AnthropicMessage {
|
||||
|
||||
Reference in New Issue
Block a user