Merge feature/feat-14c: Charakterbogen as preferred AI character source (suppress admin notes, weave traits to prose), +4 tests [god-QA pending]
This commit is contained in:
@@ -73,6 +73,63 @@ namespace GerbilManager.Tests
|
|||||||
Assert.Contains("Großer und kleiner Bruder Dynamik", prompt);
|
Assert.Contains("Großer und kleiner Bruder Dynamik", prompt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── FEAT-14c: Charakterbogen (Traits + Notiz) im Prompt ────────────
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void UserPrompt_enthält_Traits_und_Charakternotiz()
|
||||||
|
{
|
||||||
|
var request = new SaleAdRequest(
|
||||||
|
[new SaleAdAnimal("Balu", "CP-Agouti", "2024-03-12", "alte Verwaltungsnotiz",
|
||||||
|
Traits: ["zutraulich", "buddelt gern"],
|
||||||
|
CharacterNote: "klettert abends auf die Hand")],
|
||||||
|
"FREI", "");
|
||||||
|
var prompt = SaleAdPromptBuilder.BuildUserPrompt(request);
|
||||||
|
|
||||||
|
Assert.Contains("Charakter: zutraulich, buddelt gern", prompt);
|
||||||
|
Assert.Contains("Charakter-Notiz: klettert abends auf die Hand", prompt);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void UserPrompt_bevorzugt_Charakterbogen_vor_generischen_Notizen()
|
||||||
|
{
|
||||||
|
// Traits vorhanden -> die generische Notiz (oft Verwaltungs-Info)
|
||||||
|
// gehört NICHT in den Prompt.
|
||||||
|
var request = new SaleAdRequest(
|
||||||
|
[new SaleAdAnimal("Balu", null, null, "Käfig wurde am 3.5. gereinigt",
|
||||||
|
Traits: ["neugierig"])],
|
||||||
|
"FREI", "");
|
||||||
|
var prompt = SaleAdPromptBuilder.BuildUserPrompt(request);
|
||||||
|
|
||||||
|
Assert.Contains("Charakter: neugierig", prompt);
|
||||||
|
Assert.DoesNotContain("Notizen:", prompt);
|
||||||
|
Assert.DoesNotContain("Käfig wurde", prompt);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void UserPrompt_fällt_ohne_Charakterbogen_auf_Notizen_zurück()
|
||||||
|
{
|
||||||
|
// Kein Charakterbogen (null bzw. leer) -> Notizen wie bisher.
|
||||||
|
var request = new SaleAdRequest(
|
||||||
|
[
|
||||||
|
new SaleAdAnimal("Mysti", null, null, "sehr verschmust", Traits: null),
|
||||||
|
new SaleAdAnimal("Bo", null, null, "mag Kolbenhirse", Traits: []),
|
||||||
|
],
|
||||||
|
"FREI", "");
|
||||||
|
var prompt = SaleAdPromptBuilder.BuildUserPrompt(request);
|
||||||
|
|
||||||
|
Assert.Contains("Notizen: sehr verschmust", prompt);
|
||||||
|
Assert.Contains("Notizen: mag Kolbenhirse", prompt);
|
||||||
|
Assert.DoesNotContain("Charakter:", prompt);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SystemPrompt_verlangt_fließende_Prosa_statt_Stichwortliste()
|
||||||
|
{
|
||||||
|
var prompt = SaleAdPromptBuilder.BuildSystemPrompt();
|
||||||
|
Assert.Contains("Charakter-Eigenschaften", prompt);
|
||||||
|
Assert.Contains("niemals als Aufzählung", prompt);
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("2024-03-12", "12.03.2024")]
|
[InlineData("2024-03-12", "12.03.2024")]
|
||||||
[InlineData("kaputt", "kaputt")] // unparsebar -> unverändert durchreichen
|
[InlineData("kaputt", "kaputt")] // unparsebar -> unverändert durchreichen
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ namespace GerbilManagerWebAPI.SaleAd
|
|||||||
|
|
||||||
Harte Regeln:
|
Harte Regeln:
|
||||||
- NIEMALS Preise oder Schutzgebühren nennen.
|
- 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.
|
- KEINE Fakten erfinden: Verwende ausschließlich die mitgelieferten Daten (Namen, Farbschläge, Geburtsdaten, Charakter-Angaben, Notizen). Fehlt eine Angabe, lässt du sie weg.
|
||||||
|
- Charakter-Eigenschaften (Stichworte wie „zutraulich“, „buddelt gern“) und die Charakter-Notiz sind die Grundlage der Persönlichkeits-Prosa: Verwebe sie zu FLIESSENDEM Text — niemals als Aufzählung oder Stichwortliste ausgeben.
|
||||||
- Sprache: Deutsch, warm und liebevoll, aber nicht kitschig-übertrieben.
|
- Sprache: Deutsch, warm und liebevoll, aber nicht kitschig-übertrieben.
|
||||||
- Gib NUR den Inserat-Text aus — keine Erklärungen, keine Markdown-Code-Blöcke.
|
- Gib NUR den Inserat-Text aus — keine Erklärungen, keine Markdown-Code-Blöcke.
|
||||||
|
|
||||||
@@ -85,12 +86,18 @@ namespace GerbilManagerWebAPI.SaleAd
|
|||||||
sb.Append($" | Farbschlag: {animal.Farbschlag}");
|
sb.Append($" | Farbschlag: {animal.Farbschlag}");
|
||||||
if (!string.IsNullOrWhiteSpace(animal.DateOfBirth))
|
if (!string.IsNullOrWhiteSpace(animal.DateOfBirth))
|
||||||
sb.Append($" | geboren am {FormatGermanDate(animal.DateOfBirth)}");
|
sb.Append($" | geboren am {FormatGermanDate(animal.DateOfBirth)}");
|
||||||
if (!string.IsNullOrWhiteSpace(animal.Notes))
|
// FEAT-14c: Charakterbogen (Traits + Notiz) ist die BEVORZUGTE
|
||||||
sb.Append($" | Notizen: {animal.Notes}");
|
// Charakterquelle; die generischen Notizen dienen nur als
|
||||||
|
// Fallback, wenn kein Charakterbogen gepflegt ist (sie enthalten
|
||||||
|
// oft Verwaltungs-Infos, die nicht ins Inserat gehören).
|
||||||
|
var hasCharacter = animal.Traits is { Count: > 0 }
|
||||||
|
|| !string.IsNullOrWhiteSpace(animal.CharacterNote);
|
||||||
if (animal.Traits is { Count: > 0 })
|
if (animal.Traits is { Count: > 0 })
|
||||||
sb.Append($" | Charakter: {string.Join(", ", animal.Traits)}");
|
sb.Append($" | Charakter: {string.Join(", ", animal.Traits)}");
|
||||||
if (!string.IsNullOrWhiteSpace(animal.CharacterNote))
|
if (!string.IsNullOrWhiteSpace(animal.CharacterNote))
|
||||||
sb.Append($" | Charakter-Notiz: {animal.CharacterNote}");
|
sb.Append($" | Charakter-Notiz: {animal.CharacterNote}");
|
||||||
|
if (!hasCharacter && !string.IsNullOrWhiteSpace(animal.Notes))
|
||||||
|
sb.Append($" | Notizen: {animal.Notes}");
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrWhiteSpace(request.Hints))
|
if (!string.IsNullOrWhiteSpace(request.Hints))
|
||||||
|
|||||||
Reference in New Issue
Block a user