package vip.mate.agent.prompt; import lombok.extern.slf4j.Slf4j; import org.springframework.util.StreamUtils; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.concurrent.ConcurrentHashMap; /** * Loads prompt text files from {@code classpath:/prompts/} with a thread-safe * lazy cache. * *

Single-language by design: prompts are written in the system's default * language and the LLM is trusted to follow the user's input language for * its output. The previous {@code loadPrompt(name, locale)} overload and * {@code prompts/{locale}/...} fallback chain were never wired up by any * caller and have been removed.

*/ @Slf4j public final class PromptLoader { private static final String PROMPT_PATH_PREFIX = "prompts/"; private static final ConcurrentHashMap promptCache = new ConcurrentHashMap<>(); private PromptLoader() {} /** * Load a prompt file's contents. * * @param promptName file name without the {@code prompts/} prefix or {@code .txt} suffix * (e.g. {@code "graph/summarize-system"}) * @return file text content * @throws RuntimeException when the file is missing or unreadable; the loader never * silently returns an empty string */ public static String loadPrompt(String promptName) { return promptCache.computeIfAbsent(promptName, PromptLoader::readPromptFile); } private static String readPromptFile(String name) { String fileName = PROMPT_PATH_PREFIX + name + ".txt"; try (InputStream inputStream = PromptLoader.class.getClassLoader().getResourceAsStream(fileName)) { if (inputStream == null) { throw new RuntimeException("Prompt file not found: " + fileName); } return StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8); } catch (IOException e) { log.error("Failed to load prompt: {}", e.getMessage(), e); throw new RuntimeException("Failed to load prompt: " + name, e); } } /** Drop the entire cache. Useful for tests and hot-reload tooling. */ public static void clearCache() { promptCache.clear(); } /** Number of prompts currently cached. */ public static int getCacheSize() { return promptCache.size(); } }