169 lines
11 KiB
HTML
169 lines
11 KiB
HTML
<div class="section-head">
|
|
<span class="section-icon"><span class="mdi mdi-forum-outline"></span></span>
|
|
<div class="section-title">
|
|
<h2>Conversation Playground</h2>
|
|
<p>Talk to an AI voice agent. Full STT → LLM → TTS pipeline with real-time streaming and latency stats.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="conv-tabs" role="tablist" aria-label="Conversation views">
|
|
<button type="button" role="tab" id="conv-tab-chat" class="conv-tab" aria-selected="true" aria-controls="conv-main-view" tabindex="0">Conversation</button>
|
|
<button type="button" role="tab" id="conv-tab-metrics" class="conv-tab" aria-selected="false" aria-controls="conv-metrics-view" tabindex="-1">Metrics</button>
|
|
</div>
|
|
|
|
<!-- Config bar -->
|
|
<div class="conv-config-bar card" style="padding:14px">
|
|
<h2><span class="mdi mdi-tune-variant"></span> Engines & prompt</h2>
|
|
<div class="engine-setup-row" style="margin-bottom:8px">
|
|
<div class="engine-setup-col">
|
|
<label class="engine-setup-label"><span class="mdi mdi-microphone"></span> Speech to Text <a href="#" class="engine-setup-link" onclick="navTo('s-llms'); navEnginesCat('stt'); return false;" title="Configure Speech to Text settings"><span class="mdi mdi-cog-outline"></span></a></label>
|
|
<div class="engine-setup-controls">
|
|
<select id="conv-stt-select" aria-label="Speech-to-text engine"><option value="configured">Checking...</option></select>
|
|
</div>
|
|
</div>
|
|
<div class="engine-setup-col" style="flex:1.5">
|
|
<label class="engine-setup-label" for="conv-llm-endpoint"><span class="mdi mdi-brain"></span> Language Model <a href="#" class="engine-setup-link" onclick="navTo('s-llms'); navEnginesCat('llm'); return false;" title="Configure Language Model settings"><span class="mdi mdi-cog-outline"></span></a></label>
|
|
<div class="engine-setup-controls">
|
|
<select id="conv-llm-endpoint" class="conv-llm-pick"><option value="__custom__">Custom…</option></select>
|
|
<input id="conv-llm-url" class="conv-url-inp conv-llm-pick" type="text" aria-label="Custom LLM base URL" placeholder="http://localhost:11434/v1" spellcheck="false" hidden>
|
|
<button class="btn-secondary conv-llm-pick" id="conv-llm-fetch-btn" title="Fetch models" aria-label="Fetch models"><span class="mdi mdi-refresh"></span></button>
|
|
<select id="conv-llm-model-select" aria-label="Language model"><option value="">— fetch models —</option></select>
|
|
<label class="conv-thinking" title="Off = faster answers. On = better reasoning but slower, and some models may return an empty reply.">
|
|
<input type="checkbox" role="switch" id="conv-thinking-switch" aria-describedby="conv-thinking-help">
|
|
<span>Thinking</span> <span id="conv-thinking-state" class="conv-thinking-state">off</span>
|
|
</label>
|
|
<p id="conv-llm-empty-hint" class="conv-llm-hint" hidden><a href="#" onclick="navTo('s-llms'); navEnginesCat('llm'); return false;">Add language models under Engines → Language Models</a></p>
|
|
<span id="conv-thinking-help" class="sr-only">Off = faster answers. On = better reasoning but slower, and some models may return an empty reply.</span>
|
|
</div>
|
|
</div>
|
|
<div class="engine-setup-col" style="flex:1.5; border-right:none; padding-right:0">
|
|
<label class="engine-setup-label"><span class="mdi mdi-account-voice"></span> Text to Speech <a href="#" class="engine-setup-link" onclick="navTo('s-llms'); navEnginesCat('tts'); return false;" title="Configure Text to Speech settings"><span class="mdi mdi-cog-outline"></span></a></label>
|
|
<div class="engine-setup-controls">
|
|
<select id="conv-tts-backend-select" aria-label="TTS backend"><option value="">Checking...</option></select>
|
|
<button class="btn-secondary" id="conv-tts-fetch-btn" title="Fetch voices"><span class="mdi mdi-refresh"></span></button>
|
|
<select id="conv-tts-voice-select" aria-label="Voice"><option value="">— fetch voices —</option></select>
|
|
<select id="conv-emotion-select" aria-label="Reply emotion" title="Applies to every reply — for Fish-Speech, as an inline tag; for other backends, as a style instruction"><option value="">Emotion…</option></select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="conv-prompt-row" style="display:flex; gap:12px; align-items:flex-start">
|
|
<div style="flex:1">
|
|
<label class="conv-cfg-label"><span class="mdi mdi-text-box-outline"></span> System prompt</label>
|
|
<textarea id="conv-system-prompt" aria-label="System prompt" class="conv-system-textarea" rows="1" spellcheck="false">You are a helpful voice assistant. Keep replies short and conversational.</textarea>
|
|
</div>
|
|
<div style="align-self:flex-end">
|
|
<button class="btn-secondary" id="conv-clear-btn" title="Clear conversation"><span class="mdi mdi-delete-outline"></span> Clear</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Main area: chat + stats -->
|
|
<div class="conv-main" id="conv-main-view" role="tabpanel" aria-labelledby="conv-tab-chat">
|
|
|
|
<!-- Chat window -->
|
|
<div class="conv-chat-panel">
|
|
<div class="conv-chat-window" id="conv-chat-window">
|
|
<div class="conv-chat-welcome">
|
|
<span class="mdi mdi-forum-outline" style="font-size:32px;opacity:.25"></span>
|
|
<p>Type a message or press the microphone button below to start.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Input bar: text field + send + mic -->
|
|
<div class="conv-input-bar">
|
|
<div class="conv-mic-status" id="conv-mic-status">Ready</div>
|
|
<div class="conv-text-row">
|
|
<input id="conv-text-input" class="conv-text-inp"
|
|
type="text" placeholder="Type a message and press Enter or →"
|
|
spellcheck="false" autocomplete="off">
|
|
<button class="conv-send-btn" id="conv-send-btn" title="Send text (Enter)">
|
|
<span class="mdi mdi-send"></span>
|
|
</button>
|
|
<div class="conv-divider" title="or use microphone"></div>
|
|
<button class="conv-mic-btn" id="conv-mic-btn" title="Click to record via microphone">
|
|
<span class="mdi mdi-microphone" id="conv-mic-icon"></span>
|
|
</button>
|
|
<div class="conv-mic-timer" id="conv-mic-timer"></div>
|
|
<div class="conv-gate-row">
|
|
<div class="conv-level-wrap" id="conv-level-wrap">
|
|
<div class="conv-level-fill" id="conv-level-fill"></div>
|
|
<div class="conv-level-gate" id="conv-level-gate"></div>
|
|
</div>
|
|
<span class="conv-gate-label" title="Noise gate — raise to ignore background noise"><span class="mdi mdi-tune-variant"></span></span>
|
|
<input type="range" id="conv-gate-slider" class="conv-gate-slider" min="1" max="80" value="20" title="Noise gate threshold (raise to ignore background noise)">
|
|
</div>
|
|
<label class="conv-vad-label" title="Auto-stop recording when silence is detected">
|
|
<input type="checkbox" id="conv-vad-toggle" checked>
|
|
<span>Auto-stop</span>
|
|
</label>
|
|
<label class="conv-vad-label" title="Automatically restart microphone after the agent finishes speaking">
|
|
<input type="checkbox" id="conv-handsfree-toggle" checked>
|
|
<span>Hands-free</span>
|
|
</label>
|
|
<label class="conv-vad-label" title="Lower silence and interruption delays for live voice-agent turn-taking">
|
|
<input type="checkbox" id="conv-live-agent-toggle" checked>
|
|
<span>Live agent</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Stats panel (collapsible) -->
|
|
<div class="conv-stats-panel" id="conv-stats-panel">
|
|
<div class="conv-stats-toggle-row">
|
|
<span class="conv-stats-head">Latency</span>
|
|
<button class="conv-stats-collapse-btn" id="conv-stats-collapse-btn" title="Hide stats panel"><span class="mdi mdi-chevron-right"></span></button>
|
|
</div>
|
|
|
|
<div class="conv-pipeline">
|
|
<div class="conv-pipe-step" id="cps-stt">
|
|
<div class="conv-pipe-label"><span class="mdi mdi-microphone-outline"></span> STT</div>
|
|
<div class="conv-pipe-bar"><div class="conv-pipe-fill" id="cpf-stt"></div></div>
|
|
<div class="conv-pipe-val" id="cpv-stt">—</div>
|
|
</div>
|
|
<div class="conv-pipe-step" id="cps-ttft">
|
|
<div class="conv-pipe-label"><span class="mdi mdi-timer-outline"></span> LLM first token</div>
|
|
<div class="conv-pipe-bar"><div class="conv-pipe-fill" id="cpf-ttft"></div></div>
|
|
<div class="conv-pipe-val" id="cpv-ttft">—</div>
|
|
</div>
|
|
<div class="conv-pipe-step" id="cps-llm">
|
|
<div class="conv-pipe-label"><span class="mdi mdi-brain"></span> LLM total</div>
|
|
<div class="conv-pipe-bar"><div class="conv-pipe-fill" id="cpf-llm"></div></div>
|
|
<div class="conv-pipe-val" id="cpv-llm">—</div>
|
|
</div>
|
|
<div class="conv-pipe-step" id="cps-tts">
|
|
<div class="conv-pipe-label"><span class="mdi mdi-account-voice"></span> TTS</div>
|
|
<div class="conv-pipe-bar"><div class="conv-pipe-fill" id="cpf-tts"></div></div>
|
|
<div class="conv-pipe-val" id="cpv-tts">—</div>
|
|
</div>
|
|
<div class="conv-pipe-step conv-pipe-total" id="cps-total">
|
|
<div class="conv-pipe-label"><span class="mdi mdi-timer-check-outline"></span> Total</div>
|
|
<div class="conv-pipe-bar"><div class="conv-pipe-fill" id="cpf-total" style="background:var(--accent)"></div></div>
|
|
<div class="conv-pipe-val" id="cpv-total">—</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="conv-stats-head" style="margin-top:14px">Turn history</div>
|
|
<div class="conv-turn-history" id="conv-turn-history">
|
|
<div class="conv-history-empty">No turns yet.</div>
|
|
</div>
|
|
</div>
|
|
<!-- Expand button shown when stats panel is collapsed -->
|
|
<button class="conv-stats-expand-btn" id="conv-stats-expand-btn" title="Show stats panel" style="display:none">
|
|
<span class="mdi mdi-chart-timeline-variant"></span>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Metrics view (Pipecat-style): token usage + TTFB line charts, in-memory for this session -->
|
|
<div class="conv-metrics" id="conv-metrics-view" role="tabpanel" aria-labelledby="conv-tab-metrics" hidden>
|
|
<h3 class="conv-metrics-h">Token Usage</h3>
|
|
<div class="conv-tokens">
|
|
<div class="conv-token"><span class="conv-token-l">Prompt tokens</span><strong id="cm-tok-prompt">n/a</strong></div>
|
|
<div class="conv-token"><span class="conv-token-l">Completion tokens</span><strong id="cm-tok-completion">n/a</strong></div>
|
|
<div class="conv-token"><span class="conv-token-l">Total tokens</span><strong id="cm-tok-total">n/a</strong></div>
|
|
</div>
|
|
<h3 class="conv-metrics-h">TTFB Metrics</h3>
|
|
<p class="conv-history-empty" id="cm-empty">No turns yet.</p>
|
|
<div class="conv-charts" id="cm-charts"></div>
|
|
</div>
|