Skip to content

Commit 783e219

Browse files
committed
Remove deprecated code in observation context
- The commit removes deprecated methods and parameters, including - requestOptions in image observation context and proxyToolCalls in Vertex AI - Gemini options. Updates code to use ImagePrompt.getOptions() instead of - the separate parameter for more consistent API design.
1 parent f0702c3 commit 783e219

File tree

8 files changed

+46
-86
lines changed

8 files changed

+46
-86
lines changed

models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiImageModel.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ public ImageResponse call(ImagePrompt imagePrompt) {
135135
var observationContext = ImageModelObservationContext.builder()
136136
.imagePrompt(imagePrompt)
137137
.provider(OpenAiApiConstants.PROVIDER_NAME)
138-
.requestOptions(requestImagePrompt.getOptions())
139138
.build();
140139

141140
return ImageModelObservationDocumentation.IMAGE_MODEL_OPERATION

models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,8 @@ public enum OutputModality {
894894
* @param maxTokens The maximum number of tokens that can be generated in the chat
895895
* completion. This value can be used to control costs for text generated via API.
896896
* This value is now deprecated in favor of max_completion_tokens, and is not
897-
* compatible with o1 series models.
897+
* compatible with o1 series models. The field is retained for use with other openai
898+
* models and openai compatible models.
898899
* @param maxCompletionTokens An upper bound for the number of tokens that can be
899900
* generated for a completion, including visible output tokens and reasoning tokens.
900901
* @param n How many chat completion choices to generate for each input message. Note
@@ -960,8 +961,8 @@ public record ChatCompletionRequest(// @formatter:off
960961
@JsonProperty("logit_bias") Map<String, Integer> logitBias,
961962
@JsonProperty("logprobs") Boolean logprobs,
962963
@JsonProperty("top_logprobs") Integer topLogprobs,
963-
@JsonProperty("max_tokens") @Deprecated Integer maxTokens, // Use maxCompletionTokens instead
964-
@JsonProperty("max_completion_tokens") Integer maxCompletionTokens,
964+
@JsonProperty("max_tokens") Integer maxTokens, // original field for specifying token usage.
965+
@JsonProperty("max_completion_tokens") Integer maxCompletionTokens, // new field for gpt-o1 and other reasoning models
965966
@JsonProperty("n") Integer n,
966967
@JsonProperty("modalities") List<OutputModality> outputModalities,
967968
@JsonProperty("audio") AudioParameters audioParameters,

models/spring-ai-vertex-ai-gemini/src/main/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatOptions.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -440,11 +440,6 @@ public Builder safetySettings(List<VertexAiGeminiSafetySetting> safetySettings)
440440
return this;
441441
}
442442

443-
@Deprecated
444-
public Builder proxyToolCalls(boolean proxyToolCalls) {
445-
return this.internalToolExecutionEnabled(!proxyToolCalls);
446-
}
447-
448443
public Builder internalToolExecutionEnabled(boolean internalToolExecutionEnabled) {
449444
this.options.internalToolExecutionEnabled = internalToolExecutionEnabled;
450445
return this;

spring-ai-model/src/main/java/org/springframework/ai/image/observation/DefaultImageModelObservationConvention.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ public String getName() {
4141

4242
@Override
4343
public String getContextualName(ImageModelObservationContext context) {
44-
if (StringUtils.hasText(context.getRequestOptions().getModel())) {
44+
if (StringUtils.hasText(context.getRequest().getOptions().getModel())) {
4545
return "%s %s".formatted(context.getOperationMetadata().operationType(),
46-
context.getRequestOptions().getModel());
46+
context.getRequest().getOptions().getModel());
4747
}
4848
return context.getOperationMetadata().operationType();
4949
}
@@ -64,9 +64,9 @@ protected KeyValue aiProvider(ImageModelObservationContext context) {
6464
}
6565

6666
protected KeyValue requestModel(ImageModelObservationContext context) {
67-
if (StringUtils.hasText(context.getRequestOptions().getModel())) {
67+
if (StringUtils.hasText(context.getRequest().getOptions().getModel())) {
6868
return KeyValue.of(ImageModelObservationDocumentation.LowCardinalityKeyNames.REQUEST_MODEL,
69-
context.getRequestOptions().getModel());
69+
context.getRequest().getOptions().getModel());
7070
}
7171
return REQUEST_MODEL_NONE;
7272
}
@@ -84,28 +84,30 @@ public KeyValues getHighCardinalityKeyValues(ImageModelObservationContext contex
8484
// Request
8585

8686
protected KeyValues requestImageFormat(KeyValues keyValues, ImageModelObservationContext context) {
87-
if (StringUtils.hasText(context.getRequestOptions().getResponseFormat())) {
87+
if (StringUtils.hasText(context.getRequest().getOptions().getResponseFormat())) {
8888
return keyValues.and(
8989
ImageModelObservationDocumentation.HighCardinalityKeyNames.REQUEST_IMAGE_RESPONSE_FORMAT.asString(),
90-
context.getRequestOptions().getResponseFormat());
90+
context.getRequest().getOptions().getResponseFormat());
9191
}
9292
return keyValues;
9393
}
9494

9595
protected KeyValues requestImageSize(KeyValues keyValues, ImageModelObservationContext context) {
96-
if (context.getRequestOptions().getWidth() != null && context.getRequestOptions().getHeight() != null) {
96+
if (context.getRequest().getOptions().getWidth() != null
97+
&& context.getRequest().getOptions().getHeight() != null) {
9798
return keyValues.and(
9899
ImageModelObservationDocumentation.HighCardinalityKeyNames.REQUEST_IMAGE_SIZE.asString(),
99-
"%sx%s".formatted(context.getRequestOptions().getWidth(), context.getRequestOptions().getHeight()));
100+
"%sx%s".formatted(context.getRequest().getOptions().getWidth(),
101+
context.getRequest().getOptions().getHeight()));
100102
}
101103
return keyValues;
102104
}
103105

104106
protected KeyValues requestImageStyle(KeyValues keyValues, ImageModelObservationContext context) {
105-
if (StringUtils.hasText(context.getRequestOptions().getStyle())) {
107+
if (StringUtils.hasText(context.getRequest().getOptions().getStyle())) {
106108
return keyValues.and(
107109
ImageModelObservationDocumentation.HighCardinalityKeyNames.REQUEST_IMAGE_STYLE.asString(),
108-
context.getRequestOptions().getStyle());
110+
context.getRequest().getOptions().getStyle());
109111
}
110112
return keyValues;
111113
}

spring-ai-model/src/main/java/org/springframework/ai/image/observation/ImageModelObservationContext.java

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,16 @@
3232
*/
3333
public class ImageModelObservationContext extends ModelObservationContext<ImagePrompt, ImageResponse> {
3434

35-
private final ImageOptions requestOptions;
36-
37-
ImageModelObservationContext(ImagePrompt imagePrompt, String provider, ImageOptions requestOptions) {
35+
ImageModelObservationContext(ImagePrompt imagePrompt, String provider) {
3836
super(imagePrompt,
3937
AiOperationMetadata.builder().operationType(AiOperationType.IMAGE.value()).provider(provider).build());
40-
Assert.notNull(requestOptions, "requestOptions cannot be null");
41-
this.requestOptions = requestOptions;
38+
Assert.notNull(imagePrompt.getOptions(), "image options cannot be null");
4239
}
4340

4441
public static Builder builder() {
4542
return new Builder();
4643
}
4744

48-
/**
49-
* @deprecated Use {@link #getRequest().getOptions()} instead.
50-
*/
51-
@Deprecated(forRemoval = true)
52-
public ImageOptions getRequestOptions() {
53-
return this.requestOptions;
54-
}
55-
5645
public String getOperationType() {
5746
return AiOperationType.IMAGE.value();
5847
}
@@ -63,8 +52,6 @@ public static final class Builder {
6352

6453
private String provider;
6554

66-
private ImageOptions requestOptions;
67-
6855
private Builder() {
6956
}
7057

@@ -78,18 +65,8 @@ public Builder provider(String provider) {
7865
return this;
7966
}
8067

81-
/**
82-
* @deprecated ImageOptions are passed in the ImagePrompt object and should not be
83-
* set separately anymore.
84-
*/
85-
@Deprecated(forRemoval = true)
86-
public Builder requestOptions(ImageOptions requestOptions) {
87-
this.requestOptions = requestOptions;
88-
return this;
89-
}
90-
9168
public ImageModelObservationContext build() {
92-
return new ImageModelObservationContext(this.imagePrompt, this.provider, this.requestOptions);
69+
return new ImageModelObservationContext(this.imagePrompt, this.provider);
9370
}
9471

9572
}

spring-ai-model/src/test/java/org/springframework/ai/image/observation/DefaultImageModelObservationConventionTests.java

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import io.micrometer.observation.Observation;
2121
import org.junit.jupiter.api.Test;
2222

23+
import org.springframework.ai.image.ImageOptions;
2324
import org.springframework.ai.image.ImageOptionsBuilder;
2425
import org.springframework.ai.image.ImagePrompt;
2526
import org.springframework.ai.observation.conventions.AiObservationAttributes;
@@ -44,29 +45,26 @@ void shouldHaveName() {
4445
@Test
4546
void contextualNameWhenModelIsDefined() {
4647
ImageModelObservationContext observationContext = ImageModelObservationContext.builder()
47-
.imagePrompt(generateImagePrompt())
48+
.imagePrompt(generateImagePrompt(ImageOptionsBuilder.builder().model("mistral").build()))
4849
.provider("superprovider")
49-
.requestOptions(ImageOptionsBuilder.builder().model("mistral").build())
5050
.build();
5151
assertThat(this.observationConvention.getContextualName(observationContext)).isEqualTo("image mistral");
5252
}
5353

5454
@Test
5555
void contextualNameWhenModelIsNotDefined() {
5656
ImageModelObservationContext observationContext = ImageModelObservationContext.builder()
57-
.imagePrompt(generateImagePrompt())
57+
.imagePrompt(generateImagePrompt(ImageOptionsBuilder.builder().build()))
5858
.provider("superprovider")
59-
.requestOptions(ImageOptionsBuilder.builder().build())
6059
.build();
6160
assertThat(this.observationConvention.getContextualName(observationContext)).isEqualTo("image");
6261
}
6362

6463
@Test
6564
void supportsOnlyImageModelObservationContext() {
6665
ImageModelObservationContext observationContext = ImageModelObservationContext.builder()
67-
.imagePrompt(generateImagePrompt())
66+
.imagePrompt(generateImagePrompt(ImageOptionsBuilder.builder().model("mistral").build()))
6867
.provider("superprovider")
69-
.requestOptions(ImageOptionsBuilder.builder().model("mistral").build())
7068
.build();
7169
assertThat(this.observationConvention.supportsContext(observationContext)).isTrue();
7270
assertThat(this.observationConvention.supportsContext(new Observation.Context())).isFalse();
@@ -75,9 +73,8 @@ void supportsOnlyImageModelObservationContext() {
7573
@Test
7674
void shouldHaveLowCardinalityKeyValuesWhenDefined() {
7775
ImageModelObservationContext observationContext = ImageModelObservationContext.builder()
78-
.imagePrompt(generateImagePrompt())
76+
.imagePrompt(generateImagePrompt(ImageOptionsBuilder.builder().model("mistral").build()))
7977
.provider("superprovider")
80-
.requestOptions(ImageOptionsBuilder.builder().model("mistral").build())
8178
.build();
8279
assertThat(this.observationConvention.getLowCardinalityKeyValues(observationContext)).contains(
8380
KeyValue.of(AiObservationAttributes.AI_OPERATION_TYPE.value(), "image"),
@@ -87,17 +84,17 @@ void shouldHaveLowCardinalityKeyValuesWhenDefined() {
8784

8885
@Test
8986
void shouldHaveHighCardinalityKeyValuesWhenDefined() {
87+
var imageOptions = ImageOptionsBuilder.builder()
88+
.model("mistral")
89+
.N(1)
90+
.height(1080)
91+
.width(1920)
92+
.style("sketch")
93+
.responseFormat("base64")
94+
.build();
9095
ImageModelObservationContext observationContext = ImageModelObservationContext.builder()
91-
.imagePrompt(generateImagePrompt())
96+
.imagePrompt(generateImagePrompt(imageOptions))
9297
.provider("superprovider")
93-
.requestOptions(ImageOptionsBuilder.builder()
94-
.model("mistral")
95-
.N(1)
96-
.height(1080)
97-
.width(1920)
98-
.style("sketch")
99-
.responseFormat("base64")
100-
.build())
10198
.build();
10299

103100
assertThat(this.observationConvention.getHighCardinalityKeyValues(observationContext)).contains(
@@ -109,9 +106,8 @@ void shouldHaveHighCardinalityKeyValuesWhenDefined() {
109106
@Test
110107
void shouldNotHaveKeyValuesWhenEmptyValues() {
111108
ImageModelObservationContext observationContext = ImageModelObservationContext.builder()
112-
.imagePrompt(generateImagePrompt())
109+
.imagePrompt(generateImagePrompt(ImageOptionsBuilder.builder().build()))
113110
.provider("superprovider")
114-
.requestOptions(ImageOptionsBuilder.builder().build())
115111
.build();
116112

117113
assertThat(this.observationConvention.getLowCardinalityKeyValues(observationContext))
@@ -124,8 +120,8 @@ void shouldNotHaveKeyValuesWhenEmptyValues() {
124120
HighCardinalityKeyNames.REQUEST_IMAGE_STYLE.asString());
125121
}
126122

127-
private ImagePrompt generateImagePrompt() {
128-
return new ImagePrompt("here comes the sun");
123+
private ImagePrompt generateImagePrompt(ImageOptions imageOptions) {
124+
return new ImagePrompt("here comes the sun", imageOptions);
129125
}
130126

131127
}

spring-ai-model/src/test/java/org/springframework/ai/image/observation/ImageModelObservationContextTests.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import org.junit.jupiter.api.Test;
2020

21+
import org.springframework.ai.image.ImageOptions;
2122
import org.springframework.ai.image.ImageOptionsBuilder;
2223
import org.springframework.ai.image.ImagePrompt;
2324

@@ -34,25 +35,14 @@ class ImageModelObservationContextTests {
3435
@Test
3536
void whenMandatoryRequestOptionsThenReturn() {
3637
var observationContext = ImageModelObservationContext.builder()
37-
.imagePrompt(generateImagePrompt())
38+
.imagePrompt(generateImagePrompt(ImageOptionsBuilder.builder().model("supersun").build()))
3839
.provider("superprovider")
39-
.requestOptions(ImageOptionsBuilder.builder().model("supersun").build())
4040
.build();
4141

4242
assertThat(observationContext).isNotNull();
4343
}
4444

45-
@Test
46-
void whenRequestOptionsIsNullThenThrow() {
47-
assertThatThrownBy(() -> ImageModelObservationContext.builder()
48-
.imagePrompt(generateImagePrompt())
49-
.provider("superprovider")
50-
.requestOptions(null)
51-
.build()).isInstanceOf(IllegalArgumentException.class)
52-
.hasMessageContaining("requestOptions cannot be null");
53-
}
54-
55-
private ImagePrompt generateImagePrompt() {
45+
private ImagePrompt generateImagePrompt(ImageOptions imageOptions) {
5646
return new ImagePrompt("here comes the sun");
5747
}
5848

spring-ai-model/src/test/java/org/springframework/ai/image/observation/ImageModelPromptContentObservationFilterTests.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,8 @@ void whenNotSupportedObservationContextThenReturnOriginalContext() {
4949
@Test
5050
void whenEmptyPromptThenReturnOriginalContext() {
5151
var expectedContext = ImageModelObservationContext.builder()
52-
.imagePrompt(new ImagePrompt(""))
52+
.imagePrompt(new ImagePrompt("", ImageOptionsBuilder.builder().model("mistral").build()))
5353
.provider("superprovider")
54-
.requestOptions(ImageOptionsBuilder.builder().model("mistral").build())
5554
.build();
5655
var actualContext = this.observationFilter.map(expectedContext);
5756

@@ -61,9 +60,9 @@ void whenEmptyPromptThenReturnOriginalContext() {
6160
@Test
6261
void whenPromptWithTextThenAugmentContext() {
6362
var originalContext = ImageModelObservationContext.builder()
64-
.imagePrompt(new ImagePrompt("supercalifragilisticexpialidocious"))
63+
.imagePrompt(new ImagePrompt("supercalifragilisticexpialidocious",
64+
ImageOptionsBuilder.builder().model("mistral").build()))
6565
.provider("superprovider")
66-
.requestOptions(ImageOptionsBuilder.builder().model("mistral").build())
6766
.build();
6867
var augmentedContext = this.observationFilter.map(originalContext);
6968

@@ -74,10 +73,11 @@ void whenPromptWithTextThenAugmentContext() {
7473
@Test
7574
void whenPromptWithMessagesThenAugmentContext() {
7675
var originalContext = ImageModelObservationContext.builder()
77-
.imagePrompt(new ImagePrompt(List.of(new ImageMessage("you're a chimney sweep"),
78-
new ImageMessage("supercalifragilisticexpialidocious"))))
76+
.imagePrompt(new ImagePrompt(
77+
List.of(new ImageMessage("you're a chimney sweep"),
78+
new ImageMessage("supercalifragilisticexpialidocious")),
79+
ImageOptionsBuilder.builder().model("mistral").build()))
7980
.provider("superprovider")
80-
.requestOptions(ImageOptionsBuilder.builder().model("mistral").build())
8181
.build();
8282
var augmentedContext = this.observationFilter.map(originalContext);
8383

0 commit comments

Comments
 (0)