/*
* Copyright (C) 2025 Christian Schmitt, Tim Frey
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.iunera.druidmcpserver.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* Service for loading and processing prompt templates from properties files.
* Supports variable substitution and property overrides via Java system properties.
*/
@Service
public class PromptTemplateService {
private final Environment environment;
@Value("${mcp.prompts.watermark:Generated by Druid MCP Server}")
private String watermark;
@Value("${mcp.prompts.custom.organization-name:Your Organization}")
private String organizationName;
@Value("${mcp.prompts.custom.environment:production}")
private String environmentName;
@Value("${mcp.prompts.custom.contact-info:your-team@company.com}")
private String contactInfo;
public PromptTemplateService(Environment environment) {
this.environment = environment;
}
/**
* Load a prompt template and substitute variables
*
* @param templateKey The property key for the template (e.g., "prompts.druid-data-exploration.template")
* @param variables Map of variables to substitute in the template
* @return The processed template with variables substituted
*/
public String loadTemplate(String templateKey, Map<String, String> variables) {
String template = environment.getProperty(templateKey, "");
if (template.isEmpty()) {
throw new IllegalArgumentException("Template not found for key: " + templateKey);
}
// Create a combined map with default variables and provided variables
Map<String, String> allVariables = new HashMap<>();
allVariables.put("watermark", watermark);
allVariables.put("organizationName", organizationName);
allVariables.put("environment", environmentName);
allVariables.put("contactInfo", contactInfo);
// Override with provided variables
if (variables != null) {
allVariables.putAll(variables);
}
// Substitute variables in the template
String result = template;
for (Map.Entry<String, String> entry : allVariables.entrySet()) {
String placeholder = "{" + entry.getKey() + "}";
String value = entry.getValue() != null ? entry.getValue() : "";
result = result.replace(placeholder, value);
}
// Convert \n to actual newlines
result = result.replace("\\n", "\n");
return result;
}
/**
* Load a template section (like conditional sections)
*
* @param sectionKey The property key for the section
* @param variables Map of variables to substitute
* @return The processed section
*/
public String loadSection(String sectionKey, Map<String, String> variables) {
String section = environment.getProperty(sectionKey, "");
if (section.isEmpty()) {
return "";
}
// Substitute variables
String result = section;
if (variables != null) {
for (Map.Entry<String, String> entry : variables.entrySet()) {
String placeholder = "{" + entry.getKey() + "}";
String value = entry.getValue() != null ? entry.getValue() : "";
result = result.replace(placeholder, value);
}
}
// Convert \n to actual newlines
result = result.replace("\\n", "\n");
return result;
}
/**
* Convenience method to create a variables map
*/
public Map<String, String> createVariables() {
return new HashMap<>();
}
/**
* Convenience method to add a variable to the map
*/
public Map<String, String> addVariable(Map<String, String> variables, String key, String value) {
if (value != null && !value.isEmpty()) {
variables.put(key, value);
}
return variables;
}
}