parseStructuredCurriculum function
Parses the model's structuring response.
Tolerates the two things models reliably do to JSON: wrapping it in
```json fences, and adding prose before or after the object. Returns
null when nothing usable comes back, so callers show a retry rather than
crashing on a bad generation.
Implementation
@visibleForTesting
ProposedCurriculum? parseStructuredCurriculum(
String response, {
String? nameOverride,
}) {
final json = _extractJsonObject(response);
if (json == null) return null;
final structure = json['structure'];
if (structure is! List || structure.isEmpty) return null;
final chunks = json['chunks'];
final title = (nameOverride?.trim().isNotEmpty ?? false)
? nameOverride!.trim()
: (json['title'] as String?)?.trim();
if (title == null || title.isEmpty) return null;
final description = (json['description'] as String?)?.trim();
return ProposedCurriculum(
title: title,
description: (description?.isEmpty ?? true) ? null : description,
structure: structure,
chunks: chunks is List ? chunks : const [],
);
}