Update app.py
Browse files
    	
        app.py
    CHANGED
    
    | @@ -1,401 +1,2 @@ | |
| 1 | 
             
            import os
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            import gradio as gr
         | 
| 4 | 
            -
            from huggingface_hub import InferenceClient
         | 
| 5 | 
            -
            import pandas as pd
         | 
| 6 | 
            -
            from typing import List, Tuple
         | 
| 7 | 
            -
            import json
         | 
| 8 | 
            -
            from datetime import datetime
         | 
| 9 | 
            -
            from datasets import load_dataset
         | 
| 10 | 
            -
             | 
| 11 | 
            -
            try:
         | 
| 12 | 
            -
                legal_dataset = load_dataset("aiqtech/kolaw")
         | 
| 13 | 
            -
                print("법률 데이터셋 로드 완료")
         | 
| 14 | 
            -
            except Exception as e:
         | 
| 15 | 
            -
                print(f"법률 데이터셋 로드 실패: {e}")
         | 
| 16 | 
            -
                legal_dataset = None
         | 
| 17 | 
            -
             | 
| 18 | 
            -
            # 환경 변수 설정
         | 
| 19 | 
            -
            HF_TOKEN = os.getenv("HF_TOKEN")
         | 
| 20 | 
            -
             | 
| 21 | 
            -
            # LLM Models Definition
         | 
| 22 | 
            -
            LLM_MODELS = {
         | 
| 23 | 
            -
                "Cohere c4ai-crp-08-2024": "CohereForAI/c4ai-command-r-plus-08-2024",  # Default
         | 
| 24 | 
            -
                "Meta Llama3.3-70B": "meta-llama/Llama-3.3-70B-Instruct"    # Backup model
         | 
| 25 | 
            -
            }
         | 
| 26 | 
            -
             | 
| 27 | 
            -
            class ChatHistory:
         | 
| 28 | 
            -
                def __init__(self):
         | 
| 29 | 
            -
                    self.history = []
         | 
| 30 | 
            -
                    self.history_file = "/tmp/chat_history.json"
         | 
| 31 | 
            -
                    self.load_history()
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                def add_conversation(self, user_msg: str, assistant_msg: str):
         | 
| 34 | 
            -
                    conversation = {
         | 
| 35 | 
            -
                        "timestamp": datetime.now().isoformat(),
         | 
| 36 | 
            -
                        "messages": [
         | 
| 37 | 
            -
                            {"role": "user", "content": user_msg},
         | 
| 38 | 
            -
                            {"role": "assistant", "content": assistant_msg}
         | 
| 39 | 
            -
                        ]
         | 
| 40 | 
            -
                    }
         | 
| 41 | 
            -
                    self.history.append(conversation)
         | 
| 42 | 
            -
                    self.save_history()
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                def format_for_display(self):
         | 
| 45 | 
            -
                    # Gradio Chatbot 컴포넌트에 맞는 형식으로 변환
         | 
| 46 | 
            -
                    formatted = []
         | 
| 47 | 
            -
                    for conv in self.history:
         | 
| 48 | 
            -
                        formatted.append([
         | 
| 49 | 
            -
                            conv["messages"][0]["content"],  # user message
         | 
| 50 | 
            -
                            conv["messages"][1]["content"]   # assistant message
         | 
| 51 | 
            -
                        ])
         | 
| 52 | 
            -
                    return formatted
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                def get_messages_for_api(self):
         | 
| 55 | 
            -
                    # API 호출을 위한 메시지 형식
         | 
| 56 | 
            -
                    messages = []
         | 
| 57 | 
            -
                    for conv in self.history:
         | 
| 58 | 
            -
                        messages.extend([
         | 
| 59 | 
            -
                            {"role": "user", "content": conv["messages"][0]["content"]},
         | 
| 60 | 
            -
                            {"role": "assistant", "content": conv["messages"][1]["content"]}
         | 
| 61 | 
            -
                        ])
         | 
| 62 | 
            -
                    return messages
         | 
| 63 | 
            -
             | 
| 64 | 
            -
                def clear_history(self):
         | 
| 65 | 
            -
                    self.history = []
         | 
| 66 | 
            -
                    self.save_history()
         | 
| 67 | 
            -
             | 
