feat: improve AI dialogue evaluation and capability boundaries
This commit is contained in:
@@ -2,6 +2,7 @@ import 'answer_rules.dart';
|
||||
import 'core_items.dart';
|
||||
import 'course_catalog.dart';
|
||||
import 'course_models.dart';
|
||||
import '../models.dart';
|
||||
|
||||
/// A reply that is at least one real word; turns without a declared rule
|
||||
/// accept it.
|
||||
@@ -17,6 +18,24 @@ bool coreItemUsedIn(String id, String input) {
|
||||
return matchesRule(input, rule);
|
||||
}
|
||||
|
||||
LocalDialogueVerdict evaluateSegmentDialogueLocally(
|
||||
String segmentId,
|
||||
int stage,
|
||||
String response,
|
||||
) {
|
||||
final segment = findLessonSegment(segmentId);
|
||||
if (segment == null || stage >= segment.dialogueRequiredTerms.length) {
|
||||
return LocalDialogueVerdict.rejected;
|
||||
}
|
||||
final text = normalizeAnswer(response);
|
||||
final terms = segment.dialogueRequiredTerms[stage];
|
||||
if (terms.isNotEmpty && groupSatisfied(text, terms)) {
|
||||
return LocalDialogueVerdict.accepted;
|
||||
}
|
||||
if (!_isRealReply(text)) return LocalDialogueVerdict.rejected;
|
||||
return LocalDialogueVerdict.uncertain;
|
||||
}
|
||||
|
||||
bool matchesSegmentDialogue(String segmentId, int stage, String response) {
|
||||
final segment = findLessonSegment(segmentId);
|
||||
if (segment == null || stage >= segment.dialogueRequiredTerms.length) {
|
||||
@@ -24,10 +43,7 @@ bool matchesSegmentDialogue(String segmentId, int stage, String response) {
|
||||
}
|
||||
final text = normalizeAnswer(response);
|
||||
final terms = segment.dialogueRequiredTerms[stage];
|
||||
// A turn that declares no reviewed term (adapted units) just needs a real
|
||||
// reply, matching how free-scene turns are validated.
|
||||
if (terms.isEmpty) return _isRealReply(text);
|
||||
return groupSatisfied(text, terms);
|
||||
return terms.isEmpty ? _isRealReply(text) : groupSatisfied(text, terms);
|
||||
}
|
||||
|
||||
bool matchesSegmentIndependent(String segmentId, String response) {
|
||||
@@ -64,15 +80,32 @@ String? independentShortfall(String segmentId, String response) {
|
||||
|
||||
/// Whole-lesson and free-scene dialogues validate the same way segment
|
||||
/// dialogues do: the turn has to contain the language the turn is teaching.
|
||||
LocalDialogueVerdict evaluateDialogueStageLocally(
|
||||
LessonDialogue script,
|
||||
int stage,
|
||||
String response,
|
||||
) {
|
||||
final text = normalizeAnswer(response);
|
||||
if (stage < 0 || stage >= script.requiredTerms.length) {
|
||||
return _isRealReply(text)
|
||||
? LocalDialogueVerdict.uncertain
|
||||
: LocalDialogueVerdict.rejected;
|
||||
}
|
||||
final terms = script.requiredTerms[stage];
|
||||
if (terms.isNotEmpty && groupSatisfied(text, terms)) {
|
||||
return LocalDialogueVerdict.accepted;
|
||||
}
|
||||
if (!_isRealReply(text)) return LocalDialogueVerdict.rejected;
|
||||
return LocalDialogueVerdict.uncertain;
|
||||
}
|
||||
|
||||
bool matchesDialogueStage(LessonDialogue script, int stage, String response) {
|
||||
final text = normalizeAnswer(response);
|
||||
if (stage < 0 || stage >= script.requiredTerms.length) {
|
||||
// No declared requirement: accept anything that is actually a word.
|
||||
return _isRealReply(text);
|
||||
}
|
||||
final terms = script.requiredTerms[stage];
|
||||
if (terms.isEmpty) return _isRealReply(text);
|
||||
return groupSatisfied(text, terms);
|
||||
return terms.isEmpty ? _isRealReply(text) : groupSatisfied(text, terms);
|
||||
}
|
||||
|
||||
String dialogueTaskLabel(LessonDialogue script, int stage) =>
|
||||
|
||||
Reference in New Issue
Block a user