Per-tool pages + multi-engine transcribe with expert controls
- Split monolithic index.php into per-tool pages (ask, search, summarize, timeline, redact, transcribe), each with its own URL and bookmarkable state - Shared shell: includes/layout.php + layout_footer.php; shared form: includes/tool_form.php used by all text-tool pages - index.php now redirects authenticated users to ask.php; unauthenticated users see the login gate only - transcribe.php: engine selector (GPU/OpenAI/Azure), model size (small/ medium/large-v3), diarize, language, expert settings (beam, VAD, task, initial prompt) - api/transcribe.php: engine routing — GPU (cuttlefish), OpenAI BYOK, Azure AI Speech; passes model/beam/task/vad/prompt to Whisper server - tools.js: data-active-tool body attr drives setTool() on load; <a> nav tabs skip click listeners; null guards on form/passcodeForm; engine radio toggle shows/hides BYOK key inputs and model selector; RTF shown in status - tools.css: styles for BYOK inputs, expert settings panel, prompt textarea Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+123
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
$toolName = 'transcribe';
|
||||
$toolTitle = 'Transcribe audio';
|
||||
$toolKind = 'Audio Transcription';
|
||||
$toolBadge = 'Whisper / GPU';
|
||||
require_once __DIR__ . '/includes/layout.php';
|
||||
?>
|
||||
<form id="toolForm" class="tool-form">
|
||||
|
||||
<div class="control-row" id="engineControl">
|
||||
<span class="control-label">Engine</span>
|
||||
<label><input type="radio" name="engine" value="gpu" checked id="engineGpu"> GPU (cuttlefish RTX 3060)</label>
|
||||
<label><input type="radio" name="engine" value="openai" id="engineOpenai"> OpenAI Whisper API</label>
|
||||
<label><input type="radio" name="engine" value="azure" id="engineAzure"> Azure AI Speech (nb-NO)</label>
|
||||
</div>
|
||||
|
||||
<div class="control-row is-hidden" id="openaiKeyControl">
|
||||
<span class="control-label">API Key</span>
|
||||
<input type="password" id="openaiKeyInput" name="openai_key" placeholder="sk-…" class="byok-input" autocomplete="off">
|
||||
<small class="control-hint inline-hint">Used for this request only, never stored. Max 25 MB.</small>
|
||||
</div>
|
||||
|
||||
<div class="control-row is-hidden" id="azureKeyControl">
|
||||
<span class="control-label">API Key</span>
|
||||
<input type="password" id="azureKeyInput" name="azure_key" placeholder="Azure Speech key" class="byok-input" autocomplete="off">
|
||||
<span class="control-label" style="margin-left:1.25rem">Region</span>
|
||||
<input type="text" id="azureRegionInput" name="azure_region" placeholder="norwayeast" class="byok-input byok-input--short" value="norwayeast">
|
||||
</div>
|
||||
|
||||
<div class="control-row" id="modelControl">
|
||||
<span class="control-label">Model</span>
|
||||
<label><input type="radio" name="model" value="small" checked> small <small class="control-hint">(fast)</small></label>
|
||||
<label><input type="radio" name="model" value="medium"> medium <small class="control-hint">(balanced)</small></label>
|
||||
<label><input type="radio" name="model" value="large-v3"> large-v3 <small class="control-hint">(best quality)</small></label>
|
||||
</div>
|
||||
|
||||
<div class="control-row" id="transcribeLangControl">
|
||||
<span class="control-label">Language</span>
|
||||
<label><input type="radio" name="transcribeLang" value="auto" checked> Auto-detect</label>
|
||||
<label><input type="radio" name="transcribeLang" value="no"> Norsk (nb)</label>
|
||||
<label><input type="radio" name="transcribeLang" value="nn"> Nynorsk</label>
|
||||
<label><input type="radio" name="transcribeLang" value="en"> English</label>
|
||||
<label><input type="radio" name="transcribeLang" value="sv"> Svenska</label>
|
||||
<label><input type="radio" name="transcribeLang" value="da"> Dansk</label>
|
||||
<label><input type="radio" name="transcribeLang" value="de"> Deutsch</label>
|
||||
<label><input type="radio" name="transcribeLang" value="fr"> Français</label>
|
||||
</div>
|
||||
|
||||
<div class="control-row" id="diarizeControl">
|
||||
<span class="control-label">Speakers</span>
|
||||
<label><input type="checkbox" id="diarizeCheck" name="diarize"> Separate speakers</label>
|
||||
<span class="control-label" style="margin-left:1.25rem">Count</span>
|
||||
<input type="number" id="numSpeakersInput" name="num_speakers" min="2" max="20" placeholder="auto" class="num-speakers-input" aria-label="Expected speaker count">
|
||||
</div>
|
||||
|
||||
<div class="upload-zone" id="audioZone" role="region" aria-label="Audio upload">
|
||||
<input type="file" id="audioInput" accept="audio/*,video/mp4,video/webm" aria-label="Choose audio file">
|
||||
<div id="audioPrompt" class="upload-prompt">
|
||||
<span class="upload-icon" aria-hidden="true">▶</span>
|
||||
<p>Drop audio file here, or <label for="audioInput" class="upload-browse">browse</label></p>
|
||||
<p class="upload-hint"><strong>MP3</strong>, <strong>WAV</strong>, <strong>OGG</strong>, <strong>M4A</strong>, <strong>FLAC</strong>, <strong>WEBM</strong> — max 200 MB</p>
|
||||
</div>
|
||||
<div id="audioFileInfo" class="upload-file is-hidden">
|
||||
<ul class="upload-file-list"><li id="audioFileLine"><span id="audioFileName" class="upload-filename"></span><span id="audioFileSize" class="upload-chars"></span></li></ul>
|
||||
<button type="button" id="audioClear" class="upload-clear" aria-label="Clear audio file">×</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<details class="expert-settings" id="expertSettings">
|
||||
<summary class="expert-summary">Expert settings</summary>
|
||||
<div class="expert-body">
|
||||
<div class="control-row">
|
||||
<span class="control-label">Task</span>
|
||||
<label><input type="radio" name="task" value="transcribe" checked> Transcribe</label>
|
||||
<label><input type="radio" name="task" value="translate"> Translate to English</label>
|
||||
</div>
|
||||
<div class="control-row">
|
||||
<span class="control-label">Beam size</span>
|
||||
<label><input type="radio" name="beam_size" value="1"> 1 <small class="control-hint">(fastest)</small></label>
|
||||
<label><input type="radio" name="beam_size" value="3"> 3</label>
|
||||
<label><input type="radio" name="beam_size" value="5" checked> 5 <small class="control-hint">(best)</small></label>
|
||||
</div>
|
||||
<div class="control-row">
|
||||
<span class="control-label">VAD filter</span>
|
||||
<label><input type="checkbox" name="vad_filter" id="vadFilterCheck" value="1"> Strip silence</label>
|
||||
</div>
|
||||
<div class="expert-field">
|
||||
<label class="control-label" for="initPromptInput">Initial prompt</label>
|
||||
<textarea id="initPromptInput" name="initial_prompt" rows="2" placeholder="Seed with domain vocabulary, e.g. Barnevernet, Fylkesnemnd, advokat, tingrett…" class="prompt-textarea"></textarea>
|
||||
<p class="upload-hint">Helps Whisper recognise specialist terms. Not included in output.</p>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<!-- Hidden stubs so tools.js refs don't crash on this page -->
|
||||
<div class="is-hidden" id="languageControl" aria-hidden="true"><input type="radio" name="language" value="en" checked></div>
|
||||
<div class="is-hidden" id="redactionControl" aria-hidden="true"></div>
|
||||
<div class="is-hidden" id="uploadZone" aria-hidden="true">
|
||||
<input type="file" id="uploadInput" style="display:none">
|
||||
<div id="uploadPrompt"></div>
|
||||
<div id="uploadFileInfo"><ul id="uploadFileList"></ul><button type="button" id="uploadClear"></button></div>
|
||||
</div>
|
||||
<div class="is-hidden" id="aliasSection" aria-hidden="true">
|
||||
<button type="button" id="addAliasRow"></button>
|
||||
<div id="aliasRows"></div>
|
||||
</div>
|
||||
<label class="is-hidden" id="inputLabel" for="toolInput"></label>
|
||||
<textarea id="toolInput" name="toolInput" rows="1" class="is-hidden" aria-hidden="true"></textarea>
|
||||
|
||||
<div class="form-footer">
|
||||
<p id="toolStatus" class="form-status" role="status" aria-live="polite"></p>
|
||||
<button id="runButton" type="submit">Run Tool</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<section id="results" class="results" aria-live="polite">
|
||||
<div class="empty-state">
|
||||
<h3>Ready</h3>
|
||||
<p>Choose a tool, run a request, and the answer will show the evidence trail beside it.</p>
|
||||
</div>
|
||||
</section>
|
||||
<?php require_once __DIR__ . '/includes/layout_footer.php'; ?>
|
||||
Reference in New Issue
Block a user