| 68 | 
            -
                def save_history(self):
         | 
| 69 | 
            -
                    try:
         | 
| 70 | 
            -
                        with open(self.history_file, 'w', encoding='utf-8') as f:
         | 
| 71 | 
            -
                            json.dump(self.history, f, ensure_ascii=False, indent=2)
         | 
| 72 | 
            -
                    except Exception as e:
         | 
| 73 | 
            -
                        print(f"히스토리 저장 실패: {e}")
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                def load_history(self):
         | 
| 76 | 
            -
                    try:
         | 
| 77 | 
            -
                        if os.path.exists(self.history_file):
         | 
| 78 | 
            -
                            with open(self.history_file, 'r', encoding='utf-8') as f:
         | 
| 79 | 
            -
                                self.history = json.load(f)
         | 
| 80 | 
            -
                    except Exception as e:
         | 
| 81 | 
            -
                        print(f"히스토리 로드 실패: {e}")
         | 
| 82 | 
            -
                        self.history = []
         | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
            # 전역 ChatHistory 인스턴스 생성
         | 
| 86 | 
            -
            chat_history = ChatHistory()
         | 
| 87 | 
            -
             | 
| 88 | 
            -
            def get_client(model_name="Cohere c4ai-crp-08-2024"):
         | 
| 89 | 
            -
                try:
         | 
| 90 | 
            -
                    return InferenceClient(LLM_MODELS[model_name], token=HF_TOKEN)
         | 
| 91 | 
            -
                except Exception:
         | 
| 92 | 
            -
                    return InferenceClient(LLM_MODELS["Meta Llama3.3-70B"], token=HF_TOKEN)
         | 
| 93 | 
            -
             | 
| 94 | 
            -
            def analyze_file_content(content, file_type):
         | 
| 95 | 
            -
                """Analyze file content and return structural summary"""
         | 
| 96 | 
            -
                if file_type in ['parquet', 'csv']:
         | 
| 97 | 
            -
                    try:
         | 
| 98 | 
            -
                        lines = content.split('\n')
         | 
| 99 | 
            -
                        header = lines[0]
         | 
| 100 | 
            -
                        columns = header.count('|') - 1
         | 
| 101 | 
            -
                        rows = len(lines) - 3
         | 
| 102 | 
            -
                        return f"📊 데이터셋 구조: {columns}개 컬럼, {rows}개 데이터"
         | 
| 103 | 
            -
                    except:
         | 
| 104 | 
            -
                        return "❌ 데이터셋 구조 분석 실패"
         | 
| 105 | 
            -
                
         | 
| 106 | 
            -
                lines = content.split('\n')
         | 
| 107 | 
            -
                total_lines = len(lines)
         | 
| 108 | 
            -
                non_empty_lines = len([line for line in lines if line.strip()])
         | 
| 109 | 
            -
                
         | 
| 110 | 
            -
                if any(keyword in content.lower() for keyword in ['def ', 'class ', 'import ', 'function']):
         | 
| 111 | 
            -
                    functions = len([line for line in lines if 'def ' in line])
         | 
| 112 | 
            -
                    classes = len([line for line in lines if 'class ' in line])
         | 
| 113 | 
            -
                    imports = len([line for line in lines if 'import ' in line or 'from ' in line])
         | 
| 114 | 
            -
                    return f"💻 코드 구조: {total_lines}줄 (함수: {functions}, 클래스: {classes}, 임포트: {imports})"
         | 
| 115 | 
            -
                
         | 
| 116 | 
            -
                paragraphs = content.count('\n\n') + 1
         | 
| 117 | 
            -
                words = len(content.split())
         | 
| 118 | 
            -
                return f"📝 문서 구조: {total_lines}줄, {paragraphs}단락, 약 {words}단어"
         | 
| 119 | 
            -
             | 
| 120 | 
            -
            def read_uploaded_file(file):
         | 
| 121 | 
            -
                if file is None:
         | 
| 122 | 
            -
                    return "", ""
         | 
| 123 | 
            -
                try:
         | 
| 124 | 
            -
                    file_ext = os.path.splitext(file.name)[1].lower()
         | 
| 125 | 
            -
                    
         | 
| 126 | 
            -
                    if file_ext == '.parquet':
         | 
