File size: 11,079 Bytes
14015fd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
"""
会話履歴自動記録システム
=======================
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], # 結果は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("✅ テスト完了")
|