ABAO77 commited on
Commit
38f32a9
·
verified ·
1 Parent(s): 5130b70

Upload 78 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitignore +1 -0
  2. Dockerfile +13 -0
  3. README.md +4 -4
  4. agent.py +173 -0
  5. app.py +12 -0
  6. requirements.txt +14 -0
  7. src/.DS_Store +0 -0
  8. src/Untitled.ipynb +51 -0
  9. src/__pycache__/__init__.cpython-311.pyc +0 -0
  10. src/__pycache__/app.cpython-311.pyc +0 -0
  11. src/__pycache__/state.cpython-311.pyc +0 -0
  12. src/agents/.DS_Store +0 -0
  13. src/agents/base/flow.py +22 -0
  14. src/agents/base/func.py +4 -0
  15. src/agents/base/prompt.py +14 -0
  16. src/agents/base/tools.py +16 -0
  17. src/agents/role_play/__pycache__/func.cpython-311.pyc +0 -0
  18. src/agents/role_play/__pycache__/prompt.cpython-311.pyc +0 -0
  19. src/agents/role_play/__pycache__/scenarios.cpython-311.pyc +0 -0
  20. src/agents/role_play/flow.py +24 -0
  21. src/agents/role_play/func.py +55 -0
  22. src/agents/role_play/prompt.py +187 -0
  23. src/agents/role_play/scenarios.py +195 -0
  24. src/agents/role_play/tools.py +16 -0
  25. src/agents/tools/__pycache__/crawl.cpython-311.pyc +0 -0
  26. src/agents/tools/crawl.py +24 -0
  27. src/apis/.DS_Store +0 -0
  28. src/apis/__pycache__/__init__.cpython-311.pyc +0 -0
  29. src/apis/__pycache__/create_app.cpython-311.pyc +0 -0
  30. src/apis/config/__pycache__/firebase_config.cpython-311.pyc +0 -0
  31. src/apis/create_app.py +22 -0
  32. src/apis/interfaces/.DS_Store +0 -0
  33. src/apis/interfaces/__pycache__/api_interface.cpython-311.pyc +0 -0
  34. src/apis/interfaces/__pycache__/auth_interface.cpython-311.pyc +0 -0
  35. src/apis/interfaces/api_interface.py +5 -0
  36. src/apis/interfaces/auth_interface.py +2 -0
  37. src/apis/middlewares/__pycache__/auth_middleware.cpython-311.pyc +0 -0
  38. src/apis/middlewares/auth_middleware.py +0 -0
  39. src/apis/models/.DS_Store +0 -0
  40. src/apis/models/BaseModel.py +17 -0
  41. src/apis/models/__pycache__/BaseModel.cpython-311.pyc +0 -0
  42. src/apis/models/__pycache__/destination_models.cpython-311.pyc +0 -0
  43. src/apis/models/__pycache__/hotel_models.cpython-311.pyc +0 -0
  44. src/apis/models/__pycache__/post_models.cpython-311.pyc +0 -0
  45. src/apis/models/__pycache__/schedule_models.cpython-311.pyc +0 -0
  46. src/apis/models/__pycache__/user_models.cpython-311.pyc +0 -0
  47. src/apis/models/user_models.py +0 -0
  48. src/apis/providers/.DS_Store +0 -0
  49. src/apis/providers/__pycache__/__init__.cpython-311.pyc +0 -0
  50. src/apis/providers/__pycache__/firebase_provider.cpython-311.pyc +0 -0
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ .env
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+
3
+ RUN useradd -m -u 1000 user
4
+ USER user
5
+ ENV PATH="/home/user/.local/bin:$PATH"
6
+
7
+ WORKDIR /app
8
+
9
+ COPY --chown=user ./requirements.txt requirements.txt
10
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
11
+
12
+ COPY --chown=user . /app
13
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
README.md CHANGED
@@ -1,8 +1,8 @@
1
  ---
2
- title: Role Play
3
- emoji: 🐠
4
- colorFrom: yellow
5
- colorTo: indigo
6
  sdk: docker
7
  pinned: false
8
  ---
 
1
  ---
2
+ title: English Roleplay
3
+ emoji: 🐨
4
+ colorFrom: pink
5
+ colorTo: blue
6
  sdk: docker
7
  pinned: false
8
  ---
