Skip to content

Commit 2ddd37b

Browse files
committed
use Spring AI for chat completions
1 parent 79519db commit 2ddd37b

File tree

7 files changed

+58
-7
lines changed

7 files changed

+58
-7
lines changed

e2e-tests/serverConfigs/backend_application.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,5 @@ skills.config.ui.disableEncouragementsConfetti=true
8282
skills.config.ui.contactSupportEnabled=true
8383
skills.config.ui.daysToRollOff = 2
8484

85-
skills.openai.host: http://localhost:8280
86-
skills.openai.model: model1
85+
spring.ai.model.chat=openai
86+
spring.ai.openai.base-url=http://localhost:8280

e2e-tests/serverConfigs/backend_oauth_application.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,6 @@ skills.config.ui.disableEncouragementsConfetti=true
5151
skills.config.ui.contactSupportEnabled=true
5252
skills.config.ui.daysToRollOff = 2
5353

54-
skills.openai.host: http://localhost:8280
55-
skills.openai.model: model1
54+
spring.ai.model.chat=openai
55+
spring.ai.openai.base-url=http://localhost:8280
5656

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
<springboot.version>3.5.7</springboot.version>
3838

3939
<springcloud.version>3.4.0</springcloud.version>
40+
<spring-ai.version>1.1.0</spring-ai.version>
4041

4142
<logback-access.version>2.0.6</logback-access.version>
4243

service/pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@
3030
<type>pom</type>
3131
<scope>import</scope>
3232
</dependency>
33+
<dependency>
34+
<groupId>org.springframework.ai</groupId>
35+
<artifactId>spring-ai-bom</artifactId>
36+
<version>${spring-ai.version}</version>
37+
<type>pom</type>
38+
<scope>import</scope>
39+
</dependency>
3340
</dependencies>
3441
</dependencyManagement>
3542

@@ -85,6 +92,10 @@
8592
<version>10.0.2</version>
8693
<scope>compile</scope>
8794
</dependency>
95+
<dependency>
96+
<groupId>org.springframework.ai</groupId>
97+
<artifactId>spring-ai-starter-model-openai</artifactId>
98+
</dependency>
8899
<dependency>
89100
<groupId>org.springframework.boot</groupId>
90101
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
@@ -704,6 +715,7 @@
704715
<licenseMerge>Eclipse Public License - Version 2.0|Eclipse Public License - v 2.0</licenseMerge>
705716
<licenseMerge>The BSD License|BSD</licenseMerge>
706717
<licenseMerge>The BSD License|BSD License</licenseMerge>
718+
<licenseMerge>The BSD License|BSD licence</licenseMerge>
707719
<licenseMerge>MPL 2.0|Mozilla Public License, version 2.0</licenseMerge>
708720
<licenseMerge>Common Development and Distribution License / The GNU General Public License (GPL) Version 2 with the Classpath Exception|CDDL/GPLv2+CE</licenseMerge>
709721
<licenseMerge>Dual license: Common Development and Distribution License 1.1 (CDDL-1.1) and The GNU General Public License (GPL) Version 2|Dual license consisting of the CDDL v1.1 and GPL v2</licenseMerge>

service/src/main/java/skills/auth/openai/OpenAIService.groovy

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ import groovy.json.JsonSlurper
1919
import groovy.transform.Canonical
2020
import groovy.transform.ToString
2121
import groovy.util.logging.Slf4j
22+
import org.springframework.ai.chat.model.ChatResponse
23+
import org.springframework.ai.chat.prompt.Prompt
24+
import org.springframework.ai.openai.OpenAiChatModel
25+
import org.springframework.ai.openai.OpenAiChatOptions
2226
import org.springframework.beans.factory.annotation.Autowired
2327
import org.springframework.beans.factory.annotation.Qualifier
2428
import org.springframework.beans.factory.annotation.Value
@@ -37,6 +41,9 @@ class OpenAIService {
3741
@Value('#{"${skills.openai.host:null}"}')
3842
String openAiHost
3943

44+
@Value('#{"${spring.ai.openai.base-url:null}"}')
45+
String openAiBaseUrl
46+
4047
@Value('#{"${skills.openai.completionsEndpoint:/v1/chat/completions}"}')
4148
String completionsEndpoint
4249

@@ -58,6 +65,13 @@ class OpenAIService {
5865
@Autowired
5966
SslWebClientConfig sslWebClientConfig
6067

68+
@Autowired(required = false)
69+
OpenAiChatModel chatModel;
70+
71+
boolean isChatEnabled() {
72+
return chatModel != null
73+
}
74+
6175
CompletionsResponse callCompletions(String message) {
6276
if (!openAiHost) {
6377
log.debug("skills.openai.host is not configured")
@@ -107,7 +121,7 @@ class OpenAIService {
107121
return null
108122
}
109123

110-
String url = String.join("/", openAiHost, modelsEndpoint)
124+
String url = String.join("/", openAiBaseUrl, modelsEndpoint)
111125

112126
HttpHeaders headers = new HttpHeaders();
113127
headers.setContentType(MediaType.APPLICATION_JSON);
@@ -135,6 +149,26 @@ class OpenAIService {
135149
}
136150
}
137151

152+
Flux<String> streamCompletions1(GenDescRequest genDescRequest) {
153+
if (!isChatEnabled()) {
154+
return Flux.error(new IllegalStateException("Chat model is not enabled. Set spring.ai.model.chat to enable."))
155+
}
156+
157+
Prompt prompt = new Prompt(
158+
genDescRequest.instructions,
159+
OpenAiChatOptions.builder()
160+
.model(genDescRequest.model)
161+
.temperature(genDescRequest.modelTemperature)
162+
.build()
163+
)
164+
Flux<ChatResponse> response = chatModel.stream(prompt)
165+
return response.mapNotNull { ChatResponse chatResponse ->
166+
String res = (String) chatResponse.getResults().get(0).getOutput().getText()
167+
res = res?.replaceAll('\\n', '<<newline>>')
168+
log.debug("Response: [{}]", res)
169+
return res
170+
}
171+
}
138172

139173
Flux<String> streamCompletions(GenDescRequest genDescRequest) {
140174
String message = genDescRequest.instructions

service/src/main/java/skills/controller/OpenAiController.groovy

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import org.springframework.web.bind.annotation.RequestMapping
2626
import org.springframework.web.bind.annotation.RestController
2727
import reactor.core.publisher.Flux
2828
import skills.auth.openai.GenDescRequest
29-
import skills.auth.openai.LearningContentGenerator
3029
import skills.auth.openai.OpenAIService
3130
import skills.controller.exceptions.SkillsValidator
3231

@@ -44,7 +43,7 @@ class OpenAiController {
4443
SkillsValidator.isNotBlank(genDescRequest.model, "genDescRequest.model")
4544
SkillsValidator.isNotNull(genDescRequest.modelTemperature, "genDescRequest.modelTemperature")
4645
SkillsValidator.isTrue(genDescRequest.modelTemperature >= 0 && genDescRequest.modelTemperature <= 2, "genDescRequest.modelTemperature must be >= 0 and <= 2")
47-
return openAIService.streamCompletions(genDescRequest)
46+
return openAIService.streamCompletions1(genDescRequest)
4847
}
4948

5049
@GetMapping("/models")

service/src/main/resources/application.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ db-scheduler:
209209
threads: 3
210210
---
211211
spring:
212+
ai:
213+
model:
214+
chat: none
215+
openai:
216+
api-key: none
212217
cloud:
213218
aws:
214219
s3:

0 commit comments

Comments
 (0)