| import gradio as gr |
| import os |
| from openai import OpenAI |
| |
| def load_system_prompt(): |
| with open("system-prompt.md", "r") as f: |
| return f.read() |
|
|
| SYSTEM_PROMPT_CONTENT = load_system_prompt() |
|
|
| |
| README_CONTENT = """# Basic STT Transcript Cleanup Tool (Version 3) |
| |
| A foundational speech-to-text transcript remediation tool that provides purpose-agnostic text cleanup instructions. This is the **daily workhorse** for cleaning up raw speech-to-text transcripts that naturally contain undesirable material. |
| |
| ## Purpose & Philosophy |
| |
| This tool implements **Version 3** of the Basic Speech-to-Text Cleanup prompt - a carefully crafted system prompt that provides sufficiently deterministic guidance without overstepping into actual content editing. The challenge in developing this prompt was ensuring it cleans up technical artifacts of speech-to-text conversion while preserving the authentic voice and intent of the original speaker. |
| |
| ## Foundational Design |
| |
| This basic cleanup prompt serves as a **foundation layer** that can be combined with specialized text transformation prompts: |
| |
| - **Standalone Use**: Perfect for general transcript cleanup |
| - **Modular Design**: Can be concatenated with purpose-specific prompts from extensive libraries |
| - **Purpose-Agnostic**: Works across all content types and domains |
| - **Extensible**: Hundreds of specialized transformation prompts can be layered on top |
| |
| ## Features |
| |
| - **AI-Powered Cleanup**: Uses OpenAI's GPT models with a refined system prompt |
| - **BYOK (Bring Your Own Key)**: Secure - uses your own OpenAI API key |
| - **Copy to Clipboard**: Easy copying of cleaned text |
| - **Re-run Capability**: Quickly re-process the same text |
| - **System Prompt Viewer**: Transparent - see exactly how the AI processes your text |
| - **Deterministic Processing**: Consistent, predictable cleanup results |
| |
| ## How to Use |
| |
| 1. **Enter API Key**: Provide your OpenAI API key (required for processing) |
| 2. **Paste Transcript**: Add your raw speech-to-text transcript |
| 3. **Process**: Click "Clean Up Transcript" to apply remediation |
| 4. **Copy Results**: Use the cleaned output or re-run if needed |
| |
| ## What It Does |
| |
| The tool applies these **foundational improvements** to your transcripts: |
| |
| ### Core Remediations |
| - **Removes filler words** (like "um") |
| - **Adds punctuation, sentence structure, and paragraph spacing** |
| - **Fixes obvious STT hallucinations and mistranscriptions** (e.g., "McDonuts" → "McDonalds") |
| - **Removes repetitive or run-on thoughts** that would not be helpful to readers |
| - **Follows inferred instructions** to omit certain clauses (e.g., "wait .. scratch that from the note") |
| |
| ### What It Preserves |
| - **All important content** and meaning |
| - **Original speaker's voice** and intent |
| - **Factual accuracy** and details |
| - **Natural flow** of conversation |
| |
| ## Design Principles |
| |
| 1. **Light Touch Editing**: Minimal intervention while maximizing clarity |
| 2. **Content Preservation**: Never removes or alters important information |
| 3. **Deterministic Guidance**: Consistent, predictable results |
| 4. **Purpose Agnostic**: Works across all content domains |
| 5. **Modular Foundation**: Ready for specialized prompt layering |
| |
| ## Extended Ecosystem |
| |
| This basic cleanup prompt is part of a larger ecosystem: |
| - **Hundreds of specialized prompts** available in shared libraries |
| - **Domain-specific transformations** for various use cases |
| - **Concatenation-ready design** for complex workflows |
| - **Shared on Hugging Face** and other platforms |
| |
| ## System Prompt |
| |
| The tool uses a carefully crafted system prompt (Version 3, September 2025) that balances cleanup effectiveness with content preservation. View the complete prompt using the "Show System Prompt" feature in the interface. |
| """ |
|
|
| def cleanup_transcript(text, api_key): |
| """Clean up STT transcript using OpenAI API""" |
| if not text.strip(): |
| return "Please provide text to clean up." |
| |
| if not api_key.strip(): |
| return "Please provide your OpenAI API key." |
| |
| try: |
| client = OpenAI(api_key=api_key) |
| |
| response = client.chat.completions.create( |
| model="gpt-4o-mini", |
| messages=[ |
| {"role": "system", "content": SYSTEM_PROMPT_CONTENT}, |
| {"role": "user", "content": text} |
| ], |
| temperature=0.3, |
| max_tokens=4000 |
| ) |
| |
| cleaned_text = response.choices[0].message.content |
| return cleaned_text |
| |
| except Exception as e: |
| return f"Error: {str(e)}" |
|
|
| def copy_to_clipboard_js(): |
| """JavaScript function to copy text to clipboard""" |
| return """ |
| function copyToClipboard(text) { |
| navigator.clipboard.writeText(text).then(function() { |
| // You could add a toast notification here |
| }); |
| } |
| """ |
|
|
| |
| with gr.Blocks( |
| title="STT Transcript Cleanup Tool", |
| theme=gr.themes.Soft(), |
| css=""" |
| .main-header { |
| text-align: center; |
| margin-bottom: 2rem; |
| } |
| .attribution { |
| text-align: center; |
| margin-top: 2rem; |
| padding: 1rem; |
| background-color: #f8f9fa; |
| border-radius: 8px; |
| } |
| """ |
| ) as demo: |
| |
| gr.HTML(""" |
| <div class="main-header"> |
| <h1>🎤 STT Transcript Cleanup Tool</h1> |
| <p>Clean up speech-to-text transcripts by removing filler words, adding punctuation, and improving readability.</p> |
| <p><strong>Note:</strong> This tool requires your own OpenAI API key (BYOK - Bring Your Own Key)</p> |
| </div> |
| """) |
| |
| with gr.Tabs(): |
| with gr.TabItem("Cleanup Tool"): |
| with gr.Row(): |
| with gr.Column(): |
| api_key_input = gr.Textbox( |
| label="OpenAI API Key", |
| placeholder="sk-...", |
| type="password", |
| info="Your API key is not stored and only used for this session" |
| ) |
| |
| input_text = gr.Textbox( |
| label="Raw STT Transcript", |
| placeholder="Paste your speech-to-text transcript here...", |
| lines=10, |
| max_lines=20 |
| ) |
| |
| with gr.Row(): |
| cleanup_btn = gr.Button("Clean Up Transcript", variant="primary") |
| clear_btn = gr.Button("Clear", variant="secondary") |
| |
| with gr.Column(): |
| output_text = gr.Textbox( |
| label="Cleaned Transcript", |
| lines=10, |
| max_lines=20, |
| interactive=False |
| ) |
| |
| with gr.Row(): |
| copy_btn = gr.Button("Copy to Clipboard", variant="secondary") |
| rerun_btn = gr.Button("Run Again", variant="secondary") |
| |
| with gr.TabItem("System Prompt"): |
| gr.Markdown("## Current System Prompt") |
| gr.Markdown("This is the prompt used to instruct the AI on how to clean up your transcripts:") |
| gr.Code(SYSTEM_PROMPT_CONTENT, language="markdown", label="system-prompt.md") |
| |
| with gr.TabItem("About"): |
| gr.Markdown(README_CONTENT) |
| |
| |
| cleanup_btn.click( |
| fn=cleanup_transcript, |
| inputs=[input_text, api_key_input], |
| outputs=output_text |
| ) |
| |
| rerun_btn.click( |
| fn=cleanup_transcript, |
| inputs=[input_text, api_key_input], |
| outputs=output_text |
| ) |
| |
| clear_btn.click( |
| fn=lambda: ("", ""), |
| outputs=[input_text, output_text] |
| ) |
| |
| |
| copy_btn.click( |
| fn=None, |
| inputs=output_text, |
| outputs=None, |
| js="(text) => navigator.clipboard.writeText(text)" |
| ) |
| |
| |
| gr.HTML(""" |
| <div class="attribution"> |
| <p><strong>Created by:</strong> <a href="https://danielrosehill.com" target="_blank">Daniel Rosehill</a></p> |
| <p>This tool helps clean up speech-to-text transcripts by removing filler words, adding proper punctuation, |
| and improving overall readability while preserving the original meaning and important details.</p> |
| </div> |
| """) |
|
|
| if __name__ == "__main__": |
| demo.launch() |
|
|