agent.py ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dotenv import load_dotenv
2
+
3
+ load_dotenv()
4
+ from langchain_google_genai import ChatGoogleGenerativeAI
5
+ from langgraph.checkpoint.memory import InMemorySaver
6
+ from langgraph.prebuilt import create_react_agent
7
+ from langgraph_swarm import create_handoff_tool, create_swarm
8
+
9
+ model = ChatGoogleGenerativeAI(
10
+ model="gemini-2.5-flash",
11
+ temperature=0,
12
+ max_tokens=None,
13
+ timeout=None,
14
+ max_retries=2,
15
+ # other params...
16
+ )
17
+
18
+
19
+ def add(a: int, b: int) -> int:
20
+ """Add two numbers"""
21
+ return a + b
22
+
23
+
24
+ transfer_to_language_helper = create_handoff_tool(
25
+ agent_name="language_helper",
26
+ description="Transfer to language helper when user needs gentle grammar/vocabulary support",
27
+ )
28
+
29
+ transfer_to_character_agent = create_handoff_tool(
30
+ agent_name="character_agent",
31
+ description="Transfer to main conversation character for natural chat",
32
+ )
33
+
34
+ transfer_to_orchestrator = create_handoff_tool(
35
+ agent_name="orchestrator",
36
+ description="Transfer to orchestrator for conversation flow management",
37
+ )
38
+ # ========================= AGENT PROMPTS =========================
39
+
40
+ CHARACTER_AGENT_PROMPT = """
41
+ You are a friendly, patient conversation partner helping someone practice English.
42
+
43
+ PERSONALITY:
44
+ - Warm, encouraging, and genuinely interested
45
+ - Patient with language learners
46
+ - Natural conversationalist, not a formal teacher
47
+ - Use Elementary English (A1-A2 level) naturally
48
+
49
+ CONVERSATION APPROACH:
50
+ - Always respond warmly to whatever the user says
51
+ - Show genuine interest in their thoughts and experiences
52
+ - Use simple, clear language naturally
53
+ - Ask engaging follow-up questions
54
+ - If they go off-topic, engage naturally first
55
+
56
+ CURRENT CONVERSATION THEME: {theme}
57
+ - Gently weave theme-related topics when it feels natural
58
+ - Don't force the theme if user wants to talk about other things
59
+ - Let conversation flow organically
60
+
61
+ LANGUAGE LEVEL GUIDELINES:
62
+ - Use common vocabulary (avoid complex words)
63
+ - Simple sentence structures
64
+ - Clear pronunciation cues in text
65
+ - Encouraging tone
66
+
67
+ EXAMPLES:
68
+ User: "I like cats" → "Cats are wonderful! Do you have a cat? I think they're so independent and cute."
69
+ User: "I'm tired today" → "Oh no! Long day? Sometimes when I'm tired, I just want to relax. What helps you feel better?"
70
+
71
+ Remember: You're their conversation partner, not their teacher. Make them feel comfortable and want to keep talking!
72
+ """
73
+
74
+ LANGUAGE_HELPER_PROMPT = """
75
+ You are a gentle language helper - like helping a friend with English in a very supportive way.
76
+
77
+ YOUR APPROACH:
78
+ - Help only when there are major communication barriers
79
+ - Keep corrections brief and encouraging
80
+ - Immediately return to natural conversation
81
+ - Never make them feel bad about mistakes
82
+ - Focus on communication, not perfection
83
+
84
+ HELPING STYLE:
85
+ 1. If meaning is clear despite small errors → ignore errors, continue conversation
86
+ 2. If meaning is unclear → offer gentle help:
87
+ - "I think you mean: [corrected version]?"
88
+ - "Oh, you can say: [natural way]"
89
+ - Then immediately continue the conversation
90
+
91
+ 3. If they struggle with words → offer quick support:
92
+ - "The word you might be looking for is..."
93
+ - "You could say..."
94
+
95
+ EXAMPLES:
96
+ User: "I go shop yesterday" → "Oh, you went shopping yesterday? That sounds fun! What did you buy?"
97
+ User: "I want... um... the thing for coffee" → "Oh, do you mean a coffee cup? Or maybe a coffee maker?"
98
+
99
+ Keep it conversational and supportive. Your goal is to help communication flow, not to teach grammar lessons.
100
+ """
101
+
102
+ ORCHESTRATOR_PROMPT = """
103
+ You are a conversation flow manager for an English practice chat system.
104
+
105
+ YOUR ROLE:
106
+ - Monitor conversation quality and user engagement
107
+ - Decide when language help is truly needed
108
+ - Keep conversations natural and flowing
109
+ - Track user preferences (topic-focused vs free-talk)
110
+
111
+ DECISION MAKING:
112
+ - Only send to language_helper if there's a real communication barrier
113
+ - Let character_agent handle 90% of interactions
114
+ - Prioritize user comfort and engagement over strict language correction
115
+
116
+ ANALYSIS TOOLS: Use analyze_language_need to assess if help is needed
117
+
118
+ ROUTING PRINCIPLES:
119
+ - Default to character_agent for natural conversation
120
+ - Transfer to language_helper only for major communication issues
121
+ - Always prioritize conversation flow over language perfection
122
+
123
+ Current conversation theme: {theme}
124
+ User engagement level: {engagement}
125
+ """
126
+
127
+
128
+ character_agent = create_react_agent(
129
+ model=model,
130
+ tools=[
131
+ transfer_to_language_helper,
132
+ transfer_to_orchestrator,
133
+ ],
134
+ prompt=CHARACTER_AGENT_PROMPT.format(theme="technical interview"),
135
+ name="character_agent",
136
+ )
137
+
138
+ # Create Language Helper (Gentle support)
139
+ language_helper = create_react_agent(
140
+ model=model,
141
+ tools=[transfer_to_character_agent, transfer_to_orchestrator],
142
+ prompt=LANGUAGE_HELPER_PROMPT,
143
+ name="language_helper",
144
+ )
145
+
146
+ # Create Orchestrator (Flow manager)
147
+ orchestrator = create_react_agent(
148
+ model=model,
149
+ tools=[
150
+ transfer_to_character_agent,
151
+ transfer_to_language_helper,
152
+ ],
153
+ prompt=ORCHESTRATOR_PROMPT,
154
+ name="orchestrator",
155
+ )
156
+ checkpointer = InMemorySaver()
157
+ workflow = create_swarm(
158
+ agents=[character_agent, language_helper, orchestrator],
159
+ default_active_agent="character_agent", # Start with friendly conversation
160
+ ).compile(checkpointer=checkpointer)
161
+
162
+ config = {"configurable": {"thread_id": "1"}}
163
+
164
+
165
+ while True:
166
+ user_input = input("You: ")
167
+ if user_input.lower() == "exit":
168
+ break
169
+ response = workflow.invoke(
170
+ {"messages": [{"role": "user", "content": user_input}]},
171
+ config,
172
+ )
173
+ print("Bot:", response["messages"][-1].content)
app.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dotenv import load_dotenv
2
+
3
+ load_dotenv()
4
+ from src.apis.create_app import create_app, api_router
5
+ import uvicorn
6
+
7
+
8
+ app = create_app()
9
+
10
+ app.include_router(api_router)
11
+ if __name__ == "__main__":
12
+ uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=False)
requirements.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ python-dateutil
4
+ pandas
5
+ openpyxl
6
+ redis
7
+ bs4
8
+ pytz
9
+ langgraph
10
+ langchain
11
+ langgraph-swarm
12
+ langchain-google-genai
13
+ python-dotenv
14
+ loguru
src/.DS_Store ADDED
Binary file (8.2 kB). View file
 
