1 package fr.paris.lutece.plugins.knowledge.service;
2
3 import dev.langchain4j.data.message.ChatMessage;
4 import dev.langchain4j.store.memory.chat.ChatMemoryStore;
5 import fr.paris.lutece.plugins.knowledge.business.Bot;
6 import fr.paris.lutece.plugins.knowledge.business.BotSession;
7 import fr.paris.lutece.plugins.knowledge.business.BotSessionHome;
8 import fr.paris.lutece.plugins.knowledge.rs.RequestData;
9 import fr.paris.lutece.portal.service.security.LuteceUser;
10 import fr.paris.lutece.portal.service.security.SecurityService;
11 import org.apache.commons.lang3.tuple.Pair;
12 import org.apache.commons.lang3.tuple.ImmutablePair;
13
14
15
16 import static dev.langchain4j.data.message.ChatMessageDeserializer.messagesFromJson;
17 import static dev.langchain4j.data.message.ChatMessageSerializer.messagesToJson;
18
19 import javax.servlet.http.HttpServletRequest;
20 import javax.servlet.http.HttpSession;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 public class ChatMemoryService
26 {
27 private static final String ATTRIBUTE_CHAT_MEMORY_MAP = "CHAT_MEMORY_MAP";
28
29
30
31
32
33
34
35
36
37
38
39 @SuppressWarnings( "unchecked" )
40 public static Pair<PersistentChatMemoryStore, String> getChatMemory(HttpServletRequest request, RequestData data, Bot bot, String sessionId ) {
41 LuteceUser luteceUser = SecurityService.getInstance().getRegisteredUser(request);
42 HttpSession session = request.getSession();
43 PersistentChatMemoryStore chatMemoryStore = null;
44
45 Map<String, PersistentChatMemoryStore> chatMemoryStoreMap = (Map<String, PersistentChatMemoryStore>) session.getAttribute(ATTRIBUTE_CHAT_MEMORY_MAP);
46
47 if (chatMemoryStoreMap == null) {
48 chatMemoryStoreMap = new HashMap<>();
49 session.setAttribute(ATTRIBUTE_CHAT_MEMORY_MAP, chatMemoryStoreMap);
50 }
51
52
53 if( data.getBotSessionId() != null ) {
54 chatMemoryStore = chatMemoryStoreMap.get( data.getBotSessionId() );
55 }
56
57 String botSessionId;
58
59 if (chatMemoryStore == null) {
60 if (data.getBotSessionId() != null) {
61 BotSession botSession = BotSessionHome.findByAccessCode( luteceUser.getAccessCode(), data.getBotSessionId() ).get();
62 chatMemoryStore = new PersistentChatMemoryStore();
63 chatMemoryStore.updateMessages(botSession.getSessionId(), messagesFromJson(botSession.getContent()));
64 chatMemoryStoreMap.put( botSession.getSessionId() , chatMemoryStore);
65 botSessionId = botSession.getSessionId();
66 } else {
67 BotSession botSession = createNewBotSession(bot, sessionId, luteceUser );
68 chatMemoryStore = new PersistentChatMemoryStore();
69 chatMemoryStoreMap.put(sessionId, chatMemoryStore);
70 botSessionId = botSession.getSessionId();
71 }
72 } else {
73 botSessionId = data.getBotSessionId();
74 }
75
76 return new ImmutablePair<>(chatMemoryStore, botSessionId);
77 }
78
79 private static BotSession createNewBotSession(Bot bot, String sessionId, LuteceUser luteceUser ) {
80 long timestamp = System.currentTimeMillis();
81 BotSessiondge/business/BotSession.html#BotSession">BotSession botSession = new BotSession();
82 botSession.setCreationDate(new java.sql.Date(timestamp));
83 botSession.setBotId(bot.getId());
84 botSession.setAccessCode( luteceUser.getAccessCode( ) );
85 botSession.setSessionId( sessionId );
86 return BotSessionHome.create(botSession);
87 }
88
89 static class PersistentChatMemoryStore implements ChatMemoryStore {
90 @Override
91 public List<ChatMessage> getMessages(Object memoryId) {
92
93 BotSession botSession = BotSessionHome.findBySessionId( (String) memoryId ).get( );
94 return messagesFromJson( botSession.getContent( ) );
95 }
96
97 @Override
98 public void updateMessages(Object memoryId, List<ChatMessage> messages) {
99
100 BotSession botSession = BotSessionHome.findBySessionId( (String) memoryId ).get( );
101 botSession.setContent( messagesToJson( messages ) );
102 BotSessionHome.update( botSession );
103 }
104
105 @Override
106 public void deleteMessages(Object memoryId) {
107 BotSessionHome.remove( (int) memoryId );
108 }
109 }
110
111 }