Skip to content

Commit 1d38fd1

Browse files
apappascsilayaperumalg
authored andcommitted
Refactor AnthropicChatOptions builder methods
- Refactor the builder methods to remove `with` as the prefix. - Introduce new methods with updated naming conventions. - Deprecate the existing `with*` methods to maintain backward compatibility. - Update AnthropicChatOptions builder documentation
1 parent de29df7 commit 1d38fd1

File tree

12 files changed

+175
-67
lines changed

12 files changed

+175
-67
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@ public class AnthropicChatModel extends AbstractToolCallSupport implements ChatM
128128
public AnthropicChatModel(AnthropicApi anthropicApi) {
129129
this(anthropicApi,
130130
AnthropicChatOptions.builder()
131-
.withModel(DEFAULT_MODEL_NAME)
132-
.withMaxTokens(DEFAULT_MAX_TOKENS)
133-
.withTemperature(DEFAULT_TEMPERATURE)
131+
.model(DEFAULT_MODEL_NAME)
132+
.maxTokens(DEFAULT_MAX_TOKENS)
133+
.temperature(DEFAULT_TEMPERATURE)
134134
.build());
135135
}
136136

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

Lines changed: 129 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
*
3939
* @author Christian Tzolov
4040
* @author Thomas Vitale
41+
* @author Alexandros Pappas
4142
* @since 1.0.0
4243
*/
4344
@JsonInclude(Include.NON_NULL)
@@ -89,17 +90,17 @@ public static Builder builder() {
8990
}
9091

9192
public static AnthropicChatOptions fromOptions(AnthropicChatOptions fromOptions) {
92-
return builder().withModel(fromOptions.getModel())
93-
.withMaxTokens(fromOptions.getMaxTokens())
94-
.withMetadata(fromOptions.getMetadata())
95-
.withStopSequences(fromOptions.getStopSequences())
96-
.withTemperature(fromOptions.getTemperature())
97-
.withTopP(fromOptions.getTopP())
98-
.withTopK(fromOptions.getTopK())
99-
.withFunctionCallbacks(fromOptions.getFunctionCallbacks())
100-
.withFunctions(fromOptions.getFunctions())
101-
.withProxyToolCalls(fromOptions.getProxyToolCalls())
102-
.withToolContext(fromOptions.getToolContext())
93+
return builder().model(fromOptions.getModel())
94+
.maxTokens(fromOptions.getMaxTokens())
95+
.metadata(fromOptions.getMetadata())
96+
.stopSequences(fromOptions.getStopSequences())
97+
.temperature(fromOptions.getTemperature())
98+
.topP(fromOptions.getTopP())
99+
.topK(fromOptions.getTopK())
100+
.functionCallbacks(fromOptions.getFunctionCallbacks())
101+
.functions(fromOptions.getFunctions())
102+
.proxyToolCalls(fromOptions.getProxyToolCalls())
103+
.toolContext(fromOptions.getToolContext())
103104
.build();
104105
}
105106

