|
""" |
|
会話履歴自動記録システム |
|
======================= |
|
|
|
GitHub Copilotとの会話を自動的にSQLiteに保存するためのフックシステム |
|
|
|
使用方法: |
|
1. このモジュールをインポート |
|
2. log_conversation()を呼び出すだけで自動保存 |
|
3. セッション管理も自動化 |
|
""" |
|
|
|
import uuid |
|
import datetime |
|
import json |
|
import os |
|
import traceback |
|
import sqlite3 |
|
from typing import Optional, Dict, List |
|
from controllers.conversation_history import ConversationManager |
|
|
|
class ConversationLogger: |
|
def __init__(self): |
|
"""会話ログシステムの初期化""" |
|
self.conversation_manager = ConversationManager() |
|
self.current_session_id = self.generate_session_id() |
|
self.session_start_time = datetime.datetime.now() |
|
|
|
print(f"🎯 会話ログシステム開始 - セッションID: {self.current_session_id[:8]}") |
|
|
|
def generate_session_id(self) -> str: |
|
"""新しいセッションIDを生成""" |
|
return str(uuid.uuid4()) |
|
|
|
def start_new_session(self, session_name: str = None) -> str: |
|
"""新しいセッションを開始""" |
|
self.current_session_id = self.generate_session_id() |
|
self.session_start_time = datetime.datetime.now() |
|
|
|
if session_name: |
|
|
|
try: |
|
conn = sqlite3.connect(self.conversation_manager.db_path) |
|
cursor = conn.cursor() |
|
cursor.execute(''' |
|
UPDATE sessions |
|
SET session_name = ? |
|
WHERE session_id = ? |
|
''', (session_name, self.current_session_id)) |
|
conn.commit() |
|
conn.close() |
|
except Exception as e: |
|
print(f"⚠️ セッション名更新エラー: {e}") |
|
|
|
print(f"🆕 新しいセッション開始: {self.current_session_id[:8]}") |
|
return self.current_session_id |
|
|
|
def log_conversation(self, |
|
user_message: str, |
|
assistant_response: str, |
|
context_info: str = "", |
|
files_involved: List[str] = None, |
|
tools_used: List[str] = None, |
|
tags: List[str] = None, |
|
project_name: str = "ContBK統合システム") -> Optional[int]: |
|
""" |
|
会話を自動記録 |
|
|
|
Args: |
|
user_message: ユーザーからのメッセージ |
|
assistant_response: アシスタントの応答 |
|
context_info: コンテキスト情報 |
|
files_involved: 関連ファイルのリスト |
|
tools_used: 使用ツールのリスト |
|
tags: タグのリスト |
|
project_name: プロジェクト名 |
|
|
|
Returns: |
|
会話ID (保存に成功した場合) |
|
""" |
|
try: |
|
|
|
files_str = ", ".join(files_involved) if files_involved else "" |
|
tools_str = ", ".join(tools_used) if tools_used else "" |
|
tags_str = ", ".join(tags) if tags else "" |
|
|
|
|
|
conversation_id = self.conversation_manager.save_conversation( |
|
session_id=self.current_session_id, |
|
user_message=user_message, |
|
assistant_response=assistant_response, |
|
context_info=context_info, |
|
files_involved=files_str, |
|
tools_used=tools_str, |
|
tags=tags_str |
|
) |
|
|
|
print(f"✅ 会話を記録しました (ID: {conversation_id})") |
|
return conversation_id |
|
|
|
except Exception as e: |
|
print(f"❌ 会話記録エラー: {e}") |
|
print(traceback.format_exc()) |
|
return None |
|
|
|
def log_tool_usage(self, tool_name: str, parameters: Dict, result: str): |
|
"""ツール使用ログを記録""" |
|
tool_info = { |
|
"tool": tool_name, |
|
"parameters": parameters, |
|
"result": result[:500], |
|
"timestamp": datetime.datetime.now().isoformat() |
|
} |
|
|
|
|
|
try: |
|
conn = sqlite3.connect(self.conversation_manager.db_path) |
|
cursor = conn.cursor() |
|
|
|
|
|
cursor.execute(''' |
|
SELECT id, tools_used FROM conversations |
|
WHERE session_id = ? |
|
ORDER BY timestamp DESC |
|
LIMIT 1 |
|
''', (self.current_session_id,)) |
|
|
|
row = cursor.fetchone() |
|
if row: |
|
conversation_id, existing_tools = row |
|
|
|
|
|
updated_tools = existing_tools + f", {tool_name}" if existing_tools else tool_name |
|
|
|
cursor.execute(''' |
|
UPDATE conversations |
|
SET tools_used = ?, updated_at = CURRENT_TIMESTAMP |
|
WHERE id = ? |
|
''', (updated_tools, conversation_id)) |
|
|
|
conn.commit() |
|
|
|
conn.close() |
|
print(f"🔧 ツール使用を記録: {tool_name}") |
|
|
|
except Exception as e: |
|
print(f"⚠️ ツール使用記録エラー: {e}") |
|
|
|
def get_session_summary(self) -> Dict: |
|
"""現在のセッションの要約を取得""" |
|
try: |
|
conversations = self.conversation_manager.get_conversations( |
|
session_id=self.current_session_id |
|
) |
|
|
|
return { |
|
"session_id": self.current_session_id, |
|
"start_time": self.session_start_time.isoformat(), |
|
"conversation_count": len(conversations), |
|
"duration_minutes": (datetime.datetime.now() - self.session_start_time).total_seconds() / 60, |
|
"latest_conversation": conversations[0] if conversations else None |
|
} |
|
except Exception as e: |
|
print(f"⚠️ セッション要約取得エラー: {e}") |
|
return {} |
|
|
|
def export_session(self, session_id: str = None) -> str: |
|
"""セッションをJSON形式でエクスポート""" |
|
target_session = session_id or self.current_session_id |
|
|
|
try: |
|
conversations = self.conversation_manager.get_conversations( |
|
session_id=target_session |
|
) |
|
|
|
export_data = { |
|
"session_id": target_session, |
|
"export_time": datetime.datetime.now().isoformat(), |
|
"conversation_count": len(conversations), |
|
"conversations": conversations |
|
} |
|
|
|
filename = f"session_export_{target_session[:8]}_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.json" |
|
|
|
with open(filename, 'w', encoding='utf-8') as f: |
|
json.dump(export_data, f, ensure_ascii=False, indent=2) |
|
|
|
print(f"📥 セッションエクスポート完了: {filename}") |
|
return filename |
|
|
|
except Exception as e: |
|
print(f"❌ セッションエクスポートエラー: {e}") |
|
return "" |
|
|
|
|
|
conversation_logger = ConversationLogger() |
|
|
|
def log_this_conversation(user_msg: str, assistant_msg: str, |
|
context: str = "", files: List[str] = None, |
|
tools: List[str] = None, tags: List[str] = None): |
|
""" |
|
簡単な会話ログ記録関数 |
|
|
|
使用例: |
|
log_this_conversation( |
|
user_msg="ContBK統合システムについて教えて", |
|
assistant_msg="ContBK統合システムは...", |
|
files=["controllers/contbk_example.py"], |
|
tools=["create_file", "insert_edit_into_file"], |
|
tags=["contbk", "gradio"] |
|
) |
|
""" |
|
return conversation_logger.log_conversation( |
|
user_message=user_msg, |
|
assistant_response=assistant_msg, |
|
context_info=context, |
|
files_involved=files, |
|
tools_used=tools, |
|
tags=tags |
|
) |
|
|
|
def start_new_conversation_session(session_name: str = None): |
|
"""新しい会話セッションを開始""" |
|
return conversation_logger.start_new_session(session_name) |
|
|
|
def get_current_session_info(): |
|
"""現在のセッション情報を取得""" |
|
return conversation_logger.get_session_summary() |
|
|
|
|
|
def auto_log_conversation(tags: List[str] = None): |
|
""" |
|
関数の実行を自動的にログに記録するデコレーター |
|
|
|
使用例: |
|
@auto_log_conversation(tags=["gradio", "interface"]) |
|
def create_interface(): |
|
# 関数の処理 |
|
pass |
|
""" |
|
def decorator(func): |
|
def wrapper(*args, **kwargs): |
|
start_time = datetime.datetime.now() |
|
|
|
try: |
|
result = func(*args, **kwargs) |
|
|
|
|
|
conversation_logger.log_conversation( |
|
user_message=f"関数実行: {func.__name__}", |
|
assistant_response=f"関数 {func.__name__} が正常に実行されました", |
|
context_info=f"実行時間: {(datetime.datetime.now() - start_time).total_seconds():.2f}秒", |
|
tools_used=[func.__name__], |
|
tags=tags or ["自動実行"] |
|
) |
|
|
|
return result |
|
|
|
except Exception as e: |
|
|
|
conversation_logger.log_conversation( |
|
user_message=f"関数実行エラー: {func.__name__}", |
|
assistant_response=f"エラーが発生しました: {str(e)}", |
|
context_info=f"実行時間: {(datetime.datetime.now() - start_time).total_seconds():.2f}秒", |
|
tools_used=[func.__name__], |
|
tags=(tags or []) + ["エラー"] |
|
) |
|
raise |
|
|
|
return wrapper |
|
return decorator |
|
|
|
if __name__ == "__main__": |
|
|
|
print("🧪 会話ログシステムテスト") |
|
|
|
|
|
log_this_conversation( |
|
user_msg="会話履歴システムのテストです", |
|
assistant_msg="会話履歴システムが正常に動作しています!", |
|
context="テスト実行", |
|
files=["controllers/conversation_logger.py"], |
|
tools=["create_file"], |
|
tags=["テスト", "会話履歴"] |
|
) |
|
|
|
|
|
session_info = get_current_session_info() |
|
print(f"📊 セッション情報: {session_info}") |
|
|
|
print("✅ テスト完了") |
|
|