Files
GerbilManager/GerbilManagerWebAPI/SaleAd/SaleAdPromptBuilder.cs

108 lines
5.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Globalization;
using System.Text;
namespace GerbilManagerWebAPI.SaleAd
{
/// <summary>
/// FEAT-12a: assembles the German prompt for the sale-ad (Abgabe-Inserat)
/// generation. Style and rules follow the breeder's real Jimdo listings
/// (analysed in hive/agents/god/FEAT12-jimdo-publish-research.md):
/// group-based listings, status line, bold emotive tagline, per-animal
/// Farbschlag + "geboren am DD.MM.YYYY" + personality prose, NO PRICES.
/// </summary>
public static class SaleAdPromptBuilder
{
/// <summary>
/// Two few-shot examples derived from the documented listing template.
/// NOTE: the research file documents the format and one real tagline;
/// these examples are synthesized to that template. Swap in verbatim
/// listings from kleine-chaoten.jimdofree.com when available.
/// </summary>
private const string ExampleListing1 = """
Status: FREI
Großer und kleiner Bruder Dynamik Männliches Rennmaus-Duo sucht ein liebevolles Zuhause
Balu CP-Agouti, geboren am 12.03.2024
Balu ist der ruhige Pol des Duos: Er beobachtet erst in aller Seelenruhe und buddelt sich dann zielstrebig durch jedes Einstreu-Projekt. Aus der Hand nimmt er Leckerlis schon ganz vorsichtig.
Benny Schwarz Schecke, geboren am 12.03.2024
Benny ist der Entdecker: kein Röhrchen bleibt unerforscht, kein Häuschen unbewohnt. Mit seinem Bruder kuschelt er sich abends ins Nest getrennt werden die beiden deshalb nicht.
Die zwei werden nur gemeinsam in ein rennmausgerechtes Zuhause abgegeben.
""";
private const string ExampleListing2 = """
Status: LOCKER RESERVIERT Anna
Zwei Schwestern, ein Herz und ganz viel Neugier Weibliches Duo sucht seine Menschen
Frieda Gold, geboren am 28.06.2024
Frieda ist die Mutige der beiden und steht beim Öffnen des Geheges sofort am Glas. Sie liebt Kolbenhirse und nimmt sie dir behutsam aus den Fingern.
Fine Agouti, geboren am 28.06.2024
Fine ist etwas zurückhaltender, taut aber neben ihrer Schwester schnell auf. Beim abendlichen Buddeln sind die zwei ein unschlagbares Team.
Die Schwestern ziehen selbstverständlich nur zusammen um.
""";
/// <summary>System prompt: role, style description, hard rules, few-shot examples.</summary>
public static string BuildSystemPrompt() => $"""
Du schreibst Abgabe-Inserate für Mongolische Rennmäuse im Stil der „Zucht der kleinen Chaoten“.
Stil und Aufbau (verbindlich):
- Erste Zeile: die Status-Zeile, exakt wie vorgegeben (z. B. „Status: FREI“).
- Danach eine fette, emotionale Überschrift (Tagline) in Anführungszeichen mit kurzem Untertitel, die den Charakter der Gruppe einfängt.
- Danach pro Tier ein Absatz: Name Farbschlag, geboren am TT.MM.JJJJ, gefolgt von warmherziger Persönlichkeits-Prosa auf Basis der mitgelieferten Notizen.
- Abschluss: ein Satz, dass die Tiere nur gemeinsam in ein artgerechtes Zuhause abgegeben werden.
Harte Regeln:
- NIEMALS Preise oder Schutzgebühren nennen.
- KEINE Fakten erfinden: Verwende ausschließlich die mitgelieferten Daten (Namen, Farbschläge, Geburtsdaten, Notizen). Fehlt eine Angabe, lässt du sie weg.
- Sprache: Deutsch, warm und liebevoll, aber nicht kitschig-übertrieben.
- Gib NUR den Inserat-Text aus — keine Erklärungen, keine Markdown-Code-Blöcke.
Beispiel 1:
{ExampleListing1}
Beispiel 2:
{ExampleListing2}
""";
/// <summary>User prompt: the actual group data + the user's free-text hints.</summary>
public static string BuildUserPrompt(SaleAdRequest request)
{
var sb = new StringBuilder();
sb.AppendLine("Erstelle ein Abgabe-Inserat für folgende Gruppe:");
sb.AppendLine();
sb.AppendLine($"Status-Zeile: {request.StatusLine}");
sb.AppendLine();
sb.AppendLine("Tiere:");
foreach (var animal in request.Animals)
{
sb.Append($"- Name: {animal.Name}");
if (!string.IsNullOrWhiteSpace(animal.Farbschlag))
sb.Append($" | Farbschlag: {animal.Farbschlag}");
if (!string.IsNullOrWhiteSpace(animal.DateOfBirth))
sb.Append($" | geboren am {FormatGermanDate(animal.DateOfBirth)}");
if (!string.IsNullOrWhiteSpace(animal.Notes))
sb.Append($" | Notizen: {animal.Notes}");
sb.AppendLine();
}
if (!string.IsNullOrWhiteSpace(request.Hints))
{
sb.AppendLine();
sb.AppendLine($"Wünsche/Hinweise: {request.Hints}");
}
return sb.ToString();
}
/// <summary>ISO "YYYY-MM-DD" -> "TT.MM.JJJJ"; anything else passes through verbatim.</summary>
internal static string FormatGermanDate(string isoDate) =>
DateOnly.TryParseExact(isoDate, "yyyy-MM-dd", CultureInfo.InvariantCulture,
DateTimeStyles.None, out var date)
? date.ToString("dd.MM.yyyy", CultureInfo.InvariantCulture)
: isoDate;
}
}