Yasu777 commited on
Commit
d0ad526
·
verified ·
1 Parent(s): e81d0e0

Update chat.py

Browse files
Files changed (1) hide show
  1. chat.py +200 -1
chat.py CHANGED
@@ -2,7 +2,7 @@ import streamlit as st
2
  import re
3
  import os
4
  from groq import Groq
5
- from utils import load_system_prompt, extract_all_code_blocks, is_physics_related, save_generated_code_to_new_file # save_generated_code_to_new_fileutilsからインポート
6
 
7
  def setup_chat(api_key, mobile=False):
8
  """チャット機能とその関連機能をセットアップする"""
@@ -67,6 +67,11 @@ def process_chat_input(prompt, api_key):
67
  process_mode_command(prompt)
68
  return
69
 
 
 
 
 
 
70
  # 通常の質問処理
71
  process_normal_query(prompt, api_key)
72
 
@@ -165,6 +170,95 @@ def process_mode_command(prompt):
165
  # アシスタントメッセージをセッション状態に追加
166
  st.session_state.messages.append({"role": "assistant", "content": response})
167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  def process_normal_query(prompt, api_key):
169
  """通常の質問を処理し、AIからの応答を生成する"""
170
  # APIキーがある場合のみ実行
@@ -298,6 +392,31 @@ def generate_chain_response(user_input, api_key):
298
  editor_code = st.session_state.files[st.session_state.current_file]
299
  editor_reference = f"現在エディタで開かれているファイル '{st.session_state.current_file}':\n```\n{editor_code}\n```"
300
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  # 通常モード用のシステムプロンプトをロード
302
  system_prompt = load_system_prompt(MODELS["qwen_coder"], "通常モード")
303
 
@@ -320,6 +439,10 @@ def generate_chain_response(user_input, api_key):
320
  if editor_code:
321
  qwen_prompt += f"\n\n{editor_reference}\n\nエディタで開かれているコードに関して、ユーザーの質問に答えるか、必要に応じてコードの改善を提案してください。"
322
 
 
 
 
 