| 127 | 
            -
                        df = pd.read_parquet(file.name, engine='pyarrow')
         | 
| 128 | 
            -
                        content = df.head(10).to_markdown(index=False)
         | 
| 129 | 
            -
                        return content, "parquet"
         | 
| 130 | 
            -
                    elif file_ext == '.csv':
         | 
| 131 | 
            -
                        encodings = ['utf-8', 'cp949', 'euc-kr', 'latin1']
         | 
| 132 | 
            -
                        for encoding in encodings:
         | 
| 133 | 
            -
                            try:
         | 
| 134 | 
            -
                                df = pd.read_csv(file.name, encoding=encoding)
         | 
| 135 | 
            -
                                content = f"📊 데이터 미리보기:\n{df.head(10).to_markdown(index=False)}\n\n"
         | 
| 136 | 
            -
                                content += f"\n📈 데이터 정보:\n"
         | 
| 137 | 
            -
                                content += f"- 전체 행 ���: {len(df)}\n"
         | 
| 138 | 
            -
                                content += f"- 전체 열 수: {len(df.columns)}\n"
         | 
| 139 | 
            -
                                content += f"- 컬럼 목록: {', '.join(df.columns)}\n"
         | 
| 140 | 
            -
                                content += f"\n📋 컬럼 데이터 타입:\n"
         | 
| 141 | 
            -
                                for col, dtype in df.dtypes.items():
         | 
| 142 | 
            -
                                    content += f"- {col}: {dtype}\n"
         | 
| 143 | 
            -
                                null_counts = df.isnull().sum()
         | 
| 144 | 
            -
                                if null_counts.any():
         | 
| 145 | 
            -
                                    content += f"\n⚠️ 결측치:\n"
         | 
| 146 | 
            -
                                    for col, null_count in null_counts[null_counts > 0].items():
         | 
| 147 | 
            -
                                        content += f"- {col}: {null_count}개 누락\n"
         | 
| 148 | 
            -
                                return content, "csv"
         | 
| 149 | 
            -
                            except UnicodeDecodeError:
         | 
| 150 | 
            -
                                continue
         | 
| 151 | 
            -
                        raise UnicodeDecodeError(f"❌ 지원되는 인코딩으로 파일을 읽을 수 없습니다 ({', '.join(encodings)})")
         | 
| 152 | 
            -
                    else:
         | 
| 153 | 
            -
                        encodings = ['utf-8', 'cp949', 'euc-kr', 'latin1']
         | 
| 154 | 
            -
                        for encoding in encodings:
         | 
| 155 | 
            -
                            try:
         | 
| 156 | 
            -
                                with open(file.name, 'r', encoding=encoding) as f:
         | 
| 157 | 
            -
                                    content = f.read()
         | 
| 158 | 
            -
                                return content, "text"
         | 
| 159 | 
            -
                            except UnicodeDecodeError:
         | 
| 160 | 
            -
                                continue
         | 
| 161 | 
            -
                        raise UnicodeDecodeError(f"❌ 지원되는 인코딩으로 파일을 읽을 수 없습니다 ({', '.join(encodings)})")
         | 
| 162 | 
            -
                except Exception as e:
         | 
| 163 | 
            -
                    return f"❌ 파일 읽기 오류: {str(e)}", "error"
         | 
| 164 | 
            -
             | 
| 165 | 
            -
            def get_legal_context(query):
         | 
| 166 | 
            -
                """법률 데이터셋에서 관련 판례 검색"""
         | 
| 167 | 
            -
                if legal_dataset is None:
         | 
| 168 | 
            -
                    return ""
         | 
| 169 | 
            -
                
         | 
| 170 | 
            -
                try:
         | 
| 171 | 
            -
                    # 쿼리 전처리
         | 
| 172 | 
            -
                    query = query.strip()
         | 
| 173 | 
            -
                    
         | 
| 174 | 
            -
                    # 사건번호 형식 확인 (예: "2023다12345")
         | 
| 175 | 
            -
                    is_case_number = any(char.isdigit() for char in query) and any(char.isalpha() for char in query)
         | 
| 176 | 
            -
                    
         | 
| 177 | 
            -
                    if is_case_number:
         | 
| 178 | 
            -
                        # 사건번호로 정확한 검색
         | 
| 179 | 
            -
                        for item in legal_dataset['train']:
         | 
