sirochild commited on
Commit
d207861
·
verified ·
1 Parent(s): a569292

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -34
app.py CHANGED
@@ -11,11 +11,17 @@ import re
11
  load_dotenv()
12
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
13
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
 
 
14
  if not GEMINI_API_KEY or not GROQ_API_KEY:
15
- raise ValueError("GEMINI_API_KEY と GROQ_API_KEY をSecretsに設定してください。")
 
 
 
 
16
 
17
  genai.configure(api_key=GEMINI_API_KEY)
18
- gemini_model = genai.GenerativeModel('gemini-2.5-flash-lite')
19
  groq_client = Groq(api_key=GROQ_API_KEY)
20
 
21
  print("日本語感情分析モデルをロード中...")
@@ -43,7 +49,7 @@ DEFAULT_SCENE_PARAMS = {
43
  "constraints": ["会話を「別に。」のような一言で終わらせない", "必ず相手の発言を拾ってリアクションを返す"]
44
  }
45
 
46
- # --- 2. 機能定義(省略なし) ---
47
 
48
  def detect_scene_change(history, message):
49
  history_text = "\n".join([f"ユーザー: {u}\n麻理: {m}" for u, m in history[-4:]])
@@ -121,7 +127,7 @@ def generate_dialogue_with_gemini(history, message, affection, stage_name, scene
121
  try:
122
  generation_config = genai.types.GenerationConfig(max_output_tokens=200, temperature=0.95)
123
  response = gemini_model.generate_content(system_prompt, generation_config=generation_config)
124
- return response.text
125
  except Exception as e:
126
  print(f"応答生成エラー(Gemini): {e}")
127
  return "(ごめんなさい、ちょっと考えがまとまらない……)"
@@ -142,7 +148,7 @@ def update_affection(message, affection):
142
  return affection
143
  return affection
144
 
145
- # --- メイン応答処理 ---
146
 
147
  def respond(message, chat_history, affection, history, scene_params):
148
  new_affection = update_affection(message, affection)
@@ -151,40 +157,30 @@ def respond(message, chat_history, affection, history, scene_params):
151
 
152
  final_scene_params = scene_params
153
 
154
- if new_scene_name:
 
155
  new_params_base = generate_scene_instruction_with_groq(new_affection, stage_name, new_scene_name, message)
156
  if new_params_base:
157
  final_scene_params = {**DEFAULT_SCENE_PARAMS, **new_params_base}
158
  instruction = final_scene_params.get("initial_dialogue_instruction")
159
  bot_message = generate_dialogue_with_gemini(history, message, new_affection, stage_name, final_scene_params, instruction=instruction)
160
- else:
 
161
  bot_message = generate_dialogue_with_gemini(history, message, new_affection, stage_name, final_scene_params)
162
  else:
163
  bot_message = generate_dialogue_with_gemini(history, message, new_affection, stage_name, final_scene_params)
164
 
165
  new_history = history + [(message, bot_message)]
166
  chat_history.append((message, bot_message))
 
167
  theme_name = final_scene_params.get("theme", "default")
168
- background_url = THEME_URLS.get(theme_name, THEME_URLS["default"])
169
-
170
- js_script = f"""
171
- <script>
172
- setTimeout(() => {{
173
- const chat = document.getElementById("chat_area");
174
- if (chat) {{
175
- console.log("背景画像を設定: {background_url}");
176
- chat.style.backgroundImage = "url('{background_url}')";
177
- chat.style.backgroundSize = "cover";
178
- chat.style.backgroundPosition = "center";
179
- chat.style.transition = "background-image 1s ease-in-out";
180
- }}
181
- }}, 100);
182
- </script>
183
- """
184
-
185
- return "", chat_history, new_affection, stage_name, new_affection, new_history, final_scene_params, js_script
186
-
187
- # --- Gradio UI ---
188
 
189
  with gr.Blocks(css="style.css", theme=gr.themes.Soft(primary_hue="rose", secondary_hue="pink")) as demo:
190
  scene_state = gr.State(DEFAULT_SCENE_PARAMS)
@@ -194,19 +190,36 @@ with gr.Blocks(css="style.css", theme=gr.themes.Soft(primary_hue="rose", seconda
194
  gr.Markdown("# 麻理チャット")
195
  with gr.Row():
196
  with gr.Column(scale=2):
197
- chatbot = gr.Chatbot(label="麻理との会���", height=600, bubble_full_width=False, elem_id="chat_area")
198
- msg_input = gr.Textbox(label="あなたのメッセージ", placeholder="「水族館はどう?」と聞いた後、「いいね、行こう!」のように返してみてください", scale=5)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  with gr.Column(scale=1):
200
- stage_display = gr.Textbox(label="現在の関係ステージ", interactive=False)
201
  affection_gauge = gr.Slider(minimum=0, maximum=100, label="麻理の好感度", value=30, interactive=False)
202
- js_injector = gr.HTML(elem_classes="hidden")
203
 
 
204
  msg_input.submit(
205
  respond,
206
  [msg_input, chatbot, affection_state, history_state, scene_state],
207
- [msg_input, chatbot, affection_gauge, stage_display, affection_state, history_state, scene_state, js_injector]
208
  )
 
 
209
 
210
  if __name__ == "__main__":
211
- demo.launch()
212
-
 
11
  load_dotenv()
12
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
13
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
14
+
15
+ # Hugging Face SpacesのSecretsに設定されているかチェック
16
  if not GEMINI_API_KEY or not GROQ_API_KEY:
17
+ # ローカルでの実行のために、環境変数が設定されていない場合はダミー値を設定
18
+ print("警告: APIキーがSecretsに設定されていません。")
19
+ # 実行を止めないようにダミーを設定(デプロイ時はSecrets設定が必須)
20
+ GEMINI_API_KEY = "your_gemini_api_key_here"
21
+ GROQ_API_KEY = "your_groq_api_key_here"
22
 
23
  genai.configure(api_key=GEMINI_API_KEY)
24
+ gemini_model = genai.GenerativeModel('gemini-1.5-flash')
25
  groq_client = Groq(api_key=GROQ_API_KEY)
26
 
27
  print("日本語感情分析モデルをロード中...")
 
49
  "constraints": ["会話を「別に。」のような一言で終わらせない", "必ず相手の発言を拾ってリアクションを返す"]
50
  }
51
 
52
+ # --- 2. 機能定義 ---
53
 
54
  def detect_scene_change(history, message):
55
  history_text = "\n".join([f"ユーザー: {u}\n麻理: {m}" for u, m in history[-4:]])
 
127
  try:
128
  generation_config = genai.types.GenerationConfig(max_output_tokens=200, temperature=0.95)
129
  response = gemini_model.generate_content(system_prompt, generation_config=generation_config)
130
+ return response.text.strip()
131
  except Exception as e:
132
  print(f"応答生成エラー(Gemini): {e}")
133
  return "(ごめんなさい、ちょっと考えがまとまらない……)"
 
148
  return affection
149
  return affection
150
 
151
+ # --- 3. メイン応答処理 ---
152
 
153
  def respond(message, chat_history, affection, history, scene_params):
154
  new_affection = update_affection(message, affection)
 
157
 
158
  final_scene_params = scene_params
159
 
160
+ if new_scene_name and new_scene_name in THEME_URLS:
161
+ print(f"シーンチェンジを検出: {new_scene_name}")
162
  new_params_base = generate_scene_instruction_with_groq(new_affection, stage_name, new_scene_name, message)
163
  if new_params_base:
164
  final_scene_params = {**DEFAULT_SCENE_PARAMS, **new_params_base}
165
  instruction = final_scene_params.get("initial_dialogue_instruction")
166
  bot_message = generate_dialogue_with_gemini(history, message, new_affection, stage_name, final_scene_params, instruction=instruction)
167
+ else: # Groqが失敗した場合のフォールバック
168
+ final_scene_params["theme"] = new_scene_name
169
  bot_message = generate_dialogue_with_gemini(history, message, new_affection, stage_name, final_scene_params)
170
  else:
171
  bot_message = generate_dialogue_with_gemini(history, message, new_affection, stage_name, final_scene_params)
172
 
173
  new_history = history + [(message, bot_message)]
174
  chat_history.append((message, bot_message))
175
+
176
  theme_name = final_scene_params.get("theme", "default")
177
+
178
+ # 背景レイヤーのHTMLコンテンツをクラス名付きで生成
179
+ background_html = f'<div class="chat-background {theme_name}"></div>'
180
+
181
+ return "", chat_history, new_affection, stage_name, new_affection, new_history, final_scene_params, background_html
182
+
183
+ # --- 4. Gradio UI ---
 
 
 
 
 
 
 
 
 
 
 
 
 
184
 
185
  with gr.Blocks(css="style.css", theme=gr.themes.Soft(primary_hue="rose", secondary_hue="pink")) as demo:
186
  scene_state = gr.State(DEFAULT_SCENE_PARAMS)
 
190
  gr.Markdown("# 麻理チャット")
191
  with gr.Row():
192
  with gr.Column(scale=2):
193
+ # チャットボットと背景を重ねるためのコンテナ
194
+ with gr.Column(elem_id="chat_container"):
195
+ # 背景レイヤー
196
+ background_display = gr.HTML(
197
+ f'<div class="chat-background {DEFAULT_SCENE_PARAMS["theme"]}"></div>',
198
+ elem_id="background_container"
199
+ )
200
+ # チャットボット
201
+ chatbot = gr.Chatbot(
202
+ label="麻理との会話", bubble_full_width=False, elem_id="chat_area", show_label=False
203
+ )
204
+
205
+ msg_input = gr.Textbox(
206
+ label="あなたのメッセージ",
207
+ placeholder="「水族館はどう?」と聞いた後、「いいね、行こう!」のように返してみてください",
208
+ scale=5,
209
+ show_label=False
210
+ )
211
  with gr.Column(scale=1):
212
+ stage_display = gr.Textbox(label="現在の関係ステージ", interactive=False, value=get_relationship_stage(30))
213
  affection_gauge = gr.Slider(minimum=0, maximum=100, label="麻理の好感度", value=30, interactive=False)
 
214
 
215
+ # 応答関数とUIコンポーネントの接続を更新
216
  msg_input.submit(
217
  respond,
218
  [msg_input, chatbot, affection_state, history_state, scene_state],
219
+ [msg_input, chatbot, affection_gauge, stage_display, affection_state, history_state, scene_state, background_display]
220
  )
221
+ # ページロード時に初期ステージを表示
222
+ demo.load(lambda affection: get_relationship_stage(affection), affection_state, stage_display)
223
 
224
  if __name__ == "__main__":
225
+ demo.launch()