Skip to content

Commit 3763e9a

Browse files
Encapsulate Advisor Parameters with ChatMemoryAdvisorOptions
Signed-off-by: jonghoonpark <[email protected]>
1 parent 8329402 commit 3763e9a

File tree

5 files changed

+137
-15
lines changed

5 files changed

+137
-15
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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.client.advisor;
18+
19+
import org.springframework.ai.chat.client.ChatClient.AdvisorSpec;
20+
import org.springframework.util.Assert;
21+
22+
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.*;
23+
24+
/**
25+
* Provides a way to configure an AdvisorSpec with a conversation ID and retrieval size.
26+
*
27+
* @author Jonghoon Park
28+
*/
29+
public class ChatMemoryAdvisorOptions {
30+
31+
private Object conversationId = DEFAULT_CHAT_MEMORY_CONVERSATION_ID;
32+
33+
private Integer retrieveSize = DEFAULT_CHAT_MEMORY_RESPONSE_SIZE;
34+
35+
public static Builder builder() {
36+
return new Builder();
37+
}
38+
39+
public static class Builder {
40+
41+
private final ChatMemoryAdvisorOptions options;
42+
43+
public Builder() {
44+
this.options = new ChatMemoryAdvisorOptions();
45+
}
46+
47+
public Builder conversationId(Object conversationId) {
48+
this.options.conversationId = conversationId;
49+
return this;
50+
}
51+
52+
public Builder retrieveSize(int retrieveSize) {
53+
this.options.retrieveSize = retrieveSize;
54+
return this;
55+
}
56+
57+
public ChatMemoryAdvisorOptions build() {
58+
return this.options;
59+
}
60+
61+
}
62+
63+
public void applyTo(AdvisorSpec advisorSpec) {
64+
Assert.notNull(advisorSpec, "advisorSpec must not be null");
65+
66+
advisorSpec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversationId);
67+
advisorSpec.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, retrieveSize);
68+
}
69+
70+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2023-2024 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.client.advisor;
18+
19+
import org.junit.jupiter.api.Test;
20+
import org.springframework.ai.chat.client.DefaultChatClient;
21+
22+
import static org.junit.jupiter.api.Assertions.assertEquals;
23+
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.*;
24+
25+
/**
26+
* @author Jonghoon Park
27+
*/
28+
public class ChatMemoryAdvisorOptionsTests {
29+
30+
@Test
31+
public void testChatMemoryAdvisorConfigurator() {
32+
DefaultChatClient.DefaultAdvisorSpec spec = new DefaultChatClient.DefaultAdvisorSpec();
33+
spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, 1);
34+
spec.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100);
35+
36+
DefaultChatClient.DefaultAdvisorSpec spec2 = new DefaultChatClient.DefaultAdvisorSpec();
37+
ChatMemoryAdvisorOptions options = ChatMemoryAdvisorOptions.builder()
38+
.conversationId(1)
39+
.retrieveSize(100)
40+
.build();
41+
options.applyTo(spec2);
42+
43+
assertEquals(spec.getParams().get(CHAT_MEMORY_CONVERSATION_ID_KEY),
44+
spec2.getParams().get(CHAT_MEMORY_CONVERSATION_ID_KEY));
45+
assertEquals(spec.getParams().get(CHAT_MEMORY_RETRIEVE_SIZE_KEY),
46+
spec2.getParams().get(CHAT_MEMORY_RETRIEVE_SIZE_KEY));
47+
}
48+
49+
}

spring-ai-docs/src/main/antora/modules/ROOT/pages/api/advisors.adoc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@ var chatClient = ChatClient.builder(chatModel)
1818
)
1919
.build();
2020
21+
// Set advisor parameters at runtime
22+
ChatMemoryAdvisorOptions options = ChatMemoryAdvisorOptions.builder()
23+
.conversationId("678")
24+
.retrieveSize(100)
25+
.build();
26+
2127
String response = this.chatClient.prompt()
22-
// Set advisor parameters at runtime
23-
.advisors(advisor -> advisor.param("chat_memory_conversation_id", "678")
24-
.param("chat_memory_response_size", 100))
28+
.advisors(options::applyTo)
2529
.user(userText)
2630
.call()
2731
.content();

spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chatclient.adoc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -420,9 +420,6 @@ A sample `@Service` implementation that uses several advisors is shown below.
420420

421421
[source,java]
422422
----
423-
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
424-
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;
425-
426423
@Service
427424
public class CustomerSupportAssistant {
428425
@@ -452,11 +449,14 @@ public class CustomerSupportAssistant {
452449
453450
public Flux<String> chat(String chatId, String userMessageContent) {
454451
452+
ChatMemoryAdvisorOptions options = ChatMemoryAdvisorOptions.builder()
453+
.conversationId(chatId)
454+
.retrieveSize(100)
455+
.build();
456+
455457
return this.chatClient.prompt()
456458
.user(userMessageContent)
457-
.advisors(a -> a
458-
.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
459-
.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100))
459+
.advisors(options::applyTo)
460460
.stream().content();
461461
}
462462

spring-ai-integration-tests/src/test/java/org/springframework/ai/integration/tests/client/advisor/RetrievalAugmentationAdvisorIT.java

Lines changed: 5 additions & 6 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.
@@ -24,7 +24,7 @@
2424
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
2525

2626
import org.springframework.ai.chat.client.ChatClient;
27-
import org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor;
27+
import org.springframework.ai.chat.client.advisor.ChatMemoryAdvisorOptions;
2828
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
2929
import org.springframework.ai.chat.client.advisor.RetrievalAugmentationAdvisor;
3030
import org.springframework.ai.chat.memory.InMemoryChatMemory;
@@ -147,11 +147,11 @@ void ragWithCompression() {
147147
.build();
148148

149149
String conversationId = "007";
150+
ChatMemoryAdvisorOptions options = ChatMemoryAdvisorOptions.builder().conversationId(conversationId).build();
150151

151152
ChatResponse chatResponse1 = chatClient.prompt()
152153
.user("Where does the adventure of Anacletus and Birba take place?")
153-
.advisors(advisors -> advisors.param(AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY,
154-
conversationId))
154+
.advisors(options::applyTo)
155155
.call()
156156
.chatResponse();
157157

@@ -161,8 +161,7 @@ void ragWithCompression() {
161161

162162
ChatResponse chatResponse2 = chatClient.prompt()
163163
.user("Did they meet any cow?")
164-
.advisors(advisors -> advisors.param(AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY,
165-
conversationId))
164+
.advisors(options::applyTo)
166165
.call()
167166
.chatResponse();
168167

0 commit comments

Comments
 (0)