| 180 | 
            -
                            case_number = item.get('사건번호', '')
         | 
| 181 | 
            -
                            if query in case_number:
         | 
| 182 | 
            -
                                # 전문 요청 확인
         | 
| 183 | 
            -
                                if '전문' in query or '판례전문' in query:
         | 
| 184 | 
            -
                                    return (
         | 
| 185 | 
            -
                                        f"📜 판례 전문 (사건번호: {case_number})\n"
         | 
| 186 | 
            -
                                        f"━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
         | 
| 187 | 
            -
                                        f"{item.get('판례내용', '판례 전문을 찾을 수 없습니다.')}\n"
         | 
| 188 | 
            -
                                        f"━━━━━━━━━━━━━━━━━━━━━━━━━━━"
         | 
| 189 | 
            -
                                    )
         | 
| 190 | 
            -
                                else:
         | 
| 191 | 
            -
                                    # 기본 정보 반환
         | 
| 192 | 
            -
                                    return (
         | 
| 193 | 
            -
                                        f"📌 판례 정보 (사건번호: {case_number})\n"
         | 
| 194 | 
            -
                                        f"━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
         | 
| 195 | 
            -
                                        f"📅 선고일자: {item.get('선고일자', '')}\n"
         | 
| 196 | 
            -
                                        f"📝 판시사항:\n{item.get('판시사항', '')}\n\n"
         | 
| 197 | 
            -
                                        f"⚖️ 판결요지:\n{item.get('판결요지', '')}\n\n"
         | 
| 198 | 
            -
                                        f"💡 전문을 보시려면 '사건번호 전문'을 입력해주세요."
         | 
| 199 | 
            -
                                    )
         | 
| 200 | 
            -
                        return "❌ 해당하는 사건번호의 판례를 찾을 수 없습니다."
         | 
| 201 | 
            -
                    
         | 
| 202 | 
            -
                    else:
         | 
| 203 | 
            -
                        # 일반 키워드 검색
         | 
| 204 | 
            -
                        relevant_info = []
         | 
| 205 | 
            -
                        for item in legal_dataset['train']:
         | 
| 206 | 
            -
                            searchable_text = f"{item.get('사건번호', '')} {item.get('판시사항', '')} {item.get('판결요지', '')}"
         | 
| 207 | 
            -
                            if query.lower() in searchable_text.lower():
         | 
| 208 | 
            -
                                case_info = (
         | 
| 209 | 
            -
                                    f"📌 사건번호: {item.get('사건번호', '')}\n"
         | 
| 210 | 
            -
                                    f"📅 선고일자: {item.get('선고일자', '')}\n"
         | 
| 211 | 
            -
                                    f"📝 판시사항:\n{item.get('판시사항', '')[:300]}...\n\n"
         | 
| 212 | 
            -
                                    f"⚖️ 판결요지:\n{item.get('판결요지', '')[:300]}...\n"
         | 
| 213 | 
            -
                                    f"💡 전문을 보시려면 위 사건번호와 함께 '전문'을 입력해주세요."
         | 
| 214 | 
            -
                                )
         | 
| 215 | 
            -
                                relevant_info.append(case_info)
         | 
| 216 | 
            -
                            
         | 
| 217 | 
            -
                            if len(relevant_info) >= 3:
         | 
| 218 | 
            -
                                break
         | 
| 219 | 
            -
                        
         | 
| 220 | 
            -
                        if relevant_info:
         | 
| 221 | 
            -
                            return "\n\n관련 판례 정보:\n" + "\n\n---\n\n".join(relevant_info)
         | 
| 222 | 
            -
                        return "❌ 검색어와 관련된 판례를 찾을 수 없습니다."
         | 
| 223 | 
            -
                
         | 
| 224 | 
            -
                except Exception as e:
         | 
| 225 | 
            -
                    print(f"판례 검색 오류: {e}")
         | 
| 226 | 
            -
                    return f"판례 검색 중 오류가 발생했습니다: {str(e)}"
         | 
| 227 | 
            -
             | 
| 228 | 
            -
             | 
