Update app.py
Browse files
app.py
CHANGED
@@ -2034,6 +2034,192 @@ def generate_fallback_response(theme_id: str, level: str) -> str:
|
|
2034 |
logging.error(f"Error generating fallback response: {str(e)}")
|
2035 |
return "What happens next?"
|
2036 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2037 |
def show_main_interface():
|
2038 |
"""Display main story interface"""
|
2039 |
col1, col2 = st.columns([3, 1])
|
@@ -2073,6 +2259,14 @@ def main():
|
|
2073 |
init_session_state()
|
2074 |
init_theme_state()
|
2075 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2076 |
# Add watermark
|
2077 |
st.markdown("""
|
2078 |
<div style='position: fixed; bottom: 10px; right: 10px; z-index: 1000;
|
@@ -2099,11 +2293,37 @@ def main():
|
|
2099 |
if not st.session_state.current_theme:
|
2100 |
show_theme_selection()
|
2101 |
else:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2102 |
show_main_interface()
|
|
|
|
|
|
|
|
|
|
|
2103 |
|
2104 |
# Handle reset if needed
|
2105 |
if st.session_state.should_reset:
|
2106 |
reset_story()
|
|
|
|
|
|
|
|
|
2107 |
|
2108 |
# Auto-save progress periodically
|
2109 |
if st.session_state.story:
|
|
|
2034 |
logging.error(f"Error generating fallback response: {str(e)}")
|
2035 |
return "What happens next?"
|
2036 |
|
2037 |
+
def show_story_progress():
|
2038 |
+
"""Display story progress metrics"""
|
2039 |
+
if st.session_state.story:
|
2040 |
+
total_sentences = len(st.session_state.story)
|
2041 |
+
st.markdown(f"""
|
2042 |
+
<div style="
|
2043 |
+
background-color: #f0f7ff;
|
2044 |
+
padding: 15px;
|
2045 |
+
border-radius: 10px;
|
2046 |
+
margin: 10px 0;
|
2047 |
+
">
|
2048 |
+
<div style="margin-bottom: 10px;">
|
2049 |
+
📊 ความยาวเรื่อง: {total_sentences} ประโยค
|
2050 |
+
</div>
|
2051 |
+
<div class="progress-bar">
|
2052 |
+
<div class="progress-bar-fill" style="width: {min(total_sentences * 10, 100)}%;"></div>
|
2053 |
+
</div>
|
2054 |
+
<div style="font-size: 0.9em; color: #666; margin-top: 5px;">
|
2055 |
+
เรื่องควรยาว 10-20 ประโยค เพื่อความสมบูรณ์
|
2056 |
+
</div>
|
2057 |
+
</div>
|
2058 |
+
""", unsafe_allow_html=True)
|
2059 |
+
|
2060 |
+
def show_story_ending_options():
|
2061 |
+
"""Display story ending options and guidance"""
|
2062 |
+
if len(st.session_state.story) >= 10: # แสดงตัวเลือกเมื่อเรื่องยาวพอ
|
2063 |
+
st.markdown("### 🎭 ต้องการจบเรื่องหรือไม่?")
|
2064 |
+
|
2065 |
+
# แสดงตัวเลือกวิธีจบเรื่อง
|
2066 |
+
ending_type = st.radio(
|
2067 |
+
"เลือกวิธีจบเรื่อง:",
|
2068 |
+
options=[
|
2069 |
+
"Happy Ending - จบแบบมีความสุข",
|
2070 |
+
"Mysterious Ending - จบแบบทิ้งท้ายให้คิดต่อ",
|
2071 |
+
"Lesson Learned - จบแบบได้ข้อคิด",
|
2072 |
+
"Surprise Ending - จบแบบพลิกความคาดหมาย"
|
2073 |
+
],
|
2074 |
+
index=0,
|
2075 |
+
help="เลือกรูปแบบการจบเรื่องที่คุณต้องการ"
|
2076 |
+
)
|
2077 |
+
|
2078 |
+
if st.button("🎬 เริ่มจบเรื่อง", use_container_width=True):
|
2079 |
+
st.session_state.ending_mode = True
|
2080 |
+
st.session_state.ending_type = ending_type
|
2081 |
+
st.session_state.sentences_to_end = 5
|
2082 |
+
st.rerun()
|
2083 |
+
|
2084 |
+
def handle_ending_mode(text: str):
|
2085 |
+
"""Handle story submission during ending mode"""
|
2086 |
+
remaining = st.session_state.sentences_to_end
|
2087 |
+
|
2088 |
+
# แสดงการแจ้งเตือนจำนวนประโยคที่เหลือ
|
2089 |
+
st.info(f"🎯 เหลืออีก {remaining} ประโยคในการจบเรื่อง")
|
2090 |
+
|
2091 |
+
# สร้าง prompt พิเศษสำหรับ AI ในโหมดจบเรื่อง
|
2092 |
+
ending_prompts = {
|
2093 |
+
"Happy Ending": "Work towards a positive and uplifting conclusion",
|
2094 |
+
"Mysterious Ending": "Create an intriguing open-ended conclusion",
|
2095 |
+
"Lesson Learned": "Incorporate a meaningful life lesson",
|
2096 |
+
"Surprise Ending": "Build up to an unexpected twist"
|
2097 |
+
}
|
2098 |
+
|
2099 |
+
# ปรับ AI response ให้พยายามจบเรื่อง
|
2100 |
+
modified_continuation = generate_ending_continuation(
|
2101 |
+
text,
|
2102 |
+
ending_type=st.session_state.ending_type,
|
2103 |
+
remaining_sentences=remaining
|
2104 |
+
)
|
2105 |
+
|
2106 |
+
# อัพเดทจำนวนประโยคที่เหลือ
|
2107 |
+
st.session_state.sentences_to_end -= 1
|
2108 |
+
|
2109 |
+
# ตรวจสอบว่าถึงจบเรื่องหรือยัง
|
2110 |
+
if st.session_state.sentences_to_end <= 0:
|
2111 |
+
complete_story()
|
2112 |
+
|
2113 |
+
def generate_ending_continuation(text: str, ending_type: str, remaining_sentences: int) -> str:
|
2114 |
+
"""Generate AI continuation focusing on story conclusion"""
|
2115 |
+
try:
|
2116 |
+
ending_prompts = {
|
2117 |
+
"Happy Ending": """
|
2118 |
+
Role: Story concluder aiming for a happy ending
|
2119 |
+
Goal: Create a satisfying, positive conclusion
|
2120 |
+
Rules:
|
2121 |
+
- Build towards joy, success, or resolution
|
2122 |
+
- Use uplifting and positive language
|
2123 |
+
- Connect to previous story elements
|
2124 |
+
""",
|
2125 |
+
"Mysterious Ending": """
|
2126 |
+
Role: Mystery writer creating intrigue
|
2127 |
+
Goal: Leave readers thinking and wondering
|
2128 |
+
Rules:
|
2129 |
+
- Add subtle hints and clues
|
2130 |
+
- Create atmospheric descriptions
|
2131 |
+
- Leave some questions unanswered
|
2132 |
+
""",
|
2133 |
+
"Lesson Learned": """
|
2134 |
+
Role: Moral story concluder
|
2135 |
+
Goal: Incorporate meaningful life lessons
|
2136 |
+
Rules:
|
2137 |
+
- Connect actions to consequences
|
2138 |
+
- Show character growth
|
2139 |
+
- Express the moral naturally
|
2140 |
+
""",
|
2141 |
+
"Surprise Ending": """
|
2142 |
+
Role: Plot twist creator
|
2143 |
+
Goal: Deliver unexpected but satisfying conclusion
|
2144 |
+
Rules:
|
2145 |
+
- Plant subtle hints earlier
|
2146 |
+
- Subvert expectations logically
|
2147 |
+
- Maintain story coherence
|
2148 |
+
"""
|
2149 |
+
}
|
2150 |
+
|
2151 |
+
response = client.chat.completions.create(
|
2152 |
+
model="gpt-4",
|
2153 |
+
messages=[
|
2154 |
+
{
|
2155 |
+
"role": "system",
|
2156 |
+
"content": f"""
|
2157 |
+
{ending_prompts[ending_type]}
|
2158 |
+
|
2159 |
+
Additional Rules:
|
2160 |
+
- You have {remaining_sentences} sentences to conclude
|
2161 |
+
- Each response should be max 2 sentences
|
2162 |
+
- Build towards the finale naturally
|
2163 |
+
- Connect to previous story elements
|
2164 |
+
"""
|
2165 |
+
},
|
2166 |
+
{
|
2167 |
+
"role": "user",
|
2168 |
+
"content": f"Continue and work towards ending this story: {text}"
|
2169 |
+
}
|
2170 |
+
],
|
2171 |
+
max_tokens=100,
|
2172 |
+
temperature=0.7
|
2173 |
+
)
|
2174 |
+
|
2175 |
+
return response.choices[0].message.content.strip()
|
2176 |
+
|
2177 |
+
except Exception as e:
|
2178 |
+
logging.error(f"Error generating ending: {str(e)}")
|
2179 |
+
return "The story moved towards its conclusion..."
|
2180 |
+
|
2181 |
+
def complete_story():
|
2182 |
+
"""Handle story completion and celebration"""
|
2183 |
+
st.balloons() # แสดงเอฟเฟคฉลอง
|
2184 |
+
|
2185 |
+
# สร้าง Story Summary
|
2186 |
+
story_summary = generate_story_summary(st.session_state.story)
|
2187 |
+
|
2188 |
+
# แสดงหน้าจบเรื่อง
|
2189 |
+
st.markdown(f"""
|
2190 |
+
<div style="
|
2191 |
+
background-color: #e8f5e9;
|
2192 |
+
padding: 20px;
|
2193 |
+
border-radius: 10px;
|
2194 |
+
text-align: center;
|
2195 |
+
margin: 20px 0;
|
2196 |
+
">
|
2197 |
+
<h2>🎉 ยินดีด้วย! คุณเขียนเรื่องราวจบสมบูรณ์แล้ว</h2>
|
2198 |
+
|
2199 |
+
<div style="margin: 20px 0;">
|
2200 |
+
<h3>📝 สรุปเรื่องราว</h3>
|
2201 |
+
<p>{story_summary}</p>
|
2202 |
+
</div>
|
2203 |
+
|
2204 |
+
<div style="margin: 20px 0;">
|
2205 |
+
<h3>🏆 ความสำเร็จ</h3>
|
2206 |
+
<p>จำนวนประโยค: {len(st.session_state.story)}</p>
|
2207 |
+
<p>คำศัพท์ที่ใช้: {len(st.session_state.stats['vocabulary_used'])}</p>
|
2208 |
+
<p>ความแม่นยำ: {st.session_state.stats['accuracy_rate']:.1f}%</p>
|
2209 |
+
</div>
|
2210 |
+
</div>
|
2211 |
+
""", unsafe_allow_html=True)
|
2212 |
+
|
2213 |
+
# แสดงตัวเลือกหลังจบเรื่อง
|
2214 |
+
col1, col2 = st.columns(2)
|
2215 |
+
with col1:
|
2216 |
+
if st.button("💾 บันทึกเรื่องราว", use_container_width=True):
|
2217 |
+
save_completed_story()
|
2218 |
+
with col2:
|
2219 |
+
if st.button("🔄 เริ่มเรื่องใหม่", use_container_width=True):
|
2220 |
+
reset_story()
|
2221 |
+
st.rerun()
|
2222 |
+
|
2223 |
def show_main_interface():
|
2224 |
"""Display main story interface"""
|
2225 |
col1, col2 = st.columns([3, 1])
|
|
|
2259 |
init_session_state()
|
2260 |
init_theme_state()
|
2261 |
|
2262 |
+
# Initialize ending system state if not exists
|
2263 |
+
if 'ending_mode' not in st.session_state:
|
2264 |
+
st.session_state.ending_mode = False
|
2265 |
+
if 'sentences_to_end' not in st.session_state:
|
2266 |
+
st.session_state.sentences_to_end = 5
|
2267 |
+
if 'ending_type' not in st.session_state:
|
2268 |
+
st.session_state.ending_type = None
|
2269 |
+
|
2270 |
# Add watermark
|
2271 |
st.markdown("""
|
2272 |
<div style='position: fixed; bottom: 10px; right: 10px; z-index: 1000;
|
|
|
2293 |
if not st.session_state.current_theme:
|
2294 |
show_theme_selection()
|
2295 |
else:
|
2296 |
+
# Show story progress if story exists
|
2297 |
+
if st.session_state.story:
|
2298 |
+
show_story_progress()
|
2299 |
+
|
2300 |
+
# Show ending options if story is long enough and not in ending mode
|
2301 |
+
if (len(st.session_state.story) >= 10 and
|
2302 |
+
not st.session_state.ending_mode):
|
2303 |
+
show_story_ending_options()
|
2304 |
+
|
2305 |
+
# Show ending mode warning if active
|
2306 |
+
if st.session_state.ending_mode:
|
2307 |
+
st.warning(f"""
|
2308 |
+
🎭 กำลังอยู่ในโหมดจบเรื่อง - เหลือ {st.session_state.sentences_to_end} ประโยค
|
2309 |
+
\nรูปแบบการจบ: {st.session_state.ending_type}
|
2310 |
+
""")
|
2311 |
+
|
2312 |
+
# Show main interface
|
2313 |
show_main_interface()
|
2314 |
+
|
2315 |
+
# Check if story is complete
|
2316 |
+
if (st.session_state.ending_mode and
|
2317 |
+
st.session_state.sentences_to_end <= 0):
|
2318 |
+
complete_story()
|
2319 |
|
2320 |
# Handle reset if needed
|
2321 |
if st.session_state.should_reset:
|
2322 |
reset_story()
|
2323 |
+
# Reset ending mode states
|
2324 |
+
st.session_state.ending_mode = False
|
2325 |
+
st.session_state.sentences_to_end = 5
|
2326 |
+
st.session_state.ending_type = None
|
2327 |
|
2328 |
# Auto-save progress periodically
|
2329 |
if st.session_state.story:
|