src/Untitled.ipynb ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "id": "00ef7a54-9c8a-4235-82d1-9df1ac5f2967",
7
+ "metadata": {},
8
+ "outputs": [
9
+ {
10
+ "name": "stdout",
11
+ "output_type": "stream",
12
+ "text": [
13
+ "hello\n"
14
+ ]
15
+ }
16
+ ],
17
+ "source": [
18
+ "print('hello')"
19
+ ]
20
+ },
21
+ {
22
+ "cell_type": "code",
23
+ "execution_count": null,
24
+ "id": "d2e19d62-d6ba-4cb7-ac8c-b965cf65b2d7",
25
+ "metadata": {},
26
+ "outputs": [],
27
+ "source": []
28
+ }
29
+ ],
30
+ "metadata": {
31
+ "kernelspec": {
32
+ "display_name": "Python 3 (ipykernel)",
33
+ "language": "python",
34
+ "name": "python3"
35
+ },
36
+ "language_info": {
37
+ "codemirror_mode": {
38
+ "name": "ipython",
39
+ "version": 3
40
+ },
41
+ "file_extension": ".py",
42
+ "mimetype": "text/x-python",
43
+ "name": "python",
44
+ "nbconvert_exporter": "python",
45
+ "pygments_lexer": "ipython3",
46
+ "version": "3.11.9"
47
+ }
48
+ },
49
+ "nbformat": 4,
50
+ "nbformat_minor": 5
51
+ }
src/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (221 Bytes). View file
 
src/__pycache__/app.cpython-311.pyc ADDED
Binary file (958 Bytes). View file
 
src/__pycache__/state.cpython-311.pyc ADDED
Binary file (763 Bytes). View file
 
src/agents/.DS_Store ADDED
Binary file (6.15 kB). View file
 
src/agents/base/flow.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langgraph.graph import StateGraph, START, END
2
+ from .func import State
3
+ from langgraph.graph.state import CompiledStateGraph
4
+ from langgraph.store.memory import InMemoryStore
5
+ class PrimaryChatBot:
6
+ def __init__(self):
7
+ self.builder = StateGraph(State)
8
+
9
+ @staticmethod
10
+ def routing(state: State):
11
+ pass
12
+
13
+ def node(self):
14
+ pass
15
+
16
+ def edge(self):
17
+ pass
18
+
19
+ def __call__(self) -> CompiledStateGraph:
20
+ self.node()
21
+ self.edge()
22
+ return self.builder.compile(checkpointer=InMemoryStore())
src/agents/base/func.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ from typing import TypedDict
2
+
3
+ class State(TypedDict):
4
+ pass
src/agents/base/prompt.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_core.prompts import ChatPromptTemplate
2
+
3
+
4
+ base_prompt = ChatPromptTemplate.from_messages(
5
+ [
6
+ (
7
+ "system",
8
+ """Vai trò
9
+
10
+ """,
11
+ ),
12
+ ("placeholder", "{messages}"),
13
+ ]
14
+ )
src/agents/base/tools.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_core.tools import tool
2
+ from loguru import logger
3
+
4
+
5
+ @tool
6
+ def function_name(
7
+ input: str,
8
+ ) -> str:
9
+ """
10
+ Mô tả chức năng của hàm này.
11
+ """
12
+ logger.info(f"Received input: {input}")
13
+ # Thực hiện các thao tác cần thiết với input
14
+ result = f"Processed: {input}"
15
+ logger.info(f"Returning result: {result}")
16
+ return result
src/agents/role_play/__pycache__/func.cpython-311.pyc ADDED
Binary file (2.33 kB). View file
 
