Spaces:
Sleeping
Sleeping
<html lang="ko"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>RAG κ²μ μ±λ΄</title> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"> | |
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}"> | |
<link rel="stylesheet" href="{{ url_for('static', filename='css/device-style.css') }}"> | |
</head> | |
<body> | |
<div class="container"> | |
<header> | |
<h1>RAG κ²μ μ±λ΄</h1> | |
<div class="header-actions"> | |
<div class="llm-selector"> | |
<label for="llmSelect">LLM μ ν:</label> | |
<select id="llmSelect"> | |
<!-- μ΅μ μ JavaScriptμμ λμ μΌλ‘ λ‘λλ©λλ€ --> | |
</select> | |
</div> | |
<div class="user-info"> | |
<span>μ¬μ©μ: {% if session.username %}{{ session.username }}{% else %}μλ{% endif %}</span> | |
<a href="{{ url_for('logout') }}" class="logout-button"> | |
<i class="fas fa-sign-out-alt"></i> λ‘κ·Έμμ | |
</a> | |
</div> | |
</div> | |
<div class="tabs"> | |
<button id="chatTab" class="tab active">λν</button> | |
<button id="docsTab" class="tab">λ¬Έμκ΄λ¦¬</button> | |
<button id="deviceTab" class="tab">μ₯μΉμ μ΄</button> | |
</div> | |
</header> | |
<main> | |
<!-- λν ν --> | |
<section id="chatSection" class="tab-content active"> | |
<div class="chat-container"> | |
<div class="chat-messages" id="chatMessages"> | |
<div class="message system"> | |
<div class="message-content"> | |
<p>μλ νμΈμ! μ§μλ² μ΄μ€μ λν΄ κΆκΈν μ μ λ¬Όμ΄λ³΄μΈμ. μμ±μΌλ‘ μ§λ¬Ένμλ €λ©΄ λ§μ΄ν¬ λ²νΌμ λλ₯΄μΈμ.</p> | |
</div> | |
</div> | |
</div> | |
<div class="chat-input-container"> | |
<textarea id="userInput" placeholder="λ©μμ§λ₯Ό μ λ ₯νμΈμ..." rows="1"></textarea> | |
<button id="micButton" class="mic-button"> | |
<i class="fas fa-microphone"></i> | |
</button> | |
<button id="sendButton" class="send-button"> | |
<i class="fas fa-paper-plane"></i> | |
</button> | |
</div> | |
<div id="recordingStatus" class="recording-status hidden"> | |
<div class="recording-indicator"> | |
<div class="recording-pulse"></div> | |
</div> | |
<span>λ Ήμ μ€...</span> | |
<button id="stopRecordingButton" class="stop-recording-button"> | |
<i class="fas fa-stop"></i> | |
</button> | |
</div> | |
</div> | |
</section> | |
<!-- λ¬Έμκ΄λ¦¬ ν --> | |
<section id="docsSection" class="tab-content"> | |
<div class="docs-container"> | |
<div class="upload-section"> | |
<h2>λ¬Έμ μ λ‘λ</h2> | |
<p>μ§μλ² μ΄μ€μ μΆκ°ν λ¬Έμλ₯Ό μ λ‘λνμΈμ. (μ§μ νμ: .txt, .md, .csv)</p> | |
<form id="uploadForm" enctype="multipart/form-data"> | |
<div class="file-upload"> | |
<input type="file" id="documentFile" name="document" accept=".txt,.md,.csv"> | |
<label for="documentFile">νμΌ μ ν</label> | |
<span id="fileName">μ νλ νμΌ μμ</span> | |
</div> | |
<button type="submit" id="uploadButton" class="upload-button"> | |
<i class="fas fa-upload"></i> μ λ‘λ | |
</button> | |
</form> | |
<div id="uploadStatus" class="upload-status hidden"></div> | |
</div> | |
<div class="docs-list-section"> | |
<h2>λ¬Έμ λͺ©λ‘</h2> | |
<button id="refreshDocsButton" class="refresh-button"> | |
<i class="fas fa-sync-alt"></i> μλ‘κ³ μΉ¨ | |
</button> | |
<div class="docs-list-container"> | |
<table id="docsList" class="docs-list"> | |
<thead> | |
<tr> | |
<th>νμΌλͺ </th> | |
<th>μ²ν¬ μ</th> | |
<th>μ ν</th> | |
</tr> | |
</thead> | |
<tbody> | |
<!-- λ¬Έμ λͺ©λ‘μ΄ μ¬κΈ°μ λμ μΌλ‘ μΆκ°λ©λλ€ --> | |
</tbody> | |
</table> | |
<div id="docsLoading" class="loading-indicator"> | |
<div class="spinner"></div> | |
<p>λ¬Έμ λ‘λ© μ€...</p> | |
</div> | |
<div id="noDocsMessage" class="no-docs-message hidden"> | |
<p>μ§μλ² μ΄μ€μ λ±λ‘λ λ¬Έμκ° μμ΅λλ€. λ¬Έμλ₯Ό μ λ‘λν΄ μ£ΌμΈμ.</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
</section> | |
<!-- μ₯μΉ μ μ΄ ν --> | |
<section id="deviceSection" class="tab-content"> | |
<div class="device-connection"> | |
<h3>1. μ₯μΉ μλ² μ°κ²°</h3> | |
<div class="device-connection-form"> | |
<input type="text" id="deviceServerUrlInput" placeholder="LocalPCAgent Ngrok URL μ λ ₯ (https://xxxx-xx-xxx-xxx.ngrok-free.app νμ)"> | |
<button id="connectDeviceServerBtn">μ°κ²°</button> | |
</div> | |
<div id="deviceConnectionStatus" class="connection-status disconnected">μ°κ²° μν: μ°κ²°λμ§ μμ</div> | |
</div> | |
<div id="deviceBasicFunctions" class="device-functions"> | |
<h3>2. κΈ°λ³Έ κΈ°λ₯</h3> | |
<div class="function-buttons"> | |
<button id="checkDeviceStatusBtn">μ₯μΉ μν νμΈ</button> | |
</div> | |
<textarea id="deviceStatusResult" class="device-status-result" readonly></textarea> | |
</div> | |
<div id="deviceProgramControl" class="program-control"> | |
<h3>3. νλ‘κ·Έλ¨ μ€ν</h3> | |
<div class="function-buttons"> | |
<button id="getProgramsBtn">νλ‘κ·Έλ¨ λͺ©λ‘ μλ‘κ³ μΉ¨</button> | |
</div> | |
<div id="programsList" class="program-list-container"> | |
<div class="no-programs-message">νλ‘κ·Έλ¨ λͺ©λ‘μ΄ μ¬κΈ°μ νμλ©λλ€.</div> | |
</div> | |
<div class="program-select-container"> | |
<select id="programSelectDropdown"> | |
<option value="">-- λͺ©λ‘ μλ‘κ³ μΉ¨ ν μ ν --</option> | |
</select> | |
</div> | |
<button id="executeProgramBtn" class="execute-btn" disabled>μ νν νλ‘κ·Έλ¨ μ€ν</button> | |
<div id="executeResult" class="execute-result"></div> | |
</div> | |
</section> | |
</main> | |
<footer> | |
<p>Β© 2025 RAG κ²μ μ±λ΄ | OpenAI/DeepSeek LLM & VITO STT νμ©</p> | |
<div class="current-llm"> | |
<span>Current LLM: </span> | |
<span id="currentLLMInfo">-</span> | |
</div> | |
</footer> | |
</div> | |
<script src="{{ url_for('static', filename='js/app-core.js') }}"></script> | |
<script src="{{ url_for('static', filename='js/app-device.js') }}"></script> | |
<script src="{{ url_for('static', filename='js/app.js') }}"></script> | |
</body> | |
</html> | |