323
  qwen_response = client.chat.completions.create(
324
  model=MODELS["qwen_coder"],
325
  messages=[
@@ -341,6 +464,26 @@ def generate_chain_response(user_input, api_key):
341
  deepseek_section = f"DeepSeekの物理学的知見:\n{deepseek_knowledge}"
342
  physics_note = "この実装には物理シミュレーションが含まれているため、物理法則の正確性と数値的安定性を特に重視してください。"
343
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
  # Step 2a: 設計フェーズ - 専用のプロンプトを使用
345
  design_system_prompt = load_system_prompt(MODELS["qwen_coder"], "実装モード_設計")
346
 
@@ -357,6 +500,10 @@ def generate_chain_response(user_input, api_key):
357
  if is_physics:
358
  design_prompt += f"\n\n{deepseek_section}"
359
 
 
 
 
 
360
  design_response = client.chat.completions.create(
361
  model=MODELS["qwen_coder"],
362
  messages=[
@@ -389,6 +536,10 @@ def generate_chain_response(user_input, api_key):
389
  {user_input}
390
  """
391
 
 
 
 
 
392
  implementation_response = client.chat.completions.create(
393
  model=MODELS["qwen_coder"],
394
  messages=[
@@ -426,6 +577,26 @@ def generate_chain_response(user_input, api_key):
426
  if is_physics:
427
  deepseek_section = f"DeepSeekの物理学的知見:\n{deepseek_knowledge}"
428
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
429
  # エラー修正モード用のシステムプロンプトをロード
430
  error_system_prompt = load_system_prompt(MODELS["qwen_coder"], "エラー修正モード")
431
 
@@ -454,6 +625,10 @@ def generate_chain_response(user_input, api_key):
454
  if is_physics:
455
  error_prompt += f"\n\n{deepseek_section}"
456
 
 
 
 
 
457
  error_response = client.chat.completions.create(
458
  model=MODELS["qwen_coder"],
459
  messages=[
@@ -504,6 +679,26 @@ def generate_direct_response(user_input, api_key):
504
  editor_code = st.session_state.files[st.session_state.current_file]
505
  editor_reference = f"\n\n現在エディタで開かれているファイル '{st.session_state.current_file}':\n```\n{editor_code}\n```\n\nエディタで開かれているコードに関して、ユーザーの質問に答えるか、必要に応じてコードの改善を提案してください。"
506
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
507
  qwen_prompt = f"""
508
  あなたはユーザーと継続的な会話を行っているアシスタントです。
509
  これまでの会話の流れを踏まえて、最新のユーザー入力に適切に応答してください。
@@ -521,6 +716,10 @@ def generate_direct_response(user_input, api_key):
521
  if editor_code:
522
  qwen_prompt += editor_reference
523
 
 
 
 
 
524
  qwen_response = client.chat.completions.create(
525
  model=MODELS["qwen_coder"],
526
  messages=[
 
2
  import re
3
  import os
4
  from groq import Groq
5
+ from utils import load_system_prompt, extract_all_code_blocks, is_physics_related, save_generated_code_to_new_file, get_file_dependencies # get_file_dependenciesをインポート
6
 
7
  def setup_chat(api_key, mobile=False):
8
  """チャット機能とその関連機能をセットアップする"""
 
67
  process_mode_command(prompt)
68
  return
69
 
70
+ # ファイル解析コマンドを検出
71
+ if prompt.strip().startswith("/analyse") or prompt.strip().startswith("/analyze"):
72
+ process_analyze_command(api_key)
73
+ return
74
+
75
  # 通常の質問処理
76
  process_normal_query(prompt, api_key)
77
 
 
170
  # アシスタントメッセージをセッション状態に追加
171
  st.session_state.messages.append({"role": "assistant", "content": response})
172
 
173
+ def process_analyze_command(api_key):
174
+ """アップロードされたファイル群を解析するコマンドを処理する"""
175
+ # ファイルが存在するか確認
176
+ if not st.session_state.files:
177
+ response = "解析するファイルがありません。まずはファイルをアップロードするか作成してください。"
178
+ st.chat_message("assistant").markdown(response)
179
+ st.session_state.messages.append({"role": "assistant", "content": response})
180
+ return
181
+
182
+ with st.spinner("ファイル群を解析中..."):
183
+ # 依存関係の分析を実行
184
+ dependencies, file_summary = get_file_dependencies(st.session_state.files)
185
+
186
+ # 解析結果を生成
187
+ all_files_content = ""
188
+ for filename, content in st.session_state.files.items():
189
+ # ファイルサイズが大きい場合は先頭部分のみ
190
+ if len(content) > 1000:
191
+ all_files_content += f"\n\nファイル '{filename}'(先頭部分):\n```\n{content[:1000]}...\n```"
192
+ else:
193
+ all_files_content += f"\n\nファイル '{filename}':\n```\n{content}\n```"
194
+
195
+ # AIに解析を依頼
196
+ client = Groq(api_key=api_key)
197
+
198
+ # モデル名のマッピング
199
+ from config import MODELS
200
+
201
+ system_prompt = load_system_prompt(MODELS["qwen_coder"], "通常モード")
202
+ system_prompt += """
203
+ 複数のファイルからなるプロジェクトを解析する際は、以下の点に注目してください:
204
+ 1. ファイル間の依存関係と呼び出し構造
205
+ 2. 主要なクラスやモジュールの責任範囲
206
+ 3. データの流れと状態管理の方法
207
+ 4. アプリケーションのアーキテクチャパターン
208
+ 5. コードの再利用性と保守性
209
+
210
+ 解析結果は以下の構造で提供してください:
211
+ 1. プロジェクト概要 - 全体の目的と機能
212
+ 2. 主要コンポーネント - 各ファイルの役割と責任
213
+ 3. 依存関係図 - ファイル間の関係性
214
+ 4. アーキテクチャ評価 - 設計パターンと原則の適用状況
215
+ 5. 改善提案 - リファクタリングや拡張のための提案
216
+ """
217
+
218
+ analyze_prompt = f"""
219
+ 以下のファイル群からなるプロジェクトの構造と依存関係を分析してください。
220
+ 各ファイルの役割、相互関係、データフローを明確にし、システム全体の理解を深めるための
221
+ 包括的な分析を提供してください。
222
+
223
+ ファイル依存関係の分析結果:
224
+ {dependencies}
225
+
226
+ ファイル概要:
227
+ {file_summary}
228
+
229
+ アップロードされたファイル群の内容(一部省略あり):
230
+ {all_files_content}
231
+ """
232
+
233
+ # 回答の生成
234
+ response = client.chat.completions.create(
235
+ model=MODELS["qwen_coder"],
236
+ messages=[
237
+ {"role": "system", "content": system_prompt},
238
+ {"role": "user", "content": analyze_prompt}
239
+ ],
240
+ temperature=0.5,
241
+ max_tokens=4000
242
+ )
243
+
244
+ analysis_result = response.choices[0].message.content
245
+
246
+ # 分析結果を思考プロセスに追加
247
+ st.session_state.thinking_process.append({
248
+ "title": "プロジェクト構造解析",
249
+ "content": f"依存関係:\n{dependencies}\n\nファイル概要:\n{file_summary}"
250
+ })
251
+
252
+ # レスポンスを表示
253
+ st.chat_message("assistant").markdown(analysis_result)
254
+
255
+ # アシスタントメッセージをセッション状態に追加
256
+ st.session_state.messages.append({"role": "assistant", "content": analysis_result})
257
+
258
+ # 明示的に表示を更新するために変数を設定
259
+ st.session_state.ui_needs_update = True
260
+ st.rerun()
261
+
262
  def process_normal_query(prompt, api_key):
263
  """通常の質問を処理し、AIからの応答を生成する"""
264
  # APIキーがある場合のみ実行
 
392
  editor_code = st.session_state.files[st.session_state.current_file]
393
  editor_reference = f"現在エディタで開かれているファイル '{st.session_state.current_file}':\n```\n{editor_code}\n```"
394
 
395
+ # アップロードされた全ファイルのリストを作成
396
+ all_files_context = ""
397
+ mentioned_files = []
398
+
399
+ # ユーザー入力で言及されたファイル名を抽出
400
+ for filename in st.session_state.files.keys():
401
+ if filename in user_input and filename != st.session_state.current_file:
402
+ mentioned_files.append(filename)
403
+
404
+ # ファイルコンテキストの生成
405
+ if mentioned_files:
406
+ all_files_context = "ユーザーが言及したファイル:\n"
407
+ for filename in mentioned_files:
408
+ file_content = st.session_state.files[filename]
409
+ # ファイルサイズが大きい場合は先頭部分のみ含める
410
+ if len(file_content) > 1500:
411
+ all_files_context += f"\nファイル '{filename}'(先頭部分):\n```\n{file_content[:1500]}...\n```"
412
+ else:
413
+ all_files_context += f"\nファイル '{filename}':\n```\n{file_content}\n```"
414
+ elif len(st.session_state.files) > 1: # 複数ファイルがある場合
415
+ all_files_context = "アップロードされたファイル一覧:\n"
416
+ for filename in st.session_state.files.keys():
417
+ if filename != st.session_state.current_file: # 現在開いているファイル以外
418
+ all_files_context += f"- {filename}\n"
419
+
420
  # 通常モード用のシステムプロンプトをロード
421
  system_prompt = load_system_prompt(MODELS["qwen_coder"], "通常モード")
422
 
 
439
  if editor_code:
440
  qwen_prompt += f"\n\n{editor_reference}\n\nエディタで開かれているコードに関して、ユーザーの質問に答えるか、必要に応じてコードの改善を提案してください。"
441
 
442
+ # アップロードされたファイル情報を追加
443
+ if all_files_context:
444
+ qwen_prompt += f"\n\n{all_files_context}"
445
+
446
  qwen_response = client.chat.completions.create(
447
  model=MODELS["qwen_coder"],
448
  messages=[
 
464
  deepseek_section = f"DeepSeekの物理学的知見:\n{deepseek_knowledge}"
465
  physics_note = "この実装には物理シミュレーションが含まれているため、物理法則の正確性と数値的安定性を特に重視してください。"
466
 
467
+ # アップロードされたファイル情報を取得
468
+ all_files_context = ""
469
+ mentioned_files = []
470
+
471
+ # ユーザー入力で言及されたファイル名を抽出
472
+ for filename in st.session_state.files.keys():
473
+ if filename in user_input:
474
+ mentioned_files.append(filename)
475
+
476
+ # ファイルコンテキストの生成
477
+ if mentioned_files:
478
+ all_files_context = "参照すべきファイル:\n"
479
+ for filename in mentioned_files:
480
+ file_content = st.session_state.files[filename]
481
+ # ファイルサイズが大きい場合は先頭部分のみ含める
482
+ if len(file_content) > 1000:
483
+ all_files_context += f"\nファイル '{filename}'(先頭部分):\n```\n{file_content[:1000]}...\n```"
484
+ else:
485
+ all_files_context += f"\nファイル '{filename}':\n```\n{file_content}\n```"
486
+
487
  # Step 2a: 設計フェーズ - 専用のプロンプトを使用
488
  design_system_prompt = load_system_prompt(MODELS["qwen_coder"], "実装モード_設計")
489
 
 
500
  if is_physics:
501
  design_prompt += f"\n\n{deepseek_section}"
502
 
503
+ # アップロードされたファイル情報を追加
504
+ if all_files_context:
505
+ design_prompt += f"\n\n{all_files_context}\n\n上記ファイルの構造や機能を考慮して設計を行ってください。"
506
+
507
  design_response = client.chat.completions.create(
508
  model=MODELS["qwen_coder"],
509
  messages=[
 
536
  {user_input}
537
  """
538
 
539
+ # アップロードされたファイル情報を追加(実装フェーズでも必要)
540
+ if all_files_context:
541
+ implementation_prompt += f"\n\n{all_files_context}\n\n上記の既存ファイルと互換性のあるコードを生成してください。"
542
+
543
  implementation_response = client.chat.completions.create(
544
  model=MODELS["qwen_coder"],
545
  messages=[
 
577
  if is_physics:
578
  deepseek_section = f"DeepSeekの物理学的知見:\n{deepseek_knowledge}"
579
 
580
+ # アップロードされたファイル情報を取得
581
+ all_files_context = ""
582
+ mentioned_files = []
583
+
584
+ # ユーザー入力で言及されたファイル名を抽出
585
+ for filename in st.session_state.files.keys():
586
+ if filename in user_input and filename != st.session_state.current_file:
587
+ mentioned_files.append(filename)
588
+
589
+ # ファイルコンテキストの生成
590
+ if mentioned_files:
591
+ all_files_context = "関連するファイル:\n"
592
+ for filename in mentioned_files:
593
+ file_content = st.session_state.files[filename]
594
+ # ファイルサイズが大きい場合は先頭部分のみ含める
595
+ if len(file_content) > 1000:
596
+ all_files_context += f"\nファイル '{filename}'(先頭部分):\n```\n{file_content[:1000]}...\n```"
597
+ else:
598
+ all_files_context += f"\nファイル '{filename}':\n```\n{file_content}\n```"
599
+
600
  # エラー修正モード用のシステムプロンプトをロード
601
  error_system_prompt = load_system_prompt(MODELS["qwen_coder"], "エラー修正モード")
602
 
 
625
  if is_physics:
626
  error_prompt += f"\n\n{deepseek_section}"
627
 
628
+ # 関連ファイル情報を追加
629
+ if all_files_context:
630
+ error_prompt += f"\n\n{all_files_context}"
631
+
632
  error_response = client.chat.completions.create(
633
  model=MODELS["qwen_coder"],
634
  messages=[
 
679
  editor_code = st.session_state.files[st.session_state.current_file]
680
  editor_reference = f"\n\n現在エディタで開かれているファイル '{st.session_state.current_file}':\n```\n{editor_code}\n```\n\nエディタで開かれているコードに関して、ユーザーの質問に答えるか、必要に応じてコードの改善を提案してください。"
681
 
682
+ # ユーザー入力で言及されたファイルに関する情報を追加
683
+ all_files_context = ""
684
+ mentioned_files = []
685
+
686
+ # ユーザー入力で言及されたファイル名を抽出
687
+ for filename in st.session_state.files.keys():
688
+ if filename in user_input and filename != st.session_state.current_file:
689
+ mentioned_files.append(filename)
690
+
691
+ # ファイルコンテキストの生成
692
+ if mentioned_files:
693
+ all_files_context = "\n\nユーザーが言及したファイル:\n"
694
+ for filename in mentioned_files:
695
+ file_content = st.session_state.files[filename]
696
+ # ファイルサイズが大きい場合は先頭部分のみ含める
697
+ if len(file_content) > 1000:
698
+ all_files_context += f"\nファイル '{filename}'(先頭部分):\n```\n{file_content[:1000]}...\n```"
699
+ else:
700
+ all_files_context += f"\nファイル '{filename}':\n```\n{file_content}\n```"
701
+
702
  qwen_prompt = f"""
703
  あなたはユーザーと継続的な会話を行っているアシスタントです。
704
  これまでの会話の流れを踏まえて、最新のユーザー入力に適切に応答してください。
 
716
  if editor_code:
717
  qwen_prompt += editor_reference
718
 
719
+ # 言及されたファイルがある場合はコンテキストに追加
720
+ if all_files_context:
721
+ qwen_prompt += all_files_context
722
+
723
  qwen_response = client.chat.completions.create(
724
  model=MODELS["qwen_coder"],
725
  messages=[