Skip to content

Commit c6ccc1a

Browse files
dev-jonghoonparkilayaperumalg
authored andcommitted
Make allow image url for Anthropic API
Signed-off-by: jonghoonpark <[email protected]>
1 parent d7eb9bb commit c6ccc1a

File tree

3 files changed

+24
-9
lines changed

3 files changed

+24
-9
lines changed

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

+14-2
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
* @author Thomas Vitale
8989
* @author Claudio Silva Junior
9090
* @author Alexandros Pappas
91+
* @author Jonghoon Park
9192
* @since 1.0.0
9293
*/
9394
public class AnthropicChatModel implements ChatModel {
@@ -355,6 +356,18 @@ private ChatResponseMetadata from(AnthropicApi.ChatCompletionResponse result, Us
355356
.build();
356357
}
357358

359+
private Source getSourceByMedia(Media media) {
360+
String data = this.fromMediaData(media.getData());
361+
362+
// http is not allowed and redirect not allowed
363+
if (data.startsWith("https://")) {
364+
return new Source(data);
365+
}
366+
else {
367+
return new Source(media.getMimeType().toString(), data);
368+
}
369+
}
370+
358371
private String fromMediaData(Object mediaData) {
359372
if (mediaData instanceof byte[] bytes) {
360373
return Base64.getEncoder().encodeToString(bytes);
@@ -455,8 +468,7 @@ ChatCompletionRequest createRequest(Prompt prompt, boolean stream) {
455468
if (!CollectionUtils.isEmpty(userMessage.getMedia())) {
456469
List<ContentBlock> mediaContent = userMessage.getMedia().stream().map(media -> {
457470
Type contentBlockType = getContentBlockTypeByMedia(media);
458-
var source = new Source(media.getMimeType().toString(),
459-
this.fromMediaData(media.getData()));
471+
var source = getSourceByMedia(media);
460472
return new ContentBlock(contentBlockType, source);
461473
}).toList();
462474
contents.addAll(mediaContent);

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

+7-2
Original file line numberDiff line numberDiff line change
@@ -933,7 +933,8 @@ public record Source(
933933
// @formatter:off
934934
@JsonProperty("type") String type,
935935
@JsonProperty("media_type") String mediaType,
936-
@JsonProperty("data") String data) {
936+
@JsonProperty("data") String data,
937+
@JsonProperty("url") String url) {
937938
// @formatter:on
938939

939940
/**
@@ -942,7 +943,11 @@ public record Source(
942943
* @param data The content data.
943944
*/
944945
public Source(String mediaType, String data) {
945-
this("base64", mediaType, data);
946+
this("base64", mediaType, data, null);
947+
}
948+
949+
public Source(String url) {
950+
this("url", null, null, url);
946951
}
947952

948953
}

models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/client/AnthropicChatClientIT.java

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 the original author or authors.
2+
* Copyright 2023-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -301,14 +301,12 @@ void multiModalityEmbeddedImage(String modelName) throws IOException {
301301
assertThat(response).containsAnyOf("bananas", "apple", "bowl", "basket", "fruit stand");
302302
}
303303

304-
@Disabled("Currently Anthropic API does not support external image URLs")
305304
@ParameterizedTest(name = "{0} : {displayName} ")
306-
@ValueSource(strings = { "claude-3-opus-latest", "claude-3-5-sonnet-latest", "claude-3-haiku-latest",
307-
"claude-3-7-sonnet-latest" })
305+
@ValueSource(strings = { "claude-3-opus-latest", "claude-3-5-sonnet-latest", "claude-3-7-sonnet-latest" })
308306
void multiModalityImageUrl(String modelName) throws IOException {
309307

310308
// TODO: add url method that wrapps the checked exception.
311-
URL url = new URL("https://docs.spring.io/spring-ai/reference/1.0.0-SNAPSHOT/_images/multimodal.test.png");
309+
URL url = new URL("https://docs.spring.io/spring-ai/reference/_images/multimodal.test.png");
312310

313311
// @formatter:off
314312
String response = ChatClient.create(this.chatModel).prompt()

0 commit comments

Comments
 (0)