@@ -227,69 +228,69 @@ public static class Builder {
227228

228229
private final AnthropicChatOptions options = new AnthropicChatOptions();
229230

230-
public Builder withModel(String model) {
231+
public Builder model(String model) {
231232
this.options.model = model;
232233
return this;
233234
}
234235

235-
public Builder withModel(AnthropicApi.ChatModel model) {
236+
public Builder model(AnthropicApi.ChatModel model) {
236237
this.options.model = model.getValue();
237238
return this;
238239
}
239240

240-
public Builder withMaxTokens(Integer maxTokens) {
241+
public Builder maxTokens(Integer maxTokens) {
241242
this.options.maxTokens = maxTokens;
242243
return this;
243244
}
244245

245-
public Builder withMetadata(ChatCompletionRequest.Metadata metadata) {
246+
public Builder metadata(ChatCompletionRequest.Metadata metadata) {
246247
this.options.metadata = metadata;
247248
return this;
248249
}
249250

250-
public Builder withStopSequences(List<String> stopSequences) {
251+
public Builder stopSequences(List<String> stopSequences) {
251252
this.options.stopSequences = stopSequences;
252253
return this;
253254
}
254255

255-
public Builder withTemperature(Double temperature) {
256+
public Builder temperature(Double temperature) {
256257
this.options.temperature = temperature;
257258
return this;
258259
}
259260

260-
public Builder withTopP(Double topP) {
261+
public Builder topP(Double topP) {
261262
this.options.topP = topP;
262263
return this;
263264
}
264265

265-
public Builder withTopK(Integer topK) {
266+
public Builder topK(Integer topK) {
266267
this.options.topK = topK;
267268
return this;
268269
}
269270

270-
public Builder withFunctionCallbacks(List<FunctionCallback> functionCallbacks) {
271+
public Builder functionCallbacks(List<FunctionCallback> functionCallbacks) {
271272
this.options.functionCallbacks = functionCallbacks;
272273
return this;
273274
}
274275

275-
public Builder withFunctions(Set<String> functionNames) {
276+
public Builder functions(Set<String> functionNames) {
276277
Assert.notNull(functionNames, "Function names must not be null");
277278
this.options.functions = functionNames;
278279
return this;
279280
}
280281

281-
public Builder withFunction(String functionName) {
282+
public Builder function(String functionName) {
282283
Assert.hasText(functionName, "Function name must not be empty");
283284
this.options.functions.add(functionName);
284285
return this;
285286
}
286287

287-
public Builder withProxyToolCalls(Boolean proxyToolCalls) {
288+
public Builder proxyToolCalls(Boolean proxyToolCalls) {
288289
this.options.proxyToolCalls = proxyToolCalls;
289290
return this;
290291
}
291292

292-
public Builder withToolContext(Map<String, Object> toolContext) {
293+
public Builder toolContext(Map<String, Object> toolContext) {
293294
if (this.options.toolContext == null) {
294295
this.options.toolContext = toolContext;
295296
}
@@ -299,6 +300,110 @@ public Builder withToolContext(Map<String, Object> toolContext) {
299300
return this;
300301
}
301302

303+
/**
304+
* @deprecated use {@link #model(String)} instead.
305+
*/
306+
@Deprecated(forRemoval = true, since = "1.0.0-M5")
307+
public Builder withModel(String model) {
308+
return model(model);
309+
}
310+
311+
/**
312+
* @deprecated use {@link #model(AnthropicApi.ChatModel)} instead.
313+
*/
314+
@Deprecated(forRemoval = true, since = "1.0.0-M5")
315+
public Builder withModel(AnthropicApi.ChatModel model) {
316+
return model(model);
317+
}
318+
319+
/**
320+
* @deprecated use {@link #maxTokens(Integer)} instead.
321+
*/
322+
@Deprecated(forRemoval = true, since = "1.0.0-M5")
323+
public Builder withMaxTokens(Integer maxTokens) {
324+
return maxTokens(maxTokens);
325+
}
326+
327+
/**
328+
* @deprecated use {@link #metadata(ChatCompletionRequest.Metadata)} instead.
329+
*/
330+
@Deprecated(forRemoval = true, since = "1.0.0-M5")
331+
public Builder withMetadata(ChatCompletionRequest.Metadata metadata) {
332+
return metadata(metadata);
333+
}
334+
335+
/**
336+
* @deprecated use {@link #stopSequences(List)} instead.
337+
*/
338+
@Deprecated(forRemoval = true, since = "1.0.0-M5")
339+
public Builder withStopSequences(List<String> stopSequences) {
340+
return stopSequences(stopSequences);
341+
}
342+
343+
/**
344+
* @deprecated use {@link #temperature(Double)} instead.
345+
*/
346+
@Deprecated(forRemoval = true, since = "1.0.0-M5")
347+
public Builder withTemperature(Double temperature) {
348+
return temperature(temperature);
349+
}
350+
351+
/**
352+
* @deprecated use {@link #topP(Double)} instead.
353+
*/
354+
@Deprecated(forRemoval = true, since = "1.0.0-M5")
355+
public Builder withTopP(Double topP) {
356+
return topP(topP);
357+
}
358+
359+
/**
360+
* @deprecated use {@link #topK(Integer)} instead.
361+
*/
362+
@Deprecated(forRemoval = true, since = "1.0.0-M5")
363+
public Builder withTopK(Integer topK) {
364+
return topK(topK);
365+
}
366+
367+
/**
368+
* @deprecated use {@link #functionCallbacks(List)} instead.
369+
*/
370+
@Deprecated(forRemoval = true, since = "1.0.0-M5")
371+
public Builder withFunctionCallbacks(List<FunctionCallback> functionCallbacks) {
372+
return functionCallbacks(functionCallbacks);
373+
}
374+
375+
/**
376+
* @deprecated use {@link #functions(Set)} instead.
377+
*/
378+
@Deprecated(forRemoval = true, since = "1.0.0-M5")
379+
public Builder withFunctions(Set<String> functionNames) {
380+
return functions(functionNames);
381+
}
382+
383+
/**
384+
* @deprecated use {@link #function(String)} instead.
385+
*/
386+
@Deprecated(forRemoval = true, since = "1.0.0-M5")
387+
public Builder withFunction(String functionName) {
388+
return function(functionName);
389+
}
390+
391+
/**
392+
* @deprecated use {@link #proxyToolCalls(Boolean)} instead.
393+
*/
394+
@Deprecated(forRemoval = true, since = "1.0.0-M5")
395+
public Builder withProxyToolCalls(Boolean proxyToolCalls) {
396+
return proxyToolCalls(proxyToolCalls);
397+
}
398+
399+
/**
400+
* @deprecated use {@link #toolContext(Map)} instead.
401+
*/
402+
@Deprecated(forRemoval = true, since = "1.0.0-M5")
403+
public Builder withToolContext(Map<String, Object> toolContext) {
404+
return toolContext(toolContext);
405+
}
406+
302407
public AnthropicChatOptions build() {
303408
return this.options;
304409
}

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ void roleTest(String modelName) {
9797
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(this.systemResource);
9898
Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", "Bob", "voice", "pirate"));
9999
Prompt prompt = new Prompt(List.of(userMessage, systemMessage),
100-
AnthropicChatOptions.builder().withModel(modelName).build());
100+
AnthropicChatOptions.builder().model(modelName).build());
101101
ChatResponse response = this.chatModel.call(prompt);
102102
assertThat(response.getResults()).hasSize(1);
103103
assertThat(response.getMetadata().getUsage().getGenerationTokens()).isGreaterThan(0);
@@ -118,7 +118,7 @@ void testMessageHistory() {
118118
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(this.systemResource);
119119
Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", "Bob", "voice", "pirate"));
120120
Prompt prompt = new Prompt(List.of(userMessage, systemMessage),
121-
AnthropicChatOptions.builder().withModel("claude-3-sonnet-20240229").build());
121+
AnthropicChatOptions.builder().model("claude-3-sonnet-20240229").build());
122122

123123
ChatResponse response = this.chatModel.call(prompt);
124124
assertThat(response.getResult().getOutput().getText()).containsAnyOf("Blackbeard", "Bartholomew");
@@ -132,7 +132,7 @@ void testMessageHistory() {
132132

133133
@Test
134134
void streamingWithTokenUsage() {
135-
var promptOptions = AnthropicChatOptions.builder().withTemperature(0.0).build();
135+
var promptOptions = AnthropicChatOptions.builder().temperature(0.0).build();
136136

137137
var prompt = new Prompt("List two colors of the Polish flag. Be brief.", promptOptions);
138138
var streamingTokenUsage = this.chatModel.stream(prompt).blockLast().getMetadata().getUsage();
@@ -273,8 +273,8 @@ void functionCallTest() {
273273
List<Message> messages = new ArrayList<>(List.of(userMessage));
274274

275275
var promptOptions = AnthropicChatOptions.builder()
276-
.withModel(AnthropicApi.ChatModel.CLAUDE_3_OPUS.getName())
277-
.withFunctionCallbacks(List.of(FunctionCallback.builder()
276+
.model(AnthropicApi.ChatModel.CLAUDE_3_OPUS.getName())
277+
.functionCallbacks(List.of(FunctionCallback.builder()
278278
.function("getCurrentWeather", new MockWeatherService())
279279
.description(
280280
"Get the weather in location. Return temperature in 36°F or 36°C format. Use multi-turn if needed.")
@@ -306,8 +306,8 @@ void streamFunctionCallTest() {
306306
List<Message> messages = new ArrayList<>(List.of(userMessage));
307307

308308
var promptOptions = AnthropicChatOptions.builder()
309-
.withModel(AnthropicApi.ChatModel.CLAUDE_3_5_SONNET.getName())
310-
.withFunctionCallbacks(List.of(FunctionCallback.builder()
309+
.model(AnthropicApi.ChatModel.CLAUDE_3_5_SONNET.getName())
310+
.functionCallbacks(List.of(FunctionCallback.builder()
311311
.function("getCurrentWeather", new MockWeatherService())
312312
.description(
313313
"Get the weather in location. Return temperature in 36°F or 36°C format. Use multi-turn if needed.")
@@ -362,7 +362,7 @@ void validateCallResponseMetadata() {
362362
String model = AnthropicApi.ChatModel.CLAUDE_2_1.getName();
363363
// @formatter:off
364364
ChatResponse response = ChatClient.create(this.chatModel).prompt()
365-
.options(AnthropicChatOptions.builder().withModel(model).build())
365+
.options(AnthropicChatOptions.builder().model(model).build())
366366
.user("Tell me about 3 famous pirates from the Golden Age of Piracy and what they did")
367367
.call()
368368
.chatResponse();
@@ -377,7 +377,7 @@ void validateStreamCallResponseMetadata() {
377377
String model = AnthropicApi.ChatModel.CLAUDE_3_5_SONNET.getName();
378378
// @formatter:off
379379
ChatResponse response = ChatClient.create(this.chatModel).prompt()
380-
.options(AnthropicChatOptions.builder().withModel(model).build())
380+
.options(AnthropicChatOptions.builder().model(model).build())
381381
.user("Tell me about 3 famous pirates from the Golden Age of Piracy and what they did")
382382
.stream()
383383
.chatResponse()

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

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
* Integration tests for observation instrumentation in {@link AnthropicChatModel}.
4949
*
5050
* @author Thomas Vitale
51+
* @author Alexandros Pappas
5152
*/
5253
@SpringBootTest(classes = AnthropicChatModelObservationIT.Config.class,
5354
properties = "spring.ai.retry.on-http-codes=429")
@@ -68,12 +69,12 @@ void beforeEach() {
6869
@Test
6970
void observationForChatOperation() {
7071
var options = AnthropicChatOptions.builder()
71-
.withModel(AnthropicApi.ChatModel.CLAUDE_3_HAIKU.getValue())
72-
.withMaxTokens(2048)
73-
.withStopSequences(List.of("this-is-the-end"))
74-
.withTemperature(0.7)
75-
.withTopK(1)
76-
.withTopP(1.0)
72+
.model(AnthropicApi.ChatModel.CLAUDE_3_HAIKU.getValue())
73+
.maxTokens(2048)
74+
.stopSequences(List.of("this-is-the-end"))
75+
.temperature(0.7)
76+
.topK(1)
77+
.topP(1.0)
7778
.build();
7879

7980
Prompt prompt = new Prompt("Why does a raven look like a desk?", options);
@@ -90,12 +91,12 @@ void observationForChatOperation() {
9091
@Test
9192
void observationForStreamingChatOperation() {
9293
var options = AnthropicChatOptions.builder()
93-
.withModel(AnthropicApi.ChatModel.CLAUDE_3_HAIKU.getValue())
94-
.withMaxTokens(2048)
95-
.withStopSequences(List.of("this-is-the-end"))
96-
.withTemperature(0.7)
97-
.withTopK(1)
98-
.withTopP(1.0)
94+
.model(AnthropicApi.ChatModel.CLAUDE_3_HAIKU.getValue())
95+
.maxTokens(2048)
96+
.stopSequences(List.of("this-is-the-end"))
97+
.temperature(0.7)
98+
.topK(1)
99+
.topP(1.0)
99100
.build();
100101

101102
Prompt prompt = new Prompt("Why does a raven look like a desk?", options);

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@
2525

2626
/**
2727
* @author Christian Tzolov
28+
* @author Alexandros Pappas
2829
*/
2930
public class ChatCompletionRequestTests {
3031

3132
@Test
3233
public void createRequestWithChatOptions() {
3334

3435
var client = new AnthropicChatModel(new AnthropicApi("TEST"),
35-
AnthropicChatOptions.builder().withModel("DEFAULT_MODEL").withTemperature(66.6).build());
36+
AnthropicChatOptions.builder().model("DEFAULT_MODEL").temperature(66.6).build());
3637

3738
var request = client.createRequest(new Prompt("Test message content"), false);
3839

@@ -43,7 +44,7 @@ public void createRequestWithChatOptions() {
4344
assertThat(request.temperature()).isEqualTo(66.6);
4445

4546
request = client.createRequest(new Prompt("Test message content",
46-
AnthropicChatOptions.builder().withModel("PROMPT_MODEL").withTemperature(99.9).build()), true);
47+
AnthropicChatOptions.builder().model("PROMPT_MODEL").temperature(99.9).build()), true);
4748

4849
assertThat(request.messages()).hasSize(1);
4950
assertThat(request.stream()).isTrue();

0 commit comments

Comments
 (0)