Function bodies 269 total
getAgentNames method · java · L82-L86 (5 LOC)src/main/java/com/matoe/service/DynamicPromptService.java
public Set<String> getAgentNames() {
Set<String> names = new TreeSet<>(yamlDefaults.keySet());
promptRepo.findByActiveTrueOrderByAgentName().forEach(e -> names.add(e.getAgentName()));
return names;
}LlmCostTrackingService class · java · L18-L124 (107 LOC)src/main/java/com/matoe/service/LlmCostTrackingService.java
public class LlmCostTrackingService {
private static final Logger log = LoggerFactory.getLogger(LlmCostTrackingService.class);
// Approximate per-token costs (USD) by provider — updated periodically
private static final Map<String, double[]> TOKEN_COSTS = Map.of(
"claude-3-5-sonnet", new double[]{0.000003, 0.000015}, // input, output per token
"claude-3-opus", new double[]{0.000015, 0.000075},
"claude-3-haiku", new double[]{0.00000025, 0.00000125},
"gpt-4o", new double[]{0.000005, 0.000015},
"gpt-4o-mini", new double[]{0.00000015, 0.0000006},
"llama-3-8b", new double[]{0.0, 0.0}, // local = free
"mistral-7b", new double[]{0.0, 0.0},
"default", new double[]{0.000003, 0.000015}
);
private final LlmCostLogRepository costLogRepository;
@Value("${travel-agency.cost-tracking.per-session-budget-usd:2.00}")
private double perSessiLlmCostTrackingService method · java · L42-L44 (3 LOC)src/main/java/com/matoe/service/LlmCostTrackingService.java
public LlmCostTrackingService(LlmCostLogRepository costLogRepository) {
this.costLogRepository = costLogRepository;
}logCall method · java · L46-L64 (19 LOC)src/main/java/com/matoe/service/LlmCostTrackingService.java
public void logCall(String sessionId, String agentName, String model, String provider,
int inputTokens, int outputTokens, long durationMs, boolean success, String error) {
double cost = estimateCost(model, inputTokens, outputTokens);
LlmCostLogEntity entry = new LlmCostLogEntity();
entry.setSessionId(sessionId);
entry.setAgentName(agentName);
entry.setModel(model);
entry.setProvider(provider);
entry.setInputTokens(inputTokens);
entry.setOutputTokens(outputTokens);
entry.setEstimatedCost(cost);
entry.setDurationMs(durationMs);
entry.setSuccess(success);
entry.setErrorMessage(error);
costLogRepository.save(entry);
if (sessionId != null) checkBudget(sessionId, cost);
}isBudgetExceeded method · java · L66-L70 (5 LOC)src/main/java/com/matoe/service/LlmCostTrackingService.java
public boolean isBudgetExceeded(String sessionId) {
if (sessionId == null) return false;
Double total = costLogRepository.sumCostBySessionId(sessionId);
return total != null && total >= perSessionBudgetUsd;
}getSessionCostSummary method · java · L72-L81 (10 LOC)src/main/java/com/matoe/service/LlmCostTrackingService.java
public Map<String, Object> getSessionCostSummary(String sessionId) {
Double total = costLogRepository.sumCostBySessionId(sessionId);
List<LlmCostLogEntity> entries = costLogRepository.findBySessionIdOrderByCreatedAt(sessionId);
return Map.of(
"sessionId", sessionId,
"totalCostUsd", total != null ? total : 0.0,
"budgetUsd", perSessionBudgetUsd,
"callCount", entries.size()
);
}getCostDashboard method · java · L83-L105 (23 LOC)src/main/java/com/matoe/service/LlmCostTrackingService.java
public Map<String, Object> getCostDashboard(int lastHours) {
LocalDateTime since = LocalDateTime.now().minusHours(lastHours);
Double totalCost = costLogRepository.sumCostSince(since);
List<Object[]> byAgent = costLogRepository.costBreakdownByAgentSince(since);
List<Object[]> byModel = costLogRepository.costBreakdownByModelSince(since);
List<Map<String, Object>> agentBreakdown = new ArrayList<>();
for (Object[] row : byAgent) {
agentBreakdown.add(Map.of("agent", row[0], "calls", row[1], "cost", row[2]));
}
List<Map<String, Object>> modelBreakdown = new ArrayList<>();
for (Object[] row : byModel) {
modelBreakdown.add(Map.of("model", row[0], "calls", row[1],
"inputTokens", row[2], "outputTokens", row[3], "cost", row[4]));
}
return Map.of(
"periodHours", lastHours,
"totalCostUsd", totalCost != null ? totalCost : 0.0,
"byAgSource: Repobility analyzer · https://repobility.com
estimateCost method · java · L107-L112 (6 LOC)src/main/java/com/matoe/service/LlmCostTrackingService.java
private double estimateCost(String model, int inputTokens, int outputTokens) {
String key = TOKEN_COSTS.keySet().stream()
.filter(k -> model.toLowerCase().contains(k)).findFirst().orElse("default");
double[] rates = TOKEN_COSTS.get(key);
return (inputTokens * rates[0]) + (outputTokens * rates[1]);
}checkBudget method · java · L114-L123 (10 LOC)src/main/java/com/matoe/service/LlmCostTrackingService.java
private void checkBudget(String sessionId, double addedCost) {
Double total = costLogRepository.sumCostBySessionId(sessionId);
if (total == null) return;
double pct = (total / perSessionBudgetUsd) * 100;
if (pct >= 100) {
log.warn("Session {} EXCEEDED budget: ${} / ${}", sessionId, total, perSessionBudgetUsd);
} else if (pct >= warnAtPercent) {
log.warn("Session {} approaching budget: ${} / ${} ({}%)", sessionId, total, perSessionBudgetUsd, (int) pct);
}
}LlmService function · java · L58-L61 (4 LOC)src/main/java/com/matoe/service/LlmService.java
public LlmService(WebClient.Builder webClientBuilder, ObjectMapper objectMapper) {
this.webClient = webClientBuilder.build();
this.objectMapper = objectMapper;
}call function · java · L71-L99 (29 LOC)src/main/java/com/matoe/service/LlmService.java
public String call(String modelString, String systemPrompt, String userPrompt) {
if (modelString == null || modelString.isBlank()) {
modelString = "anthropic/" + defaultAnthropicModel;
}
if (modelString.startsWith("anthropic/")) {
return callAnthropic(resolveAnthropicModel(modelString), systemPrompt, userPrompt);
} else if (modelString.startsWith("lmstudio/")) {
return callOpenAiCompatible(
stripPrefix(modelString), lmStudioUrl, null,
systemPrompt, userPrompt, "LM Studio"
);
} else if (modelString.startsWith("ollama/")) {
return callOpenAiCompatible(
stripPrefix(modelString), ollamaUrl, null,
systemPrompt, userPrompt, "Ollama"
);
} else if (modelString.startsWith("openrouter/")) {
// "openrouter/openai/gpt-4o" → model = "openai/gpt-4o"
String model = modelString.substring("opecallAnthropic function · java · L103-L141 (39 LOC)src/main/java/com/matoe/service/LlmService.java
private String callAnthropic(String model, String systemPrompt, String userPrompt) {
try {
Map<String, Object> body = new LinkedHashMap<>();
body.put("model", model);
body.put("max_tokens", 4096);
body.put("system", systemPrompt != null ? systemPrompt : "");
body.put("messages", List.of(Map.of("role", "user", "content", userPrompt)));
log.debug("Calling Anthropic with model={}", model);
Map<?, ?> response = webClient.post()
.uri(anthropicBaseUrl + "/v1/messages")
.header("x-api-key", anthropicApiKey)
.header("anthropic-version", anthropicVersion)
.header("content-type", "application/json")
.bodyValue(body)
.retrieve()
.onStatus(
status -> !status.is2xxSuccessful(),
r -> r.bodyToMono(String.class)
.flatMap(err -> MocallOpenAiCompatible function · java · L143-L192 (50 LOC)src/main/java/com/matoe/service/LlmService.java
private String callOpenAiCompatible(
String model, String baseUrl, String apiKey,
String systemPrompt, String userPrompt, String label) {
try {
Map<String, Object> body = new LinkedHashMap<>();
body.put("model", model);
body.put("messages", List.of(
Map.of("role", "system", "content", systemPrompt != null ? systemPrompt : ""),
Map.of("role", "user", "content", userPrompt != null ? userPrompt : "")
));
body.put("max_tokens", 4096);
body.put("temperature", 0.7);
log.debug("Calling {} at {} with model={}", label, baseUrl, model);
var req = webClient.post()
.uri(baseUrl + "/chat/completions")
.header("content-type", "application/json");
if (apiKey != null && !apiKey.isBlank()) {
req = req.header("authorization", "Bearer " + apiKey);
}
Map<?resolveAnthropicModel function · java · L197-L206 (10 LOC)src/main/java/com/matoe/service/LlmService.java
String resolveAnthropicModel(String modelString) {
String lower = modelString.toLowerCase();
if (lower.contains("opus-4-6") || lower.contains("opus4")) return "claude-opus-4-6";
if (lower.contains("sonnet-4-6") || lower.contains("sonnet4")) return "claude-sonnet-4-6";
if (lower.contains("haiku-4-5") || lower.contains("haiku4")) return "claude-haiku-4-5-20251001";
if (lower.contains("3-5-sonnet")) return "claude-3-5-sonnet-20241022";
if (lower.contains("3-opus")) return "claude-3-opus-20240229";
if (lower.contains("3-haiku")) return "claude-3-haiku-20240307";
return defaultAnthropicModel;
}stripPrefix function · java · L209-L212 (4 LOC)src/main/java/com/matoe/service/LlmService.java
String stripPrefix(String modelString) {
int slash = modelString.indexOf('/');
return slash >= 0 ? modelString.substring(slash + 1) : modelString;
}Repobility analyzer · published findings · https://repobility.com
extractJson function · java · L215-L219 (5 LOC)src/main/java/com/matoe/service/LlmService.java
public String extractJson(String raw) {
if (raw == null) return null;
Matcher m = JSON_FENCE.matcher(raw);
return m.find() ? m.group(1).trim() : raw.trim();
}parseJson function · java · L222-L224 (3 LOC)src/main/java/com/matoe/service/LlmService.java
public <T> T parseJson(String json, Class<T> targetClass) throws Exception {
return objectMapper.readValue(json, targetClass);
}PdfExportService class · java · L33-L205 (173 LOC)src/main/java/com/matoe/service/PdfExportService.java
public class PdfExportService {
private static final DeviceRgb HEADING_COLOR = new DeviceRgb(30, 64, 175);
private static final DeviceRgb MUTED_COLOR = new DeviceRgb(100, 116, 139);
private static final DeviceRgb WARNING_COLOR = new DeviceRgb(180, 83, 9);
public byte[] render(UnforgettableItinerary itinerary) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (PdfWriter writer = new PdfWriter(baos);
PdfDocument pdf = new PdfDocument(writer);
Document doc = new Document(pdf)) {
renderCover(doc, itinerary);
renderInsights(doc, itinerary);
renderAccommodations(doc, itinerary.accommodations());
renderTransport(doc, itinerary.transport());
renderVariants(doc, itinerary.variants());
renderAttractions(doc, itinerary.attractions());
} catch (Exception e) {
throw new RuntimeException("PDF render failed: " + e.getMessage(), e);
render method · java · L39-L55 (17 LOC)src/main/java/com/matoe/service/PdfExportService.java
public byte[] render(UnforgettableItinerary itinerary) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (PdfWriter writer = new PdfWriter(baos);
PdfDocument pdf = new PdfDocument(writer);
Document doc = new Document(pdf)) {
renderCover(doc, itinerary);
renderInsights(doc, itinerary);
renderAccommodations(doc, itinerary.accommodations());
renderTransport(doc, itinerary.transport());
renderVariants(doc, itinerary.variants());
renderAttractions(doc, itinerary.attractions());
} catch (Exception e) {
throw new RuntimeException("PDF render failed: " + e.getMessage(), e);
}
return baos.toByteArray();
}renderCover method · java · L59-L73 (15 LOC)src/main/java/com/matoe/service/PdfExportService.java
private void renderCover(Document doc, UnforgettableItinerary it) {
doc.add(new Paragraph("M.A.T.O.E — Unforgettable Itinerary")
.setFontSize(10).setFontColor(MUTED_COLOR));
doc.add(new Paragraph(it.destination())
.setFontSize(32).setFontColor(HEADING_COLOR).setBold());
doc.add(new Paragraph(it.startDate() + " → " + it.endDate())
.setFontSize(14).setFontColor(MUTED_COLOR));
doc.add(new Paragraph(it.guestCount() + " guest(s) · est. total €" +
String.format("%.0f", it.totalEstimatedCost())));
if (it.createdAt() != null) {
doc.add(new Paragraph("Generated " + it.createdAt())
.setFontSize(9).setFontColor(MUTED_COLOR));
}
doc.add(new Paragraph("\n"));
}renderInsights method · java · L75-L80 (6 LOC)src/main/java/com/matoe/service/PdfExportService.java
private void renderInsights(Document doc, UnforgettableItinerary it) {
heading(doc, "Destination Intelligence");
appendMap(doc, "Regional insights", it.regionInsights());
appendMap(doc, "Weather forecast", it.weatherForecast());
appendMap(doc, "Currency", it.currencyInfo());
}renderAccommodations method · java · L82-L97 (16 LOC)src/main/java/com/matoe/service/PdfExportService.java
private void renderAccommodations(Document doc, List<AccommodationOption> list) {
if (list == null || list.isEmpty()) return;
heading(doc, "Accommodations");
Table t = new Table(UnitValue.createPercentArray(new float[]{3, 2, 2, 1, 2, 1}))
.useAllAvailableWidth();
headerRow(t, "Name", "Location", "Type", "Tier", "Per night", "Source");
for (AccommodationOption a : list) {
t.addCell(cell(a.name()));
t.addCell(cell(a.location()));
t.addCell(cell(a.type()));
t.addCell(cell(a.tier()));
t.addCell(cell("€" + String.format("%.0f", a.pricePerNight())));
t.addCell(sourceCell(a.source()));
}
doc.add(t);
}renderTransport method · java · L99-L115 (17 LOC)src/main/java/com/matoe/service/PdfExportService.java
private void renderTransport(Document doc, List<TransportOption> list) {
if (list == null || list.isEmpty()) return;
heading(doc, "Transport");
Table t = new Table(UnitValue.createPercentArray(new float[]{2, 2, 3, 2, 1, 1}))
.useAllAvailableWidth();
headerRow(t, "Type", "Provider", "Origin → Destination", "Duration", "Price", "Source");
for (TransportOption tr : list) {
t.addCell(cell(tr.type()));
t.addCell(cell(tr.provider()));
t.addCell(cell((tr.origin() != null ? tr.origin() : "?") + " → "
+ (tr.destination() != null ? tr.destination() : "?")));
t.addCell(cell(tr.duration()));
t.addCell(cell("€" + String.format("%.0f", tr.price())));
t.addCell(sourceCell(tr.source()));
}
doc.add(t);
}Repobility · MCP-ready · https://repobility.com
renderVariants method · java · L117-L148 (32 LOC)src/main/java/com/matoe/service/PdfExportService.java
private void renderVariants(Document doc, List<ItineraryVariant> variants) {
if (variants == null || variants.isEmpty()) return;
heading(doc, "3-Tier Variants");
for (ItineraryVariant v : variants) {
doc.add(new Paragraph(safe(v.tier()).toUpperCase() + " — €"
+ String.format("%.0f", v.totalEstimatedCost()))
.setFontSize(14).setFontColor(HEADING_COLOR).setBold());
if (v.highlights() != null && !v.highlights().isEmpty()) {
doc.add(new Paragraph("Highlights: " + String.join(", ", v.highlights())));
}
if (v.tradeoffs() != null && !v.tradeoffs().isBlank()) {
doc.add(new Paragraph("Trade-offs: " + v.tradeoffs()).setFontColor(MUTED_COLOR));
}
if (v.dayByDay() != null) {
for (ItineraryDay d : v.dayByDay()) {
doc.add(new Paragraph(" Day " + d.dayNumber() + " — " + safe(d.date())
renderAttractions method · java · L150-L164 (15 LOC)src/main/java/com/matoe/service/PdfExportService.java
private void renderAttractions(Document doc, List<AttractionOption> list) {
if (list == null || list.isEmpty()) return;
heading(doc, "Attractions & Experiences");
for (AttractionOption a : list) {
doc.add(new Paragraph(safe(a.name())).setBold());
doc.add(new Paragraph(safe(a.description())).setFontColor(MUTED_COLOR));
doc.add(new Paragraph(String.format(" %s · €%.0f · %s · %s",
safe(a.category()), a.price(), safe(a.duration()), safe(a.location())))
.setFontSize(10));
if ("llm".equalsIgnoreCase(a.source())) {
doc.add(new Paragraph(" (AI-generated estimate — verify before booking)")
.setFontSize(9).setFontColor(WARNING_COLOR));
}
}
}heading method · java · L168-L170 (3 LOC)src/main/java/com/matoe/service/PdfExportService.java
private void heading(Document doc, String text) {
doc.add(new Paragraph(text).setFontSize(18).setFontColor(HEADING_COLOR).setBold());
}headerRow method · java · L172-L177 (6 LOC)src/main/java/com/matoe/service/PdfExportService.java
private void headerRow(Table t, String... cols) {
for (String c : cols) {
t.addHeaderCell(new Cell().add(new Paragraph(c).setBold())
.setBackgroundColor(new DeviceRgb(241, 245, 249)));
}
}cell method · java · L179-L181 (3 LOC)src/main/java/com/matoe/service/PdfExportService.java
private Cell cell(String s) {
return new Cell().add(new Paragraph(safe(s)).setFontSize(10));
}sourceCell method · java · L183-L191 (9 LOC)src/main/java/com/matoe/service/PdfExportService.java
private Cell sourceCell(String source) {
Cell c = new Cell().add(new Paragraph(safe(source)).setFontSize(9));
if ("llm".equalsIgnoreCase(source)) {
c.setFontColor(WARNING_COLOR);
} else if ("browser".equalsIgnoreCase(source)) {
c.setFontColor(ColorConstants.DARK_GRAY);
}
return c.setTextAlignment(TextAlignment.CENTER);
}appendMap method · java · L193-L197 (5 LOC)src/main/java/com/matoe/service/PdfExportService.java
private void appendMap(Document doc, String label, Map<String, Object> map) {
if (map == null || map.isEmpty()) return;
doc.add(new Paragraph(label + ":").setBold());
map.forEach((k, v) -> doc.add(new Paragraph(" " + k + ": " + v).setFontSize(10)));
}line method · java · L199-L202 (4 LOC)src/main/java/com/matoe/service/PdfExportService.java
private void line(Document doc, String label, String value) {
if (value == null || value.isBlank()) return;
doc.add(new Paragraph(label + ": " + value).setFontSize(10));
}Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
PromptTemplateService class · java · L15-L175 (161 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
public class PromptTemplateService {
/**
* Build a user prompt for hotel search by substituting variables into the template.
*/
public String buildHotelPrompt(String template, TravelRequest request) {
long nights = calculateNights(request);
Map<String, String> variables = buildBaseVariables(request, nights);
variables.put("nights", String.valueOf(nights));
return substituteVariables(template, variables);
}
/**
* Build a user prompt for B&B search.
*/
public String buildBBPrompt(String template, TravelRequest request) {
long nights = calculateNights(request);
Map<String, String> variables = buildBaseVariables(request, nights);
variables.put("nights", String.valueOf(nights));
return substituteVariables(template, variables);
}
/**
* Build a user prompt for apartment search.
*/
public String buildApartmentPrompt(String template, TravelRequest request) {
lbuildHotelPrompt method · java · L20-L25 (6 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
public String buildHotelPrompt(String template, TravelRequest request) {
long nights = calculateNights(request);
Map<String, String> variables = buildBaseVariables(request, nights);
variables.put("nights", String.valueOf(nights));
return substituteVariables(template, variables);
}buildBBPrompt method · java · L30-L35 (6 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
public String buildBBPrompt(String template, TravelRequest request) {
long nights = calculateNights(request);
Map<String, String> variables = buildBaseVariables(request, nights);
variables.put("nights", String.valueOf(nights));
return substituteVariables(template, variables);
}buildApartmentPrompt method · java · L40-L46 (7 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
public String buildApartmentPrompt(String template, TravelRequest request) {
long nights = calculateNights(request);
Map<String, String> variables = buildBaseVariables(request, nights);
variables.put("nights", String.valueOf(nights));
variables.put("guestCount", String.valueOf(request.guestCount()));
return substituteVariables(template, variables);
}buildHostelPrompt method · java · L51-L56 (6 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
public String buildHostelPrompt(String template, TravelRequest request) {
long nights = calculateNights(request);
Map<String, String> variables = buildBaseVariables(request, nights);
variables.put("nights", String.valueOf(nights));
return substituteVariables(template, variables);
}buildFlightPrompt method · java · L61-L67 (7 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
public String buildFlightPrompt(String template, TravelRequest request) {
Map<String, String> variables = buildBaseVariables(request, 0);
variables.put("guestCount", String.valueOf(request.guestCount()));
variables.put("maxBudget", String.format("%.2f", request.budgetMax()));
variables.put("originCity", request.originCity() != null ? request.originCity() : "nearest major airport");
return substituteVariables(template, variables);
}buildCarBusPrompt method · java · L72-L79 (8 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
public String buildCarBusPrompt(String template, TravelRequest request) {
long days = calculateNights(request);
Map<String, String> variables = buildBaseVariables(request, days);
variables.put("days", String.valueOf(days));
variables.put("guestCount", String.valueOf(request.guestCount()));
variables.put("maxBudget", String.format("%.2f", request.budgetMax()));
return substituteVariables(template, variables);
}buildTrainPrompt method · java · L82-L88 (7 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
public String buildTrainPrompt(String template, TravelRequest request) {
Map<String, String> variables = buildBaseVariables(request, calculateNights(request));
variables.put("days", String.valueOf(calculateNights(request)));
variables.put("guestCount", String.valueOf(request.guestCount()));
variables.put("maxBudget", String.format("%.2f", request.budgetMax()));
return substituteVariables(template, variables);
}Source: Repobility analyzer · https://repobility.com
buildFerryPrompt method · java · L91-L95 (5 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
public String buildFerryPrompt(String template, TravelRequest request) {
Map<String, String> variables = buildBaseVariables(request, calculateNights(request));
variables.put("guestCount", String.valueOf(request.guestCount()));
return substituteVariables(template, variables);
}buildAttractionsPrompt method · java · L98-L105 (8 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
public String buildAttractionsPrompt(String template, TravelRequest request) {
long nights = calculateNights(request);
Map<String, String> variables = buildBaseVariables(request, nights);
variables.put("nights", String.valueOf(nights));
variables.put("interestTags", request.interestTags() != null ?
String.join(", ", request.interestTags()) : "general sightseeing");
return substituteVariables(template, variables);
}buildWeatherPrompt method · java · L108-L111 (4 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
public String buildWeatherPrompt(String template, TravelRequest request) {
Map<String, String> variables = buildBaseVariables(request, 0);
return substituteVariables(template, variables);
}buildCurrencyPrompt method · java · L114-L118 (5 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
public String buildCurrencyPrompt(String template, TravelRequest request) {
Map<String, String> variables = new HashMap<>();
variables.put("destination", request.destination());
return substituteVariables(template, variables);
}buildReviewPrompt method · java · L121-L125 (5 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
public String buildReviewPrompt(String template, TravelRequest request) {
Map<String, String> variables = new HashMap<>();
variables.put("destination", request.destination());
return substituteVariables(template, variables);
}buildCountrySpecialistPrompt method · java · L128-L133 (6 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
public String buildCountrySpecialistPrompt(String template, TravelRequest request) {
Map<String, String> variables = new HashMap<>();
variables.put("destination", request.destination());
variables.put("travelStyle", request.travelStyle());
return substituteVariables(template, variables);
}substituteVariables method · java · L138-L145 (8 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
private String substituteVariables(String template, Map<String, String> variables) {
String result = template;
for (Map.Entry<String, String> entry : variables.entrySet()) {
String placeholder = "{{" + entry.getKey() + "}}";
result = result.replace(placeholder, entry.getValue());
}
return result;
}calculateNights method · java · L150-L153 (4 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
private long calculateNights(TravelRequest request) {
long nights = ChronoUnit.DAYS.between(request.startDate(), request.endDate());
return nights > 0 ? nights : 1;
}Repobility analyzer · published findings · https://repobility.com
buildBaseVariables method · java · L158-L174 (17 LOC)src/main/java/com/matoe/service/PromptTemplateService.java
private Map<String, String> buildBaseVariables(TravelRequest request, long nights) {
Map<String, String> vars = new HashMap<>();
vars.put("destination", request.destination());
vars.put("startDate", request.startDate().toString());
vars.put("endDate", request.endDate().toString());
vars.put("guestCount", String.valueOf(request.guestCount()));
vars.put("budgetMin", String.format("%.2f", request.budgetMin()));
vars.put("budgetMax", String.format("%.2f", request.budgetMax()));
vars.put("travelStyle", request.travelStyle());
vars.put("originCity", request.originCity() != null ? request.originCity() : "");
vars.put("interestTags", request.interestTags() != null ?
String.join(", ", request.interestTags()) : "");
if (nights > 0) {
vars.put("nights", String.valueOf(nights));
}
return vars;
}SearchTargetService class · java · L27-L109 (83 LOC)src/main/java/com/matoe/service/SearchTargetService.java
public class SearchTargetService {
private static final Logger log = LoggerFactory.getLogger(SearchTargetService.class);
private final SearchTargetRepository searchTargetRepo;
/** Rolling request counters keyed by site URL. Value is (windowStartMs, count). */
private final Map<String, long[]> counters = new ConcurrentHashMap<>();
/** Global fallback limit when a YAML-only site has no DB row. */
private static final int DEFAULT_RPM_LIMIT = 30;
public SearchTargetService(SearchTargetRepository searchTargetRepo) {
this.searchTargetRepo = searchTargetRepo;
}
/**
* Get active sites for an agent. Returns DB-configured sites if any exist,
* otherwise falls back to the YAML default. In both cases, sites whose
* {@code rateLimitRpm} budget has been exhausted in the current 60s window
* are filtered out.
*
* @param agentName e.g. "hotel-agent"
* @param yamlDefault comma-separated default from {@code @Value}
SearchTargetService method · java · L38-L40 (3 LOC)src/main/java/com/matoe/service/SearchTargetService.java
public SearchTargetService(SearchTargetRepository searchTargetRepo) {
this.searchTargetRepo = searchTargetRepo;
}