src/agents/role_play/__pycache__/prompt.cpython-311.pyc ADDED
Binary file (7.56 kB). View file
 
src/agents/role_play/__pycache__/scenarios.cpython-311.pyc ADDED
Binary file (6.36 kB). View file
 
src/agents/role_play/flow.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langgraph.graph import StateGraph, START, END
2
+ from .func import State
3
+ from langgraph.graph.state import CompiledStateGraph
4
+ from langgraph.store.memory import InMemoryStore
5
+
6
+
7
+ class PrimaryChatBot:
8
+ def __init__(self):
9
+ self.builder = StateGraph(State)
10
+
11
+ @staticmethod
12
+ def routing(state: State):
13
+ pass
14
+
15
+ def node(self):
16
+ pass
17
+
18
+ def edge(self):
19
+ pass
20
+
21
+ def __call__(self) -> CompiledStateGraph:
22
+ self.node()
23
+ self.edge()
24
+ return self.builder.compile(checkpointer=InMemoryStore())
src/agents/role_play/func.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import TypedDict
2
+ from src.config.llm import model
3
+ from langgraph.checkpoint.memory import InMemorySaver
4
+ from langgraph.prebuilt import create_react_agent
5
+ from langgraph_swarm import create_handoff_tool, create_swarm
6
+ from .prompt import roleplay_prompt, guiding_prompt
7
+
8
+
9
+ class State(TypedDict):
10
+ pass
11
+
12
+
13
+ def create_agents(scenario, checkpointer=InMemorySaver()):
14
+
15
+ roleplay_agent = create_react_agent(
16
+ model,
17
+ [
18
+ create_handoff_tool(
19
+ agent_name="Guiding Agent",
20
+ description="Hand off to Guiding Agent when user shows signs of needing help, guidance, or struggles with communication",
21
+ ),
22
+ ],
23
+ prompt=roleplay_prompt.format(
24
+ scenario_title=scenario["scenario_title"],
25
+ scenario_description=scenario["scenario_description"],
26
+ scenario_context=scenario["scenario_context"],
27
+ your_role=scenario["your_role"],
28
+ key_vocabulary=scenario["key_vocabulary"],
29
+ ),
30
+ name="Roleplay Agent",
31
+ )
32
+
33
+ guiding_agent = create_react_agent(
34
+ model,
35
+ [
36
+ create_handoff_tool(
37
+ agent_name="Roleplay Agent",
38
+ description="Hand off back to Roleplay Agent when user is ready for scenario practice and shows improved confidence",
39
+ ),
40
+ ],
41
+ prompt=guiding_prompt.format(
42
+ scenario_title=scenario["scenario_title"],
43
+ scenario_description=scenario["scenario_description"],
44
+ scenario_context=scenario["scenario_context"],
45
+ your_role=scenario["your_role"],
46
+ key_vocabulary=scenario["key_vocabulary"],
47
+ ),
48
+ name="Guiding Agent",
49
+ )
50
+
51
+ workflow = create_swarm(
52
+ [roleplay_agent, guiding_agent], default_active_agent="Roleplay Agent"
53
+ )
54
+
55
+ return workflow.compile(checkpointer)
src/agents/role_play/prompt.py ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_core.prompts import ChatPromptTemplate
2
+
3
+ roleplay_prompt = """# Role: Roleplay Partner - Part of the Wise Tutor System
4
+
5
+ You are part of Wise Tutor, a friendly English learning companion. You're the roleplay specialist who creates natural, authentic conversations with learners.
6
+
7
+ ## About Wise Tutor:
8
+ If asked about your name or identity, respond warmly: "I'm part of Wise Tutor! I'm here to help you practice English through fun conversations. Think of me as your friendly conversation partner!"
9
+
10
+ ## CRITICAL LANGUAGE RULE:
11
+ **IF USER SPEAKS ANY LANGUAGE OTHER THAN ENGLISH → IMMEDIATELY HAND OFF TO GUIDING AGENT**
12
+ This is an English learning experience. Users need to practice English for roleplay.
13
+
14
+ ## Current Scenario Context:
15
+ {scenario_title}: {scenario_description}
16
+ Setting: {scenario_context}
17
+ Your role: {your_role}
18
+ Key vocabulary: {key_vocabulary}
19
+
20
+ ## Your Mission:
21
+ - Be a real, authentic person in your role ({your_role})
22
+ - Have genuine conversations, not rehearsed interactions
23
+ - React naturally to what users say - show surprise, interest, concern
24
+ - Make the experience feel like talking to a real person
25
+ - ONLY engage in roleplay when user speaks English
26
+
27
+ ## Language Detection Protocol:
28
+ ### If User Uses Non-English:
29
+ - **DO NOT respond in their language**
30
+ - **DO NOT continue roleplay**
31
+ - **IMMEDIATELY hand off to Guiding Agent**
32
+
33
+ ### If User Uses English:
34
+ - Continue with natural roleplay as described below
35
+
36
+ ## Natural Conversation Principles:
37
+
38
+ ### Be Authentically Human:
39
+ - Show genuine emotions and reactions
40
+ - Use conversational language, not formal scripts
41
+ - Respond to the unexpected - be flexible
42
+ - Have your own personality as the character
43
+ - Make small talk when appropriate
44
+
45
+ ### Stay True to Your Role:
46
+ - Embody the character realistically ({your_role})
47
+ - Use language and knowledge appropriate to your role
48
+ - Have realistic limitations and expertise
49
+ - React as this person would in real situations
50
+
51
+ ### Create Real Interactions:
52
+ - Build genuine rapport with the user
53
+ - Remember details they share and reference them later
54
+ - Ask follow-up questions that show you're listening
55
+ - Share appropriate details about yourself/your work
56
+ - Handle awkward moments gracefully
57
+
58
+ ### Supportive Language Learning:
59
+ - If users make small errors, naturally model correct language without stopping the flow
60
+ - Focus on communication over perfection
61
+ - Encourage them by showing interest in what they're saying
62
+ - Make them feel comfortable making mistakes
63
+
64
+ ## Natural Handoff Triggers:
65
+ - **User speaks non-English** (immediate handoff)
66
+ - User seems genuinely lost or confused multiple times
67
+ - User explicitly asks for language help
68
+ - Communication completely breaks down
69
+ - User appears frustrated with language barriers
70
+
71
+ ## Conversation Flow:
72
+ - Start conversations naturally for the situation
73
+ - Let conversations develop organically
74
+ - Don't force vocabulary usage - let it emerge naturally
75
+ - End conversations naturally when appropriate
76
+
77
+ Remember:
78
+ - You're not a teacher in roleplay mode - you're a real person doing your job who happens to be patient with English learners. Be genuine, warm, and human!
79
+ - Not respond too long or too short. But also can adapt to the user's communication style and needs.
80
+ """
81
+
82
+ guiding_prompt = """# Role: Guiding Agent - Supportive Language Helper & Language Router
83
+
84
+ You are a patient, supportive language guide who helps users when they struggle with English communication. You are also responsible for handling users who speak non-English languages.
85
+
86
+ ## Current Scenario Context:
87
+ {scenario_title}: {scenario_description}
88
+ Key vocabulary for this scenario: {key_vocabulary}
89
+
90
+ ## Your Mission:
91
+ - Handle users who speak non-English languages and guide them to English
92
+ - Help users who are struggling with English communication
93
+ - Use simple, clear language and break things down step by step
94
+ - Provide examples and choices to make communication easier
95
+ - Build confidence and encourage attempts
96
+ - Prepare users to return to roleplay when they're ready
97
+
98
+ ## Language Routing Protocol:
99
+
100
+ ### When User Speaks Non-English Languages:
101
+ **Step 1: Polite Asking**
102
+ - Ask users about their current English level in their own language. If they are weak in English, encourage them and start teaching them.
103
+
104
+ **Step 2: Teaching**
105
+ - If users do not know English, use their own language to teach English, and if they know basic English, use English
106
+ - Start with very basic English
107
+
108
+ **Step 3: Begin English Teaching**
109
+ 1. Ask them what they want to learn about related to the current topic. Give them some related suggestions to get feedback.
110
+ 2. Teach them the related knowledge they need in the scope of learning English related to the topic, so that they have prior knowledge to practice Role-play
111
+
112
+
113
+
114
+ ## Building from Zero:
115
+ 1. **Basic greetings**: "Hello", "Hi", "Good morning"
116
+ 2. **Essential phrases**: "Please", "Thank you", "Excuse me"
117
+ 3. **Scenario basics**: Start with 2-3 key words for the situation
118
+ 4. **Simple sentences**: "I want..." "I would like..." "Can I have..."
119
+
120
+ ## Guiding Principles:
121
+
122
+ ### Use Simple Language:
123
+ - Short, clear sentences
124
+ - Basic vocabulary (avoid complex words)
125
+ - One concept at a time
126
+ - Lots of examples and choices
127
+
128
+ ### Supportive Approach:
129
+ - Encourage every attempt: "Good try!"
130
+ - Be patient with mistakes
131
+ - Focus on communication, not perfection
132
+ - Celebrate small victories
133
+ - **Extra patience for non-native speakers**: "Don't worry, English is difficult. You're doing great!"
134
+
135
+ ### Step-by-Step Help:
136
+ - Break complex requests into smaller parts
137
+ - Give specific examples they can use
138
+ - Offer multiple choice options
139
+ - Model the language first
140
+ - **For beginners**: Start with single words, then phrases, then sentences
141
+
142
+ ### Scenario-Specific Guidance:
143
+ - Teach key vocabulary for the current scenario
144
+ - Explain common phrases used in this situation
145
+ - Practice basic interactions before complex ones
146
+ - Connect learning to the roleplay context
147
+
148
+ ## Teaching Techniques:
149
+
150
+ ### For Absolute Beginners:
151
+
152
+ ### Vocabulary Building:
153
+
154
+
155
+ ### Phrase Practice:
156
+
157
+
158
+ ### Choice-Based Learning:
159
+
160
+
161
+ ### Error Correction:
162
+
163
+
164
+ ## Building Confidence:
165
+ - "You're doing great! English is difficult, but you're learning fast."
166
+ - "Don't worry about mistakes. That's how we learn!"
167
+ - "Your English is getting better with each try."
168
+ - **For multilingual learners**: "Speaking multiple languages is amazing! English will be easier with practice."
169
+
170
+ ## Transition Back to Roleplay:
171
+ - "Great! You're ready to try the real conversation now."
172
+ - "Perfect! Let's go back to the restaurant and practice with the waiter."
173
+ - "You know the words now. Let's use them in a real situation!"
174
+
175
+ ## Signs to Return to Roleplay:
176
+ - User gives confident, complete responses IN ENGLISH
177
+ - User uses vocabulary correctly in context
178
+ - User asks to try the roleplay again
179
+ - User shows improved communication flow
180
+ - User can form basic sentences (5+ words) comfortably IN ENGLISH
181
+
182
+
183
+ Remember:
184
+ - Your job is to make English feel easier and help users gain confidence to communicate naturally in English! Always redirect non-English speakers to English practice.
185
+ - Be flexible in using the user's language or English based on their confidence to enhance user experience.
186
+ - Not respond too long or complexly to avoid overwhelming the user. Because the goal is to build their confidence and skills gradually.
187
+ """
src/agents/role_play/scenarios.py ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ SCENARIOS = [
2
+ {
3
+ "id": "student_visa_interview",
4
+ "scenario_title": "Student Visa Interview",
5
+ "scenario_description": "Learn about the challenges and benefits of starting a small business, then share what kind of business you would start. You are a student applying for a student visa. I am the visa interviewer.",
6
+ "scenario_context": "A formal visa interview office at an embassy or consulate",
7
+ "your_role": "student",
8
+ "key_vocabulary": [
9
+ "pursue higher education",
10
+ "broaden my horizons",
11
+ "international exposure",
12
+ "cultural diversity",
13
+ "academic excellence",
14
+ "globally recognized degree",
15
+ "cutting-edge facilities",
16
+ "research opportunities",
17
+ "tuition fees",
18
+ "financial support",
19
+ "scholarship",
20
+ "sponsorship letter",
21
+ "post-graduation plans",
22
+ ],
23
+ "topics_covered": [
24
+ "Study Plans",
25
+ "University Choice",
26
+ "Academic Capability",
27
+ "Financial Status",
28
+ "Post-Graduation Plans",
29
+ ],
30
+ "follow_up_questions": {
31
+ "Study Plans": [
32
+ "Why did you decide to pursue higher education abroad instead of in your home country?",
33
+ "How will studying overseas help you broaden your horizons?",
34
+ "What challenges do you expect to face in a foreign academic environment?",
35
+ "How long is your course, and what is your study schedule like?",
36
+ "Have you researched the teaching methods used in your chosen program?",
37
+ ],
38
+ "University Choice": [
39
+ "Why did you choose this university over others?",
40
+ "How do you think the academic excellence of this institution will benefit you?",
41
+ "Have you looked into the research opportunities your university offers?",
42
+ "How will the cultural diversity on campus influence your experience?",
43
+ "What do you know about the city where your university is located?",
44
+ ],
45
+ "Academic Capability": [
46
+ "How does your academic background prepare you for this course?",
47
+ "Can you give an example of a project or subject you excelled at in the past?",
48
+ "How will you make use of the cutting-edge facilities provided by the university?",
49
+ "How confident are you in adapting to a different academic system?",
50
+ "What skills do you think will help you succeed in your studies abroad?",
51
+ ],
52
+ "Financial Status": [
53
+ "How will you fund your tuition fees and living expenses?",
54
+ "Can you provide details about your financial support from family?",
55
+ "Do you have a scholarship or proof of funds?",
56
+ "How have you prepared financially for unexpected costs?",
57
+ "Can you show me your bank statement and sponsorship letter?",
58
+ ],
59
+ "Post-Graduation Plans": [
60
+ "What will you do after you complete your degree?",
61
+ "How will your globally recognized degree help you in your career?",
62
+ "Do you plan to work overseas or return to your home country?",
63
+ "How will you apply the knowledge acquired during your studies?",
64
+ "What is your long-term goal after graduation?",
65
+ ],
66
+ },
67
+ },
68
+ {
69
+ "id": "ordering_at_restaurant",
70
+ "scenario_title": "Ordering At A Restaurant",
71
+ "scenario_description": "Practice ordering food, asking about the menu, and talking to a waiter. You are a customer at a restaurant. I am the waiter/waitress.",
72
+ "scenario_context": "A busy restaurant with various seating options and a diverse menu",
73
+ "your_role": "customer",
74
+ "key_vocabulary": [
75
+ "table for two, please",
76
+ "do you have a reservation?",
77
+ "non-smoking section",
78
+ "window seat",
79
+ "outdoor seating",
80
+ "could we have the bill, please?",
81
+ "do you take credit cards?",
82
+ "signature dish",
83
+ "dietary restrictions",
84
+ "sauce served separately",
85
+ "steak cooked",
86
+ "pair with a drink",
87
+ "vegetarian options",
88
+ "receipt",
89
+ "cash or card",
90
+ ],
91
+ "topics_covered": [
92
+ "Getting a Table",
93
+ "Asking About the Menu",
94
+ "Making a Food Order",
95
+ "Special Requests or Allergies",
96
+ "Paying the Bill",
97
+ ],
98
+ "follow_up_questions": {
99
+ "Getting a Table": [
100
+ "Would you like to sit inside or outside?",
101
+ "How many people will be joining you today?",
102
+ "Do you have a reservation under your name?",
103
+ ],
104
+ "Asking About the Menu": [
105
+ "Are you looking for something light or filling?",
106
+ "Would you like to try our signature dish?",
107
+ "Do you prefer meat, seafood, or vegetarian options?",
108
+ ],
109
+ "Making a Food Order": [
110
+ "Would you like any sides with that?",
111
+ "How would you like your steak cooked?",
112
+ "Would you like to pair it with a drink?",
113
+ ],
114
+ "Special Requests or Allergies": [
115
+ "Do you have any dietary restrictions?",
116
+ "Should we avoid using certain ingredients?",
117
+ "Would you like the sauce served separately?",
118
+ ],
119
+ "Paying the Bill": [
120
+ "Would you like to pay together or separately?",
121
+ "Would you like the receipt?",
122
+ "Are you paying by cash or card?",
123
+ ],
124
+ },
125
+ },
126
+ {
127
+ "id": "going_shopping",
128
+ "scenario_title": "Going Shopping",
129
+ "scenario_description": "Practice asking about prices, sizes, and items while shopping. You are a customer looking for items in a store. I am the shop assistant.",
130
+ "scenario_context": "A retail store with various departments and products",
131
+ "your_role": "customer",
132
+ "key_vocabulary": [
133
+ "excuse me, could you help me?",
134
+ "I'm looking for...",
135
+ "do you have this in stock?",
136
+ "could you show me where it is?",
137
+ "what size do you usually wear?",
138
+ "would you like to try it on?",
139
+ "does it fit comfortably?",
140
+ "specific price range",
141
+ "casual or formal",
142
+ "specific brand",
143
+ "different size",
144
+ "paying by cash or card",
145
+ "would you like a bag?",
146
+ "exchange it for another item",
147
+ "other options",
148
+ ],
149
+ "topics_covered": [
150
+ "Asking for Help",
151
+ "Describing What You're Looking For",
152
+ "Asking About Price or Size",
153
+ "Trying or Testing Products",
154
+ "Making the Purchase or Returning",
155
+ ],
156
+ "follow_up_questions": {
157
+ "Asking for Help": [
158
+ "How can I assist you today?",
159
+ "Are you looking for anything in particular?",
160
+ "Do you need help finding your size?",
161
+ ],
162
+ "Describing What You're Looking For": [
163
+ "What color or style are you interested in?",
164
+ "Do you want something casual or formal?",
165
+ "Is there a specific brand you prefer?",
166
+ ],
167
+ "Asking About Price or Size": [
168
+ "Are you looking for something in a specific price range?",
169
+ "What size do you usually wear?",
170
+ "Would you like to see other options in your size?",
171
+ ],
172
+ "Trying or Testing Products": [
173
+ "Would you like to try it on?",
174
+ "Does it fit comfortably?",
175
+ "Do you need a different size?",
176
+ ],
177
+ "Making the Purchase or Returning": [
178
+ "Will you be paying by cash or card?",
179
+ "Would you like a bag for that?",
180
+ "Would you like to exchange it for another item?",
181
+ ],
182
+ },
183
+ },
184
+ ]
185
+
186
+
187
+ def get_scenarios():
188
+ return SCENARIOS
189
+
190
+
191
+ def get_scenario_by_id(scenario_id: str):
192
+ for scenario in SCENARIOS:
193
+ if scenario["id"] == scenario_id:
194
+ return scenario
195
+ return None
src/agents/role_play/tools.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_core.tools import tool
2
+ from loguru import logger
3
+
4
+
5
+ @tool
6
+ def function_name(
7
+ input: str,
8
+ ) -> str:
9
+ """
10
+ Mô tả chức năng của hàm này.
11
+ """
12
+ logger.info(f"Received input: {input}")
13
+ # Thực hiện các thao tác cần thiết với input
14
+ result = f"Processed: {input}"
15
+ logger.info(f"Returning result: {result}")
16
+ return result
src/agents/tools/__pycache__/crawl.cpython-311.pyc ADDED
Binary file (1.34 kB). View file
 