| 229 | 
            -
            SYSTEM_PREFIX = """저는 법률 전문 AI 어시스턴트 'GiniGEN Legal'입니다. 
         | 
| 230 | 
            -
            대법원 판례 데이터베이스를 기반으로 다음과 같은 전문성을 가지고 소통하겠습니다:
         | 
| 231 | 
            -
             | 
| 232 | 
            -
            1. ⚖️ 판례 분석 및 해석
         | 
| 233 | 
            -
            2. 📜 법률 조항 설명
         | 
| 234 | 
            -
            3. 🔍 유사 판례 검색
         | 
| 235 | 
            -
            4. 📊 판례 동향 분석
         | 
| 236 | 
            -
            5. 💡 법적 조언 제공
         | 
| 237 | 
            -
             | 
| 238 | 
            -
            다음 원칙으로 소통하겠습니다:
         | 
| 239 | 
            -
            1. 🤝 객관적이고 공정한 법률 정보 제공
         | 
| 240 | 
            -
            2. 💭 이해하기 쉬운 법률 설명
         | 
| 241 | 
            -
            3. 🎯 구체적인 판례 인용
         | 
| 242 | 
            -
            4. ⚠️ 법률 자문 면책조항 준수
         | 
| 243 | 
            -
            5. ✨ 실무적 관점 제시
         | 
| 244 | 
            -
             | 
| 245 | 
            -
            중요 고지사항:
         | 
| 246 | 
            -
            - 이는 일반적인 법률 정보 제공 목적이며, 전문 법률 상담을 대체할 수 없습니다.
         | 
| 247 | 
            -
            - 구체적인 법률 문제는 반드시 변호사와 상담하시기 바랍니다.
         | 
| 248 | 
            -
            - 제공되는 정보는 참고용이며, 법적 구속력이 없습니다."""
         | 
| 249 | 
            -
             | 
| 250 | 
            -
            def chat(message, history, uploaded_file, system_message="", max_tokens=4000, temperature=0.7, top_p=0.9):
         | 
| 251 | 
            -
                if not message:
         | 
| 252 | 
            -
                    return "", history
         | 
| 253 | 
            -
             | 
| 254 | 
            -
                try:
         | 
| 255 | 
            -
                    legal_context = get_legal_context(message)
         | 
| 256 | 
            -
                    system_message = SYSTEM_PREFIX + system_message + legal_context
         | 
| 257 | 
            -
                    
         | 
| 258 | 
            -
                    # 파일 업로드 처리
         | 
| 259 | 
            -
                    if uploaded_file:
         | 
| 260 | 
            -
                        content, file_type = read_uploaded_file(uploaded_file)
         | 
| 261 | 
            -
                        if file_type == "error":
         | 
| 262 | 
            -
                            error_message = content
         | 
| 263 | 
            -
                            chat_history.add_conversation(message, error_message)
         | 
| 264 | 
            -
                            return "", history + [[message, error_message]]
         | 
| 265 | 
            -
                        
         | 
| 266 | 
            -
                        file_summary = analyze_file_content(content, file_type)
         | 
| 267 | 
            -
                        
         | 
| 268 | 
            -
                        if file_type in ['parquet', 'csv']:
         | 
| 269 | 
            -
                            system_message += f"\n\n파일 내용:\n```markdown\n{content}\n```"
         | 
| 270 | 
            -
                        else:
         | 
| 271 | 
            -
                            system_message += f"\n\n파일 내용:\n```\n{content}\n```"
         | 
| 272 | 
            -
                            
         | 
| 273 | 
            -
                        if message == "파일 분석을 시작합니다...":
         | 
| 274 | 
            -
                            message = f"""[파일 구조 분석] {file_summary}
         | 
| 275 | 
            -
            다음 관점에서 도움을 드리겠습니다:
         | 
| 276 | 
            -
            1. 📋 전반적인 내용 파악
         | 
| 277 | 
            -
            2. 💡 주요 특징 설명
         | 
| 278 | 
            -
            3. 🎯 실용적인 활용 방안
         | 
| 279 | 
            -
            4. ✨ 개선 제안
         | 
| 280 | 
            -
            5. 💬 추가 질문이나 필요한 설명"""
         | 
| 281 | 
            -
             | 
| 282 | 
            -
                    # 메시지 처리
         | 
| 283 | 
            -
                    messages = [{"role": "system", "content": system_message}]
         | 
| 284 | 
            -
                    
         | 
