| | |
| | | |
| | | import com.vincent.rsf.server.ai.config.AiDefaults; |
| | | import com.vincent.rsf.server.ai.dto.AiResolvedConfig; |
| | | import com.vincent.rsf.server.ai.store.AiConfigCacheStore; |
| | | import com.vincent.rsf.server.ai.service.AiConfigResolverService; |
| | | import com.vincent.rsf.server.ai.service.AiMcpMountService; |
| | | import com.vincent.rsf.server.ai.service.AiParamService; |
| | |
| | | private final AiParamService aiParamService; |
| | | private final AiPromptService aiPromptService; |
| | | private final AiMcpMountService aiMcpMountService; |
| | | private final AiConfigCacheStore aiConfigCacheStore; |
| | | |
| | | /** |
| | | * 按租户解析一次完整的 AI 运行配置。 |
| | |
| | | */ |
| | | @Override |
| | | public AiResolvedConfig resolve(String promptCode, Long tenantId) { |
| | | return resolve(promptCode, tenantId, null); |
| | | } |
| | | |
| | | @Override |
| | | public AiResolvedConfig resolve(String promptCode, Long tenantId, Long aiParamId) { |
| | | if (tenantId == null) { |
| | | throw new CoolException("当前租户不存在"); |
| | | } |
| | | String finalPromptCode = StringUtils.hasText(promptCode) ? promptCode : AiDefaults.DEFAULT_PROMPT_CODE; |
| | | return AiResolvedConfig.builder() |
| | | // 配置解析是多个入口共享的热点路径,命中缓存时可以避免三张配置表的重复查询。 |
| | | AiResolvedConfig cached = aiConfigCacheStore.getResolvedConfig(tenantId, finalPromptCode, aiParamId); |
| | | if (cached != null) { |
| | | return cached; |
| | | } |
| | | AiResolvedConfig resolvedConfig = AiResolvedConfig.builder() |
| | | .promptCode(finalPromptCode) |
| | | .aiParam(aiParamService.getActiveParam(tenantId)) |
| | | .aiParam(aiParamService.getChatParam(tenantId, aiParamId)) |
| | | .prompt(aiPromptService.getActivePrompt(finalPromptCode, tenantId)) |
| | | .mcpMounts(aiMcpMountService.listActiveMounts(tenantId)) |
| | | .build(); |
| | | aiConfigCacheStore.cacheResolvedConfig(tenantId, finalPromptCode, aiParamId, resolvedConfig); |
| | | return resolvedConfig; |
| | | } |
| | | } |