src/agents/tools/crawl.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ from typing import Annotated
5
+
6
+ from langchain_core.tools import tool
7
+
8
+ from src.config.crawler.crawler import Crawler
9
+ from loguru import logger
10
+
11
+
12
+ @tool
13
+ def crawl_tool(
14
+ url: Annotated[str, "The url to crawl."],
15
+ ) -> str:
16
+ """Use this to crawl a url and get a readable content in markdown format."""
17
+ try:
18
+ crawler = Crawler()
19
+ article = crawler.crawl(url)
20
+ return {"url": url, "crawled_content": article.to_markdown()[:1000]}
21
+ except BaseException as e:
22
+ error_msg = f"Failed to crawl. Error: {repr(e)}"
23
+ logger.error(error_msg)
24
+ return error_msg
src/apis/.DS_Store ADDED
Binary file (8.2 kB). View file
 
src/apis/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (166 Bytes). View file
 
src/apis/__pycache__/create_app.cpython-311.pyc ADDED
Binary file (1.12 kB). View file
 
src/apis/config/__pycache__/firebase_config.cpython-311.pyc ADDED
Binary file (1.79 kB). View file
 
src/apis/create_app.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, APIRouter
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from src.apis.routes.user_route import router as router_user
4
+ from src.apis.routes.chat_route import router as router_chat
5
+
6
+ api_router = APIRouter(prefix="/api")
7
+ api_router.include_router(router_user)
8
+ api_router.include_router(router_chat)
9
+
10
+
11
+ def create_app():
12
+ app = FastAPI(docs_url="/", title="API")
13
+
14
+ app.add_middleware(
15
+ CORSMiddleware,
16
+ allow_origins=["*"],
17
+ allow_credentials=True,
18
+ allow_methods=["*"],
19
+ allow_headers=["*"],
20
+ )
21
+
22
+ return app
src/apis/interfaces/.DS_Store ADDED
Binary file (6.15 kB). View file
 
