package com.vincent.rsf.server.ai.service.impl;
|
|
import com.vincent.rsf.server.ai.config.AiDefaults;
|
import com.vincent.rsf.server.ai.dto.AiChatMemoryDto;
|
import com.vincent.rsf.server.ai.dto.AiChatModelOptionDto;
|
import com.vincent.rsf.server.ai.dto.AiChatRequest;
|
import com.vincent.rsf.server.ai.dto.AiChatRuntimeDto;
|
import com.vincent.rsf.server.ai.dto.AiChatSessionDto;
|
import com.vincent.rsf.server.ai.dto.AiChatSessionPinRequest;
|
import com.vincent.rsf.server.ai.dto.AiChatSessionRenameRequest;
|
import com.vincent.rsf.server.ai.dto.AiResolvedConfig;
|
import com.vincent.rsf.server.ai.service.AiChatMemoryService;
|
import com.vincent.rsf.server.ai.service.AiChatService;
|
import com.vincent.rsf.server.ai.service.AiConfigResolverService;
|
import com.vincent.rsf.server.ai.service.AiParamService;
|
import com.vincent.rsf.server.ai.service.impl.chat.AiChatOrchestrator;
|
import com.vincent.rsf.server.ai.service.impl.chat.AiChatRuntimeAssembler;
|
import com.vincent.rsf.server.ai.store.AiConversationCacheStore;
|
import lombok.RequiredArgsConstructor;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.stereotype.Service;
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
|
import java.util.List;
|
import java.util.Objects;
|
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.Executor;
|
|
@Service
|
@RequiredArgsConstructor
|
public class AiChatServiceImpl implements AiChatService {
|
|
private final AiConfigResolverService aiConfigResolverService;
|
private final AiChatMemoryService aiChatMemoryService;
|
private final AiParamService aiParamService;
|
private final AiConversationCacheStore aiConversationCacheStore;
|
private final AiChatRuntimeAssembler aiChatRuntimeAssembler;
|
private final AiChatOrchestrator aiChatOrchestrator;
|
@Qualifier("aiChatTaskExecutor")
|
private final Executor aiChatTaskExecutor;
|
|
@Override
|
public AiChatRuntimeDto getRuntime(String promptCode, Long sessionId, Long aiParamId, Long userId, Long tenantId) {
|
AiResolvedConfig config = aiConfigResolverService.resolve(promptCode, tenantId, aiParamId);
|
AiChatRuntimeDto cached = aiConversationCacheStore.getRuntime(tenantId, userId, config.getPromptCode(), sessionId, aiParamId);
|
if (cached != null) {
|
return cached;
|
}
|
AiChatMemoryDto memory = aiChatMemoryService.getMemory(userId, tenantId, config.getPromptCode(), sessionId);
|
List<AiChatModelOptionDto> modelOptions = aiParamService.listChatModelOptions(tenantId);
|
AiChatRuntimeDto runtime = aiChatRuntimeAssembler.buildRuntimeSnapshot(
|
null,
|
memory.getSessionId(),
|
config,
|
modelOptions,
|
config.getMcpMounts().size(),
|
config.getMcpMounts().stream().map(item -> item.getName()).toList(),
|
List.of(),
|
memory
|
);
|
aiConversationCacheStore.cacheRuntime(tenantId, userId, config.getPromptCode(), sessionId, aiParamId, runtime);
|
if (memory.getSessionId() != null && !Objects.equals(memory.getSessionId(), sessionId)) {
|
aiConversationCacheStore.cacheRuntime(tenantId, userId, config.getPromptCode(), memory.getSessionId(), aiParamId, runtime);
|
}
|
return runtime;
|
}
|
|
@Override
|
public List<AiChatSessionDto> listSessions(String promptCode, String keyword, Long userId, Long tenantId) {
|
AiResolvedConfig config = aiConfigResolverService.resolve(promptCode, tenantId);
|
return aiChatMemoryService.listSessions(userId, tenantId, config.getPromptCode(), keyword);
|
}
|
|
@Override
|
public SseEmitter stream(AiChatRequest request, Long userId, Long tenantId) {
|
SseEmitter emitter = new SseEmitter(AiDefaults.SSE_TIMEOUT_MS);
|
CompletableFuture.runAsync(() -> aiChatOrchestrator.executeStream(request, userId, tenantId, emitter), aiChatTaskExecutor);
|
return emitter;
|
}
|
|
@Override
|
public void removeSession(Long sessionId, Long userId, Long tenantId) {
|
aiChatMemoryService.removeSession(userId, tenantId, sessionId);
|
}
|
|
@Override
|
public AiChatSessionDto renameSession(Long sessionId, AiChatSessionRenameRequest request, Long userId, Long tenantId) {
|
return aiChatMemoryService.renameSession(userId, tenantId, sessionId, request);
|
}
|
|
@Override
|
public AiChatSessionDto pinSession(Long sessionId, AiChatSessionPinRequest request, Long userId, Long tenantId) {
|
return aiChatMemoryService.pinSession(userId, tenantId, sessionId, request);
|
}
|
|
@Override
|
public void clearSessionMemory(Long sessionId, Long userId, Long tenantId) {
|
aiChatMemoryService.clearSessionMemory(userId, tenantId, sessionId);
|
}
|
|
@Override
|
public void retainLatestRound(Long sessionId, Long userId, Long tenantId) {
|
aiChatMemoryService.retainLatestRound(userId, tenantId, sessionId);
|
}
|
}
|