Skip to content

Commit fe323fb

Browse files
ilayaperumalgmarkpollack
authored andcommitted
Support store and metadata OpenAI chat options
- Add store and metadata as OpenAI Chat options - Add test Resolves #2103
1 parent bca65de commit fe323fb

File tree

3 files changed

+54
-7
lines changed

3 files changed

+54
-7
lines changed

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

Lines changed: 42 additions & 4 deletions
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.
@@ -45,6 +45,7 @@
4545
* @author Christian Tzolov
4646
* @author Mariusz Bernacki
4747
* @author Thomas Vitale
48+
* @author Ilayaperumal Gopinathan
4849
* @since 0.8.0
4950
*/
5051
@JsonInclude(Include.NON_NULL)
@@ -173,7 +174,14 @@ public class OpenAiChatOptions implements FunctionCallingOptions {
173174
* Defaults to true.
174175
*/
175176
private @JsonProperty("parallel_tool_calls") Boolean parallelToolCalls;
176-
177+
/**
178+
* Whether to store the output of this chat completion request for use in our model <a href="https://platform.openai.com/docs/guides/distillation">distillation</a> or <a href="https://platform.openai.com/docs/guides/evals">evals</a> products.
179+
*/
180+
private @JsonProperty("store") Boolean store;
181+
/**
182+
* Developer-defined tags and values used for filtering completions in the <a href="https://platform.openai.com/chat-completions">dashboard</a>.
183+
*/
184+
private @JsonProperty("metadata") Map<String, String> metadata = new HashMap<>();
177185
/**
178186
* OpenAI Tool Function Callbacks to register with the ChatModel.
179187
* For Prompt Options the functionCallbacks are automatically enabled for the duration of the prompt execution.
@@ -246,6 +254,8 @@ public static OpenAiChatOptions fromOptions(OpenAiChatOptions fromOptions) {
246254
.httpHeaders(fromOptions.getHttpHeaders())
247255
.proxyToolCalls(fromOptions.getProxyToolCalls())
248256
.toolContext(fromOptions.getToolContext())
257+
.store(fromOptions.getStore())
258+
.metadata(fromOptions.getMetadata())
249259
.build();
250260
}
251261

@@ -494,6 +504,22 @@ public void setToolContext(Map<String, Object> toolContext) {
494504
this.toolContext = toolContext;
495505
}
496506

507+
public Boolean getStore() {
508+
return this.store;
509+
}
510+
511+
public void setStore(Boolean store) {
512+
this.store = store;
513+
}
514+
515+
public Map<String, String> getMetadata() {
516+
return this.metadata;
517+
}
518+
519+
public void setMetadata(Map<String, String> metadata) {
520+
this.metadata = metadata;
521+
}
522+
497523
@Override
498524
public OpenAiChatOptions copy() {
499525
return OpenAiChatOptions.fromOptions(this);
@@ -505,7 +531,8 @@ public int hashCode() {
505531
this.maxTokens, this.maxCompletionTokens, this.n, this.presencePenalty, this.responseFormat,
506532
this.streamOptions, this.seed, this.stop, this.temperature, this.topP, this.tools, this.toolChoice,
507533
this.user, this.parallelToolCalls, this.functionCallbacks, this.functions, this.httpHeaders,
508-
this.proxyToolCalls, this.toolContext, this.outputModalities, this.outputAudio);
534+
this.proxyToolCalls, this.toolContext, this.outputModalities, this.outputAudio, this.store,
535+
this.metadata);
509536
}
510537

511538
@Override
@@ -535,7 +562,8 @@ public boolean equals(Object o) {
535562
&& Objects.equals(this.toolContext, other.toolContext)
536563
&& Objects.equals(this.proxyToolCalls, other.proxyToolCalls)
537564
&& Objects.equals(this.outputModalities, other.outputModalities)
538-
&& Objects.equals(this.outputAudio, other.outputAudio);
565+
&& Objects.equals(this.outputAudio, other.outputAudio) && Objects.equals(this.store, other.store)
566+
&& Objects.equals(this.metadata, other.metadata);
539567
}
540568

541569
@Override
@@ -702,6 +730,16 @@ public Builder toolContext(Map<String, Object> toolContext) {
702730
return this;
703731
}
704732

733+
public Builder store(Boolean store) {
734+
this.options.store = store;
735+
return this;
736+
}
737+
738+
public Builder metadata(Map<String, String> metadata) {
739+
this.options.metadata = metadata;
740+
return this;
741+
}
742+
705743
public OpenAiChatOptions build() {
706744
return this.options;
707745
}

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

Lines changed: 2 additions & 2 deletions
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.
@@ -804,7 +804,7 @@ public record ChatCompletionRequest(// @formatter:off
804804
@JsonProperty("messages") List<ChatCompletionMessage> messages,
805805
@JsonProperty("model") String model,
806806
@JsonProperty("store") Boolean store,
807-
@JsonProperty("metadata") Object metadata,
807+
@JsonProperty("metadata") Map<String, String> metadata,
808808
@JsonProperty("frequency_penalty") Double frequencyPenalty,
809809
@JsonProperty("logit_bias") Map<String, Integer> logitBias,
810810
@JsonProperty("logprobs") Boolean logprobs,

models/spring-ai-openai/src/test/java/org/springframework/ai/openai/chat/OpenAiChatModelIT.java

Lines changed: 10 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.
@@ -599,6 +599,15 @@ void validateCallResponseMetadata() {
599599
assertThat(response.getMetadata().getUsage().getTotalTokens()).isPositive();
600600
}
601601

602+
@Test
603+
void validateStoreAndMetadata() {
604+
OpenAiChatOptions options = OpenAiChatOptions.builder().store(true).metadata(Map.of("type", "dev")).build();
605+
606+
ChatResponse response = this.openAiChatModel.call(new Prompt("Tell me a joke", options));
607+
608+
assertThat(response).isNotNull();
609+
}
610+
602611
record ActorsFilmsRecord(String actor, List<String> movies) {
603612

604613
}

0 commit comments

Comments
 (0)