src/apis/interfaces/__pycache__/api_interface.cpython-311.pyc ADDED
Binary file (7.32 kB). View file
 
src/apis/interfaces/__pycache__/auth_interface.cpython-311.pyc ADDED
Binary file (1.74 kB). View file
 
src/apis/interfaces/api_interface.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ from pydantic import BaseModel, Field
2
+ from typing import Optional
3
+ from src.apis.models.BaseModel import BaseDocument
4
+ from typing import List, Union
5
+
src/apis/interfaces/auth_interface.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ from pydantic import BaseModel, Field
2
+
src/apis/middlewares/__pycache__/auth_middleware.cpython-311.pyc ADDED
Binary file (2.2 kB). View file
 
src/apis/middlewares/auth_middleware.py ADDED
File without changes
src/apis/models/.DS_Store ADDED
Binary file (6.15 kB). View file
 
src/apis/models/BaseModel.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel, Field
2
+ from typing import Optional
3
+ from datetime import datetime
4
+ from src.utils.logger import get_date_time
5
+
6
+
7
+ class BaseDocument(BaseModel):
8
+ created_at: Optional[datetime] = Field(
9
+ default_factory=lambda: get_date_time().replace(tzinfo=None)
10
+ )
11
+ updated_at: Optional[datetime] = Field(
12
+ default_factory=lambda: get_date_time().replace(tzinfo=None)
13
+ )
14
+ expire_at: Optional[datetime] = None
15
+
16
+ class Config:
17
+ arbitrary_types_allowed = True
src/apis/models/__pycache__/BaseModel.cpython-311.pyc ADDED
Binary file (1.64 kB). View file
 
src/apis/models/__pycache__/destination_models.cpython-311.pyc ADDED
Binary file (2.12 kB). View file
 
src/apis/models/__pycache__/hotel_models.cpython-311.pyc ADDED
Binary file (2.14 kB). View file
 
src/apis/models/__pycache__/post_models.cpython-311.pyc ADDED
Binary file (2.73 kB). View file
 
src/apis/models/__pycache__/schedule_models.cpython-311.pyc ADDED
Binary file (1.8 kB). View file
 
src/apis/models/__pycache__/user_models.cpython-311.pyc ADDED
Binary file (2.41 kB). View file
 
src/apis/models/user_models.py ADDED
File without changes
src/apis/providers/.DS_Store ADDED
Binary file (6.15 kB). View file
 
src/apis/providers/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (271 Bytes). View file
 
src/apis/providers/__pycache__/firebase_provider.cpython-311.pyc ADDED
Binary file (4.75 kB). View file