wangzhibo
2026-08-30 c8515170fd399b4d2dfaebb59128d4674e58915e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import uuid
from typing import AsyncIterator
 
from app.services.scene_engine import GENERIC_GREETING
 
 
class DialogueService:
    def create_dialogue_id(self) -> str:
        return str(uuid.uuid4())
 
    async def stream_dialogue(
        self,
        dialogue_id: str,
        user_text: str | None = None,
        scene_prompt: str | None = None,
        difficulty: str = "A2",
    ) -> AsyncIterator[dict]:
        opening = scene_prompt or GENERIC_GREETING
        chunks = [
            {
                "dialogue_id": dialogue_id,
                "text": opening,
                "audio_url": None,
                "intent_type": "greeting",
                "difficulty_level": difficulty,
            }
        ]
 
        if user_text:
            feedback = self._evaluate_response(user_text)
            chunks.append(
                {
                    "dialogue_id": dialogue_id,
                    "text": feedback["text"],
                    "audio_url": None,
                    "intent_type": feedback["intent_type"],
                    "difficulty_level": difficulty,
                }
            )
            if feedback["follow_up"]:
                chunks.append(
                    {
                        "dialogue_id": dialogue_id,
                        "text": feedback["follow_up"],
                        "audio_url": None,
                        "intent_type": "question",
                        "difficulty_level": difficulty,
                    }
                )
 
        for chunk in chunks:
            yield chunk
 
    def _evaluate_response(self, text: str) -> dict:
        normalized = text.strip()
        if not normalized:
            return {
                "text": "I didn't catch that. Could you try again?",
                "intent_type": "correction",
                "follow_up": "Please repeat your answer slowly.",
            }
 
        if normalized[0].islower():
            return {
                "text": f'Good try! Remember to capitalize: "{normalized[0].upper()}{normalized[1:]}"',
                "intent_type": "correction",
                "follow_up": "Can you say the full sentence again?",
            }
 
        if not normalized.endswith((".", "!", "?")):
            return {
                "text": "Nice answer! Don't forget punctuation at the end.",
                "intent_type": "praise",
                "follow_up": "Tell me one more detail about it.",
            }
 
        return {
            "text": "Great job! Your sentence looks correct.",
            "intent_type": "praise",
            "follow_up": "What would you do differently next time?",
        }