95 lines
3.9 KiB
HTML
95 lines
3.9 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}{{ agent_name }} — Chat{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="chat-container">
|
|
|
|
<!-- Messages -->
|
|
<div class="chat-messages" id="chat-messages">
|
|
<div class="message assistant">
|
|
<div class="message-bubble">
|
|
Hello. What can I help you with?
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Image attachment preview strip -->
|
|
<div id="attach-preview" style="display:none;padding:6px 12px 2px;gap:8px;flex-wrap:wrap;
|
|
align-items:center;border-top:1px solid var(--border)"></div>
|
|
|
|
<!-- Input bar -->
|
|
<div class="chat-input-wrap">
|
|
<input id="img-file-input" type="file" multiple
|
|
accept="image/jpeg,image/png,image/gif,image/webp,image/avif,application/pdf"
|
|
style="display:none">
|
|
<button id="attach-btn" class="btn btn-ghost" title="Attach file(s)"
|
|
onclick="document.getElementById('img-file-input').click()"
|
|
style="display:none;padding:6px 8px;font-size:16px;line-height:1">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
width="16" height="16" style="vertical-align:-2px">
|
|
<path d="m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48"/>
|
|
</svg>
|
|
</button>
|
|
<textarea
|
|
id="chat-input"
|
|
class="chat-input"
|
|
placeholder="Message {{ agent_name }}… (Enter to send, Shift+Enter for newline)"
|
|
rows="1"
|
|
autofocus
|
|
></textarea>
|
|
<button class="btn btn-primary" id="send-btn">Send</button>
|
|
<button class="btn btn-ghost" id="clear-btn" title="Clear conversation">✕</button>
|
|
</div>
|
|
|
|
<!-- Status bar -->
|
|
<div class="status-bar">
|
|
<span class="status-dot" id="status-dot"></span>
|
|
<span id="status-label">Connecting…</span>
|
|
<span style="margin-left:auto;display:flex;align-items:center;gap:8px">
|
|
<span id="model-caps" style="display:flex;gap:4px;align-items:center"></span>
|
|
<button id="model-btn" onclick="openModelPicker()" title="Change model" style="
|
|
background:var(--bg2);border:1px solid var(--border);color:var(--text-dim);
|
|
border-radius:4px;padding:2px 10px 2px 8px;font-size:11px;cursor:pointer;
|
|
max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
|
|
font-family:var(--font);
|
|
">Loading…</button>
|
|
<span style="color:var(--text-dim);font-size:11px">Session: <code>{{ session_id[:8] }}</code></span>
|
|
</span>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- Model picker modal -->
|
|
<div class="modal-overlay hidden" id="model-picker-modal" onclick="if(event.target===this)closeModelPicker()">
|
|
<div class="modal" style="max-width:480px;width:90%;display:flex;flex-direction:column;max-height:75vh;padding:20px">
|
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px">
|
|
<h3 style="font-size:15px;font-weight:600">Select Model</h3>
|
|
<button class="btn btn-ghost" style="padding:3px 8px;font-size:12px" onclick="closeModelPicker()">✕</button>
|
|
</div>
|
|
<input id="model-picker-search" type="text" class="form-input"
|
|
placeholder="Search models…" autocomplete="off"
|
|
style="margin-bottom:10px;flex-shrink:0"
|
|
oninput="_renderModelPicker(this.value)">
|
|
<div id="model-picker-list" style="overflow-y:auto;flex:1;margin:0 -4px"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Confirmation modal -->
|
|
<div class="modal-overlay hidden" id="confirm-modal">
|
|
<div class="modal">
|
|
<h3>⚠ Confirm action: <span id="confirm-tool-name"></span></h3>
|
|
<div class="modal-desc" id="confirm-description"></div>
|
|
<div class="modal-buttons">
|
|
<button class="btn btn-ghost" onclick="respondConfirm(false)">Deny</button>
|
|
<button class="btn btn-primary" onclick="respondConfirm(true)">Approve</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_scripts %}
|
|
<script>
|
|
window.SESSION_ID = "{{ session_id }}";
|
|
</script>
|
|
{% endblock %}
|