Skip to content

Commit bed6df5

Browse files
committed
feature: Update AnthropicChatModel and Spring AI Documentation for Multimodal Support
- Enhance AnthropicChatModel to support PDF and document content types - Introduce getContentBlockTypeByMedia method for flexible media type handling - Update ContentBlock handling to dynamically determine content type for media - Add multimodal PDF support test case for Claude 3.5 Sonnet - Update documentation to reflect PDF and multimodal capabilities - Modify comparison chart to show PDF support for Anthropic Claude Release #1819
1 parent 979de19 commit bed6df5

File tree

8 files changed

+386
-308
lines changed

8 files changed

+386
-308
lines changed

models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/AnthropicChatModel.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.springframework.ai.anthropic.api.AnthropicApi.ChatCompletionRequest;
3838
import org.springframework.ai.anthropic.api.AnthropicApi.ChatCompletionResponse;
3939
import org.springframework.ai.anthropic.api.AnthropicApi.ContentBlock;
40+
import org.springframework.ai.anthropic.api.AnthropicApi.ContentBlock.Source;
4041
import org.springframework.ai.anthropic.api.AnthropicApi.ContentBlock.Type;
4142
import org.springframework.ai.anthropic.api.AnthropicApi.Role;
4243
import org.springframework.ai.anthropic.metadata.AnthropicUsage;
@@ -58,6 +59,7 @@
5859
import org.springframework.ai.chat.prompt.ChatOptions;
5960
import org.springframework.ai.chat.prompt.ChatOptionsBuilder;
6061
import org.springframework.ai.chat.prompt.Prompt;
62+
import org.springframework.ai.model.Media;
6163
import org.springframework.ai.model.ModelOptionsUtils;
6264
import org.springframework.ai.model.function.FunctionCallback;
6365
import org.springframework.ai.model.function.FunctionCallbackContext;
@@ -355,6 +357,16 @@ else if (mediaData instanceof String text) {
355357

356358
}
357359

360+
private Type getContentBlockTypeByMedia(Media media) {
361+
if (media.getMimeType().toString().startsWith("image")) {
362+
return Type.IMAGE;
363+
}
364+
else if (media.getMimeType().toString().contains("pdf")) {
365+
return Type.DOCUMENT;
366+
}
367+
return Type.IMAGE;
368+
}
369+
358370
ChatCompletionRequest createRequest(Prompt prompt, boolean stream) {
359371

360372
Set<String> functionsForThisRequest = new HashSet<>();
@@ -367,11 +379,12 @@ ChatCompletionRequest createRequest(Prompt prompt, boolean stream) {
367379
List<ContentBlock> contents = new ArrayList<>(List.of(new ContentBlock(message.getContent())));
368380
if (message instanceof UserMessage userMessage) {
369381
if (!CollectionUtils.isEmpty(userMessage.getMedia())) {
370-
List<ContentBlock> mediaContent = userMessage.getMedia()
371-
.stream()
372-
.map(media -> new ContentBlock(media.getMimeType().toString(),
373-
this.fromMediaData(media.getData())))
374-
.toList();
382+
List<ContentBlock> mediaContent = userMessage.getMedia().stream().map(media -> {
383+
Type contentBlockType = getContentBlockTypeByMedia(media);
384+
var source = new Source(media.getMimeType().toString(),
385+
this.fromMediaData(media.getData()));
386+
return new ContentBlock(contentBlockType, source);
387+
}).toList();
375388
contents.addAll(mediaContent);
376389
}
377390
}

0 commit comments

Comments
 (0)