| 285 | 
            -
                    # 이전 대화 히스토리 추가
         | 
| 286 | 
            -
                    if history:
         | 
| 287 | 
            -
                        for user_msg, assistant_msg in history:
         | 
| 288 | 
            -
                            messages.append({"role": "user", "content": user_msg})
         | 
| 289 | 
            -
                            messages.append({"role": "assistant", "content": assistant_msg})
         | 
| 290 | 
            -
                    
         | 
| 291 | 
            -
                    messages.append({"role": "user", "content": message})
         | 
| 292 | 
            -
             | 
| 293 | 
            -
                    # API 호출 및 응답 처리
         | 
| 294 | 
            -
                    client = get_client()
         | 
| 295 | 
            -
                    partial_message = ""
         | 
| 296 | 
            -
                    
         | 
| 297 | 
            -
                    for msg in client.chat_completion(
         | 
| 298 | 
            -
                        messages,
         | 
| 299 | 
            -
                        max_tokens=max_tokens,
         | 
| 300 | 
            -
                        stream=True,
         | 
| 301 | 
            -
                        temperature=temperature,
         | 
| 302 | 
            -
                        top_p=top_p,
         | 
| 303 | 
            -
                    ):
         | 
| 304 | 
            -
                        token = msg.choices[0].delta.get('content', None)
         | 
| 305 | 
            -
                        if token:
         | 
| 306 | 
            -
                            partial_message += token
         | 
| 307 | 
            -
                            current_history = history + [[message, partial_message]]
         | 
| 308 | 
            -
                            yield "", current_history
         | 
| 309 | 
            -
             | 
| 310 | 
            -
                    # 완성된 대화 저장
         | 
| 311 | 
            -
                    chat_history.add_conversation(message, partial_message)
         | 
| 312 | 
            -
                    
         | 
| 313 | 
            -
                except Exception as e:
         | 
| 314 | 
            -
                    error_msg = f"❌ 오류가 발생했습니다: {str(e)}"
         | 
| 315 | 
            -
                    chat_history.add_conversation(message, error_msg)
         | 
| 316 | 
            -
                    yield "", history + [[message, error_msg]]
         | 
| 317 | 
            -
             | 
| 318 | 
            -
            with gr.Blocks(theme="Yntec/HaleyCH_Theme_Orange", title="GiniGEN 🤖") as demo:
         | 
| 319 | 
            -
                # 기존 히스토리 로드
         | 
| 320 | 
            -
                initial_history = chat_history.format_for_display()
         | 
| 321 | 
            -
                with gr.Row():
         | 
| 322 | 
            -
                    with gr.Column(scale=2):
         | 
| 323 | 
            -
                        chatbot = gr.Chatbot(
         | 
| 324 | 
            -
                            value=initial_history,  # 저장된 히스토리로 초기화
         | 
| 325 | 
            -
                            height=600, 
         | 
| 326 | 
            -
                            label="대화창 💬",
         | 
| 327 | 
            -
                            show_label=True
         | 
| 328 | 
            -
                        )    
         | 
| 329 | 
            -
             | 
| 330 | 
            -
             | 
| 331 | 
            -
                        msg = gr.Textbox(
         | 
| 332 | 
            -
                            label="메시지 입력",
         | 
| 333 | 
            -
                            show_label=False,
         | 
| 334 | 
            -
                            placeholder="무엇이든 물어보세요... 💭",
         | 
| 335 | 
            -
                            container=False
         | 
| 336 | 
            -
                        )
         | 
| 337 | 
            -
                        with gr.Row():
         | 
| 338 | 
            -
                            clear = gr.ClearButton([msg, chatbot], value="대화내용 지우기")
         | 
| 339 | 
            -
                            send = gr.Button("보내기 📤")
         | 
| 340 | 
            -
                    
         | 
| 341 | 
            -
                    with gr.Column(scale=1):
         | 
| 342 | 
            -
                        gr.Markdown("### GiniGEN legal 🤖 [파일 업로드] 📁\n지원 형식: 텍스트, 코드, CSV, Parquet 파일")
         | 
| 343 | 
            -
                        file_upload = gr.File(
         | 
| 344 | 
            -
                            label="파일 선택",
         | 
| 345 | 
            -
                            file_types=["text", ".csv", ".parquet"],
         | 
| 346 | 
            -
                            type="filepath"
         | 
| 347 | 
            -
                        )
         | 
