Skip to content

Commit eb364dc

Browse files
committed
feat: Add builder for AssistantMessage
Signed-off-by: Thomas Vitale <[email protected]>
1 parent c2103b0 commit eb364dc

File tree

2 files changed

+108
-1
lines changed

2 files changed

+108
-1
lines changed

spring-ai-model/src/main/java/org/springframework/ai/chat/messages/AssistantMessage.java

Lines changed: 57 additions & 1 deletion
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.
@@ -33,6 +33,7 @@
3333
*
3434
* @author Mark Pollack
3535
* @author Christian Tzolov
36+
* @author Thomas Vitale
3637
* @since 1.0.0
3738
*/
3839
public class AssistantMessage extends AbstractMessage implements MediaContent {
@@ -45,14 +46,26 @@ public AssistantMessage(String content) {
4546
this(content, Map.of());
4647
}
4748

49+
/**
50+
* @deprecated in favor of {@link AssistantMessage#builder()}.
51+
*/
52+
@Deprecated
4853
public AssistantMessage(String content, Map<String, Object> properties) {
4954
this(content, properties, List.of());
5055
}
5156

57+
/**
58+
* @deprecated in favor of {@link AssistantMessage#builder()}.
59+
*/
60+
@Deprecated
5261
public AssistantMessage(String content, Map<String, Object> properties, List<ToolCall> toolCalls) {
5362
this(content, properties, toolCalls, List.of());
5463
}
5564

65+
/**
66+
* @deprecated in favor of {@link AssistantMessage#builder()}.
67+
*/
68+
@Deprecated
5669
public AssistantMessage(String content, Map<String, Object> properties, List<ToolCall> toolCalls,
5770
List<Media> media) {
5871
super(MessageType.ASSISTANT, content, properties);
@@ -104,4 +117,47 @@ public record ToolCall(String id, String type, String name, String arguments) {
104117

105118
}
106119

120+
public static Builder builder() {
121+
return new Builder();
122+
}
123+
124+
public static class Builder {
125+
126+
private String content;
127+
128+
private Map<String, Object> properties = Map.of();
129+
130+
private List<ToolCall> toolCalls = List.of();
131+
132+
private List<Media> media = List.of();
133+
134+
private Builder() {
135+
}
136+
137+
public Builder content(String content) {
138+
this.content = content;
139+
return this;
140+
}
141+
142+
public Builder properties(Map<String, Object> properties) {
143+
this.properties = properties;
144+
return this;
145+
}
146+
147+
public Builder toolCalls(List<ToolCall> toolCalls) {
148+
this.toolCalls = toolCalls;
149+
return this;
150+
}
151+
152+
public Builder media(List<Media> media) {
153+
this.media = media;
154+
return this;
155+
}
156+
157+
public AssistantMessage build() {
158+
return new AssistantMessage(this.content, this.properties, this.toolCalls, this.media);
159+
}
160+
161+
}
162+
107163
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2023-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ai.chat.messages;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
22+
23+
/**
24+
* Unit tests for {@link AssistantMessage}.
25+
*
26+
* @author Thomas Vitale
27+
*/
28+
class AssistantMessageTests {
29+
30+
@Test
31+
void whenMediaIsNullThenThrow() {
32+
assertThatThrownBy(() -> AssistantMessage.builder().media(null).build())
33+
.isInstanceOf(IllegalArgumentException.class)
34+
.hasMessageContaining("Media must not be null");
35+
}
36+
37+
@Test
38+
void whenMetadataIsNullThenThrow() {
39+
assertThatThrownBy(() -> AssistantMessage.builder().properties(null).build())
40+
.isInstanceOf(IllegalArgumentException.class)
41+
.hasMessageContaining("Metadata must not be null");
42+
}
43+
44+
@Test
45+
void whenToolCallsIsNullThenThrow() {
46+
assertThatThrownBy(() -> AssistantMessage.builder().toolCalls(null).build())
47+
.isInstanceOf(IllegalArgumentException.class)
48+
.hasMessageContaining("Tool calls must not be null");
49+
}
50+
51+
}

0 commit comments

Comments
 (0)