KI-Backend: Umfangs-Umschalter + Prompt Caching (4.5.15/4.5.16)
Umfangs-Umschalter: Checkbox "Auch bestehende Stundeninhalte anpassen" im AiAssistDialog steuert, ob die KI bestehende Stunden inhaltlich ändern darf oder die Einheit nur um neue Stunden erweitern soll. Zweifach durchgesetzt (Systemprompt + hartes client-seitiges Verwerfen in ApplyResponse), nicht nur der KI-Antwort vertraut. Dabei auch einen Bug gefixt: eine bereits "Durchgeführt" markierte Stunde wurde durch eine übernommene KI-Änderung stillschweigend auf "Geplant" zurückgesetzt. Prompt Caching: der Systemprompt ist jetzt vollständig statisch (Voraussetzung für Caching) und wird von AnthropicProvider.php als "cache_control: ephemeral" markiert — wiederholte Anfragen innerhalb der 5-Minuten-TTL zahlen nur den reduzierten Cache-Read-Preis. transactions-Tabelle und Preistabelle um Cache-Token-Spalten erweitert, Migration für bereits deployte Installationen beigelegt.
This commit is contained in:
@@ -125,6 +125,52 @@ public sealed class AiPlanningServiceTests
|
||||
Assert.Equal(group.Id, lesson.GroupId);
|
||||
}
|
||||
|
||||
/// Die KI kennt/liefert keinen Status — ohne diese Absicherung würde eine bereits gehaltene
|
||||
/// Stunde durch eine übernommene KI-Änderung stillschweigend auf "Geplant" zurückgesetzt.
|
||||
[Fact]
|
||||
public void ApplyResponse_BekannteId_BehaeltStatusDerBestehendenLessonBei()
|
||||
{
|
||||
var group = new LearningGroup();
|
||||
var unit = new Unit { GroupId = group.Id, Title = "T" };
|
||||
var existing = new Lesson { UnitId = unit.Id, GroupId = group.Id, Topic = "Alt", Status = LessonStatus.Conducted };
|
||||
var lessons = new FakeLessons();
|
||||
lessons.Add(existing);
|
||||
|
||||
var service = Build(lessons, new FakeGroups([group]), new FakeSubjects([]),
|
||||
new FakeCompetencyDomains(), new FakeAlternativeLessonPaths([]));
|
||||
|
||||
var accepted = new List<AiLesson> { new() { Id = existing.Id, Topic = "Nachträglich präzisiert" } };
|
||||
var result = service.ApplyResponse(unit, accepted);
|
||||
|
||||
Assert.Equal(LessonStatus.Conducted, Assert.Single(result).Status);
|
||||
}
|
||||
|
||||
/// Umfangs-Umschalter (Nutzer-Nachtrag): "Einheit umplanen ohne Stunden zu ändern" muss auch
|
||||
/// dann greifen, wenn die KI die Anweisung im Systemprompt ignoriert und trotzdem eine
|
||||
/// bestehende Id zurückgibt — client-seitig hart durchgesetzt, nicht nur per Prompt erbeten.
|
||||
[Fact]
|
||||
public void ApplyResponse_AenderungVerboten_VerwirftUpdateBestehenderLesson()
|
||||
{
|
||||
var group = new LearningGroup();
|
||||
var unit = new Unit { GroupId = group.Id, Title = "T" };
|
||||
var existing = new Lesson { UnitId = unit.Id, GroupId = group.Id, Topic = "Alt" };
|
||||
var lessons = new FakeLessons();
|
||||
lessons.Add(existing);
|
||||
|
||||
var service = Build(lessons, new FakeGroups([group]), new FakeSubjects([]),
|
||||
new FakeCompetencyDomains(), new FakeAlternativeLessonPaths([]));
|
||||
|
||||
var accepted = new List<AiLesson>
|
||||
{
|
||||
new() { Id = existing.Id, Topic = "Sollte verworfen werden" },
|
||||
new() { Id = null, Topic = "Neue Stunde bleibt erlaubt" },
|
||||
};
|
||||
var result = service.ApplyResponse(unit, accepted, allowModifyingExistingLessons: false);
|
||||
|
||||
var lesson = Assert.Single(result);
|
||||
Assert.Equal("Neue Stunde bleibt erlaubt", lesson.Topic);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplyResponse_NullId_WirdAlsNeueLessonBehandelt()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user