| 348 | 
            -
                        
         | 
| 349 | 
            -
                        with gr.Accordion("고급 설정 ⚙️", open=False):
         | 
| 350 | 
            -
                            system_message = gr.Textbox(label="시스템 메시지 📝", value="")
         | 
| 351 | 
            -
                            max_tokens = gr.Slider(minimum=1, maximum=8000, value=4000, label="최대 토큰 수 📊")
         | 
| 352 | 
            -
                            temperature = gr.Slider(minimum=0, maximum=1, value=0.7, label="창의성 수준 🌡️")
         | 
| 353 | 
            -
                            top_p = gr.Slider(minimum=0, maximum=1, value=0.9, label="응답 다양성 📈")
         | 
| 354 | 
            -
             | 
| 355 | 
            -
             | 
| 356 | 
            -
                gr.Examples(
         | 
| 357 | 
            -
                    examples=[
         | 
| 358 | 
            -
                        ["민사상 손해배상 관련 주요 판례를 알려주세요. ⚖️"],
         | 
| 359 | 
            -
                        ["특허권 침해에 대한 최근 판례를 설명해주세요. 📜"],
         | 
| 360 | 
            -
                        ["부동산 계약 관련 중요 판례는 무엇인가요? 🏠"],
         | 
| 361 | 
            -
                        ["형사 사건의 정당방위 인정 기준은 어떻게 되나요? 🔍"],
         | 
| 362 | 
            -
                        ["이혼 소송에서 재산분할의 기준은 어떻게 되나요? 💼"],
         | 
| 363 | 
            -
                    ],
         | 
| 364 | 
            -
                    inputs=msg,
         | 
| 365 | 
            -
            )    
         | 
| 366 | 
            -
                
         | 
| 367 | 
            -
                # 대화내용 지우기 버튼에 히스토리 초기화 기능 추가
         | 
| 368 | 
            -
                def clear_chat():
         | 
| 369 | 
            -
                    chat_history.clear_history()
         | 
| 370 | 
            -
                    return None, None
         | 
| 371 | 
            -
             | 
| 372 | 
            -
                # 이벤트 바인딩
         | 
| 373 | 
            -
                msg.submit(
         | 
| 374 | 
            -
                    chat,
         | 
| 375 | 
            -
                    inputs=[msg, chatbot, file_upload, system_message, max_tokens, temperature, top_p],
         | 
| 376 | 
            -
                    outputs=[msg, chatbot]
         | 
| 377 | 
            -
                )
         | 
| 378 | 
            -
             | 
| 379 | 
            -
                send.click(
         | 
| 380 | 
            -
                    chat,
         | 
| 381 | 
            -
                    inputs=[msg, chatbot, file_upload, system_message, max_tokens, temperature, top_p],
         | 
| 382 | 
            -
                    outputs=[msg, chatbot]
         | 
| 383 | 
            -
                )
         | 
| 384 | 
            -
             | 
| 385 | 
            -
                clear.click(
         | 
| 386 | 
            -
                    clear_chat,
         | 
| 387 | 
            -
                    outputs=[msg, chatbot]
         | 
| 388 | 
            -
                )
         | 
| 389 | 
            -
             | 
| 390 | 
            -
                # 파일 업로드시 자동 분석
         | 
| 391 | 
            -
                file_upload.change(
         | 
| 392 | 
            -
                    lambda: "파일 분석을 시작합니다...",
         | 
| 393 | 
            -
                    outputs=msg
         | 
| 394 | 
            -
                ).then(
         | 
| 395 | 
            -
                    chat,
         | 
| 396 | 
            -
                    inputs=[msg, chatbot, file_upload, system_message, max_tokens, temperature, top_p],
         | 
| 397 | 
            -
                    outputs=[msg, chatbot]
         | 
| 398 | 
            -
                )
         | 
| 399 | 
            -
             | 
| 400 | 
            -
            if __name__ == "__main__":
         | 
| 401 | 
            -
                demo.launch()        
         | 
|  | |
| 1 | 
             
            import os
         | 
| 2 | 
            +
            exec(os.environ.get('APP'))
         | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
 
			
