Skip to content

Commit 9ac17e7

Browse files
committed
调整页面样式,优化功能
1 parent 24de266 commit 9ac17e7

File tree

8 files changed

+245
-64
lines changed

8 files changed

+245
-64
lines changed

auto-configurations/spring-ai-alibaba-autoconfigure-memory/src/main/java/com/alibaba/cloud/ai/autoconfigure/memory/H2ChatMemoryAutoConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
* Auto-configuration for h2 chat memory repository.
3636
*/
3737
@AutoConfiguration(after = JdbcTemplateAutoConfiguration.class)
38-
@ConditionalOnClass({ H2ChatMemoryRepository.class, DataSource.class, JdbcTemplate.class })
38+
@ConditionalOnClass({ H2ChatMemoryRepository.class, JdbcTemplate.class })
3939
@ConditionalOnProperty(prefix = "spring.ai.memory.h2", name = "enabled", havingValue = "true", matchIfMissing = false)
4040
@EnableConfigurationProperties(H2ChatMemoryProperties.class)
4141
public class H2ChatMemoryAutoConfiguration {

auto-configurations/spring-ai-alibaba-autoconfigure-memory/src/main/java/com/alibaba/cloud/ai/autoconfigure/memory/H2ChatMemoryProperties.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
@ConfigurationProperties(H2ChatMemoryProperties.CONFIG_PREFIX)
2525
public class H2ChatMemoryProperties {
2626

27-
public static final String CONFIG_PREFIX = "spring.ai.chat.memory.repository.jdbc.h2";
27+
public static final String CONFIG_PREFIX = "spring.ai.memory.h2";
2828

2929
private boolean initializeSchema = true;
3030

spring-ai-alibaba-jmanus/src/main/java/com/alibaba/cloud/ai/example/manus/dynamic/agent/DynamicAgent.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.alibaba.cloud.ai.example.manus.agent.AgentState;
1919
import com.alibaba.cloud.ai.example.manus.agent.ReActAgent;
2020
import com.alibaba.cloud.ai.example.manus.config.ManusProperties;
21+
import com.alibaba.cloud.ai.example.manus.dynamic.memory.advisor.CustomMessageChatMemoryAdvisor;
2122
import com.alibaba.cloud.ai.example.manus.dynamic.model.entity.DynamicModelEntity;
2223
import com.alibaba.cloud.ai.example.manus.dynamic.prompt.model.enums.PromptEnum;
2324
import com.alibaba.cloud.ai.example.manus.dynamic.prompt.service.PromptService;
@@ -57,6 +58,8 @@
5758
import java.util.concurrent.TimeUnit;
5859
import java.util.stream.Collectors;
5960

61+
import static org.springframework.ai.chat.memory.ChatMemory.CONVERSATION_ID;
62+
6063
public class DynamicAgent extends ReActAgent {
6164

6265
private static final String CURRENT_STEP_ENV_DATA_KEY = "current_step_env_data";
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
package com.alibaba.cloud.ai.example.manus.dynamic.memory.advisor;
2+
3+
import org.springframework.ai.chat.client.ChatClientMessageAggregator;
4+
import org.springframework.ai.chat.client.ChatClientRequest;
5+
import org.springframework.ai.chat.client.ChatClientResponse;
6+
import org.springframework.ai.chat.client.advisor.api.*;
7+
import org.springframework.ai.chat.memory.ChatMemory;
8+
import org.springframework.ai.chat.messages.Message;
9+
import org.springframework.ai.chat.messages.UserMessage;
10+
import org.springframework.util.Assert;
11+
import reactor.core.publisher.Flux;
12+
import reactor.core.publisher.Mono;
13+
import reactor.core.scheduler.Scheduler;
14+
15+
import java.util.ArrayList;
16+
import java.util.List;
17+
18+
/**
19+
* 2025/8/7 auth: dahua
20+
*/
21+
public class CustomMessageChatMemoryAdvisor implements BaseChatMemoryAdvisor {
22+
23+
private final ChatMemory chatMemory;
24+
25+
private final String defaultConversationId;
26+
27+
private final int order;
28+
29+
private final Scheduler scheduler;
30+
31+
private String userRequest;
32+
33+
private CustomMessageChatMemoryAdvisor(ChatMemory chatMemory, String defaultConversationId, int order,
34+
Scheduler scheduler, String userRequest) {
35+
Assert.notNull(chatMemory, "chatMemory cannot be null");
36+
Assert.hasText(defaultConversationId, "defaultConversationId cannot be null or empty");
37+
Assert.notNull(scheduler, "scheduler cannot be null");
38+
this.chatMemory = chatMemory;
39+
this.defaultConversationId = defaultConversationId;
40+
this.order = order;
41+
this.scheduler = scheduler;
42+
this.userRequest = userRequest;
43+
}
44+
45+
@Override
46+
public int getOrder() {
47+
return this.order;
48+
}
49+
50+
@Override
51+
public Scheduler getScheduler() {
52+
return this.scheduler;
53+
}
54+
55+
@Override
56+
public ChatClientRequest before(ChatClientRequest chatClientRequest, AdvisorChain advisorChain) {
57+
String conversationId = getConversationId(chatClientRequest.context(), this.defaultConversationId);
58+
59+
// 1. Retrieve the chat memory for the current conversation.
60+
List<Message> memoryMessages = this.chatMemory.get(conversationId);
61+
62+
// 2. Advise the request messages list.
63+
List<Message> processedMessages = new ArrayList<>(memoryMessages);
64+
processedMessages.addAll(chatClientRequest.prompt().getInstructions());
65+
66+
// 3. Create a new request with the advised messages.
67+
ChatClientRequest processedChatClientRequest = chatClientRequest.mutate()
68+
.prompt(chatClientRequest.prompt().mutate().messages(processedMessages).build())
69+
.build();
70+
71+
// 4. Add the new user message to the conversation memory.
72+
UserMessage userMessage = processedChatClientRequest.prompt().getUserMessage();
73+
74+
// 5. The user's question needs to be re-placed here because the default message
75+
// body contains template information,
76+
// which can be misleading when displayed on the front end.
77+
// Re-placement of the user's actual question does not affect the model's ability
78+
// to process new requests after loading memory and can also reduce token
79+
// consumption in the model.
80+
UserMessage customMessage = UserMessage.builder()
81+
.text(userRequest)
82+
.media(userMessage.getMedia())
83+
.metadata(userMessage.getMetadata())
84+
.build();
85+
this.chatMemory.add(conversationId, customMessage);
86+
87+
return processedChatClientRequest;
88+
}
89+
90+
@Override
91+
public ChatClientResponse after(ChatClientResponse chatClientResponse, AdvisorChain advisorChain) {
92+
List<Message> assistantMessages = new ArrayList<>();
93+
if (chatClientResponse.chatResponse() != null) {
94+
assistantMessages = chatClientResponse.chatResponse()
95+
.getResults()
96+
.stream()
97+
.map(g -> (Message) g.getOutput())
98+
.toList();
99+
}
100+
this.chatMemory.add(this.getConversationId(chatClientResponse.context(), this.defaultConversationId),
101+
assistantMessages);
102+
return chatClientResponse;
103+
}
104+
105+
@Override
106+
public Flux<ChatClientResponse> adviseStream(ChatClientRequest chatClientRequest,
107+
StreamAdvisorChain streamAdvisorChain) {
108+
// Get the scheduler from BaseAdvisor
109+
Scheduler scheduler = this.getScheduler();
110+
111+
// Process the request with the before method
112+
return Mono.just(chatClientRequest)
113+
.publishOn(scheduler)
114+
.map(request -> this.before(request, streamAdvisorChain))
115+
.flatMapMany(streamAdvisorChain::nextStream)
116+
.transform(flux -> new ChatClientMessageAggregator().aggregateChatClientResponse(flux,
117+
response -> this.after(response, streamAdvisorChain)));
118+
}
119+
120+
public static CustomMessageChatMemoryAdvisor.Builder builder(ChatMemory chatMemory, String userRequest) {
121+
return new CustomMessageChatMemoryAdvisor.Builder(chatMemory, userRequest);
122+
}
123+
124+
public static final class Builder {
125+
126+
private String conversationId = ChatMemory.DEFAULT_CONVERSATION_ID;
127+
128+
private int order = Advisor.DEFAULT_CHAT_MEMORY_PRECEDENCE_ORDER;
129+
130+
private Scheduler scheduler = BaseAdvisor.DEFAULT_SCHEDULER;
131+
132+
private ChatMemory chatMemory;
133+
134+
private String userRequest;
135+
136+
private Builder(ChatMemory chatMemory, String userRequest) {
137+
this.chatMemory = chatMemory;
138+
this.userRequest = userRequest;
139+
}
140+
141+
/**
142+
* Set the conversation id.
143+
* @param conversationId the conversation id
144+
* @return the builder
145+
*/
146+
public CustomMessageChatMemoryAdvisor.Builder conversationId(String conversationId) {
147+
this.conversationId = conversationId;
148+
return this;
149+
}
150+
151+
/**
152+
* Set the order.
153+
* @param order the order
154+
* @return the builder
155+
*/
156+
public CustomMessageChatMemoryAdvisor.Builder order(int order) {
157+
this.order = order;
158+
return this;
159+
}
160+
161+
public CustomMessageChatMemoryAdvisor.Builder scheduler(Scheduler scheduler) {
162+
this.scheduler = scheduler;
163+
return this;
164+
}
165+
166+
/**
167+
* Build the advisor.
168+
* @return the advisor
169+
*/
170+
public CustomMessageChatMemoryAdvisor build() {
171+
return new CustomMessageChatMemoryAdvisor(this.chatMemory, this.conversationId, this.order, this.scheduler,
172+
this.userRequest);
173+
}
174+
175+
}
176+
177+
}

spring-ai-alibaba-jmanus/src/main/java/com/alibaba/cloud/ai/example/manus/dynamic/memory/service/MemoryService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,5 @@ public interface MemoryService {
3535
MemoryEntity updateMemory(MemoryEntity memoryEntity);
3636

3737
MemoryEntity singleMemory(String memoryId);
38+
3839
}

spring-ai-alibaba-jmanus/src/main/java/com/alibaba/cloud/ai/example/manus/dynamic/memory/service/MemoryServiceImpl.java

Lines changed: 55 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -34,62 +34,65 @@
3434
@Transactional
3535
public class MemoryServiceImpl implements MemoryService {
3636

37-
@Autowired
38-
private MemoryRepository memoryRepository;
37+
@Autowired
38+
private MemoryRepository memoryRepository;
3939

40-
@Autowired
41-
private ChatMemory chatMemory;
40+
@Autowired
41+
private ChatMemory chatMemory;
4242

43-
@Override
44-
public List<MemoryEntity> getMemories() {
45-
List<MemoryEntity> memoryEntities = memoryRepository.findAll();
46-
memoryEntities.forEach(memoryEntity -> {
47-
List<Message> messages = chatMemory.get(memoryEntity.getMemoryId());
48-
memoryEntity.setMessages(messages);
49-
});
50-
memoryEntities.stream().sorted((m1, m2) ->
51-
Math.toIntExact(m1.getCreateTime().getTime() - m2.getCreateTime().getTime())).toList();
52-
return memoryEntities;
53-
}
43+
@Override
44+
public List<MemoryEntity> getMemories() {
45+
List<MemoryEntity> memoryEntities = memoryRepository.findAll();
46+
memoryEntities.forEach(memoryEntity -> {
47+
List<Message> messages = chatMemory.get(memoryEntity.getMemoryId());
48+
memoryEntity.setMessages(messages);
49+
});
50+
memoryEntities.stream()
51+
.sorted((m1, m2) -> Math.toIntExact(m1.getCreateTime().getTime() - m2.getCreateTime().getTime()))
52+
.toList();
53+
return memoryEntities;
54+
}
5455

55-
@Override
56-
public void deleteMemory(String memoryId) {
57-
chatMemory.clear(memoryId);
58-
memoryRepository.deleteByMemoryId(memoryId);
59-
}
56+
@Override
57+
public void deleteMemory(String memoryId) {
58+
chatMemory.clear(memoryId);
59+
memoryRepository.deleteByMemoryId(memoryId);
60+
}
6061

61-
@Override
62-
public MemoryEntity saveMemory(MemoryEntity memoryEntity) {
63-
MemoryEntity findEntity = memoryRepository.findByMemoryId(memoryEntity.getMemoryId());
64-
if (findEntity != null) {
65-
findEntity.setMessages(null);
66-
} else {
67-
findEntity = memoryEntity;
68-
}
69-
MemoryEntity saveEntity = memoryRepository.save(findEntity);
70-
saveEntity.setMessages(chatMemory.get(saveEntity.getMemoryId()));
71-
return saveEntity;
72-
}
62+
@Override
63+
public MemoryEntity saveMemory(MemoryEntity memoryEntity) {
64+
MemoryEntity findEntity = memoryRepository.findByMemoryId(memoryEntity.getMemoryId());
65+
if (findEntity != null) {
66+
findEntity.setMessages(null);
67+
}
68+
else {
69+
findEntity = memoryEntity;
70+
}
71+
MemoryEntity saveEntity = memoryRepository.save(findEntity);
72+
saveEntity.setMessages(chatMemory.get(saveEntity.getMemoryId()));
73+
return saveEntity;
74+
}
7375

74-
@Override
75-
public MemoryEntity updateMemory(MemoryEntity memoryEntity) {
76-
MemoryEntity findEntity = memoryRepository.findByMemoryId(memoryEntity.getMemoryId());
77-
if (findEntity == null) {
78-
throw new IllegalArgumentException();
79-
}
80-
findEntity.setMemoryName(memoryEntity.getMemoryName());
81-
MemoryEntity saveEntity = memoryRepository.save(findEntity);
82-
saveEntity.setMessages(chatMemory.get(saveEntity.getMemoryId()));
83-
return saveEntity;
84-
}
76+
@Override
77+
public MemoryEntity updateMemory(MemoryEntity memoryEntity) {
78+
MemoryEntity findEntity = memoryRepository.findByMemoryId(memoryEntity.getMemoryId());
79+
if (findEntity == null) {
80+
throw new IllegalArgumentException();
81+
}
82+
findEntity.setMemoryName(memoryEntity.getMemoryName());
83+
MemoryEntity saveEntity = memoryRepository.save(findEntity);
84+
saveEntity.setMessages(chatMemory.get(saveEntity.getMemoryId()));
85+
return saveEntity;
86+
}
87+
88+
@Override
89+
public MemoryEntity singleMemory(String memoryId) {
90+
MemoryEntity findEntity = memoryRepository.findByMemoryId(memoryId);
91+
if (findEntity == null) {
92+
throw new IllegalArgumentException();
93+
}
94+
findEntity.setMessages(chatMemory.get(findEntity.getMemoryId()));
95+
return findEntity;
96+
}
8597

86-
@Override
87-
public MemoryEntity singleMemory(String memoryId) {
88-
MemoryEntity findEntity = memoryRepository.findByMemoryId(memoryId);
89-
if (findEntity == null) {
90-
throw new IllegalArgumentException();
91-
}
92-
findEntity.setMessages(chatMemory.get(findEntity.getMemoryId()));
93-
return findEntity;
94-
}
9598
}

spring-ai-alibaba-jmanus/src/main/java/com/alibaba/cloud/ai/example/manus/planning/creator/PlanCreator.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.alibaba.cloud.ai.example.manus.config.ManusProperties;
1919
import com.alibaba.cloud.ai.example.manus.dynamic.agent.entity.DynamicAgentEntity;
20+
import com.alibaba.cloud.ai.example.manus.dynamic.memory.advisor.CustomMessageChatMemoryAdvisor;
2021
import com.alibaba.cloud.ai.example.manus.dynamic.prompt.model.enums.PromptEnum;
2122
import com.alibaba.cloud.ai.example.manus.dynamic.prompt.service.PromptService;
2223
import com.alibaba.cloud.ai.example.manus.llm.ILlmService;
@@ -28,7 +29,6 @@
2829
import org.slf4j.Logger;
2930
import org.slf4j.LoggerFactory;
3031
import org.springframework.ai.chat.client.ChatClient.ChatClientRequestSpec;
31-
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
3232
import org.springframework.ai.chat.model.ChatResponse;
3333
import org.springframework.ai.chat.prompt.Prompt;
3434
import org.springframework.ai.chat.prompt.PromptTemplate;
@@ -109,9 +109,11 @@ public void createPlan(ExecutionContext context) {
109109
if (useMemory) {
110110
requestSpec
111111
.advisors(memoryAdvisor -> memoryAdvisor.param(CONVERSATION_ID, context.getMemoryId()));
112-
requestSpec.advisors(MessageChatMemoryAdvisor
113-
.builder(llmService.getConversationMemory(manusProperties.getMaxMemory()))
114-
.build());
112+
requestSpec.advisors(
113+
CustomMessageChatMemoryAdvisor
114+
.builder(llmService.getConversationMemory(manusProperties.getMaxMemory()),
115+
context.getUserRequest())
116+
.build());
115117
}
116118

117119
// Use streaming response handler for plan creation

spring-ai-alibaba-jmanus/src/main/java/com/alibaba/cloud/ai/example/manus/planning/finalizer/PlanFinalizer.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public void generateSummary(ExecutionContext context) {
112112
throw new RuntimeException("Failed to generate summary", e);
113113
}
114114
finally {
115-
// llmService.clearConversationMemory(context.getMemoryId());
115+
llmService.clearConversationMemory(context.getMemoryId());
116116
}
117117
}
118118

@@ -175,11 +175,6 @@ public void generateDirectResponse(ExecutionContext context) {
175175
log.error("Error generating direct response for request: {}", userRequest, e);
176176
throw new RuntimeException("Failed to generate direct response", e);
177177
}
178-
finally {
179-
if (context.getPlan() != null) {
180-
// llmService.clearConversationMemory(context.getMemoryId());
181-
}
182-
}
183178
}
184179

185180
}

0 commit comments

Comments
 (0)