feat(backend/story-integration): Phase 4 - AI Integration with CEFR-level prompts
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
- Enhanced StoryGenerationService with CEFR-level-specific prompt templates - Added GetStoryRequirements() method with level-specific requirements for A1-C1 - Added GetSegmentRequirements() method with level-specific requirements - Story prompts now include detailed CEFR-level constraints: - A1: Simple present tense, basic SVO structure, max 500 words - A2: Present/past/future, subordinate clauses, max 1000 words - B1: All tenses, modal verbs, complex sentences, max 2000 words - B2: Nuanced tenses, all cases, Konjunktiv I/II, Passiv, max 3000 words - C1: All tenses/moods, sophisticated vocabulary, literary devices - Updated docs/features/story-integration.md for Phase 4 completion - All 324 tests still pass Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
parent
01f6a1fd30
commit
536382641d
2 changed files with 85 additions and 16 deletions
|
|
@ -344,21 +344,58 @@ public class StoryGenerationService
|
||||||
private string BuildStoryPrompt(int levelId, string theme, IReadOnlyList<string> vocabulary, int segmentCount)
|
private string BuildStoryPrompt(int levelId, string theme, IReadOnlyList<string> vocabulary, int segmentCount)
|
||||||
{
|
{
|
||||||
var levelCode = GetLevelCode(levelId);
|
var levelCode = GetLevelCode(levelId);
|
||||||
var vocabularyString = string.Join(", ", vocabulary.Take(20)); // Limit to first 20 words
|
var vocabularyString = string.Join(", ", vocabulary.Take(20));
|
||||||
|
|
||||||
if (vocabulary.Count > 20)
|
if (vocabulary.Count > 20)
|
||||||
{
|
{
|
||||||
vocabularyString += ", ...";
|
vocabularyString += ", ...";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var requirements = GetStoryRequirements(levelCode);
|
||||||
return $@"Write a {segmentCount}-part continuous story for a German {levelCode} learner.
|
return $@"Write a {segmentCount}-part continuous story for a German {levelCode} learner.
|
||||||
The story theme is: {theme}.
|
The story theme is: {theme}.
|
||||||
Include these German words and phrases: {vocabularyString}.
|
Include these German words and phrases: {vocabularyString}.
|
||||||
Use only {levelCode} level vocabulary and grammar.
|
|
||||||
Write each part as a separate paragraph.
|
REQUIREMENTS:
|
||||||
Make the story engaging and appropriate for language learners.";
|
{requirements}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetStoryRequirements(string levelCode) => levelCode switch
|
||||||
|
{
|
||||||
|
"A1" => "- Use ONLY A1-level vocabulary and grammar\n" +
|
||||||
|
"- Use simple present tense (ich bin, ich habe, ich gehe)\n" +
|
||||||
|
"- Basic sentence structure: Subject-Verb-Object\n" +
|
||||||
|
"- Vocabulary: max 500 words, sentence length: max 10 words\n" +
|
||||||
|
"- Each part: 2-3 short sentences\n" +
|
||||||
|
"- Do NOT use: subjunctive, genitive, complex prepositions",
|
||||||
|
"A2" => "- Use ONLY A2-level vocabulary and grammar\n" +
|
||||||
|
"- Use present, past (Perfekt), future tense\n" +
|
||||||
|
"- Can use subordinate clauses with weil, dass, wenn\n" +
|
||||||
|
"- Vocabulary: 500-1000 words, sentence length: max 15 words\n" +
|
||||||
|
"- Each part: 3-4 sentences\n" +
|
||||||
|
"- Do NOT use: Konjunktiv II, Passiv, complex noun compounds",
|
||||||
|
"B1" => "- Use ONLY B1-level vocabulary and grammar\n" +
|
||||||
|
"- Use all tenses: present, past (Praeteritum/Perfekt), future\n" +
|
||||||
|
"- Use modal verbs: koennen, muessen, duerfen, sollen, wollen, moegen\n" +
|
||||||
|
"- Sentence structure: complex sentences with subordinate clauses\n" +
|
||||||
|
"- Vocabulary: 1000-2000 words, sentence length: max 20 words\n" +
|
||||||
|
"- Each part: 4-5 sentences",
|
||||||
|
"B2" => "- Use ONLY B2-level vocabulary and grammar\n" +
|
||||||
|
"- Use nuanced tenses: Present, Praeteritum, Perfekt, Plusquamperfekt, Future I/II\n" +
|
||||||
|
"- Use all cases: Nominativ, Akkusativ, Dativ, Genitiv\n" +
|
||||||
|
"- Use Konjunktiv I (indirect speech) and Konjunktiv II\n" +
|
||||||
|
"- Use Passiv where appropriate\n" +
|
||||||
|
"- Vocabulary: 2000-3000 words, sentence length: max 25 words\n" +
|
||||||
|
"- Each part: 5-6 sentences",
|
||||||
|
"C1" => "- Use C1-level vocabulary and grammar with precision\n" +
|
||||||
|
"- Use all tenses and moods: Indikativ, Konjunktiv I/II, Passiv in all forms\n" +
|
||||||
|
"- Sentence structure: highly complex with nested relative clauses\n" +
|
||||||
|
"- Use sophisticated vocabulary including idiomatic expressions\n" +
|
||||||
|
"- Vocabulary: 3000-5000 words, sentence length: can exceed 25 words\n" +
|
||||||
|
"- Each part: 6-8 sentences",
|
||||||
|
_ => "- Use only " + levelCode + " level vocabulary and grammar"
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Builds a prompt for a single story segment.
|
/// Builds a prompt for a single story segment.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -375,13 +412,44 @@ Make the story engaging and appropriate for language learners.";
|
||||||
vocabularyString += ", ...";
|
vocabularyString += ", ...";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $@"Write a short story segment (5-8 sentences) for a German {levelCode} learner.
|
var sentenceCount = levelCode switch { "A1" => "3-5", "A2" => "4-6", "B1" => "5-7", "B2" => "6-8", "C1" => "7-10", _ => "5-8" };
|
||||||
|
var requirements = GetSegmentRequirements(levelCode);
|
||||||
|
return $@"Write a short story segment ({sentenceCount} sentences) for a German {levelCode} learner.
|
||||||
The theme is: {theme}.
|
The theme is: {theme}.
|
||||||
Include these German words: {vocabularyString}.
|
Include these German words: {vocabularyString}.
|
||||||
Use only {levelCode} level vocabulary and grammar.
|
|
||||||
Make it engaging and appropriate for language learners.";
|
REQUIREMENTS:
|
||||||
|
{requirements}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetSegmentRequirements(string levelCode) => levelCode switch
|
||||||
|
{
|
||||||
|
"A1" => "- Use ONLY A1-level vocabulary and grammar\n" +
|
||||||
|
"- Use simple present tense only (ich bin, ich habe, ich gehe)\n" +
|
||||||
|
"- Basic sentence structure: Subject-Verb-Object\n" +
|
||||||
|
"- Sentence length: max 8 words\n" +
|
||||||
|
"- Do NOT use: subjunctive, genitive, complex prepositions",
|
||||||
|
"A2" => "- Use ONLY A2-level vocabulary and grammar\n" +
|
||||||
|
"- Use present, past (Perfekt), future tense\n" +
|
||||||
|
"- Can use simple subordinate clauses with weil, dass, wenn\n" +
|
||||||
|
"- Sentence length: max 12 words",
|
||||||
|
"B1" => "- Use ONLY B1-level vocabulary and grammar\n" +
|
||||||
|
"- Use present, past (Praeteritum/Perfekt), future tense\n" +
|
||||||
|
"- Use modal verbs: koennen, muessen, duerfen, sollen, wollen\n" +
|
||||||
|
"- Sentence structure: complex sentences with subordinate clauses\n" +
|
||||||
|
"- Sentence length: max 20 words",
|
||||||
|
"B2" => "- Use ONLY B2-level vocabulary and grammar\n" +
|
||||||
|
"- Use nuanced tenses including Plusquamperfekt and Konjunktiv II\n" +
|
||||||
|
"- Use all cases: Nominativ, Akkusativ, Dativ, Genitiv\n" +
|
||||||
|
"- Use Passiv where appropriate\n" +
|
||||||
|
"- Sentence length: max 25 words",
|
||||||
|
"C1" => "- Use C1-level vocabulary and grammar with precision\n" +
|
||||||
|
"- Use all tenses, moods, and cases correctly\n" +
|
||||||
|
"- Use sophisticated vocabulary including idiomatic expressions\n" +
|
||||||
|
"- Sentence structure: complex nested sentences with multiple clauses",
|
||||||
|
_ => "- Use only " + levelCode + " level vocabulary and grammar"
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Splits a full story text into segments.
|
/// Splits a full story text into segments.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# Feature: Story Integration
|
# Feature: Story Integration
|
||||||
|
|
||||||
> **Status**: 🚀 In Progress
|
> **Status**: 🚀 In Progress
|
||||||
> **📊 Current Progress**: Phase 1-3 ✅ Complete (Database & Models, Backend Services, Unit Tests), Phase 4 Next (AI Integration)
|
> **📊 Current Progress**: Phase 1-4 ✅ Complete (Database & Models, Backend Services, Unit Tests, AI Integration), Phase 5 Next (Audio Generation)
|
||||||
> **Priority**: High
|
> **Priority**: High
|
||||||
> **Complexity**: High
|
> **Complexity**: High
|
||||||
> **Estimate**: 8-12 hours
|
> **Estimate**: 8-12 hours
|
||||||
|
|
@ -157,13 +157,13 @@ Order: 1
|
||||||
- [x] Write unit tests for StoryProgressRepository (Tests/Unit/Infrastructure/Data/Repositories/StoryProgressRepositoryTests.cs)
|
- [x] Write unit tests for StoryProgressRepository (Tests/Unit/Infrastructure/Data/Repositories/StoryProgressRepositoryTests.cs)
|
||||||
- [x] All 324 tests pass
|
- [x] All 324 tests pass
|
||||||
|
|
||||||
### Phase 4: AI Integration (2-3 hours)
|
### Phase 4: AI Integration (2-3 hours) - COMPLETE
|
||||||
- [ ] Configure Mistral-Medium API client
|
- [x] Configure Mistral-Medium API client (MistralConfig with retry, rate limiting, circuit breaker)
|
||||||
- [ ] Create prompt templates for each level
|
- [x] Create prompt templates for each level (A1-C1 with CEFR-specific requirements)
|
||||||
- [ ] Implement vocabulary extraction from lessons
|
- [x] Implement vocabulary extraction from lessons (ExtractVocabularyFromLessons)
|
||||||
- [ ] Implement story text segmentation
|
- [x] Implement story text segmentation (SplitStoryIntoSegments, AdjustSegmentCount)
|
||||||
- [ ] Handle AI API errors gracefully
|
- [x] Handle AI API errors gracefully (AiServiceException with error codes)
|
||||||
- [ ] Add retry logic for failed generations
|
- [x] Add retry logic for failed generations (ExecuteWithRetryAsync with exponential backoff)
|
||||||
|
|
||||||
### Phase 5: Audio Generation (2 hours)
|
### Phase 5: Audio Generation (2 hours)
|
||||||
- [ ] Integrate with Coqui TTS service
|
- [ ] Integrate with Coqui TTS service
|
||||||
|
|
@ -193,7 +193,7 @@ Order: 1
|
||||||
| Database & Models | June 13, 2025 | ✅ |
|
| Database & Models | June 13, 2025 | ✅ |
|
||||||
| Backend Services | June 13, 2025 | ✅ |
|
| Backend Services | June 13, 2025 | ✅ |
|
||||||
| Unit Tests | June 13, 2025 | ✅ |
|
| Unit Tests | June 13, 2025 | ✅ |
|
||||||
| AI Integration | - | ⏳ |
|
| AI Integration | June 13, 2025 | ✅ |
|
||||||
| Audio Generation | - | ⏳ |
|
| Audio Generation | - | ⏳ |
|
||||||
| Frontend Integration | - | ⏳ |
|
| Frontend Integration | - | ⏳ |
|
||||||
| User Progress | - | ⏳ |
|
| User Progress | - | ⏳ |
|
||||||
|
|
@ -416,6 +416,7 @@ Make the story engaging and suitable for adult learners.
|
||||||
| May 31, 2025 | Created | Initial plan based on application-plan.md |
|
| May 31, 2025 | Created | Initial plan based on application-plan.md |
|
||||||
| June 13, 2025 | Phase 1-2 Complete | Database & Models, Backend Services implemented |
|
| June 13, 2025 | Phase 1-2 Complete | Database & Models, Backend Services implemented |
|
||||||
| June 13, 2025 | Phase 3 Complete | All unit tests written and passing (324 tests) |
|
| June 13, 2025 | Phase 3 Complete | All unit tests written and passing (324 tests) |
|
||||||
|
| June 13, 2025 | Phase 4 Complete | Enhanced prompts with CEFR-level-specific requirements for story generation |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue