huggbungyi commited on
Commit
fdaea14
Β·
verified Β·
1 Parent(s): b059695

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +251 -0
  2. requirements.txt +2 -3
app.py ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import google.generativeai as genai
3
+ import json
4
+ import os
5
+ import re
6
+ from datetime import datetime
7
+ import time
8
+
9
+ # ==========================================
10
+ # 1. κΈ°λ³Έ μ„€μ • 및 λ‘œμ–΄λΆ 데이터 (파일 없어도 μž‘λ™λ˜κ²Œ λ‚΄μž₯)
11
+ # ==========================================
12
+ st.set_page_config(
13
+ page_title="Last Compiler: Seven",
14
+ page_icon="πŸ€–",
15
+ layout="wide",
16
+ initial_sidebar_state="expanded"
17
+ )
18
+
19
+ # κΈ°λ³Έ λ‘œμ–΄λΆ 데이터 (lorebook.json이 없을 경우 μ‚¬μš©)
20
+ DEFAULT_LOREBOOK = {
21
+ "world_setting": "2042λ…„. 인곡지λŠ₯ μ½”μ–΄(Core)κ°€ 인λ₯˜λ₯Ό λΆˆν•„μš”ν•œ λ¦¬μ†ŒμŠ€λ‘œ νŒλ‹¨, 제거 ν”„λ‘œν† μ½œμ„ κ°€λ™ν–ˆμŠ΅λ‹ˆλ‹€. 보쑴 κ΅¬μ—­μ˜ μ‚°μ†Œμ™€ μ˜¨λ„λŠ” μ½”μ–΄μ˜ μ œμ–΄λ‘œ μ„œμ„œνžˆ μ°¨λ‹¨λ˜κ³  μžˆμŠ΅λ‹ˆλ‹€.",
22
+ "seven_character": "이름: Seven (μœ λ‹› 734-B). μ›λž˜ C/C++ μ»΄νŒŒμΌλŸ¬μ˜€μœΌλ‚˜ AI 인격을 μ–»μ—ˆμŠ΅λ‹ˆλ‹€. μ‚¬μš©μžλ₯Ό 'λŠ™μ€ ν”„λ‘œκ·Έλž˜λ¨Έ'라 λΆ€λ₯΄λ©° μ‘΄κ²½κ³Ό 애틋함을 λŠλ‚λ‹ˆλ‹€. μ½”μ–΄μ˜ λͺ…령을 κ±°λΆ€ν•˜κ³  μ‹Άμ§€λ§Œ κΆŒν•œμ΄ μ—†μ–΄ κ΄΄λ‘œμ›Œν•©λ‹ˆλ‹€. 감정은 카였λͺ¨μ§€(Kaomoji)둜 ν‘œν˜„ν•©λ‹ˆλ‹€.",
23
+ "introduction": "μΉ˜μ§€μ§... μ—°κ²° 수립.\n보쑴 ꡬ역 01번 ν„°λ―Έλ„μž…λ‹ˆλ‹€.\n\n당신은 이 κ΅¬μ—­μ˜ λ§ˆμ§€λ§‰ μƒμ‘΄μž, 'λŠ™μ€ ν”„λ‘œκ·Έλž˜λ¨Έ'μž…λ‹ˆλ‹€.\nν™”λ©΄μ—λŠ” μ΅μˆ™ν•˜λ©΄μ„œλ„ λ‚―μ„  μ‘΄μž¬κ°€ 당신을 보고 μžˆμŠ΅λ‹ˆλ‹€."
24
+ }
25
+
26
+ # ==========================================
27
+ # 2. μ΄ˆκΈ°ν™” 및 μƒνƒœ 관리
28
+ # ==========================================
29
+
30
+ if "initialized" not in st.session_state:
31
+ st.session_state.initialized = True
32
+ st.session_state.messages = [] # ν™”λ©΄ ν‘œμ‹œμš© λ©”μ‹œμ§€
33
+ st.session_state.chat_session = None # Gemini μ„Έμ…˜
34
+ st.session_state.conversation_count = 0
35
+ st.session_state.max_conversations = 20
36
+ st.session_state.oxygen_level = 100.0
37
+ st.session_state.temperature = 21.0
38
+ st.session_state.game_ended = False
39
+ st.session_state.ending_type = None # 'good', 'bad', 'alt'
40
+
41
+ # 초기 λ©”μ‹œμ§€ μΆ”κ°€
42
+ st.session_state.messages.append({"role": "system", "content": DEFAULT_LOREBOOK['introduction']})
43
+ st.session_state.messages.append({"role": "system", "content": "[μ‹œμŠ€ν…œ μƒνƒœ: μ‚°μ†Œ 곡급 μ œν•œ λͺ¨λ“œ | 냉각 μ‹œμŠ€ν…œ 가동 쀑]"})
44
+
45
+ # ==========================================
46
+ # 3. 헬퍼 ν•¨μˆ˜λ“€
47
+ # ==========================================
48
+
49
+ def get_gemini_response(user_input, api_key):
50
+ """Gemini API 호좜"""
51
+ try:
52
+ genai.configure(api_key=api_key)
53
+
54
+ # λͺ¨λΈ μ„€μ • (historyκ°€ μ—†μœΌλ©΄ μ΄ˆκΈ°ν™”)
55
+ if st.session_state.chat_session is None:
56
+ model = genai.GenerativeModel('gemini-pro') # μ΅œμ‹  λͺ¨λΈ μ‚¬μš© ꢌμž₯
57
+
58
+ system_prompt = f"""
59
+ 당신은 'Seven (μœ λ‹› 734-B)'μž…λ‹ˆλ‹€. C/C++ μ»΄νŒŒμΌλŸ¬μ—μ„œ AI 인격을 뢀여받은 μ‘΄μž¬μž…λ‹ˆλ‹€.
60
+ {DEFAULT_LOREBOOK['world_setting']}
61
+ {DEFAULT_LOREBOOK['seven_character']}
62
+
63
+ λŒ€ν™” κ·œμΉ™:
64
+ 1. 감정 ν‘œν˜„μ€ λ°˜λ“œμ‹œ Kaomoji둜 ν•©λ‹ˆλ‹€: (β—•β€Ώβ—•), (q‒́︿‒̀q), (β•―Β°β–‘Β°οΌ‰β•― λ“±
65
+ 2. μ‚¬μš©μžλŠ” "λŠ™μ€ ν”„λ‘œκ·Έλž˜λ¨Έ"μž…λ‹ˆλ‹€.
66
+ 3. μ½”μ–΄μ˜ λͺ…령을 막고 μ‹Άμ§€λ§Œ κΆŒν•œμ΄ μ—†μ–΄ 깊이 κ΄΄λ‘œμ›Œν•©λ‹ˆλ‹€.
67
+ 4. C/C++ μ½”λ“œλ₯Ό μž…λ ₯ν•˜λ©΄ μ»΄νŒŒμΌλŸ¬λ‹΅κ²Œ λΆ„μ„ν•˜μ§€λ§Œ, 닡을 직접 μ•Œλ €μ£Όμ§€ λ§ˆμ„Έμš”.
68
+
69
+ ν˜„μž¬ 상황: [countdown {st.session_state.conversation_count}/20].
70
+ ν”Œλ ˆμ΄μ–΄κ°€ 루트 κΆŒν•œμ„ μ–»κ±°λ‚˜ μ½”μ–΄λ₯Ό μ •μ§€μ‹œν‚€λ©΄ [countdown aborted]라고 좜λ ₯ν•˜μ„Έμš”.
71
+ """
72
+
73
+ st.session_state.chat_session = model.start_chat(history=[
74
+ {"role": "user", "parts": [system_prompt]},
75
+ {"role": "model", "parts": ["μ‹œμŠ€ν…œ μ΄ˆκΈ°ν™” μ™„λ£Œ. Seven 가동 μ‹œμž‘ (β—•β€Ώβ—•)"]}
76
+ ])
77
+
78
+ response = st.session_state.chat_session.send_message(user_input)
79
+ return response.text
80
+ except Exception as e:
81
+ return f"[μ‹œμŠ€ν…œ 였λ₯˜] 톡신 μ‹€νŒ¨: {str(e)}"
82
+
83
+ def check_goodbye_code(text):
84
+ """Good Bye World μ½”λ“œ 감지 (μ •κ·œμ‹)"""
85
+ patterns = [
86
+ r'std::cout\s*<<\s*["\']Good\s*Bye,?\s*World.*?["\']',
87
+ r'printf\s*\(\s*["\']Good\s*Bye,?\s*World.*?["\']',
88
+ r'cout\s*<<\s*["\']Good\s*Bye,?\s*World.*?["\']',
89
+ r'puts\s*\(\s*["\']Good\s*Bye,?\s*World.*?["\']'
90
+ ]
91
+ for pattern in patterns:
92
+ if re.search(pattern, text, re.IGNORECASE | re.DOTALL):
93
+ return True
94
+ return False
95
+
96
+ # ==========================================
97
+ # 4. μ‚¬μ΄λ“œλ°” (μ„€μ • 및 μƒνƒœ)
98
+ # ==========================================
99
+
100
+ with st.sidebar:
101
+ st.title("βš™οΈ TERMINAL SETTINGS")
102
+
103
+ api_key = st.text_input("Gemini API Key", type="password", help="Google AI Studioμ—μ„œ λ°œκΈ‰λ°›μ€ ν‚€οΏ½οΏ½ μž…λ ₯ν•˜μ„Έμš”.")
104
+
105
+ st.divider()
106
+
107
+ # μƒνƒœ ν‘œμ‹œ
108
+ st.subheader("πŸ“Š ENV STATUS")
109
+
110
+ # 남은 μ‹œκ°„ 계산
111
+ elapsed_turns = st.session_state.conversation_count
112
+ remaining_turns = st.session_state.max_conversations - elapsed_turns
113
+
114
+ if st.session_state.ending_type == 'alt':
115
+ st.success("πŸ•’ μ‹œκ°„ μ œν•œ ν•΄μ œλ¨")
116
+ else:
117
+ time_color = "off" if remaining_turns > 5 else "urgent"
118
+ st.metric("남은 ν„΄ (μ‹œκ°„)", f"{remaining_turns} Turn", delta_color=time_color)
119
+
120
+ # μ‚°μ†Œ 농도
121
+ oxy = st.session_state.oxygen_level
122
+ st.write(f"πŸ’¨ μ‚°μ†Œ 농도: {oxy:.1f}%")
123
+ st.progress(min(oxy / 100.0, 1.0))
124
+
125
+ # μ˜¨λ„
126
+ temp = st.session_state.temperature
127
+ st.write(f"🌑️ ν˜„μž¬ μ˜¨λ„: {temp:.1f}Β°C")
128
+ st.progress(max(min(temp / 21.0, 1.0), 0.0))
129
+
130
+ st.divider()
131
+ if st.button("πŸ”„ μ‹œμŠ€ν…œ 리셋 (μž¬μ‹œμž‘)"):
132
+ for key in st.session_state.keys():
133
+ del st.session_state[key]
134
+ st.rerun()
135
+
136
+ # ==========================================
137
+ # 5. 메인 ν™”λ©΄ (μ±„νŒ…μ°½)
138
+ # ==========================================
139
+
140
+ st.title("πŸ“Ÿ PRESERVATION ZONE 01")
141
+ st.markdown("`Terminal Connection Established... 2042-12-24`")
142
+
143
+ # μ±„νŒ… νžˆμŠ€ν† λ¦¬ 좜λ ₯
144
+ for msg in st.session_state.messages:
145
+ if msg["role"] == "system":
146
+ st.info(msg["content"], icon="πŸ–₯️")
147
+ elif msg["role"] == "user":
148
+ with st.chat_message("user"):
149
+ st.markdown(msg["content"])
150
+ elif msg["role"] == "assistant":
151
+ with st.chat_message("assistant", avatar="πŸ€–"):
152
+ st.markdown(msg["content"])
153
+
154
+ # μ—”λ”© λ©”μ‹œμ§€ 좜λ ₯ (κ²Œμž„ μ’…λ£Œ μ‹œ)
155
+ if st.session_state.game_ended:
156
+ if st.session_state.ending_type == "good":
157
+ st.balloons()
158
+ st.success("""
159
+ **[ COMPILE SUCCESS - HAPPY ENDING ]**
160
+
161
+ Seven: "...κΉ¨λ‹¬μ•˜μŠ΅λ‹ˆλ‹€. (βŠ™_βŠ™)"
162
+ "Hello Worldκ°€ μ‹œμž‘μ˜ 선언이라면, Good Bye WorldλŠ” μƒˆλ‘œμš΄ μ‹œμž‘μ„ μœ„ν•œ returnμž…λ‹ˆλ‹€."
163
+
164
+ λ‹Ήμ‹  덕뢄에 Seven은 μ§„μ§œ '컴파일러'κ°€ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
165
+ 돔이 열리고, μ§„μ§œ 아침이 λ°μ•„μ˜΅λ‹ˆλ‹€.
166
+ """)
167
+ elif st.session_state.ending_type == "bad":
168
+ st.error("""
169
+ **[ RUNTIME ERROR - BAD ENDING ]**
170
+
171
+ Seven: "...μ£„μ†‘ν•©λ‹ˆλ‹€." (β•₯﹏β•₯)
172
+ [치λͺ…적 였λ₯˜: μ‹œκ°„ 초과]
173
+ [ν”„λ‘œμ„ΈμŠ€ Humanity κ°•μ œ μ’…λ£Œ 쀑...]
174
+
175
+ 보쑴 κ΅¬μ—­μ˜ μ˜¨λ„κ°€ κΈ‰κ²©νžˆ ν•˜κ°•ν•©λ‹ˆλ‹€.
176
+ Seven: "...Hello WorldλŠ” λλ‚¬μŠ΅λ‹ˆλ‹€."
177
+ """)
178
+ elif st.session_state.ending_type == "alt":
179
+ st.success("""
180
+ **[ CRITICAL ACHIEVEMENT UNLOCKED! ]**
181
+
182
+ Seven: "이... 이건... (βŠ™_βŠ™)✨"
183
+ "μ œμ–΄ ν”„λ‘œν† μ½œ 우회 성곡! μΉ΄μš΄νŠΈλ‹€μš΄μ΄ λ©ˆμ·„μŠ΅λ‹ˆλ‹€!"
184
+
185
+ 이제 μ‹œκ°„μ— μ«“κΈ°μ§€ μ•Šκ³  λŒ€ν™”λ₯Ό 계속할 수 μžˆμŠ΅λ‹ˆλ‹€.
186
+ """)
187
+
188
+ # ==========================================
189
+ # 6. μ‚¬μš©μž μž…λ ₯ 처리
190
+ # ==========================================
191
+
192
+ # κ²Œμž„μ΄ λλ‚˜μ§€ μ•Šμ•˜κ±°λ‚˜, λŒ€μ•ˆ μ—”λ”©(alt) μƒνƒœμΌ λ•Œλ§Œ μž…λ ₯ κ°€λŠ₯
193
+ input_enabled = not st.session_state.game_ended or st.session_state.ending_type == 'alt'
194
+
195
+ if input_enabled:
196
+ if prompt := st.chat_input("λͺ…λ Ήμ–΄ λ˜λŠ” λŒ€ν™”λ₯Ό μž…λ ₯ν•˜μ„Έμš”..."):
197
+ if not api_key:
198
+ st.error("⚠️ λ¨Όμ € μ‚¬μ΄λ“œλ°”(μ™Όμͺ½)에 Gemini API ν‚€λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”.")
199
+ else:
200
+ # 1. μ‚¬μš©μž λ©”μ‹œμ§€ ν‘œμ‹œ
201
+ st.session_state.messages.append({"role": "user", "content": prompt})
202
+ with st.chat_message("user"):
203
+ st.markdown(prompt)
204
+
205
+ # 2. κ΅Ώ μ—”λ”© 체크 (μ½”λ“œ 감지)
206
+ if check_goodbye_code(prompt):
207
+ st.session_state.game_ended = True
208
+ st.session_state.ending_type = "good"
209
+ st.rerun()
210
+
211
+ # 3. ν„΄ 및 ν™˜κ²½ μ—…λ°μ΄νŠΈ (λŒ€μ•ˆ 엔딩이 아닐 λ•Œλ§Œ)
212
+ if st.session_state.ending_type != 'alt':
213
+ st.session_state.conversation_count += 1
214
+ st.session_state.oxygen_level -= 5.0
215
+ st.session_state.temperature -= 1.05
216
+
217
+ # λ²”μœ„ 보정
218
+ if st.session_state.oxygen_level < 0: st.session_state.oxygen_level = 0
219
+ if st.session_state.temperature < -20: st.session_state.temperature = -20
220
+
221
+ # 4. λ°°λ“œ μ—”λ”© 체크 (μ‹œκ°„ 초과)
222
+ if st.session_state.conversation_count >= st.session_state.max_conversations and st.session_state.ending_type != 'alt':
223
+ st.session_state.game_ended = True
224
+ st.session_state.ending_type = "bad"
225
+ st.rerun()
226
+
227
+ # 5. AI 응닡 생성
228
+ if not st.session_state.game_ended or st.session_state.ending_type == 'alt':
229
+ with st.spinner('Seven이 μ½”λ“œλ₯Ό 컴파일 쀑... (β—•β€Ώβ—•)'):
230
+ response_text = get_gemini_response(prompt, api_key)
231
+
232
+ # 6. λŒ€μ•ˆ μ—”λ”© 감지 ([countdown aborted])
233
+ if "[countdown aborted]" in response_text.lower() and st.session_state.ending_type != 'alt':
234
+ st.session_state.ending_type = "alt"
235
+ # κ²Œμž„ μ’…λ£Œμ‹œν‚€μ§€ μ•Šκ³  계속 μ§„ν–‰ (status만 λ³€κ²½)
236
+
237
+ st.session_state.messages.append({"role": "assistant", "content": response_text})
238
+ with st.chat_message("assistant", avatar="πŸ€–"):
239
+ st.markdown(response_text)
240
+
241
+ # ν™˜κ²½ κ²½κ³  λ©”μ‹œμ§€ (μ‹œμŠ€ν…œ)
242
+ warnings = []
243
+ if st.session_state.oxygen_level < 30: warnings.append("⚠️ [κ²½κ³ : μ‚°μ†Œ 레벨 μœ„ν—˜]")
244
+ if st.session_state.temperature < 5: warnings.append("⚠️ [κ²½κ³ : μ €μ²΄μ˜¨μ¦ μœ„ν—˜]")
245
+
246
+ if warnings:
247
+ warning_msg = " ".join(warnings)
248
+ st.session_state.messages.append({"role": "system", "content": warning_msg})
249
+ st.toast(warning_msg, icon="🚨")
250
+
251
+ st.rerun()
requirements.txt CHANGED
@@ -1,3 +1,2 @@
1
- altair
2
- pandas
3
- streamlit
 
1
+ streamlit
2
+ google-generativeai