feat: improve AI dialogue evaluation and capability boundaries

This commit is contained in:
shen
2026-09-19 18:58:14 -07:00
parent 335d0304b1
commit 7306dc0f85
23 changed files with 1308 additions and 452 deletions
@@ -87,16 +87,17 @@ class _ReviewPageState extends State<ReviewPage>
checkingWithAi = true;
aiFeedbackError = null;
});
final feedback = await AiService.instance.answerFeedback(
provider: widget.state.aiProvider,
endpoint: widget.state.aiEndpoint,
model: widget.state.aiModel,
answerId: item.id,
target: item.target,
taskPrompt: item.prompt,
answer: answer,
level: itemLevel(item.id),
);
final feedback = await AiService.instance.capabilities.evaluation
.evaluateAnswer(
provider: widget.state.aiProvider,
endpoint: widget.state.aiEndpoint,
model: widget.state.aiModel,
answerId: item.id,
target: item.target,
taskPrompt: item.prompt,
answer: answer,
level: itemLevel(item.id),
);
// The learner may have moved on or kept typing while the request ran.
if (!mounted || controller.text.trim() != answer) {
if (mounted) setState(() => checkingWithAi = false);
@@ -243,13 +244,14 @@ class _ReviewPageState extends State<ReviewPage>
Future<void> _generateVariant(ReviewItem item) async {
setState(() => generatingVariant = true);
final variant = await AiService.instance.generateReviewVariant(
provider: widget.state.aiProvider,
endpoint: widget.state.aiEndpoint,
model: widget.state.aiModel,
targetItemId: item.id,
basePrompt: item.prompt,
);
final variant = await AiService.instance.capabilities.review
.generateVariant(
provider: widget.state.aiProvider,
endpoint: widget.state.aiEndpoint,
model: widget.state.aiModel,
targetItemId: item.id,
basePrompt: item.prompt,
);
if (!mounted) return;
setState(() => generatingVariant = false);
if (variant == null) {
@@ -268,13 +270,14 @@ class _ReviewPageState extends State<ReviewPage>
if (!isCoreItem(item.id)) return;
final label = coreItemEnglish(item.id);
setState(() => generatingLesson = true);
final lesson = await AiService.instance.generateAdaptiveLesson(
provider: widget.state.aiProvider,
endpoint: widget.state.aiEndpoint,
model: widget.state.aiModel,
targetItemId: item.id,
targetLabel: label,
);
final lesson = await AiService.instance.capabilities.review
.generateAdaptiveLesson(
provider: widget.state.aiProvider,
endpoint: widget.state.aiEndpoint,
model: widget.state.aiModel,
targetItemId: item.id,
targetLabel: label,
);
if (lesson == null) {
if (mounted) setState(() => generatingLesson = false);
if (mounted) {
@@ -284,12 +287,13 @@ class _ReviewPageState extends State<ReviewPage>
}
return;
}
final approved = await AiService.instance.auditGeneratedLesson(
provider: widget.state.aiProvider,
endpoint: widget.state.aiEndpoint,
model: widget.state.aiModel,
lesson: lesson,
);
final approved = await AiService.instance.capabilities.review
.auditAdaptiveLesson(
provider: widget.state.aiProvider,
endpoint: widget.state.aiEndpoint,
model: widget.state.aiModel,
lesson: lesson,
);
if (!mounted) return;
setState(() => generatingLesson = false);
if (!approved) {
@@ -772,15 +776,16 @@ class _AdaptiveLessonPageState extends State<AdaptiveLessonPage>
checkingWithAi = true;
aiCheckError = null;
});
final feedback = await AiService.instance.answerFeedback(
provider: widget.state.aiProvider,
endpoint: widget.state.aiEndpoint,
model: widget.state.aiModel,
answerId: task.taskId,
target: task.answer,
taskPrompt: '${task.prompt} ${task.stimulus}',
answer: answer,
);
final feedback = await AiService.instance.capabilities.evaluation
.evaluateAnswer(
provider: widget.state.aiProvider,
endpoint: widget.state.aiEndpoint,
model: widget.state.aiModel,
answerId: task.taskId,
target: task.answer,
taskPrompt: '${task.prompt} ${task.stimulus}',
answer: answer,
);
// The learner may have kept typing or moved on while the request ran.
if (!mounted || controller.text.trim() != answer) {
if (mounted) setState(() => checkingWithAi = false);